// screens-projects.jsx
function NewProjectModal({ onClose, onCreated }) {
const [name, setName] = React.useState('');
const [saving, setSaving] = React.useState(false);
const [err, setErr] = React.useState(null);
const create = () => {
if (!name.trim()) { setErr('Name is required'); return; }
setSaving(true); setErr(null);
window.ZAMPP_API.fetch('/projects', { method: 'POST', body: JSON.stringify({ name: name.trim() }) })
.then(p => { onCreated(p); onClose(); })
.catch(e => { setSaving(false); setErr(e.message || 'Failed to create project'); });
};
return (
e.stopPropagation()}>
setName(e.target.value)}
placeholder="e.g. Sunday Night Game" autoFocus
onKeyDown={e => e.key === 'Enter' && !saving && create()} />
{err &&
{err}
}
);
}
function Projects({ onOpenProject, navigate }) {
const [projects, setProjects] = React.useState(window.ZAMPP_DATA.PROJECTS);
const { ASSETS } = window.ZAMPP_DATA;
const [search, setSearch] = React.useState('');
const [view, setView] = React.useState('grid');
const [showNew, setShowNew] = React.useState(false);
const onCreated = (p) => {
const updated = [p, ...window.ZAMPP_DATA.PROJECTS];
window.ZAMPP_DATA.PROJECTS = updated;
setProjects(updated);
};
let filtered = projects;
if (search) filtered = filtered.filter(p => p.name.toLowerCase().includes(search.toLowerCase()));
return (
Projects
{filtered.length} projects
setSearch(e.target.value)} placeholder="Search projects…" />
{filtered.length === 0 ? (
{search ? 'No matching projects.' : 'No projects yet.'}
{!search && (
)}
) : view === 'grid' ? (
{filtered.map(p =>
onOpenProject(p)} />)}
) : (
Project
Assets
Storage
Updated
{filtered.map(p => (
onOpenProject(p)}>
{p.assets || 0}
—
{p.updated || '—'}
))}
)}
{showNew &&
setShowNew(false)} onCreated={onCreated} />}
);
}
function ProjectCard({ project, assets, onOpen }) {
const thumbAssets = assets.filter(a => a.project_id === project.id).slice(0, 4);
return (
{Array.from({ length: 4 }).map((_, i) => (
))}
{project.name}
{project.assets || 0} assets
·
updated {project.updated || '—'}
);
}
window.Projects = Projects;