Spaces:
Sleeping
Sleeping
File size: 5,072 Bytes
198828b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | import React from 'react';
import { Button } from './ui/button';
import { Menu, Sun, Moon, Languages, ChevronDown } from 'lucide-react';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from './ui/dropdown-menu';
import clareAvatar from '../assets/dfe44dab3ad8cd93953eac4a3e68bd1a5f999653.png';
import type { Workspace } from '../App';
interface HeaderProps {
user: UserType | null;
onMenuClick: () => void;
onUserClick: () => void;
isDarkMode: boolean;
onToggleDarkMode: () => void;
language: Language;
onLanguageChange: (lang: Language) => void;
workspaces: Workspace[];
currentWorkspace: Workspace | undefined;
onWorkspaceChange: (workspaceId: string) => void;
}
type UserType = {
name: string;
email: string;
};
type Language = 'auto' | 'en' | 'zh';
export function Header({
user,
onMenuClick,
onUserClick,
isDarkMode,
onToggleDarkMode,
language,
onLanguageChange,
workspaces,
currentWorkspace,
onWorkspaceChange,
}: HeaderProps) {
const languageLabels = {
auto: 'Auto',
en: 'English',
zh: '简体中文',
};
return (
<header className="h-16 border-b border-border bg-card px-4 lg:px-6 flex items-center justify-between sticky top-0 z-[100]">
<div className="flex items-center gap-4">
<Button
variant="ghost"
size="icon"
className="lg:hidden"
onClick={onMenuClick}
>
<Menu className="h-5 w-5" />
</Button>
<div className="flex items-center gap-3">
<div className="w-10 h-10 rounded-full overflow-hidden bg-white flex items-center justify-center">
<img src={clareAvatar} alt="Clare AI" className="w-full h-full object-cover" />
</div>
<div>
<h1 className="text-lg sm:text-xl tracking-tight">
Clare <span className="text-sm font-bold text-muted-foreground hidden sm:inline ml-2">Your Personalized AI Tutor</span>
</h1>
<p className="text-xs text-muted-foreground hidden sm:block">
Personalized guidance, review, and intelligent reinforcement
</p>
</div>
</div>
</div>
<div className="flex items-center gap-2">
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
variant="ghost"
size="icon"
aria-label="Change language"
>
<Languages className="h-5 w-5" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={() => onLanguageChange('auto')}>
{language === 'auto' && '✓ '}Auto
</DropdownMenuItem>
<DropdownMenuItem onClick={() => onLanguageChange('en')}>
{language === 'en' && '✓ '}English
</DropdownMenuItem>
<DropdownMenuItem onClick={() => onLanguageChange('zh')}>
{language === 'zh' && '✓ '}简体中文
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<Button
variant="ghost"
size="icon"
onClick={onToggleDarkMode}
aria-label="Toggle dark mode"
>
{isDarkMode ? <Sun className="h-5 w-5" /> : <Moon className="h-5 w-5" />}
</Button>
{user && currentWorkspace ? (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
variant="outline"
className="gap-2 pl-2 pr-3"
aria-label="Switch workspace"
>
<img
src={currentWorkspace.avatar}
alt={currentWorkspace.name}
className="w-6 h-6 rounded-full object-cover"
/>
<span className="hidden sm:inline max-w-[120px] truncate">{currentWorkspace.name}</span>
<ChevronDown className="h-4 w-4 opacity-50" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="min-w-[14rem]">
{workspaces.map((workspace) => (
<DropdownMenuItem
key={workspace.id}
onClick={() => onWorkspaceChange(workspace.id)}
className={`gap-3 ${currentWorkspace.id === workspace.id ? 'bg-accent' : ''}`}
>
<img
src={workspace.avatar}
alt={workspace.name}
className="w-6 h-6 rounded-full object-cover flex-shrink-0"
/>
<span className="truncate">{workspace.name}</span>
{currentWorkspace.id === workspace.id && (
<span className="ml-auto text-primary">✓</span>
)}
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
) : null}
</div>
</header>
);
} |