diff --git a/frontend/src/components/layout/Footer.tsx b/frontend/src/components/layout/Footer.tsx new file mode 100644 index 0000000..4c201dc --- /dev/null +++ b/frontend/src/components/layout/Footer.tsx @@ -0,0 +1,40 @@ +/** + * Footer Component + * Simple footer for authenticated pages + */ + +'use client'; + +import Link from 'next/link'; + +export function Footer() { + const currentYear = new Date().getFullYear(); + + return ( + + ); +} diff --git a/frontend/src/components/layout/Header.tsx b/frontend/src/components/layout/Header.tsx new file mode 100644 index 0000000..fd2537b --- /dev/null +++ b/frontend/src/components/layout/Header.tsx @@ -0,0 +1,159 @@ +/** + * Header Component + * Main navigation header for authenticated users + * Includes logo, navigation links, and user menu + */ + +'use client'; + +import Link from 'next/link'; +import { usePathname } from 'next/navigation'; +import { useAuthStore } from '@/stores/authStore'; +import { useLogout } from '@/lib/api/hooks/useAuth'; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from '@/components/ui/dropdown-menu'; +import { Button } from '@/components/ui/button'; +import { Avatar, AvatarFallback } from '@/components/ui/avatar'; +import { Settings, LogOut, User, Shield } from 'lucide-react'; +import { cn } from '@/lib/utils'; + +/** + * Get user initials for avatar + */ +function getUserInitials(firstName?: string | null, lastName?: string | null): string { + if (!firstName) return 'U'; + + const first = firstName.charAt(0).toUpperCase(); + const last = lastName?.charAt(0).toUpperCase() || ''; + + return `${first}${last}`; +} + +/** + * Navigation link component + */ +function NavLink({ + href, + children, + exact = false, +}: { + href: string; + children: React.ReactNode; + exact?: boolean; +}) { + const pathname = usePathname(); + const isActive = exact ? pathname === href : pathname.startsWith(href); + + return ( + + {children} + + ); +} + +export function Header() { + const { user } = useAuthStore(); + const { mutate: logout, isPending: isLoggingOut } = useLogout(); + + const handleLogout = () => { + logout(); + }; + + return ( +
+
+ {/* Logo */} +
+ + + FastNext + + + + {/* Navigation Links */} + +
+ + {/* Right side - User menu */} +
+ + + + + + +
+

+ {user?.first_name} {user?.last_name} +

+

+ {user?.email} +

+
+
+ + + + + Profile + + + + + + Settings + + + {user?.is_superuser && ( + + + + Admin Panel + + + )} + + + + {isLoggingOut ? 'Logging out...' : 'Log out'} + +
+
+
+
+
+ ); +} diff --git a/frontend/src/components/layout/index.ts b/frontend/src/components/layout/index.ts index 7283de4..31d5973 100755 --- a/frontend/src/components/layout/index.ts +++ b/frontend/src/components/layout/index.ts @@ -1,4 +1,7 @@ -// Layout components -// Examples: Header, Footer, Sidebar, Navigation, etc. +/** + * Layout Components + * Common layout elements for authenticated pages + */ -export {}; +export { Header } from './Header'; +export { Footer } from './Footer';