"use client"; import { ChevronDown, KeyRound, Loader2, LogOut } from "lucide-react"; import { useRouter } from "next/navigation"; import { useState } from "react"; import { useTranslation } from "react-i18next"; import { toast } from "sonner"; import { putPlayerPassword } from "@/api/player-auth"; import { Avatar, AvatarFallback } from "@/components/ui/avatar"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Field, FieldDescription, FieldGroup, FieldLabel } from "@/components/ui/field"; import { Input } from "@/components/ui/input"; import { Separator } from "@/components/ui/separator"; import { validatePlayerLoginPassword } from "@/lib/player-input-validation"; import { usePlayerSessionStore } from "@/stores/player-session-store"; import { LotteryApiBizError } from "@/types/api/errors"; type AccountView = "profile" | "password"; function ProfileRow({ label, value }: { label: string; value: string }) { return (
{label}
{value}
); } function accountInitial(value: string): string { const trimmed = value.trim(); return trimmed === "" ? "P" : trimmed.slice(0, 1).toUpperCase(); } export function PlayerAccountDialog() { const { t } = useTranslation("player"); const router = useRouter(); const profile = usePlayerSessionStore((state) => state.profile); const clearBearerToken = usePlayerSessionStore((state) => state.clearBearerToken); const [open, setOpen] = useState(false); const [view, setView] = useState("profile"); const [currentPassword, setCurrentPassword] = useState(""); const [newPassword, setNewPassword] = useState(""); const [confirmPassword, setConfirmPassword] = useState(""); const [saving, setSaving] = useState(false); const displayName = profile?.nickname?.trim() || profile?.username?.trim() || (profile?.id != null ? t("player.fallback", { id: profile.id }) : t("account.loading")); const isNative = profile?.auth_source === "lottery_native"; function resetPasswordForm() { setCurrentPassword(""); setNewPassword(""); setConfirmPassword(""); } function handleOpenChange(nextOpen: boolean) { setOpen(nextOpen); if (!nextOpen) { setView("profile"); resetPasswordForm(); } } function handleLogout() { handleOpenChange(false); clearBearerToken(); router.replace("/login"); } async function handlePasswordSubmit(event: React.FormEvent) { event.preventDefault(); if (currentPassword === "" || newPassword === "" || confirmPassword === "") { toast.error(t("account.password.required")); return; } if (validatePlayerLoginPassword(newPassword) === "too_short") { toast.error(t("account.password.tooShort")); return; } if (newPassword !== confirmPassword) { toast.error(t("account.password.mismatch")); return; } if (newPassword === currentPassword) { toast.error(t("account.password.mustDiffer")); return; } setSaving(true); try { await putPlayerPassword({ current_password: currentPassword, password: newPassword, password_confirmation: confirmPassword, }); handleOpenChange(false); clearBearerToken(); router.replace("/login?password=changed"); } catch (error) { toast.error( error instanceof LotteryApiBizError ? error.message : t("account.password.failed"), ); } finally { setSaving(false); } } return ( <> {view === "profile" ? ( <> {t("account.title")} {t("account.description")}
{accountInitial(displayName)}
{displayName} {profile?.username || profile?.site_player_id || "—"}
{isNative ? t("account.auth.native") : t("account.auth.sso")} {profile?.funding_mode === "credit" ? t("account.funding.credit") : t("account.funding.wallet")}
{!isNative ? (

{t("account.ssoManaged")}

) : null} {isNative ? ( ) : null} ) : (
{t("account.password.title")} {t("account.password.description")} {t("account.password.current")} setCurrentPassword(event.target.value)} /> {t("account.password.new")} setNewPassword(event.target.value)} /> {t("account.password.hint")} {t("account.password.confirm")} setConfirmPassword(event.target.value)} />
)}
); }