From 508ec682a7be94f85f3c7a7e837e89bf38977e3c Mon Sep 17 00:00:00 2001 From: Dwindi Ramadhana Date: Thu, 1 Jan 2026 17:08:34 +0700 Subject: [PATCH] fix: login page reload + custom logout dialog 1. Login fix: - Added window.location.reload() after setting hash URL - Forces full page reload to refresh cookies from server - Resolves 'Cookie check failed' error after login 2. Logout UX improvement: - Created alert-dialog.tsx component (Radix UI AlertDialog) - Replaced window.confirm() with custom AlertDialog - Dialog shows: title, description, Cancel/Log Out buttons - Red 'Log Out' action button for clear intent --- .../src/components/ui/alert-dialog.tsx | 139 ++++++++++++++++++ .../Account/components/AccountLayout.tsx | 57 +++++-- customer-spa/src/pages/Login/index.tsx | 8 +- 3 files changed, 190 insertions(+), 14 deletions(-) create mode 100644 customer-spa/src/components/ui/alert-dialog.tsx diff --git a/customer-spa/src/components/ui/alert-dialog.tsx b/customer-spa/src/components/ui/alert-dialog.tsx new file mode 100644 index 0000000..189bf6a --- /dev/null +++ b/customer-spa/src/components/ui/alert-dialog.tsx @@ -0,0 +1,139 @@ +import * as React from "react" +import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog" +import { cn } from "@/lib/utils" + +const AlertDialog = AlertDialogPrimitive.Root + +const AlertDialogTrigger = AlertDialogPrimitive.Trigger + +const AlertDialogPortal = AlertDialogPrimitive.Portal + +const AlertDialogOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName + +const AlertDialogContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + + +)) +AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName + +const AlertDialogHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +AlertDialogHeader.displayName = "AlertDialogHeader" + +const AlertDialogFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +AlertDialogFooter.displayName = "AlertDialogFooter" + +const AlertDialogTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName + +const AlertDialogDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogDescription.displayName = + AlertDialogPrimitive.Description.displayName + +const AlertDialogAction = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName + +const AlertDialogCancel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName + +export { + AlertDialog, + AlertDialogPortal, + AlertDialogOverlay, + AlertDialogTrigger, + AlertDialogContent, + AlertDialogHeader, + AlertDialogFooter, + AlertDialogTitle, + AlertDialogDescription, + AlertDialogAction, + AlertDialogCancel, +} diff --git a/customer-spa/src/pages/Account/components/AccountLayout.tsx b/customer-spa/src/pages/Account/components/AccountLayout.tsx index 1af594c..fe462ae 100644 --- a/customer-spa/src/pages/Account/components/AccountLayout.tsx +++ b/customer-spa/src/pages/Account/components/AccountLayout.tsx @@ -2,6 +2,17 @@ import React, { ReactNode, useState } from 'react'; import { Link, useLocation } from 'react-router-dom'; import { LayoutDashboard, ShoppingBag, Download, MapPin, Heart, User, LogOut } from 'lucide-react'; import { useModules } from '@/hooks/useModules'; +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, + AlertDialogTrigger, +} from '@/components/ui/alert-dialog'; interface AccountLayoutProps { children: ReactNode; @@ -58,6 +69,38 @@ export function AccountLayout({ children }: AccountLayoutProps) { return location.pathname.startsWith(path); }; + // Logout Button with AlertDialog + const LogoutButton = () => ( + + + + + + + Log out? + + Are you sure you want to log out of your account? You'll need to sign in again to access your orders and account details. + + + + Cancel + + Log Out + + + + + ); + // Sidebar Navigation const SidebarNav = () => ( ); @@ -151,3 +183,4 @@ export function AccountLayout({ children }: AccountLayoutProps) {
); } + diff --git a/customer-spa/src/pages/Login/index.tsx b/customer-spa/src/pages/Login/index.tsx index f934fd1..ea2eee6 100644 --- a/customer-spa/src/pages/Login/index.tsx +++ b/customer-spa/src/pages/Login/index.tsx @@ -56,8 +56,12 @@ export default function Login() { toast.success('Login successful!'); - // Full page reload to refresh nonce and user state - window.location.href = window.location.origin + '/store/#' + redirectTo; + // Set the target URL with hash route, then force reload + // The hash change alone doesn't reload the page, so cookies won't be refreshed + const targetUrl = window.location.origin + '/store/#' + redirectTo; + window.location.href = targetUrl; + // Force page reload to refresh cookies and server-side state + window.location.reload(); } else { setError(data.message || 'Login failed'); }