Archive v1.1 artifacts (roadmap, requirements, phases) to milestones/. Evolve PROJECT.md with shipped requirements and new key decisions. Reorganize ROADMAP.md with collapsed milestone groupings. Update retrospective with v1.1 lessons. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
12 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | requirements | must_haves | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 04-database-planning-fixes | 02 | execute | 2 |
|
|
false |
|
|
Purpose: PLAN-01 (user can create threads without errors via modal) and PLAN-02 (polished empty state with CTA). This completes the planning tab UX overhaul. Output: Working planning tab with modal-based thread creation, educational empty state, pill tab filtering, and category-aware thread cards.
<execution_context> @/home/jean-luc-makiola/.claude/get-shit-done/workflows/execute-plan.md @/home/jean-luc-makiola/.claude/get-shit-done/templates/summary.md </execution_context>
@.planning/ROADMAP.md @.planning/phases/04-database-planning-fixes/04-CONTEXT.md @.planning/phases/04-database-planning-fixes/04-01-SUMMARY.mdFrom src/client/hooks/useThreads.ts (after Plan 01):
interface ThreadListItem {
id: number;
name: string;
status: "active" | "resolved";
resolvedCandidateId: number | null;
createdAt: string;
updatedAt: string;
candidateCount: number;
minPriceCents: number | null;
maxPriceCents: number | null;
categoryId: number;
categoryName: string;
categoryEmoji: string;
}
// useCreateThread expects { name: string; categoryId: number }
From src/client/hooks/useCategories.ts:
export function useCategories(): UseQueryResult<Category[]>;
// Category = { id: number; name: string; emoji: string; createdAt: Date }
From src/client/stores/uiStore.ts (needs createThreadModal state added):
// Existing pattern for dialogs:
// resolveThreadId: number | null;
// openResolveDialog: (threadId, candidateId) => void;
// closeResolveDialog: () => void;
From src/client/routes/collection/index.tsx (CollectionView empty state pattern):
// Lines 58-93: empty state with emoji, heading, description, CTA button
// Follow this pattern for planning empty state
- Create
src/client/components/CreateThreadModal.tsx:- A modal overlay (fixed inset-0, bg-black/50 backdrop, centered white panel) following the same pattern as the app's existing dialog styling.
- Form fields: Thread name (text input, required, min 1 char) and Category (select dropdown populated from
useCategories()hook). - Category select shows emoji + name for each option. Pre-select the first category.
- Submit calls
useCreateThread().mutate({ name, categoryId }). - On success: close modal (via
closeCreateThreadModalfrom uiStore), reset form. - On error: show inline error message.
- Cancel button and clicking backdrop closes modal.
- Disable submit button while
isPending. - Use Tailwind classes consistent with existing app styling (rounded-xl, text-sm, blue-600 primary buttons, gray-200 borders). cd /home/jean-luc-makiola/Development/projects/GearBox && bun run lint 2>&1 | tail -5 CreateThreadModal component renders a modal with name input and category dropdown, submits via useCreateThread, uiStore has createThreadModalOpen state
-
In
src/client/routes/collection/index.tsx, rewrite thePlanningViewfunction:Remove: The inline text input + button form for thread creation. Remove the
showResolvedcheckbox.Add state:
activeTab: "active" | "resolved"(default "active") for the pill tab selector.categoryFilter: number | null(default null = all categories) for filtering.- Import
useCategorieshook,useUIStore, andCreateThreadModal.
Layout (top to bottom):
a. Header row: "Planning Threads" heading on the left, "New Thread" button on the right. Button calls
openCreateThreadModal()from uiStore. Use a plus icon (inline SVG, same pattern as collection empty state button).b. Filter row: Active/Resolved pill tab selector on the left, category filter dropdown on the right.
- Pill tabs: Two buttons styled as a segment control. Active pill gets
bg-blue-600 text-white, inactive getsbg-gray-100 text-gray-600 hover:bg-gray-200. Rounded-full, px-4 py-1.5, text-sm font-medium. Wrap in aflex bg-gray-100 rounded-full p-0.5 gap-0.5container. - Category filter: A
<select>dropdown with "All categories" as default option, then each category with emoji + name. Filter threads client-side by matchingthread.categoryId === categoryFilter.
c. Thread list or empty state:
- Pass
activeTab === "resolved"asincludeResolvedtouseThreads. WhenactiveTab === "active", show only active threads. WhenactiveTab === "resolved", filter the results to show only resolved threads (sinceincludeResolved=truereturns both). - Apply
categoryFilteron the client side if set.
d. Empty state (when filtered threads array is empty AND activeTab is "active" AND no category filter):
- Guided + educational tone per user decision.
- Max-width container (max-w-lg mx-auto), centered, py-16.
- Heading: "Plan your next purchase" (text-xl font-semibold).
- Three illustrated steps showing the workflow, each as a row with a step number circle (1, 2, 3), a short title, and a description:
- "Create a thread" -- "Start a research thread for gear you're considering"
- "Add candidates" -- "Add products you're comparing with prices and weights"
- "Pick a winner" -- "Resolve the thread and the winner joins your collection"
- Style each step: flex row, step number in a 8x8 rounded-full bg-blue-100 text-blue-700 font-bold circle, title in font-medium, description in text-sm text-gray-500.
- CTA button below steps: "Create your first thread" -- calls
openCreateThreadModal(). Blue-600 bg, white text, same style as collection empty state button. - If empty because of active filter (category or "resolved" tab), show a simpler "No threads found" message instead of the full educational empty state.
e. Render
<CreateThreadModal />at the bottom of PlanningView (it reads its own open/close state from uiStore).f. Thread grid: Keep existing
grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4. PasscategoryNameandcategoryEmojias new props to ThreadCard. cd /home/jean-luc-makiola/Development/projects/GearBox && bun run lint 2>&1 | tail -5 PlanningView shows educational empty state with 3-step workflow, pill tabs for Active/Resolved, category filter dropdown, "New Thread" button opens modal, ThreadCard shows category badge, inline form is removed
<success_criteria>
- Inline thread creation form is replaced with modal dialog
- Empty state educates users about the 3-step planning workflow
- Active/Resolved pill tabs replace the "Show archived" checkbox
- Category filter allows narrowing thread list by category
- Thread cards display category information
- No lint errors </success_criteria>