Files
hope-events/frontend/src/components/layout/Navbar.tsx
T
joshua 8f69e58aa2 Add tab icons and fix mobile dashboard styling issues
- Add matching lucide-react icons to tab/mode switcher buttons on
  payments, at-the-door, manual, email-attendees, whatsapp-attendees,
  and admin cashup pages, mirroring icons already used in their help menus
- Fix navbar Logout button sitting lower than other nav links (missing
  border/padding classes that other links use for their active-underline)
- Fix stat card labels getting truncated on mobile by removing the
  ellipsis-cut label and widening the mobile grid to one column
- Fix Revenue trend / Top performing events rendering outside the
  viewport on mobile by containing horizontal overflow and truncating
  long event titles in the table
2026-08-07 00:41:52 +02:00

137 lines
5.7 KiB
TypeScript

"use client";
import Link from "next/link";
import Image from "next/image";
import { usePathname } from "next/navigation";
import { useAuth } from "@/hooks/useAuth";
import { useSiteSettings } from "@/contexts/SiteSettingsContext";
import { BottomNav } from "./BottomNav";
import churchLogo from "@/app/church_logo.jpg";
import { appName, brandColor } from "@/lib/siteConfig";
import { resolveToApiOrigin } from "@/lib/api";
type NavLink = {
href: string;
label: string;
onClick?: () => void;
};
export const Navbar = () => {
const { user, loading: authLoading, logout } = useAuth();
const { settings, loading: settingsLoading } = useSiteSettings();
const pathname = usePathname();
// Admin-configurable — applied ONLY to the org name text below via inline
// style. No other element in the navbar (or anywhere else) should read
// this; everything else uses the fixed brand-* palette.
const displayName = settings.org_name || appName;
const displayColor = settings.accent_color || brandColor;
const logoSrc = settings.logo_url ? resolveToApiOrigin(settings.logo_url) : null;
const isActive = (href: string) => {
if (href.includes("#")) return false;
if (href === "/") return pathname === "/";
return pathname?.startsWith(href) ?? false;
};
const handleLogout = () => {
logout();
window.location.href = "/";
};
const navLinks: NavLink[] = [
{ href: "/", label: "Home" },
{ href: "/events", label: "Events" },
{ href: "/contact", label: "Contact" },
];
const authLinks: NavLink[] = user
? [
{ href: "/dashboard", label: "Dashboard" },
{
href: "#",
label: "Logout",
onClick: handleLogout,
},
]
: [
{ href: "/login", label: "Login" },
{ href: "/register", label: "Register" },
];
return (
<>
<header className="bg-white shadow-md sticky top-0 z-50">
<nav className="max-w-7xl mx-auto px-4 py-3 flex items-center justify-between">
<Link href="/" className="flex items-center gap-2">
{settingsLoading ? (
<div className="h-10 w-10 rounded-sm bg-gray-100 animate-pulse" />
) : logoSrc ? (
// eslint-disable-next-line @next/next/no-img-element
<img src={logoSrc} alt="Logo" className="h-10 w-auto object-contain rounded-sm" />
) : (
<Image
src={churchLogo}
alt="Church logo"
width={50}
height={50}
className="rounded-sm object-contain"
priority
/>
)}
{!settingsLoading && (
<span className="text-xl font-bold" style={{ color: displayColor }}>{displayName}</span>
)}
</Link>
{/* Desktop links */}
<div className="hidden md:flex items-center space-x-6">
{navLinks.map(link => (
<Link
key={link.href}
href={link.href}
className={
"text-sm pb-0.5 border-b-2 transition-colors " +
(isActive(link.href)
? "text-brand-600 border-brand-600 font-medium"
: "text-gray-700 border-transparent hover:text-brand-600")
}
>
{link.label}
</Link>
))}
{/* Auth links are only known once the token has been validated —
rendering nothing here (instead of guessing "logged out") avoids
a Login/Register -> Dashboard/Logout flash on every load. */}
{!authLoading && authLinks.map(link =>
link.onClick ? (
<button
key={link.label}
onClick={link.onClick}
className="text-sm pb-0.5 border-b-2 border-transparent text-gray-700 hover:text-brand-600 transition-colors"
>
{link.label}
</button>
) : (
<Link
key={link.href}
href={link.href}
className={
"text-sm pb-0.5 border-b-2 transition-colors " +
(isActive(link.href)
? "text-brand-600 border-brand-600 font-medium"
: "text-gray-700 border-transparent hover:text-brand-600")
}
>
{link.label}
</Link>
)
)}
</div>
</nav>
</header>
<BottomNav />
</>
);
};