Show Notes
In this video, Parker refines a Google Calendar–style calendar list in Map to be drag-reorderable, stateful, and persisted locally. He uses Cursor and Aider to plan, implement, and iteratively improve the UI, focusing on a clean, intuitive experience first.
AI-assisted planning and the Architect/Engineer pattern (AER)
- Use the architect to outline a concrete plan before coding.
- Define exact file names and feature goals in the plan; you can reference related products (e.g., Google Calendar) to ground the design.
- Let the architect provide a design/read-through, including UX notes, color mapping, and accessibility considerations.
- Review the plan and cost, then confirm to let the coder proceed.
- The coder then lets the AI generate code, applying the plan step-by-step.
- Iterate: if implementation has gaps or you want changes, re-prompt with clarifications and new requirements.
Code and prompts workflow highlights:
- Start with a fresh plan that names your files and features.
- Read the AI’s plan, verify its rationale and cost, and approve to begin coding.
- Use the coding phase to apply the plan, then test and adjust as needed.
Code blocks you might see in practice:
- AER plan draft example (conceptual):
- File: components/CalendarMenu.tsx
- Behavior: draggable items, color matching, display this only, and an accessible open/close accordion
- Accessibility notes: keyboard support, clear focus states
- The plan may also specify UI touches like a Framer animation for the accordion.
UI design: Google Calendar–style calendar menu
- Draggable and reorderable calendar list
- Checkbox items colored to match calendar colors
- Visibility toggles (display this only vs. show all)
- Accordion-style open/close for the calendar list
- Dynamic labeling: when only one calendar is visible, label changes to “Show all calendars”
- Context menu (three dots) includes a “Set as default” option
- Framer animation to improve the feel of the accordion
- The initial goal is UI polish; data flow and mutations (queries/mutations) exist but are not the primary focus at first
Actionable takeaways:
- Start with a visually polished UI to mirror familiar calendars, then layer in state logic and persistence.
State management and persistence with localStorage
- Persist three aspects to localStorage:
- Calendar order
- Calendar visibility (checked/unchecked)
- Accordion open/closed state
- Use a React context to keep UI components in sync (menu, calendar list, etc.)
- Ensure both the menu and the calendar context reflect the same state
- Refresh should retain:
- Which calendars are visible
- Their order
- Whether the accordion is expanded or collapsed
Implementation notes:
- Introduce a useLocalStorage hook to manage persistent state:
- Key ideas: read from localStorage on init, write on state changes
- Centralize in context to keep UI in sync
Code snippet (illustrative useLocalStorage hook):
ts
// useLocalStorage.ts
import { useState, useEffect } from 'react';
export function useLocalStorage<T>(key: string, initial: T) {
const [state, setState] = useState<T>(() => {
try {
const raw = localStorage.getItem(key);
return raw ? (JSON.parse(raw) as T) : initial;
} catch {
return initial;
}
});
useEffect(() => {
localStorage.setItem(key, JSON.stringify(state));
}, [key, state]);
return [state, setState] as const;
}
Developer notes:
- Integrate the hook into the calendar context so the UI reads/writes visibility, order, and accordion state.
- If UI changes outpace context (or vice versa), iterate quickly to fix desynchronization.
AI-assisted coding workflow and iteration
- Start with a clean conversation/context for each major iteration to avoid context bleed.
- Focus prompts on outcomes rather than micromanaging implementation details:
- “Persist visibility, order, and expanded/collapsed state in localStorage.”
- “Make the calendar menu dynamic: if exactly one is visible, label becomes ‘Show all calendars.’”
- When a prompt yields errors or mismatches, paste the relevant error snippets and request targeted fixes.
- Use conventional commits to log changes as you go; this keeps the history clean and reviewable.
Operational tips:
- Run tests and sample builds frequently after each AI-generated change.
- If you see UI-only changes not reflected in state, prompt to fix the synchronization between menu and context.
Testing, QA, and small-step delivery
- Validate drag-and-drop reordering works and persists after refresh.
- Validate visibility toggles affect both the UI and the persisted state.
- Validate the dynamic label for the visibility state (Show all calendars vs. the specific calendar state).
- Validate the “Set as default” option appears in the menu and updates the default item accordingly.
- Confirm a pleasant UX with a Framer animation on the accordion if requested.
Best practices:
- Work in small, testable chunks; test after each AI-generated change.
- Keep changes isolated to minimize drift between UI and state logic.
- When ready, run a quick format/lint and create a conventional commit for the changes.
Final thoughts and what’s next
- A well-structured, AI-assisted workflow can turn a rough UI concept into a polished, persisted experience quickly.
- With localStorage-backed state, the calendar menu remains predictable across refreshes without requiring a server DB for this feature.
- Next steps could include adding keyboard accessibility refinements, unit tests around the context/state logic, and gradually migrating to a server-backed persistence if needed.
Links
- React useState Documentation (localStorage concepts and patterns)
- useLocalStorage Hook (patterns and examples)
- Framer Motion (for accordion animation)
- Cursor AI (AI code editor)
- Aider (AI pair programming in terminal)