From ed3084e60fd7ba992aace54a5d892f4869dbf594 Mon Sep 17 00:00:00 2001 From: ZGaetano Date: Fri, 22 May 2026 08:17:06 -0400 Subject: [PATCH] =?UTF-8?q?feat(ui):=20Dragonflight=20redesign=20=E2=80=94?= =?UTF-8?q?=20screen=20components=20batch=201:=20screens-projects.jsx?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/web-ui/public/screens-projects.jsx | 98 +++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 services/web-ui/public/screens-projects.jsx diff --git a/services/web-ui/public/screens-projects.jsx b/services/web-ui/public/screens-projects.jsx new file mode 100644 index 0000000..4cf4f88 --- /dev/null +++ b/services/web-ui/public/screens-projects.jsx @@ -0,0 +1,98 @@ +// screens-projects.jsx — projects browse + project detail + +const { PROJECTS: ALL_PROJECTS, ASSETS } = window.ZAMPP_DATA; + +function Projects({ onOpenProject, navigate }) { + const [search, setSearch] = React.useState(""); + const [view, setView] = React.useState("grid"); + let projects = ALL_PROJECTS; + if (search) projects = projects.filter(p => p.name.toLowerCase().includes(search.toLowerCase())); + + return ( +
+
+

Projects

+ {projects.length} projects +
+
+ + setSearch(e.target.value)} placeholder="Search projects…" /> +
+
+ + +
+ +
+
+ {view === "grid" ? ( +
+ {projects.map(p => onOpenProject(p)} />)} +
+ ) : ( +
+
+
Project
+
Assets
+
Storage
+
Updated
+
Members
+
+
+ {projects.map(p => ( +
onOpenProject(p)}> +
+
+
{p.name}
+
+
{p.assets}
+
{(p.assets * 1.8).toFixed(1)} GB
+
{p.updated}
+
+ {["KM", "ZG", "JT"].slice(0, 3).map((a, i) => ( +
0 ? -6 : 0, background: avatarColor(a), border: "2px solid var(--bg-1)" }}>{a}
+ ))} +
+ +
+ ))} +
+ )} +
+
+ ); +} + +function ProjectCard({ project, onOpen }) { + const thumbs = ASSETS.slice(0, project.thumbs || 4); + return ( +
+
+ {thumbs.map((a, i) => ( +
+ +
+
+ ))} +
+
+
+ + {project.name} +
+
+ {project.assets} assets + · + updated {project.updated} +
+
+
+
+
+
+
+
+ ); +} + +window.Projects = Projects;