// project.jsx — Project detail with tabs const { useState: useStateP } = React; const STATUS_OPTIONS = ["Ascending", "Holding", "Camp", "Summited", "Abandoned"]; // Brief toast shown after clipboard copy function Toast({ msg }) { return
{msg}
; } function ProjectDetail({ project, allProjects, notes, receipts, campFiles, onBack, onSwitch, onMarkWorked, onAddNote, onSave, onUploadReceipt, onUploadCampFile, onDeleteCampFile, onDeleteNote, currentUser }) { const [tab, setTab] = useStateP("overview"); const [switchOpen, setSwitchOpen] = useStateP(false); const [editingVision, setEditingVision] = useStateP(false); const [visionDraft, setVisionDraft] = useStateP(project.vision || ""); const [editingStatus, setEditingStatus] = useStateP(false); const [editingProgress, setEditingProgress] = useStateP(false); const [progressDraft, setProgressDraft] = useStateP(Math.round((project.progress || 0) * 100)); const [toast, setToast] = useStateP(null); const projectNotes = notes.filter(n => (n.project_id || n.projectId) === project.id); const projectReceipts = receipts.filter(r => (r.project_id || r.projectId) === project.id); const projectCampFiles = (campFiles || []).filter(f => f.project_id === project.id); const showToast = (msg) => { setToast(msg); setTimeout(() => setToast(null), 1500); }; const copyFolder = () => { navigator.clipboard.writeText(project.folder || "").then(() => showToast("Copied!")).catch(() => {}); }; const saveVision = () => { onSave({ vision: visionDraft }); setEditingVision(false); }; const saveStatus = (s) => { onSave({ status: s }); setEditingStatus(false); }; const saveProgress = () => { onSave({ progress: progressDraft / 100 }); setEditingProgress(false); }; const TABS = [ ["overview", "Overview"], ["docs", "Documents"], ["team", "Rope team"], ["timeline", "Route"], ["receipts", "Cache"], ["notes", "Field notes"], ["files", "Files"], ]; return ( <> {toast && }
{project.codename}

{project.name}

{/* Vision — inline editor */} {editingVision ? (