diff --git a/apps/pwa/src/routes/AdminPage.tsx b/apps/pwa/src/routes/AdminPage.tsx index 952eb24..39851b3 100644 --- a/apps/pwa/src/routes/AdminPage.tsx +++ b/apps/pwa/src/routes/AdminPage.tsx @@ -80,7 +80,11 @@ export function AdminPage() { // create ("Add member" trigger) modes (D-07 unification). const [editorOpen, setEditorOpen] = useState(false); const [editorMode, setEditorMode] = useState<'edit' | 'create'>('edit'); - const [editorMember, setEditorMember] = useState(null); + // CR-02: store only the id, not the full member object. The full member is + // derived from live query data each render (see below, after membersQuery), + // so per-section saves + invalidations keep the editor's member prop fresh + // without a stale captured reference. + const [editorMemberId, setEditorMemberId] = useState(null); // Ref to the element that opened the sheet — focus returns here on close (a11y) const editorTriggerRef = useRef(null); // Ref for the "Add member" ghost trigger button @@ -115,6 +119,13 @@ export function AdminPage() { staleTime: 60 * 1000, }); + // CR-02: derive editorMember from live query data so saves + invalidations always + // reflect the latest server state rather than a snapshot from when the row was tapped. + const editorMember = + editorMemberId !== null + ? (membersQuery.data?.members.find((m) => m.id === editorMemberId) ?? null) + : null; + // Calendars query const calendarsQuery = useQuery({ queryKey: ['admin', 'calendars'], @@ -240,7 +251,7 @@ export function AdminPage() { // Open the editor for a specific member (row tap → edit mode) function openEditorForMember(member: AdminMember, rowEl: HTMLElement) { editorTriggerRef.current = rowEl; - setEditorMember(member); + setEditorMemberId(member.id); // CR-02: store id only; editorMember is derived from live data setEditorMode('edit'); setEditorOpen(true); } @@ -248,7 +259,7 @@ export function AdminPage() { // Open the editor in create mode ("Add member" trigger) function openEditorForCreate() { editorTriggerRef.current = addMemberTriggerRef.current; - setEditorMember(null); + setEditorMemberId(null); setEditorMode('create'); setEditorOpen(true); }