fix(ui): mobile menu missing user section + logout, fix OG image

- AppLayout: add user info + 'My account' + 'Sign out' to mobile hamburger menu
- Header: add 'Sign out' button to authenticated mobile menu (landing page)
- dist/og-image.png: sync with public/ (Cohorta-branded, replaces Lovable image)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Vadym Samoilenko 2026-05-24 19:37:49 +01:00
parent 84dcfc46b9
commit bc4c3afebb
3 changed files with 42 additions and 7 deletions

BIN
dist/og-image.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 228 KiB

After

Width:  |  Height:  |  Size: 152 KiB

View file

@ -6,7 +6,7 @@ import { billingApi } from '@/lib/api';
import Logo from '@/components/brand/Logo';
import UserDropdown from '@/components/brand/UserDropdown';
import LanguageSwitcher from '@/components/LanguageSwitcher';
import { Users, MessageSquare, LayoutDashboard, CreditCard, ShieldCheck, Zap, Menu, X } from 'lucide-react';
import { Users, MessageSquare, LayoutDashboard, CreditCard, ShieldCheck, Zap, Menu, X, LogOut, User } from 'lucide-react';
import { cn } from '@/lib/utils';
const NAV_ITEMS = [
@ -17,7 +17,7 @@ const NAV_ITEMS = [
] as const;
export default function AppLayout({ children }: { children?: React.ReactNode }) {
const { user, isAuthenticated } = useAuth();
const { user, isAuthenticated, logout } = useAuth();
const navigate = useNavigate();
const { t } = useTranslation();
const [credits, setCredits] = useState<number | null>(null);
@ -119,6 +119,33 @@ export default function AppLayout({ children }: { children?: React.ReactNode })
{t(labelKey, fallback)}
</NavLink>
))}
{/* User section */}
<div className="mt-2 pt-3 border-t border-border/40 flex flex-col gap-1">
<div className="px-3 py-2 flex items-center gap-3">
<div className="h-8 w-8 rounded-full bg-primary/15 border border-primary/30 flex items-center justify-center flex-shrink-0">
<span className="text-xs font-semibold text-primary">{user?.username?.slice(0, 2).toUpperCase() || 'U'}</span>
</div>
<div className="min-w-0">
<p className="text-sm font-medium text-foreground truncate">{user?.username}</p>
<p className="text-xs text-muted-foreground truncate">{user?.email}</p>
</div>
</div>
<NavLink
to="/dashboard"
className={({ isActive }) => cn('flex items-center gap-2.5 px-3 py-2.5 rounded-xl text-sm font-medium', isActive ? 'text-primary bg-primary/10' : 'text-muted-foreground hover:text-foreground hover:bg-secondary/60')}
onClick={() => setMobileOpen(false)}
>
<User className="h-4 w-4" />
My account
</NavLink>
<button
onClick={() => { logout(); navigate('/'); setMobileOpen(false); }}
className="flex items-center gap-2.5 px-3 py-2.5 rounded-xl text-sm font-medium text-destructive hover:bg-destructive/10 transition-all text-left w-full"
>
<LogOut className="h-4 w-4" />
Sign out
</button>
</div>
</div>
)}
</header>

View file

@ -11,7 +11,7 @@ import LanguageSwitcher from '@/components/LanguageSwitcher';
import { useTranslation } from 'react-i18next';
export default function Header() {
const { isAuthenticated } = useAuth();
const { isAuthenticated, logout } = useAuth();
const navigate = useNavigate();
const location = useLocation();
const { t } = useTranslation();
@ -177,11 +177,19 @@ export default function Header() {
</nav>
<div className="flex flex-col gap-2 border-t border-border pt-3">
{isAuthenticated ? (
<Link to="/dashboard" onClick={() => setMobileOpen(false)}>
<button className="w-full px-4 py-2.5 rounded-xl text-sm font-semibold bg-primary text-primary-foreground">
{t('nav.my_account')}
<>
<Link to="/dashboard" onClick={() => setMobileOpen(false)}>
<button className="w-full px-4 py-2.5 rounded-xl text-sm font-semibold bg-primary text-primary-foreground">
{t('nav.my_account')}
</button>
</Link>
<button
onClick={() => { logout(); navigate('/'); setMobileOpen(false); }}
className="w-full px-4 py-2.5 rounded-xl text-sm font-medium border border-border text-muted-foreground hover:text-foreground hover:bg-secondary/50 transition-all"
>
Sign out
</button>
</Link>
</>
) : (
<>
<Link