From 5cbf543c167edf363ff6fae69fa1507f1224f71b Mon Sep 17 00:00:00 2001 From: Madhura68 Date: Mon, 27 Apr 2026 23:40:42 +0200 Subject: [PATCH] fix: call logoutAction directly via useTransition instead of form-ref submit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit De form-ref-dance werkte niet betrouwbaar in de huidige base-ui: - onSelect vuurde requestSubmit() op een hidden form - Form zat eerst binnen DropdownMenuContent (form geunmount → ref null) - Form daarna naar top-level verplaatst — vuurde nog steeds geen request af, vermoedelijk doordat onSelect in deze base-ui-build niet (consistent) een click-event genereerde dat de form-API trigger'de Vervang door directe call: Server Actions kunnen sinds Next.js 14 als async functie worden aangeroepen vanuit Client Components. useTransition voorkomt dat de UI bevriest tijdens de redirect. Naast onSelect ook onClick als veiligheid voor het geval base-ui later weer van event-prop wisselt — beide handlers wijzen naar dezelfde idempotente function (handleLogout via startTransition). Pendingstate ('Uitloggen…' label, disabled item) zodat dubbele klikken niet dubbele logoutAction-calls afvuren. Quality gates: lint 0 errors, tsc clean. Co-Authored-By: Claude Opus 4.7 (1M context) --- components/shared/user-menu.tsx | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/components/shared/user-menu.tsx b/components/shared/user-menu.tsx index 07d5b38..b628476 100644 --- a/components/shared/user-menu.tsx +++ b/components/shared/user-menu.tsx @@ -1,6 +1,6 @@ 'use client' -import { useRef } from 'react' +import { useTransition } from 'react' import Link from 'next/link' import { Settings, Sun, Globe, LogOut } from 'lucide-react' import { logoutAction } from '@/actions/auth' @@ -33,14 +33,19 @@ export function UserMenu({ userId, username, email, roles }: UserMenuProps) { const initials = username.slice(0, 2).toUpperCase() const roleLabels = roles.map((r) => ROLE_LABELS[r]).filter(Boolean) const subtitle = email?.trim() ? email.trim() : 'Lokaal account' - const logoutFormRef = useRef(null) + const [pendingLogout, startLogout] = useTransition() + + // Server Action direct aanroepen — geen form/ref-dance. Eerdere implementatie + // gebruikte een hidden form binnen DropdownMenuContent; die unmount op + // onSelect en in deze base-ui-versie kwam de submit niet door. + function handleLogout() { + startLogout(async () => { + await logoutAction() + }) + } return ( - <> - {/* Form buiten DropdownMenuContent — die unmount op onSelect waardoor de ref - null wordt voordat requestSubmit() vuurt. */} -
- + logoutFormRef.current?.requestSubmit()} + onClick={handleLogout} + onSelect={handleLogout} + disabled={pendingLogout} className="cursor-pointer" > - Uitloggen + {pendingLogout ? 'Uitloggen…' : 'Uitloggen'} - - + ) }