brackt/app/components/league/TimezonePromptBanner.tsx

73 lines
2.1 KiB
TypeScript
Raw Normal View History

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>
);
}