"use client"; import { PrototypeGalleryHeader, PrototypeGalleryPageLayout, } from "@prototype/components/shell/prototype-gallery-shell"; import { PrototypeSettingsProfileModal } from "@prototype/components/shell/prototype-settings-profile-modal"; import { PrototypeSettingsSourceModal } from "@prototype/components/shell/prototype-settings-source-modal"; import { Button } from "@prototype/components/ui/button"; import { Label } from "@prototype/components/ui/label"; import { formatSourceDirectoryName } from "@prototype/lib/format-source-directory-name"; import { usePersistedLocalString } from "@prototype/lib/prototypes/use-persisted-local-state"; import { cn } from "@prototype/lib/utils"; import { useEffect, useState, type ReactNode } from "react"; export type PrototypeSettingsPageProps = { sourceDirectoryName?: string; sourcePath?: string; userName?: string; }; const DEFAULT_SOURCE_DESCRIPTION = "The product codebase prototypes are built from."; const PROFILE_STORAGE_KEYS = { sourceName: "prototype-profile:source-name", sourceDescription: "prototype-profile:source-description", } as const; const SETTINGS_READ_ONLY_FIELD_CLASS = "rounded-md border border-[var(--tool-chrome-border)]/70 bg-muted/20 px-3 py-2 text-sm leading-relaxed"; function SettingsReadOnlyField({ id, label, description, value, placeholder, monospace = false, }: { id: string; label: string; description?: string; value: string; placeholder: string; monospace?: boolean; }) { const hintId = description ? `${id}-hint` : undefined; const trimmedValue = value.trim(); return (
{description ? (

{description}

) : null}
{trimmedValue || placeholder}
); } function SettingsSection({ title, onEdit, children, }: { title: string; onEdit: () => void; children: ReactNode; }) { return (

{title}

{children}
); } export function PrototypeSettingsPage({ sourceDirectoryName, sourcePath, userName: initialUserName = "", }: PrototypeSettingsPageProps) { const [profileModalOpen, setProfileModalOpen] = useState(false); const [sourceModalOpen, setSourceModalOpen] = useState(false); const [userName, setUserName] = useState(initialUserName); const resolvedPath = sourcePath?.trim() ?? ""; const linkedSourceName = sourceDirectoryName?.trim() ?? formatSourceDirectoryName(resolvedPath) ?? ""; const hasSource = Boolean(resolvedPath); useEffect(() => { setUserName(initialUserName); }, [initialUserName]); const { value: persistedSourceName, updateValue: setSourceName } = usePersistedLocalString(PROFILE_STORAGE_KEYS.sourceName, linkedSourceName); const displayedSourceName = hasSource ? linkedSourceName : persistedSourceName; const { value: sourceDescription, updateValue: setSourceDescription } = usePersistedLocalString( PROFILE_STORAGE_KEYS.sourceDescription, DEFAULT_SOURCE_DESCRIPTION, ); return ( <> } >
setProfileModalOpen(true)} > setSourceModalOpen(true)} > {hasSource ? ( ) : ( )}
{ setUserName(nextUserName); }} /> { setSourceName(nextSourceName); setSourceDescription(nextSourceDescription); }} /> ); }