diff --git a/apps/frontend/public/images/logo.png b/apps/frontend/public/images/logo.png new file mode 100644 index 0000000..10b3c35 Binary files /dev/null and b/apps/frontend/public/images/logo.png differ diff --git a/apps/frontend/src/components/sidebar/ISidebar.ts b/apps/frontend/src/components/sidebar/ISidebar.ts index d4ee5e9..592b8bb 100644 --- a/apps/frontend/src/components/sidebar/ISidebar.ts +++ b/apps/frontend/src/components/sidebar/ISidebar.ts @@ -1,14 +1,17 @@ -import { RouteKey } from './SidebarEnum'; import { ElementType } from 'react'; +import { RouteKey } from './SidebarEnum'; export type NavItem = { key: RouteKey; label: string; icon: ElementType; + sublabel?: string; href?: string; }; export type SidebarProps = { active?: RouteKey; onNavigate?: (key: RouteKey) => void; + logoUrl?: string; // default: /images/logo.png + user?: { name: string; role?: string }; }; diff --git a/apps/frontend/src/components/sidebar/sidebar.tsx b/apps/frontend/src/components/sidebar/sidebar.tsx index 6499386..c99fcb1 100644 --- a/apps/frontend/src/components/sidebar/sidebar.tsx +++ b/apps/frontend/src/components/sidebar/sidebar.tsx @@ -14,7 +14,7 @@ import { UserCircle2, } from 'lucide-react'; -const items: NavItem[] = [ +const navItems: NavItem[] = [ { key: RouteKey.Dashboard, label: 'Dashboard', icon: LayoutDashboard }, { key: RouteKey.Daily, label: 'Daily', icon: Info }, { key: RouteKey.Users, label: 'User', icon: Users }, @@ -24,104 +24,80 @@ const items: NavItem[] = [ { key: RouteKey.Sections, label: 'Edit Sections', icon: SlidersHorizontal }, ]; -const Sidebar: FC = ({ active, onNavigate }) => { +const baseItem = + 'w-full flex items-center gap-3 rounded-lg px-3 py-2 text-sm transition-[background,color] duration-150 focus:outline-none ' + + 'focus-visible:ring-2 focus-visible:ring-[var(--ring-color)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--ring-offset)]'; + +const labelShow = + 'pointer-events-none origin-left scale-0 opacity-0 transition-all duration-200 group-hover:scale-100 group-hover:opacity-100'; + +const Sidebar: FC = ({ active, onNavigate, logoUrl = '/images/logo.png', user }) => { + const userName = user?.name ?? 'Gianluca Barbieri'; + const userRole = user?.role ?? 'Lernender'; + + const renderItem = ({ key, label, icon: Icon, sublabel }: NavItem) => { + const isActive = active === key; + return ( + + ); + }; + return ( diff --git a/apps/frontend/src/index.css b/apps/frontend/src/index.css index c266f27..86f9100 100644 --- a/apps/frontend/src/index.css +++ b/apps/frontend/src/index.css @@ -2,9 +2,7 @@ @tailwind components; @tailwind utilities; -/* Theme + Tokens mit Hex UND RGB-Kanälen, State- und Surface-Varianten */ @layer base { - /* Default = Light (per :root) + optional über data-theme steuerbar */ :root, [data-theme='light'] { /* Core Hex */ @@ -46,6 +44,10 @@ --primary-active: color-mix(in srgb, var(--primary) 85%, black); --border-strong: color-mix(in srgb, var(--border) 80%, black); + --primary-background: rgb( + calc(34 + (255 - 34) * 0.2) calc(45 + (255 - 45) * 0.2) calc(67 + (255 - 67) * 0.2) + ); + /* Surfaces (semantische Ebenen) */ --surface-1: var(--card); --surface-2: color-mix(in srgb, var(--surface-1) 92%, var(--accent)); @@ -98,6 +100,10 @@ --primary-active: color-mix(in srgb, var(--primary) 80%, black); --border-strong: color-mix(in srgb, var(--border) 80%, white); + --primary-background: rgb( + calc(20 + (255 - 20) * 0.15) calc(25 + (255 - 25) * 0.15) calc(35 + (255 - 35) * 0.15) + ); + --surface-1: var(--card); --surface-2: color-mix(in srgb, var(--surface-1) 92%, white); --surface-3: color-mix(in srgb, var(--surface-1) 85%, white); @@ -109,7 +115,6 @@ --overlay-12: rgb(var(--accent-rgb) / 0.12); } - /* Basis-Anwendung */ html { --bg: var(--background); --fg: var(--foreground); @@ -117,9 +122,7 @@ } } -/* Optionale Komponenten/Utilities */ @layer components { - /* Wiederverwendbarer Fokus-Ring */ .focus-ring { @apply focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring-color)] @@ -129,7 +132,6 @@ } @layer utilities { - /* Bewegung reduzieren respektieren */ @media (prefers-reduced-motion: reduce) { .no-motion { transition: none !important;