"use client" import { useState, useEffect } from "react" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { Label } from "@/components/ui/label" import { Switch } from "@/components/ui/switch" import { Input } from "@/components/ui/input" import { Textarea } from "@/components/ui/textarea" import { Button } from "@/components/ui/button" import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import { Separator } from "@/components/ui/separator" import { usePreferences } from "@/contexts/preferences-context" import { useAuth } from "@/contexts/auth-context" import { getApiUrl } from "@/lib/api-config" import { UserAvatar } from "@/components/ui/user-avatar" import { User, Palette, Bell, Eye, Shield, Sparkles, Check, ArrowLeft } from "lucide-react" import Link from "next/link" // Avatar color palette - Jewel Tones (Primary Set) const PRESET_COLORS = [ { value: "#0F4C81", name: "Sapphire" }, { value: "#9B111E", name: "Ruby" }, { value: "#50C878", name: "Emerald" }, { value: "#9966CC", name: "Amethyst" }, { value: "#0D98BA", name: "Topaz" }, { value: "#E0115F", name: "Rose Quartz" }, { value: "#082567", name: "Lapis" }, { value: "#FF7518", name: "Carnelian" }, { value: "#006B3C", name: "Jade" }, { value: "#1C1C1C", name: "Onyx" }, { value: "#E6E200", name: "Citrine" }, { value: "#702963", name: "Garnet" }, ] export default function SettingsPage() { const { preferences, updatePreferences, loading } = usePreferences() const { user, refreshUser } = useAuth() // Profile state const [bio, setBio] = useState("") const [username, setUsername] = useState("") const [profileSaving, setProfileSaving] = useState(false) const [profileSaved, setProfileSaved] = useState(false) // Avatar state const [avatarBgColor, setAvatarBgColor] = useState("#0F4C81") const [avatarText, setAvatarText] = useState("") const [avatarSaving, setAvatarSaving] = useState(false) const [avatarSaved, setAvatarSaved] = useState(false) const [avatarError, setAvatarError] = useState("") // Privacy state const [privacySettings, setPrivacySettings] = useState({ profile_public: true, show_attendance_public: true, appear_in_leaderboards: true }) useEffect(() => { if (user) { const extUser = user as any setBio(extUser.bio || "") setUsername(extUser.email?.split('@')[0] || "") setAvatarBgColor(extUser.avatar_bg_color || "#0F4C81") setAvatarText(extUser.avatar_text || "") setPrivacySettings({ profile_public: extUser.profile_public ?? true, show_attendance_public: extUser.show_attendance_public ?? true, appear_in_leaderboards: extUser.appear_in_leaderboards ?? true }) } }, [user]) const handleSaveProfile = async () => { setProfileSaving(true) setProfileSaved(false) const token = localStorage.getItem("token") try { await fetch(`${getApiUrl()}/users/me`, { method: "PATCH", headers: { "Content-Type": "application/json", "Authorization": `Bearer ${token}` }, body: JSON.stringify({ bio, username }) }) setProfileSaved(true) setTimeout(() => setProfileSaved(false), 2000) } catch (e) { console.error(e) } finally { setProfileSaving(false) } } const handleAvatarTextChange = (value: string) => { const cleaned = value.replace(/[^A-Za-z0-9]/g, '').slice(0, 3).toUpperCase() setAvatarText(cleaned) setAvatarError("") } const handleSaveAvatar = async () => { setAvatarSaving(true) setAvatarSaved(false) setAvatarError("") try { const token = localStorage.getItem("token") const res = await fetch(`${getApiUrl()}/users/me/avatar`, { method: "PATCH", headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}`, }, body: JSON.stringify({ bg_color: avatarBgColor, text: avatarText || null, }), }) if (!res.ok) { const data = await res.json() throw new Error(data.detail || "Failed to save") } setAvatarSaved(true) refreshUser?.() setTimeout(() => setAvatarSaved(false), 2000) } catch (e: any) { setAvatarError(e.message || "Failed to save avatar") } finally { setAvatarSaving(false) } } const handlePrivacyChange = async (key: string, value: boolean) => { // Optimistic update setPrivacySettings(prev => ({ ...prev, [key]: value })) try { const token = localStorage.getItem("token") await fetch(`${getApiUrl()}/users/me/privacy`, { method: "PATCH", headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}`, }, body: JSON.stringify({ [key]: value }), }) } catch (e) { // Revert on error setPrivacySettings(prev => ({ ...prev, [key]: !value })) console.error("Failed to update privacy setting:", e) } } if (loading) { return (
You need to be logged in to access settings.
Manage your account and preferences
This will be shown on your profile and comments
Leave empty to show first letter of username
{error}
)}Account deletion is permanent and cannot be undone.
{description}