import { useEffect, useState } from "react" import { Check, Trash2 } from "lucide-react" import { AppShell } from "~/components/layout/app-shell" import { Avatar, AvatarFallback, AvatarImage } from "~/components/ui/avatar" import { Button } from "~/components/ui/button" import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "~/components/ui/card" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "~/components/ui/dropdown-menu" import { Input } from "~/components/ui/input" import { Textarea } from "~/components/ui/textarea" import { useAgents } from "~/lib/agents" import { pageTitle } from "~/lib/page-meta" import { DEFAULT_PROFILE, profileInitials, resetProfile, saveProfile, useProfile, type Profile, } from "~/lib/profile" export const meta = () => pageTitle("Profile") export default function ProfileRoute() { const profile = useProfile() const agents = useAgents() const [draft, setDraft] = useState(profile) const [savedAt, setSavedAt] = useState(null) useEffect(() => { setDraft(profile) }, [profile]) const dirty = JSON.stringify(draft) !== JSON.stringify(profile) const initials = profileInitials(draft.name || DEFAULT_PROFILE.name) const onPickAvatar = (file: File | null) => { if (!file) { setDraft((d) => ({ ...d, avatarUrl: "" })) return } const reader = new FileReader() reader.onload = () => { const result = reader.result if (typeof result === "string") setDraft((d) => ({ ...d, avatarUrl: result })) } reader.readAsDataURL(file) } const save = () => { saveProfile(draft) setSavedAt(Date.now()) } const defaultAgent = agents.find((a) => a.id === draft.defaultAgentId) ?? null return ( You Personal info shown across the app — appbar avatar, signatures, and anywhere the assistant references you.
{draft.avatarUrl ? ( ) : null} {initials}
{draft.avatarUrl && ( )} PNG, JPG, or SVG. Stored locally as a data URL.
setDraft((d) => ({ ...d, name: e.target.value })) } autoComplete="name" /> setDraft((d) => ({ ...d, email: e.target.value })) } autoComplete="email" /> setDraft((d) => ({ ...d, title: e.target.value })) } placeholder="e.g. Product designer" /> {defaultAgent ? ( <> {defaultAgent.name} {" "} — {defaultAgent.role} ) : ( "Use first available" )} setDraft((d) => ({ ...d, defaultAgentId: "" })) } data-state={!draft.defaultAgentId ? "checked" : undefined} > First available {agents.map((a) => ( setDraft((d) => ({ ...d, defaultAgentId: a.id })) } data-state={ draft.defaultAgentId === a.id ? "checked" : undefined } className="flex flex-col items-start" > {a.name} {a.role} ))}