
UNIT PROJECTS SECTION — COMPLETE REFERENCE (v3.x codebase) 1...
Prompt
UNIT PROJECTS SECTION — COMPLETE REFERENCE (v3.x codebase) 1. File Map File Role resources/app/src/components/UnitProjectView.jsx The entire section (1,795 lines, single self-contained component) resources/app/src/App.jsx Tab registration, lazy-load, error boundary wrapper resources/app/src/components/PersonaView.jsx Reads the same unit_projects data — shows a portfolio strip, has its own project edit form + "View Showcase" deep-link resources/app/src/components/TodoView.jsx Writes to unit_projects — converts "Keep Eye On" reminders into projects resources/app/src/components/ViewErrorBoundary.jsx Crash recovery (name="UnitProjectView", owns key 'unit_projects') resources/app/src/components/BusinessView.jsx Auto-prunes a legacy 'unitproject' sector from its own data (unrelated, but touches the name) resources/app/src/index.css Only 1 shared rule for the tab; everything else is inline styles + shared classes Important: there is no dedicated CSS file for this section. Styling = inline style={{}} objects + a small inline <style> block injected inside the JSX + generic shared classes (glass-panel, modal-overlay, form-input, btn-primary). 2. Data Model & State Single source of truth — localStorage key unit_projects, via the component's own local usePersistentState hook (same pattern as App.jsx: lazy-init from localStorage with JSON.parse + try/catch, write on every change with functional-update support). Seeded default (DEFAULT_PROJECTS constant): js Copy { id: 'staff_project', name: 'Staff Workspace', status: 'success', imageUrl: 'https://images.unsplash.com/photo-1531403009284-440f080d1e12?...', details, keywords: [...], idea, briefing, tools: [...], location: 'd:/Personal/Staff-win32-x64', versions: [ {id, versionNumber: 'v1.0'…'v3.0', date, details, status} ] } Full project object shape (created in handleSaveProject): js Copy { id: 'proj_' + Date.now(), name, status, details, imageUrl, keywords: [], // string array (split from comma input) idea, briefing, tools: [], location, versions: [], // { id: 'ver_'+ts, versionNumber, date, details, status } tasks: [], // { id: 'task_'+ts, text, completed: bool } links: [] // { id: 'link_'+ts, label, url } } pinned: boolean is added/removed at runtime by the pin toggle (not in the create shape). Auto-migration effect: on every projects change, each project missing versions/tasks/links/location/imageUrl gets those fields added and the list re-persisted. Props: only gainExp (function to award XP). Rendered in App.jsx ~3199: jsx Copy {activeTab === 'unitprojects' && ( <ViewErrorBoundary name="UnitProjectView" label="Unit Projects section crashed"> <UnitProjectView gainExp={gainExp} /> </ViewErrorBoundary> )} Tab config (App.jsx ~1052): { id: 'unitprojects', label: 'Unit Project', icon: 'FolderGit2', emoji: '📂', color: '#ec4899' } — icon is FolderGit2 in most themes, Folder in extern_os. Lazy-loaded at line 33. CSS: .app-container[data-active-tab=unitprojects] sets --section-accent:#ffffff + --section-accent-soft. Component-local state (~25 useState hooks): projects, searchQuery, statusFilter, isAddingProject, editingProject, showcaseProjectId, lightboxImageUrl, plus form states: formName/Status/Details/Keywords/ImageUrl/Idea/Briefing/Location, formVersions, editingVersionId, newVersionNum/Date/Details/Status, formTasks, newTaskText, editingTaskId, formLinks, newLinkLabel/Url, editingLinkId. 3. Layout / HTML Structure (top to bottom) text Copy <div flex column, gap 10, height 100%, relative> ├─ <style> block — component-scoped CSS for .project-card* classes │ ├─ SHOWCASE MODE (absolute, inset 0, zIndex 100, glass-panel) — shown when showcaseProjectId set │ └─ Header: Award icon box (status-colored) · Title (22px/900) + status pill · "Press Esc to return" │ Buttons: [⚡ Copy Briefing Report(green btn-primary)] [✏ Edit Project] [← Exit Showcase] │ └─ Body (flex row, gap 32): │ ├─ Left col (flex 1.2, scroll): │ │ image 220px (click → lightbox), Project Narrative card, │ │ Workspace Path chip (amber, click → open folder), Reference Links (blue pills, <a>), │ │ 2-col grid: "Technologies & Techniques" + "Final Briefing", │ │ Keywords "#tags" row │ └─ Right col (flex 0.9, dark panel): │ ├─ Checklist: ListTodo icon · "Project Tasks & Checklist" · "n/m DONE" badge · │ │ thin progress bar · task rows (click to toggle done, checkbox + strikethrough) │ └─ Timeline: History icon (pink) · "Version Release Timeline" · "n UPDATES" badge · │ dashed vertical line (repeating-linear-gradient pink) · version dots (glowing 8px circles) │ · version number/date/status-pill/details │ ├─ METRICS ROW (grid auto-fit minmax 180px) — 4 glass-panels, each borderLeft 3px + icon box: │ Total Projects (#6b7280 gray) · Completed/Success (#10b981) · Pending (#3b82f6) · Total Failures (#ef4444) │ ├─ CONTROL BAR: [🔍 Search input (name/details/location/tools…) + X clear] · │ [Status select: All/Success/In Progress/Failure/Ignored] · [+ Initialize Project (btn-primary)] │ ├─ PORTFOLIO GRID (flex 1, scroll, grid auto-fill minmax(380px, 1fr), gap 16): │ └─ Cards (glass-panel.project-card, border = status color, status glow shadow): │ ├─ Image (190px, hover scale(1.08), click → lightbox; onError hides container) │ ├─ Header: name (17px/800) · status pill + "vX.X Active" pill (pink) · │ │ actions row: [Pin(amber)] [Copy Briefing(green)] [Fullscreen(pink)] [Edit(blue)] [Trash(red)] │ ├─ Content: "Overview Description" · folder pill (amber Folder icon + last path segment, │ │ click → open directory) · Checklist Progress block (blue left border, "n / m Done" + bar) · │ │ Latest Update Milestone block (pink left border: vX.X (date) + details) · keyword tags │ └─ Empty state: dashed border "No projects documented matching the selected query." │ ├─ EDITOR MODAL (isAddingProject || editingProject) — modal-overlay > glass-panel-dark.modal-content │ (maxWidth 1100px, 90vw, 88vh, flex column): │ └─ Header: "Initialize Project Workspace" / "Edit Project Structure" + X close │ └─ <form> (scroll body + sticky footer): │ Name* + Outcome Status select (pending/success/failure/ignored) │ Keywords (comma) + Local Directory Location │ Showcase Image: URL input (paste image supported, disabled when data-URI) + "Upload File" │ (hidden <input type=file accept=image/*>) + preview thumb 120x70 + Remove Image │ Details textarea · Technologies textarea + Final Briefing textarea (2-col grid) │ Tasks sub-form (blue): input + Add/Save · checklist rows with checkbox/edit/X │ Links sub-form (green): Label + URL inputs + Add Link · link rows with edit/X │ Version Timeline sub-form (pink): version num + date + status select + details + Add/Update/Cancel · │ list rows with edit/X │ └─ Footer: [Cancel] [Save Project Workspace] │ └─ LIGHTBOX MODAL (zIndex 1000, dark blur bg): X Close button + img object-fit contain, max 90vh 4. Core Logic usePersistentState(key, initial) — local copy: lazy init + setPersistState that supports functional updates and writes JSON to localStorage synchronously. Stats (useMemo): total, completed (status==='success'), pending, failures, ignoredOrFailed (ignored ∪ failure). Filtering + sorting (filteredProjects useMemo): Status filter: statusFilter === 'all' || p.status === statusFilter Search (lowercased, OR across): name, details, idea, briefing, location, any keyword, any tool Sort order: pinned first → status weight (pending=1, success=2, else 3) → newest created (parseInt(id.replace('proj_','')) desc; staff_project = 0) → alphabetical by name. getStatusStyle(status) — the section's color system: status label color success Success / Completed #10b981 green pending In Progress / Pending #3b82f6 blue failure Failure #ef4444 red ignored Ignored #8b5cf6 purple default Unknown #6b7280 gray Each returns {label, color, bg: color+0.08 alpha, border: +0.2, glow: '0 0 15px color+0.06'}. Image pipeline (processImageFile): FileReader → new Image() → downscale to max 800px (preserving ratio) → canvas → toDataURL('image/jpeg', 0.7) → set formImageUrl + fires show-toast. Paste support via handlePasteImage (reads clipboardData.items, getAsFile()). Open directory (handleOpenDirectory): 1) copy path to clipboard, 2) fire show-toast "Path copied to clipboard! Opening folder explorer...", 3) window.require('electron').shell.openPath(path) with error fallback + browser-env try/catch. Copy Markdown Briefing (handleCopyMarkdownBriefing): builds a markdown report (# Project Briefing, Status + task ratio, Local Path, 📌 Overview, 🛠️ Technologies & Scope, 📝 Final Briefing, 📋 Project Checklist with - [x]/- [ ], 🔗 Reference Links, 🕒 Release Timeline) → clipboard → toast (success/failure variants). Save (handleSaveProject): New: id: 'proj_' + Date.now(), prepends to list, awards gainExp(1000) if status is 'success'. Edit: maps fields (keeps tools), awards +1000 XP on transition to success, -1000 on transition away from success. Delete (handleDeleteProject): window.showConfirm("Delete Project", ...) → removes; gainExp(-1000) if the deleted project was success; also clears editingProject/showcaseProjectId if it pointed at the deleted one. e.stopPropagation() guards card actions. Version managers: handleAddVersion — edit mode (by editingVersionId) maps+updates, else appends {id:'ver_'+Date.now(), ...}; both re-sort the array with b.versionNumber.localeCompare(a.versionNumber) (descending, so versions[0] = latest). Default date = getTodayStrPK() (from ../utils/timezone). handleRemoveVersion clears edit state if needed. Task managers: handleAddTask (add or edit-in-place via editingTaskId, ids task_+ts), handleToggleTaskForm (checkbox), handleRemoveTask, handleStartEditTask. Link managers: same pattern, ids link_+ts; requires both label & URL. Showcase task toggle (handleToggleProjectTaskShowcase): toggles completed on a task directly in the persisted project (not the form copy) — so checklist progress in showcase mode saves instantly. Cross-tab events: Listens for open-project-showcase (detail {projectId}) → opens showcase directly (used by PersonaView deep-link). Escape key closes the showcase. 5. PersonaView & TodoView Integration (shared data!) PersonaView reads the same unit_projects key: portfolioProjects useMemo (identical pin/status/newest sorting) + completedProjectsCount (status includes success/completed/done) + its own edit modal (handleSaveProjectFromPersona — note: saves versions but NOT tasks/links into the project, so editing via Persona can drop checklist/link data that UnitProjectView's modal preserves) + handleViewShowcase(projId) → dispatches navigate-tab {tab:'unitprojects'} then open-project-showcase {projectId} after 120ms. TodoView convertReminderToProjectTask (Keep Eye On → project): reads/writes unit_projects directly via localStorage, creating a status:'success' project named after the reminder with details "Completed from Keep Eye On reminders". 6. CSS Reference Inline <style> block (scoped via the component, uses !important to override the shared .glass-panel rules): .project-card transition, .project-card-header (bottom border + faint bg), .project-card-image-container (max-height 190px, border-bottom, img {height:190px; object-fit:cover}, :hover img {transform:scale(1.08)}), .project-card-content (max-height 2000px, padding 20px 22px), .project-card-actions (opacity 1, translateX 0, button {padding:8px}). Shared classes used: glass-panel / glass-panel-dark (frosted: blur(40px) saturate(180%), radius-xl, shadow-lg + top gradient overlay), modal-overlay (fixed inset 0, blur 16px, z-index 1100, overlay-fade-in), modal-content (500px default but overridden to 1100px inline; modal-pop-in spring animation), modal-title, modal-close (rotates 90° on hover), form-group (uppercase 10px labels), form-input (dark inset, focus glow + lift), btn-primary (accent, shine sweep, hover lift/glow), modal-header (overridden — header uses inline flex instead). Hard-coded palette: blue #3b82f6 (pending, links, checklist), green #10b981 (success, copy), red #ef4444 (failure, delete), pink #ec4899 (timeline/versions/fullscreen), amber #f59e0b (pin, folder path), gray #6b7280 (total). Card hover: translateY(-3px) + boxShadow: 0 10px 20px ${status.border}. Icons (lucide-react): Plus, Search, Trash2, Edit2, ShieldAlert, CheckCircle, Clock, Pin, Ban, Briefcase, ListTodo, Wrench, X, Tag, Calendar, Play, History, ArrowLeft, Maximize2, Zap, Award, Layers, Folder, FolderOpen. (Note: Ban, Calendar, Play, Wrench are imported but not visibly used in the rendered JSX.) 7. Error Recovery ViewErrorBoundary maps UnitProjectView → ['unit_projects'] — resets only that key if the section crashes. Red error panel + "Retry" button; error also logged to window.__viewErrors and localStorage['staff_view_error']. 8. Quick Facts / Gotchas (for your discussion) Three places write unit_projects: UnitProjectView (full CRUD), TodoView (creates success projects from reminders), PersonaView (edits projects but drops tasks/links on save — a real data-loss risk). XP economy: +1000 when a project becomes/arrives as success, −1000 when it leaves success or a success project is deleted. No XP for pending/failure. Versions sort is string-based (localeCompare) — "v10.0" would sort before "v2.0". Pinned flag isn't in the create payload — it only exists on already-pinned items; sorting treats missing pinned as falsy. Search does NOT cover versions, tasks, links — only name/details/idea/briefing/location/keywords/tools. The showcase panel is position:absolute; inset:0; zIndex:100 inside the view — it does not cover the whole window, just the section area. staff_project (the seed) is deliberately weighted to sort last among same-status projects (id timestamp 0). Image input is disabled once a data-URI is set (you must "Remove Image" to type a URL again). No explicit "copy project" / "duplicate" feature, and no drag-and-drop reordering — ordering is automatic. appSettings-driven CSS variables + dark-only styling: hard-coded white text on cards assumes the dark theme (matching the rest of the app). I want you to change the design of unit project section, Change the design and a to z everything about unit project section. improve it to its best of abilities.