feat: add Input, Separator, Sheet, and Sidebar components

- Implemented Input component for user input fields.
- Created Separator component for visual separation in UI.
- Added Sheet component for modal-like overlays with customizable content.
- Developed Sidebar component with collapsible functionality and mobile responsiveness.
- Introduced Skeleton component for loading placeholders.
- Implemented Tooltip component for contextual hints.
- Updated global CSS variables for sidebar theming.
- Added useIsMobile hook for responsive design handling.
- Modified projects route to include ProjectSidebar.
- Enhanced Tailwind CSS configuration for improved styling.
- Updated Vite preload configuration for custom entry file naming.
This commit is contained in:
Roberto Musso
2026-02-19 18:44:13 +01:00
parent 30fde857f4
commit 1206a73db8
22 changed files with 3325 additions and 245 deletions

101
prd.json
View File

@@ -150,12 +150,13 @@
"title": "Client CRUD UI in Projects sidebar",
"description": "As a user, I want to create, rename, and delete Clients and Sub-Clients from the Projects sidebar so that I can mirror real-world corporate structures.",
"acceptanceCriteria": [
"'New Client' button at top of Projects sidebar creates a top-level client via clients.create tRPC mutation",
"Each client item has a context menu (right-click or kebab icon) with: Rename, New Sub-Client, Delete",
"Rename activates an inline editable field replacing the label; pressing Enter or blurring saves via clients.update",
"'New Client' button at top of Projects sidebar uses shadcn/ui Button component; creates a top-level client via clients.create tRPC mutation",
"Each client item has a context menu using shadcn/ui DropdownMenu (triggered by right-click or kebab icon) with items: Rename, New Sub-Client, Delete",
"Rename activates an inline editable field (shadcn/ui Input) replacing the label; pressing Enter or blurring saves via clients.update",
"'New Sub-Client' calls clients.create with parentId set to the selected client's id",
"Delete shows a confirmation dialog; if the client has children or projects, warns the user and offers cascade-delete option",
"Delete shows a shadcn/ui AlertDialog confirmation; if the client has children or projects, warns the user and offers cascade-delete option",
"Tree updates immediately after any mutation without full page reload",
"All interactive elements use shadcn/ui primitives: install via 'npx shadcn@latest add button input dropdown-menu alert-dialog' before implementing",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
@@ -168,15 +169,16 @@
"title": "Projects sidebar tree view and project CRUD UI",
"description": "As a user, I want to see all clients, sub-clients, and projects in a collapsible tree and manage projects from the Projects section.",
"acceptanceCriteria": [
"Tree renders hierarchy: Client (folder icon, bold) → Sub-Client (folder icon) → Project (circle icon)",
"Tree renders hierarchy: Client (folder icon, bold) → Sub-Client (folder icon) → Project (circle icon); use shadcn/ui Collapsible for expand/collapse nodes",
"Clients and sub-clients have expand/collapse chevrons that work independently",
"Search input at the top of the Projects sidebar filters the tree in real-time by name (client, sub-client, or project)",
"'+ New Project' button opens a dialog with: name input field + optional client dropdown (searchable, lists all clients)",
"Search input at the top of the Projects sidebar uses shadcn/ui Input (via SidebarInput from the sidebar component); filters the tree in real-time by name",
"'+ New Project' shadcn/ui Button opens a shadcn/ui Dialog with: shadcn/ui Input for name + shadcn/ui Select (searchable) for optional client",
"Projects with no client appear under 'Internal / No Client' group",
"Project context menu has: Edit (re-parent to different client), Archive/Unarchive, Delete",
"Archived projects hidden by default; a 'Show archived' toggle reveals them",
"Project context menu uses shadcn/ui DropdownMenu with items: Edit (re-parent to different client), Archive/Unarchive, Delete",
"Archived projects hidden by default; a shadcn/ui Switch or toggle reveals them",
"Clicking a project node loads the Project Detail panel in the right pane",
"Active project highlighted in tree",
"Install shadcn/ui components via 'npx shadcn@latest add collapsible dialog select switch' before implementing",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
@@ -189,14 +191,15 @@
"title": "Global Tasks view UI",
"description": "As a user, I want a global task list where I can create, filter, search, and update tasks across all projects in one place.",
"acceptanceCriteria": [
"4 stat cards at top: Total Tasks, To Do, In Progress, Completed — each with a Lucide icon and count, reactively updated via tasks.list queries",
"Search input filters tasks by title or description (case-insensitive, 300ms debounce)",
"Status filter tabs: All | To Do | In Progress | Completed — active tab highlighted",
"'Order by' dropdown: Due Date | Priority | Created Date",
"Task rows display: checkbox, title (bold 14px), description (muted 14px), priority chip (HIGH=red bg+up-arrow, MEDIUM=gray bg+right-arrow, LOW=green bg+down-arrow), due date chip (calendar icon + 'Due Mon DD'), breadcrumb (Client > Sub-Client > Project, chevron-separated), assignee (person icon + name)",
"4 stat cards using shadcn/ui Card (Card, CardHeader, CardTitle, CardContent) at top: Total Tasks, To Do, In Progress, Completed — each with a Lucide icon and count, reactively updated via tasks.list queries",
"Search uses shadcn/ui Input; filters tasks by title or description (case-insensitive, 300ms debounce)",
"Status filter uses shadcn/ui Tabs (Tabs, TabsList, TabsTrigger): All | To Do | In Progress | Completed",
"'Order by' uses shadcn/ui DropdownMenu: Due Date | Priority | Created Date",
"Task rows display: shadcn/ui Checkbox, title (bold 14px), description (muted 14px), priority chip using shadcn/ui Badge (HIGH=destructive variant, MEDIUM=secondary variant, LOW=outline variant with green), due date chip (calendar icon + 'Due Mon DD'), breadcrumb (Client > Sub-Client > Project, chevron-separated via shadcn/ui Breadcrumb if available), assignee (person icon + name)",
"Completed task rows have green-tinted background (#f0fdf4 or similar)",
"Clicking a checkbox calls tasks.update to set status='done' (or back to 'todo') immediately",
"'New Task' button opens a creation modal: title (required), description, priority (select), due date (date picker), project (optional searchable dropdown), assignee (optional text)",
"Clicking the shadcn/ui Checkbox calls tasks.update to set status='done' (or back to 'todo') immediately",
"'New Task' shadcn/ui Button opens a shadcn/ui Dialog modal: shadcn/ui Input for title (required), Textarea for description, Select for priority, Popover+Calendar for due date, Select for project (optional searchable), Input for assignee (optional)",
"Install shadcn/ui components via 'npx shadcn@latest add card tabs checkbox badge dialog textarea select popover calendar' before implementing",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
@@ -214,9 +217,10 @@
"Dot fill: dark (#171717) = isApproved=1 + status todo, green (#16a34a) = done/approved, dashed outline = isApproved=0 (pending AI suggestion)",
"A vertical 'Today' marker line rendered at the current date",
"Component uses ResizeObserver for responsive SVG width",
"Clicking a checkpoint dot opens a Popover with: title, formatted date, and a Delete button (calls checkpoints.delete)",
"Clicking a checkpoint dot opens a shadcn/ui Popover with: title, formatted date, and a shadcn/ui Button (variant=destructive, size=sm) for Delete (calls checkpoints.delete)",
"Global Timeline route (/timeline) renders GanttChart with all checkpoints from all projects, color-coded or grouped by project",
"'+ Add' button opens a dialog: title (required), date picker (required), project dropdown (required in global view)",
"'+ Add' shadcn/ui Button opens a shadcn/ui Dialog: shadcn/ui Input for title (required), Popover+Calendar for date picker (required), Select for project dropdown (required in global view)",
"Install shadcn/ui components via 'npx shadcn@latest add popover calendar' before implementing (button, dialog, input, select already installed)",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
@@ -230,11 +234,12 @@
"description": "As a user, I want a project detail panel showing breadcrumb navigation, project name, stat cards, and an AI summary card.",
"acceptanceCriteria": [
"Right panel renders when a project is selected in the Projects tree",
"Breadcrumb at top shows Client > Sub-Client path (chevron-separated) using client data joined from the project",
"Breadcrumb at top uses shadcn/ui Breadcrumb (Breadcrumb, BreadcrumbList, BreadcrumbItem, BreadcrumbSeparator) showing Client > Sub-Client path",
"Project name renders as H1 below the breadcrumb",
"3 stat cards displayed horizontally: Notes (count from notes.list), Tasks Complete (done/total fraction from tasks.list), Checkpoints (approved/total fraction from checkpoints.list)",
"AI Project Summary card shows: sparkle (sparkles) Lucide icon + placeholder text 'AI summary will appear here' when project.aiSummary is null/empty",
"3 stat cards using shadcn/ui Card displayed horizontally: Notes (count from notes.list), Tasks Complete (done/total fraction from tasks.list), Checkpoints (approved/total fraction from checkpoints.list)",
"AI Project Summary card uses shadcn/ui Card with sparkle (sparkles) Lucide icon + placeholder text 'AI summary will appear here' when project.aiSummary is null/empty",
"When project.aiSummary is populated, the card displays the AI-generated text instead",
"Install shadcn/ui components via 'npx shadcn@latest add breadcrumb' before implementing (card already installed)",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
@@ -248,10 +253,11 @@
"description": "As a user, I want a Kanban board inside the project detail view with drag-and-drop task management between status columns.",
"acceptanceCriteria": [
"@hello-pangea/dnd installed; DragDropContext wraps 3 Droppable columns: To Do | In Progress | Completed",
"Each task card is a Draggable rendering: title, description (truncated), priority chip, due date, assignee string",
"Each task card is a Draggable wrapped in a shadcn/ui Card rendering: title, description (truncated), priority as shadcn/ui Badge, due date chip, assignee string",
"Dragging a card to another column calls tasks.update({ id, status }) via tRPC and the UI updates immediately (optimistic or on success)",
"'+ Add' button in each column header opens the new task modal with the column's status pre-selected",
"Columns show a task count in their header",
"'+ Add' shadcn/ui Button (variant=ghost, size=sm) in each column header opens the shadcn/ui Dialog new-task modal with the column's status pre-selected",
"Columns show a task count in their header using shadcn/ui Badge (variant=secondary)",
"All card content uses shadcn/ui primitives: Card, Badge, Button (already installed)",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
@@ -265,10 +271,11 @@
"description": "As a user, I want to see the project's Gantt timeline and a list of its notes within the project detail scrollable view.",
"acceptanceCriteria": [
"Project Detail view includes a 'Project Timeline' section using the GanttChart component (from US-012) scoped to the current project's checkpoints",
"'+ Add' button in the timeline section header opens the add-checkpoint dialog with the project pre-selected",
"Notes section below Kanban shows a flat list: each row has note title + formatted createdAt date",
"'+ Add' button in notes header calls notes.create with a default title and navigates to /notes/:noteId",
"'+ Add' shadcn/ui Button (variant=outline, size=sm) in the timeline section header opens the add-checkpoint shadcn/ui Dialog with the project pre-selected",
"Notes section below Kanban shows a flat list using shadcn/ui Separator between rows: each row has note title + formatted createdAt date",
"'+ Add' shadcn/ui Button in notes header calls notes.create with a default title and navigates to /notes/:noteId",
"Clicking a note title navigates to /notes/:noteId",
"All buttons/dialogs use shadcn/ui components (already installed)",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
@@ -283,10 +290,11 @@
"acceptanceCriteria": [
"@milkdown/react and @milkdown/preset-commonmark installed; Milkdown editor renders at route /notes/:noteId",
"Supported Markdown: headings (H1-H6), bold, italic, inline code, code blocks, bullet lists, ordered lists, blockquotes",
"Note title editable as a plain text input at the top of the page (separate from Milkdown content area)",
"Note title editable as a shadcn/ui Input (variant borderless/ghost style) at the top of the page (separate from Milkdown content area)",
"Content auto-saves to SQLite via notes.update on Milkdown onChange event, debounced 500ms",
"Unsaved indicator shown while save is pending (e.g., a dot or 'Saving...' label next to the title)",
"Back button or keyboard shortcut navigates to the previous route (project detail or projects list)",
"Unsaved indicator shown using shadcn/ui Badge (variant=secondary, text 'Saving...') next to the title while save is pending",
"Back button uses shadcn/ui Button (variant=ghost, size=icon) with ArrowLeft Lucide icon; navigates to the previous route",
"All UI chrome uses shadcn/ui components (already installed)",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
@@ -322,8 +330,8 @@
"ai.setToken tRPC mutation accepts { token: string } and stores it via keytar.setPassword('adiuva', 'copilot-token', token)",
"ai.hasToken tRPC query returns a boolean indicating whether a token is stored",
"On app start, main process reads the token from keychain and initializes the GitHub Copilot SDK client",
"A minimal Settings dialog (accessible from the sidebar bottom or a gear icon) allows the user to paste and save the token via ai.setToken",
"If no token is stored, AI-dependent features display a 'Configure API token in Settings' prompt instead of throwing an error",
"Settings dialog uses shadcn/ui Dialog (DialogTrigger as a SidebarMenuButton with Settings/gear icon in the sidebar footer); dialog content uses shadcn/ui Input for token paste + shadcn/ui Button to save via ai.setToken",
"If no token is stored, AI-dependent features display a prompt using shadcn/ui Card with a shadcn/ui Button linking to the Settings dialog instead of throwing an error",
"Typecheck passes"
],
"priority": 18,
@@ -352,13 +360,14 @@
"title": "Context-scoped AI chat UI",
"description": "As a user, I want the AI chat (revealed by the Fluid Curtain) to display a context header, support message input, and stream AI responses.",
"acceptanceCriteria": [
"Chat panel shows a context header: 'Chatting about: [Project Name]' when opened from a project detail view, or 'Global workspace' when opened from other sections",
"Chat input box: white background, border #d4d4d4, shadow-lg, min-height 109px, placeholder 'Ask me anything...', Send button (black bg, icon + 'Send' label) anchored bottom-right",
"User messages appear as right-aligned message bubbles; AI responses as left-aligned bubbles",
"Chat panel shows a context header using shadcn/ui Badge (variant=outline): 'Chatting about: [Project Name]' when opened from a project detail view, or 'Global workspace' when opened from other sections",
"Chat input box uses shadcn/ui Textarea: white background, border #d4d4d4, shadow-lg, min-height 109px, placeholder 'Ask me anything...'; Send uses shadcn/ui Button (black bg, Send Lucide icon + 'Send' label) anchored bottom-right",
"User messages appear as right-aligned message bubbles using shadcn/ui Card; AI responses as left-aligned Cards",
"Streaming: AI response tokens appended to the current AI bubble as they arrive from ai.chat",
"A loading spinner or pulsing indicator shown while waiting for first token",
"If ai.chat returns { error }, display the error message in a red-tinted bubble",
"A loading spinner or pulsing indicator (shadcn/ui Skeleton) shown while waiting for first token",
"If ai.chat returns { error }, display the error message in a shadcn/ui Card with destructive border styling",
"Chat history is session-only — cleared when the curtain closes or the app restarts",
"Install shadcn/ui components via 'npx shadcn@latest add textarea' before implementing (card, badge, button, skeleton already installed)",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
@@ -417,11 +426,12 @@
"title": "AI checkpoint suggestions UI",
"description": "As a user, I want the AI to suggest timeline checkpoints from my meeting notes, which I can approve or reject directly in the timeline.",
"acceptanceCriteria": [
"'Suggest checkpoints' button in the Project Detail timeline header calls ai.chat with a suggest_checkpoints intent for the current project",
"'Suggest checkpoints' shadcn/ui Button (variant=outline, sparkles Lucide icon) in the Project Detail timeline header calls ai.chat with a suggest_checkpoints intent for the current project",
"Suggested checkpoints returned by @ProjectAgent are inserted into the checkpoints table via checkpoints.create with isAiSuggested=1, isApproved=0",
"Pending suggestions appear as dismissible cards above or below the GanttChart in the Project Detail timeline section (visually distinct: dashed border or muted style)",
"'Approve' button on each card calls checkpoints.update({ id, isApproved: 1 }); the checkpoint then appears as a normal dot on the Gantt",
"'Reject' button calls checkpoints.delete({ id }) and removes the card",
"Pending suggestions appear as shadcn/ui Card components (with dashed border via className 'border-dashed') above or below the GanttChart in the Project Detail timeline section",
"'Approve' shadcn/ui Button (variant=default, size=sm) on each card calls checkpoints.update({ id, isApproved: 1 }); the checkpoint then appears as a normal dot on the Gantt",
"'Reject' shadcn/ui Button (variant=ghost, size=sm) calls checkpoints.delete({ id }) and removes the card",
"All UI uses shadcn/ui components (already installed)",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
@@ -435,12 +445,13 @@
"description": "As a user, I want the Home screen to greet me with an AI-generated daily brief and pre-populated suggestion chips for quick queries.",
"acceptanceCriteria": [
"Greeting rendered as '✦ Hello, {name}' in Geist Semibold 30px with -1px letter-spacing; name sourced from electron-store (defaults to 'there' if not set)",
"Top-right corner stat chip shows 'N Task due' where N = count of tasks with dueDate on or before end of today",
"Top-right corner stat chip uses shadcn/ui Badge (variant=secondary) showing 'N Task due' where N = count of tasks with dueDate on or before end of today",
"On app open, ai.chat called with global context to generate a daily brief paragraph highlighting tasks due today/this week and recent project activity",
"Brief displayed below greeting; bold key phrases rendered as <strong> (model wraps them in **markdown bold**)",
"4 suggestion chips rendered in a 4-column flex row below the chat box; chips are pre-populated from the AI response (model returns a JSON array of { icon: string, label: string } suggestion prompts)",
"Brief displayed below greeting in a shadcn/ui Card; bold key phrases rendered as <strong> (model wraps them in **markdown bold**)",
"4 suggestion chips rendered in a 4-column flex row below the chat box using shadcn/ui Button (variant=outline); each chip has a Lucide icon + short prompt text",
"Clicking a suggestion chip populates the chat input with the chip's prompt text",
"Chat box: white bg, border #d4d4d4, shadow-lg, min-height 109px, placeholder 'Ask me anything...', Send button (black) bottom-right",
"Chat box uses shadcn/ui Textarea: white bg, border #d4d4d4, shadow-lg, min-height 109px, placeholder 'Ask me anything...'; Send uses shadcn/ui Button (black bg) bottom-right",
"All UI uses shadcn/ui components (already installed)",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],