Instruction file imported from gregory-chris/groodo (
.cursor/rules/context-board.mdc). Copyright stays with the author.
features/board/ — Weekly Task Board
Overview
The main feature of the app. Displays tasks in a Sunday–Thursday weekly board with drag-and-drop support. Each day is a column. Users can create, edit, complete, delete, and reorder tasks, as well as navigate between weeks.
Structure
components/
- Board.jsx — Root component. Composes providers (Accessibility → Board → Drag) and renders the week grid with one
Columnper day. - Column.jsx — Single day column. Shows tasks filtered by date key, supports inline task creation, and acts as a drop zone. Excludes tasks that belong to a project (
projectId !== null). Usestask._stableKey || task.idas the React key so TaskCard instances survive persistence ID swaps without remounting. - TaskCard.jsx — Individual task card with drag handle, completion checkbox, edit/delete actions, and keyboard shortcuts (Enter=edit, Space=toggle, Delete=delete). Includes a highlight-on-update effect: a gold overlay flashes and fades out (1.5s CSS transition) when
updatedAtchanges. The effect watches only[updatedAt]— it is fully decoupled from persistence bookkeeping becauseRECONCILE_TASK(used for ID swaps and rollbacks) never touchesupdatedAt, and the component never remounts during ID swaps thanks to_stableKey. - TaskModal.jsx — Modal for editing task title and rich text description. Supports "Move to Next Week". Uses
WysiwygEditor. - WeekNav.jsx — Previous/Next/Today navigation with formatted week range display.
- DragProvider.jsx — Wraps
@dnd-kitDnD context. Handles drag start/end/over events, calculates drop positions, and callsmoveTask. - AccessibilityProvider.jsx — Screen reader announcements, keyboard navigation hooks, focus management, and skip links.
context/
- BoardContext.jsx — Central state via
useReducer. Managestasks[],currentWeek,modalState. Provides CRUD actions and week navigation. UsesusePersistencefor data loading/saving.- Actions:
ADD_TASK(sets_stableKeyfor stable React key),UPDATE_TASK(user-intent, setsupdatedAt: now),RECONCILE_TASK(silent persistence bookkeeping — updates fields likeidWITHOUT touchingupdatedAt, so it never re-triggers the highlight animation),DELETE_TASK,MOVE_TASK,TOGGLE_TASK_COMPLETE, plus week navigation actions. duplicateTaskis async — it dispatches an optimisticADD_TASKimmediately, then awaits persistence to resolve the real ID before returning the task (so the edit modal opens with the correct persisted ID).
- Actions:
hooks/
- usePersistence.js — Loads/saves tasks using the appropriate storage client. Handles optimistic updates with rollback. Supports bulk updates (for drag reordering). All persistence-internal dispatches (ID swaps after create, rollbacks on failure) use
RECONCILE_TASKinstead ofUPDATE_TASKso they never affectupdatedAtor trigger the highlight animation.handleCreateTaskreturns{ success, task }so callers can access the persisted task (with real ID). - useWeekNavigation.js — Standalone week navigation hook (available but not currently used by BoardContext, which manages navigation internally).
Key Business Rules
- Work week is Sunday through Thursday (5 days)
- Tasks are assigned to a specific date (column)
- Incomplete tasks sort before completed ones
- Every task carries a
_stableKey(set once duringADD_TASK) used as the React key inColumn, so component instances survive temp-id → server-id swaps without remounting UPDATE_TASKis for user-intent changes only;RECONCILE_TASKis for persistence plumbing (ID swap, rollback) — this separation ensures the highlight animation fires exactly once per user action regardless of storage latency- Tasks with a
projectIdare excluded from the board (they belong to the projects feature) - "Move to Next Week" moves a task to the same weekday in the following week