Add ticket system with QR scanner and PDF generation
- Add ticket validation and check-in API endpoints - Add PDF ticket generation with QR codes (pdfkit) - Add admin QR scanner page with camera support - Add admin site settings page - Update email templates with PDF ticket download link - Add checked_in_by_admin_id field for audit tracking - Update booking success page with ticket download - Various UI improvements to events and booking pages
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
import Link from 'next/link';
|
||||
import Image from 'next/image';
|
||||
import { useState } from 'react';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import { useLanguage } from '@/context/LanguageContext';
|
||||
import { useAuth } from '@/context/AuthContext';
|
||||
import LanguageToggle from '@/components/LanguageToggle';
|
||||
@@ -10,6 +11,37 @@ import Button from '@/components/ui/Button';
|
||||
import { Bars3Icon, XMarkIcon } from '@heroicons/react/24/outline';
|
||||
import clsx from 'clsx';
|
||||
|
||||
function NavLink({ href, children }: { href: string; children: React.ReactNode }) {
|
||||
const pathname = usePathname();
|
||||
const isActive = pathname === href || (href !== '/' && pathname.startsWith(href));
|
||||
|
||||
return (
|
||||
<Link
|
||||
href={href}
|
||||
className="font-medium transition-colors"
|
||||
style={{ color: isActive ? '#FBB82B' : '#002F44' }}
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
function MobileNavLink({ href, children, onClick }: { href: string; children: React.ReactNode; onClick: () => void }) {
|
||||
const pathname = usePathname();
|
||||
const isActive = pathname === href || (href !== '/' && pathname.startsWith(href));
|
||||
|
||||
return (
|
||||
<Link
|
||||
href={href}
|
||||
className="px-4 py-2 hover:bg-gray-50 rounded-lg font-medium"
|
||||
style={{ color: isActive ? '#FBB82B' : '#002F44' }}
|
||||
onClick={onClick}
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Header() {
|
||||
const { t } = useLanguage();
|
||||
const { user, isAdmin, logout } = useAuth();
|
||||
@@ -41,13 +73,9 @@ export default function Header() {
|
||||
{/* Desktop Navigation */}
|
||||
<div className="hidden md:flex items-center gap-6">
|
||||
{navLinks.map((link) => (
|
||||
<Link
|
||||
key={link.href}
|
||||
href={link.href}
|
||||
className="text-gray-700 hover:text-primary-dark font-medium transition-colors"
|
||||
>
|
||||
<NavLink key={link.href} href={link.href}>
|
||||
{link.label}
|
||||
</Link>
|
||||
</NavLink>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -115,14 +143,13 @@ export default function Header() {
|
||||
>
|
||||
<div className="flex flex-col gap-2 pt-4">
|
||||
{navLinks.map((link) => (
|
||||
<Link
|
||||
<MobileNavLink
|
||||
key={link.href}
|
||||
href={link.href}
|
||||
className="px-4 py-2 text-gray-700 hover:bg-gray-50 rounded-lg font-medium"
|
||||
onClick={() => setMobileMenuOpen(false)}
|
||||
>
|
||||
{link.label}
|
||||
</Link>
|
||||
</MobileNavLink>
|
||||
))}
|
||||
|
||||
<div className="border-t border-gray-100 mt-2 pt-4 px-4">
|
||||
|
||||
Reference in New Issue
Block a user