mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
feat(freight:auth): show real user profile in top bar and fix logout
- DashboardLayout now accepts userName, userEmail, userInitials, onLogout props; computes initials from name; replaces hardcoded "John Doe" values - Portal App.tsx pulls display name and email from useAuth user object and passes them to DashboardLayout - handleLogout performs unconditional local cleanup (cookies + localStorage + hard redirect to /auth) so a failed API call never leaves the user stuck - main.tsx purges cookies whose value is the literal string "undefined", clearing stale tokens written before the envelope interceptor fix Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -17,6 +17,10 @@ export interface DashboardLayoutProps {
|
||||
onNavigate?: (href: string) => void;
|
||||
headerRight?: ReactNode;
|
||||
enableThemeToggle?: boolean;
|
||||
userName?: string;
|
||||
userEmail?: string;
|
||||
userInitials?: string;
|
||||
onLogout?: () => void;
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
@@ -42,8 +46,20 @@ const DashboardLayout = ({
|
||||
onNavigate,
|
||||
headerRight,
|
||||
enableThemeToggle = false,
|
||||
userName = "User",
|
||||
userEmail,
|
||||
userInitials,
|
||||
onLogout,
|
||||
children,
|
||||
}: DashboardLayoutProps) => {
|
||||
const initials =
|
||||
userInitials ??
|
||||
userName
|
||||
.split(" ")
|
||||
.filter(Boolean)
|
||||
.slice(0, 2)
|
||||
.map((n) => n[0].toUpperCase())
|
||||
.join("");
|
||||
const [theme, setTheme] = useState<Theme>(() =>
|
||||
enableThemeToggle ? getInitialTheme() : "light",
|
||||
);
|
||||
@@ -148,10 +164,10 @@ const DashboardLayout = ({
|
||||
className="flex items-center gap-2 rounded-xl border border-transparent px-2 py-1.5 transition hover:border-[#33578D]/20 hover:bg-[#33578D]/5 aria-expanded:border-[#33578D]/30 aria-expanded:bg-[#33578D]/10 dark:hover:border-[#33578D]/30 dark:hover:bg-[#33578D]/10 dark:aria-expanded:border-[#33578D]/40 dark:aria-expanded:bg-[#33578D]/20"
|
||||
>
|
||||
<div className="flex h-8 w-8 items-center justify-center rounded-full bg-[#33578D] text-xs font-semibold text-white">
|
||||
JD
|
||||
{initials}
|
||||
</div>
|
||||
<span className="hidden text-sm font-medium text-slate-700 md:block dark:text-slate-200">
|
||||
John Doe
|
||||
{userName}
|
||||
</span>
|
||||
<ChevronDown
|
||||
className={`h-4 w-4 text-slate-400 transition dark:text-slate-500 ${
|
||||
@@ -167,11 +183,13 @@ const DashboardLayout = ({
|
||||
>
|
||||
<div className="border-b border-slate-100 px-4 py-3 dark:border-slate-700">
|
||||
<p className="text-sm font-semibold text-slate-900 dark:text-slate-100">
|
||||
John Doe
|
||||
</p>
|
||||
<p className="text-xs text-slate-500 dark:text-slate-400">
|
||||
john.doe@edr.com
|
||||
{userName}
|
||||
</p>
|
||||
{userEmail ? (
|
||||
<p className="text-xs text-slate-500 dark:text-slate-400">
|
||||
{userEmail}
|
||||
</p>
|
||||
) : null}
|
||||
</div>
|
||||
<a
|
||||
href="#profile"
|
||||
@@ -182,15 +200,18 @@ const DashboardLayout = ({
|
||||
<User className="h-4 w-4" />
|
||||
Profile
|
||||
</a>
|
||||
<a
|
||||
href="#logout"
|
||||
<button
|
||||
type="button"
|
||||
role="menuitem"
|
||||
onClick={() => setIsUserMenuOpen(false)}
|
||||
className="flex items-center gap-2 px-4 py-2 text-sm text-red-600 transition hover:bg-red-50 dark:text-red-400 dark:hover:bg-red-950/30"
|
||||
onClick={() => {
|
||||
setIsUserMenuOpen(false);
|
||||
onLogout?.();
|
||||
}}
|
||||
className="flex w-full items-center gap-2 px-4 py-2 text-sm text-red-600 transition hover:bg-red-50 dark:text-red-400 dark:hover:bg-red-950/30"
|
||||
>
|
||||
<LogOut className="h-4 w-4" />
|
||||
Logout
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user