Files
flyer-crawler.projectium.com/components/Header.tsx
Torben Sorensen 5eba160a55
All checks were successful
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Successful in 3m21s
move the "System Check" to a new admin area
2025-11-11 12:47:38 -08:00

140 lines
6.1 KiB
TypeScript

import React, { useState } from 'react';
import { ShoppingCartIcon } from './icons/ShoppingCartIcon';
import { DarkModeToggle } from './DarkModeToggle';
import { UnitSystemToggle } from './UnitSystemToggle';
import { Session } from '@supabase/supabase-js';
import { supabase } from '../services/supabaseClient';
import { AuthModal } from './AuthModal';
import { SignUpModal } from './SignUpModal';
import { UserIcon } from './icons/UserIcon';
import { Cog8ToothIcon } from './icons/Cog8ToothIcon';
import { MicrophoneIcon } from './icons/MicrophoneIcon';
import { Link } from 'react-router-dom';
import { ShieldCheckIcon } from './icons/ShieldCheckIcon';
import { Profile } from '../types';
type AuthStatus = 'SIGNED_OUT' | 'ANONYMOUS' | 'AUTHENTICATED';
interface HeaderProps {
isDarkMode: boolean;
toggleDarkMode: () => void;
unitSystem: 'metric' | 'imperial';
toggleUnitSystem: () => void;
session: Session | null;
authStatus: AuthStatus;
profile: Profile | null;
onOpenProfile: () => void;
onOpenVoiceAssistant: () => void;
onSignOut: () => void;
}
export const Header: React.FC<HeaderProps> = ({ isDarkMode, toggleDarkMode, unitSystem, toggleUnitSystem, session, authStatus, profile, onOpenProfile, onOpenVoiceAssistant, onSignOut }) => {
const [isSignInModalOpen, setIsSignInModalOpen] = useState(false);
const [isSignUpModalOpen, setIsSignUpModalOpen] = useState(false);
const openSignIn = () => {
setIsSignUpModalOpen(false);
setIsSignInModalOpen(true);
};
const openSignUp = () => {
setIsSignInModalOpen(false);
setIsSignUpModalOpen(true);
};
return (
<>
<header className="bg-white dark:bg-gray-900 shadow-md sticky top-0 z-20">
<div className="max-w-screen-2xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex items-center justify-between h-16">
<div className="flex items-center">
<ShoppingCartIcon className="h-8 w-8 text-brand-primary" />
<h1 className="ml-3 text-2xl font-bold text-gray-800 dark:text-white">
Flyer Crawler
</h1>
</div>
<div className="flex items-center space-x-4 md:space-x-6">
{session && (
<button
onClick={onOpenVoiceAssistant}
className="p-1.5 rounded-full hover:bg-gray-100 dark:hover:bg-gray-700/50 text-gray-500 dark:text-gray-400 transition-colors"
aria-label="Open voice assistant"
title="Voice Assistant"
>
<MicrophoneIcon className="w-5 h-5" />
</button>
)}
<UnitSystemToggle currentSystem={unitSystem} onToggle={toggleUnitSystem} />
<DarkModeToggle isDarkMode={isDarkMode} onToggle={toggleDarkMode} />
<div className="w-px h-6 bg-gray-200 dark:bg-gray-700 hidden sm:block"></div>
{session ? (
<div className="flex items-center space-x-3">
<div className="hidden md:flex items-center space-x-2 text-sm">
<UserIcon className="w-5 h-5 text-gray-500 dark:text-gray-400" />
{authStatus === 'AUTHENTICATED' ? (
<span className="font-medium text-gray-700 dark:text-gray-300">{session.user.email}</span>
) : (
<span className="font-medium text-gray-500 dark:text-gray-400 italic">Guest</span>
)}
</div>
<button
onClick={onOpenProfile}
className="p-1.5 rounded-md hover:bg-gray-100 dark:hover:bg-gray-700/50 text-gray-500 dark:text-gray-400 transition-colors"
aria-label="Open my account settings"
title="My Account"
>
<Cog8ToothIcon className="w-5 h-5" />
</button>
{profile?.role === 'admin' && (
<Link to="/admin" className="p-1.5 rounded-md hover:bg-gray-100 dark:hover:bg-gray-700/50 text-gray-500 dark:text-gray-400 transition-colors" title="Admin Area">
<ShieldCheckIcon className="w-5 h-5" />
</Link>
)}
<button
onClick={onOpenProfile}
className="p-1.5 rounded-md hover:bg-gray-100 dark:hover:bg-gray-700/50 text-gray-500 dark:text-gray-400 transition-colors"
aria-label="Open my account settings"
title="My Account"
>
<Cog8ToothIcon className="w-5 h-5" />
</button>
<button
onClick={onSignOut}
className="text-sm font-semibold text-gray-600 hover:text-brand-primary dark:text-gray-300 dark:hover:text-brand-light transition-colors"
>
Logout
</button>
</div>
) : (
<div className="flex items-center space-x-2">
<button
onClick={openSignIn}
className="text-sm font-semibold text-gray-600 hover:text-brand-primary dark:text-gray-300 dark:hover:text-brand-light transition-colors"
>
Login
</button>
<button
onClick={openSignUp}
className="px-3 py-1.5 text-sm font-semibold text-white bg-brand-primary hover:bg-brand-secondary rounded-md transition-colors"
>
Sign Up
</button>
</div>
)}
</div>
</div>
</div>
</header>
{isSignInModalOpen && supabase && (
<AuthModal
isOpen={isSignInModalOpen}
onClose={() => setIsSignInModalOpen(false)}
onSwitchToSignUp={openSignUp}
/>
)}
{isSignUpModalOpen && supabase && (
<SignUpModal isOpen={isSignUpModalOpen} onClose={() => setIsSignUpModalOpen(false)} onSwitchToSignIn={openSignIn} />
)}
</>
);
};