import type { IconStyle } from "@sprint/shared"; import type { ReactNode } from "react"; import { useEffect, useState } from "react"; import { toast } from "sonner"; import { useAuthenticatedSession } from "@/components/session-provider"; import ThemeToggle from "@/components/theme-toggle"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; import { Field } from "@/components/ui/field"; import Icon from "@/components/ui/icon"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { UploadAvatar } from "@/components/upload-avatar"; import { useUpdateUser } from "@/lib/query/hooks"; import { parseError } from "@/lib/server"; import { cn } from "@/lib/utils"; function Account({ trigger }: { trigger?: ReactNode }) { const { user: currentUser, setUser } = useAuthenticatedSession(); const updateUser = useUpdateUser(); const [open, setOpen] = useState(false); const [name, setName] = useState(""); const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const [avatarURL, setAvatarUrl] = useState(null); const [iconPreference, setIconPreference] = useState("lucide"); const [error, setError] = useState(""); const [submitAttempted, setSubmitAttempted] = useState(false); useEffect(() => { if (!open) return; setName(currentUser.name); setUsername(currentUser.username); setAvatarUrl(currentUser.avatarURL || null); setIconPreference((currentUser.iconPreference as IconStyle) ?? "lucide"); setPassword(""); setError(""); setSubmitAttempted(false); }, [open, currentUser]); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setSubmitAttempted(true); if (name.trim() === "") { return; } try { const data = await updateUser.mutateAsync({ name: name.trim(), password: password.trim() || undefined, avatarURL, iconPreference, }); setError(""); setUser(data); setPassword(""); setOpen(false); toast.success("Account updated successfully", { dismissible: false, }); } catch (err) { const message = parseError(err as Error); setError(message); toast.error(`Error updating account: ${message}`, { dismissible: false, }); } }; return ( {trigger || ( )} Account
{avatarURL && ( )} setName(e.target.value)} validate={(v) => (v.trim() === "" ? "Cannot be empty" : undefined)} submitAttempted={submitAttempted} /> setPassword(e.target.value)} placeholder="Leave empty to keep current password" hidden={true} />
{error !== "" && }
); } export default Account;