* Add overnight pause feature for draft timers Protects players from having their pick timer expire while asleep. Admins configure a nightly window (league-wide or per-user timezone); the timer freezes during that window while autodraft can still fire. Fixes #66 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Fix TS error: guard getUserDisplayName against undefined user Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
72 lines
2.1 KiB
TypeScript
72 lines
2.1 KiB
TypeScript
import { useState } from "react";
|
|
import { TIMEZONE_OPTIONS } from "~/components/league/TimezoneSelect";
|
|
|
|
const VALID_TIMEZONES = new Set(
|
|
TIMEZONE_OPTIONS.flatMap((g) => g.zones.map((z) => z.value))
|
|
);
|
|
|
|
interface TimezonePromptBannerProps {
|
|
/** Called with the saved timezone value after a successful POST. */
|
|
onSaved?: (timezone: string) => void;
|
|
}
|
|
|
|
export function TimezonePromptBanner({ onSaved }: TimezonePromptBannerProps) {
|
|
const [dismissed, setDismissed] = useState(false);
|
|
const [saving, setSaving] = useState(false);
|
|
const [saved, setSaved] = useState(false);
|
|
|
|
if (dismissed || saved) return null;
|
|
|
|
const detectedTz =
|
|
typeof window !== "undefined"
|
|
? (() => {
|
|
try {
|
|
const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
return VALID_TIMEZONES.has(tz) ? tz : null;
|
|
} catch {
|
|
return null;
|
|
}
|
|
})()
|
|
: null;
|
|
|
|
if (!detectedTz) return null;
|
|
|
|
const handleSave = async () => {
|
|
setSaving(true);
|
|
try {
|
|
const body = new FormData();
|
|
body.set("timezone", detectedTz);
|
|
const res = await fetch("/api/user/timezone", { method: "POST", body });
|
|
if (res.ok) {
|
|
setSaved(true);
|
|
onSaved?.(detectedTz);
|
|
}
|
|
} finally {
|
|
setSaving(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="flex items-center justify-between gap-3 px-4 py-2 bg-blue-950/40 border-b border-blue-800/40 text-sm text-blue-200">
|
|
<span>
|
|
Set your timezone to <strong>{detectedTz}</strong> for overnight pick
|
|
protection?
|
|
</span>
|
|
<div className="flex items-center gap-2 shrink-0">
|
|
<button
|
|
onClick={handleSave}
|
|
disabled={saving}
|
|
className="px-3 py-1 rounded bg-blue-700 hover:bg-blue-600 text-white text-xs font-medium disabled:opacity-50"
|
|
>
|
|
{saving ? "Saving…" : "Save"}
|
|
</button>
|
|
<button
|
|
onClick={() => setDismissed(true)}
|
|
className="text-blue-400 hover:text-blue-200 text-xs"
|
|
>
|
|
Dismiss
|
|
</button>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|