import { useState, useEffect } from "react"; import type { UserProfile } from "@/types/nostrill"; import useLocalState from "@/state/state"; import Icon from "@/components/Icon"; import toast from "react-hot-toast"; import Avatar from "./Avatar"; interface ProfileEditorProps { ship: string; onSave?: () => void; } const ProfileEditor: React.FC = ({ ship, onSave }) => { const { api, profiles } = useLocalState((s) => ({ api: s.api, profiles: s.profiles, })); const isOwnProfile = ship === api?.airlock.our; // Initialize state with existing profile or defaults const existingProfile = profiles.get(ship); const [name, setName] = useState(existingProfile?.name || ""); const [picture, setPicture] = useState(existingProfile?.picture || ""); const [about, setAbout] = useState(existingProfile?.about || ""); const [customFields, setCustomFields] = useState< Array<{ key: string; value: string }> >( Object.entries(existingProfile?.other || {}).map(([key, value]) => ({ key, value, })), ); const [isEditing, setIsEditing] = useState(false); const [isSaving, setIsSaving] = useState(false); useEffect(() => { const profile = profiles.get(ship); if (profile) { setName(profile.name || ""); setPicture(profile.picture || ""); setAbout(profile.about || ""); setCustomFields( Object.entries(profile.other || {}).map(([key, value]) => ({ key, value, })), ); } }, [ship, profiles]); const handleAddCustomField = () => { setCustomFields([...customFields, { key: "", value: "" }]); }; const handleUpdateCustomField = ( index: number, field: "key" | "value", newValue: string, ) => { const updated = [...customFields]; updated[index][field] = newValue; setCustomFields(updated); }; const handleRemoveCustomField = (index: number) => { setCustomFields(customFields.filter((_, i) => i !== index)); }; const handleSave = async () => { setIsSaving(true); try { // Convert custom fields array to object const other: Record = {}; customFields.forEach(({ key, value }) => { if (key.trim()) { other[key.trim()] = value; } }); const profile: UserProfile = { name, picture, about, other, }; // Call API to save profile if (api && typeof api.createProfile === "function") { await api.createProfile(profile); } else { throw new Error("Profile update API not available"); } toast.success("Profile updated successfully"); setIsEditing(false); onSave?.(); } catch (error) { toast.error("Failed to update profile"); console.error("Failed to save profile:", error); } finally { setIsSaving(false); } }; const handleCancel = () => { // Reset to original values const profile = profiles.get(ship); if (profile) { setName(profile.name || ""); setPicture(profile.picture || ""); setAbout(profile.about || ""); setCustomFields( Object.entries(profile.other || {}).map(([key, value]) => ({ key, value, })), ); } setIsEditing(false); }; if (!isOwnProfile) { // View-only mode for other users' profiles - no editing allowed return (

{name || ship}

{about &&

{about}

} {customFields.length > 0 && (

Additional Info

{customFields.map(({ key, value }, index) => (
{key}: {value}
))}
)}
); } return (

Edit Profile

{isOwnProfile && !isEditing && ( )}
{isEditing ? (
setName(e.target.value)} placeholder="Your display name" />
setPicture(e.target.value)} placeholder="https://example.com/avatar.jpg" />