import { ActionButton, Avatar, Surface, TextField, } from "@agent-native/toolkit/design-system"; import { IconCamera, IconCheck } from "@tabler/icons-react"; import { useEffect, useRef, useState, type ChangeEvent } from "react"; import type { UserProfile } from "../../user-profile/shared.js"; import { useT } from "../i18n.js"; import { useActionMutation, useActionQuery } from "../use-action.js"; import { uploadAvatar, useAvatarUrl } from "../use-avatar.js"; import { useSession } from "../use-session.js"; import { cn } from "../utils.js"; function profileInitials(name: string): string { return ( name .split(/[ @._-]+/) .filter(Boolean) .slice(0, 2) .map((part) => part[0]?.toUpperCase()) .join("") || "?" ); } export interface AccountSettingsFormProps { compact?: boolean; } export function AccountSettingsForm({ compact = false, }: AccountSettingsFormProps) { const t = useT(); const { session, isLoading } = useSession(); const email = session?.email; const profileQuery = useActionQuery( "get-user-profile", undefined, { enabled: !!email }, ); const updateProfile = useActionMutation( "update-user-profile", ); const avatarUrl = useAvatarUrl(email); const fileInputRef = useRef(null); const [uploading, setUploading] = useState(false); const [photoStatus, setPhotoStatus] = useState<"idle" | "saved" | "error">( "idle", ); const [name, setName] = useState(""); const displayName = profileQuery.data?.name || session?.name || email || t("settings.profileSignedOut"); useEffect(() => { const nextName = profileQuery.data?.name || session?.name; if (nextName) setName(nextName); }, [profileQuery.data?.name, session?.name]); const handleAvatarChange = async (event: ChangeEvent) => { const file = event.target.files?.[0]; event.target.value = ""; if (!file || !email) return; setUploading(true); setPhotoStatus("idle"); try { await uploadAvatar(file, email); setPhotoStatus("saved"); } catch { setPhotoStatus("error"); } finally { setUploading(false); } }; const handleProfileSave = () => { const nextName = name.trim(); if (!nextName || !email) return; updateProfile.mutate({ name: nextName }); }; return (

{isLoading ? t("settings.profileLoading") : displayName}

{email && (

{email}

)} {photoStatus === "saved" && (

{t("settings.profilePhotoUpdated")}

)} {photoStatus === "error" && (

{t("settings.profilePhotoError")}

)}
} onPress={() => fileInputRef.current?.click()} className="shrink-0" > {uploading ? t("settings.profileUploading") : t("settings.profileChangePhoto")}
{ updateProfile.reset(); setName(value); }} placeholder={t("settings.profileNamePlaceholder")} description={t("settings.profileNameDescription")} disabled={!email || profileQuery.isLoading || updateProfile.isPending} />
{updateProfile.isSuccess && (

{t("settings.profileSaved")}

)} {updateProfile.error && (

{t("settings.profileSaveError")}

)}
{updateProfile.isPending ? t("settings.profileSaving") : t("settings.profileSave")}
); } export interface AccountSettingsCardProps { className?: string; } export function AccountSettingsCard({ className }: AccountSettingsCardProps) { const t = useT(); return (

{t("settings.profileTitle")}

{t("settings.profileDescription")}

); }