Phase 20: Admin Member Editor & Form Declutter #25
@@ -80,7 +80,11 @@ export function AdminPage() {
|
|||||||
// create ("Add member" trigger) modes (D-07 unification).
|
// create ("Add member" trigger) modes (D-07 unification).
|
||||||
const [editorOpen, setEditorOpen] = useState(false);
|
const [editorOpen, setEditorOpen] = useState(false);
|
||||||
const [editorMode, setEditorMode] = useState<'edit' | 'create'>('edit');
|
const [editorMode, setEditorMode] = useState<'edit' | 'create'>('edit');
|
||||||
const [editorMember, setEditorMember] = useState<AdminMember | null>(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<number | null>(null);
|
||||||
// Ref to the element that opened the sheet — focus returns here on close (a11y)
|
// Ref to the element that opened the sheet — focus returns here on close (a11y)
|
||||||
const editorTriggerRef = useRef<HTMLElement | null>(null);
|
const editorTriggerRef = useRef<HTMLElement | null>(null);
|
||||||
// Ref for the "Add member" ghost trigger button
|
// Ref for the "Add member" ghost trigger button
|
||||||
@@ -115,6 +119,13 @@ export function AdminPage() {
|
|||||||
staleTime: 60 * 1000,
|
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
|
// Calendars query
|
||||||
const calendarsQuery = useQuery({
|
const calendarsQuery = useQuery({
|
||||||
queryKey: ['admin', 'calendars'],
|
queryKey: ['admin', 'calendars'],
|
||||||
@@ -240,7 +251,7 @@ export function AdminPage() {
|
|||||||
// Open the editor for a specific member (row tap → edit mode)
|
// Open the editor for a specific member (row tap → edit mode)
|
||||||
function openEditorForMember(member: AdminMember, rowEl: HTMLElement) {
|
function openEditorForMember(member: AdminMember, rowEl: HTMLElement) {
|
||||||
editorTriggerRef.current = rowEl;
|
editorTriggerRef.current = rowEl;
|
||||||
setEditorMember(member);
|
setEditorMemberId(member.id); // CR-02: store id only; editorMember is derived from live data
|
||||||
setEditorMode('edit');
|
setEditorMode('edit');
|
||||||
setEditorOpen(true);
|
setEditorOpen(true);
|
||||||
}
|
}
|
||||||
@@ -248,7 +259,7 @@ export function AdminPage() {
|
|||||||
// Open the editor in create mode ("Add member" trigger)
|
// Open the editor in create mode ("Add member" trigger)
|
||||||
function openEditorForCreate() {
|
function openEditorForCreate() {
|
||||||
editorTriggerRef.current = addMemberTriggerRef.current;
|
editorTriggerRef.current = addMemberTriggerRef.current;
|
||||||
setEditorMember(null);
|
setEditorMemberId(null);
|
||||||
setEditorMode('create');
|
setEditorMode('create');
|
||||||
setEditorOpen(true);
|
setEditorOpen(true);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user