feat: 3.01 header logos+nav, 3.09 dynamic contact types, 3.10 hot-desk window, 3.11 vault email+link

This commit is contained in:
AI Assistant
2026-02-27 11:33:20 +02:00
parent 100e52222e
commit 042e4e1108
6 changed files with 242 additions and 57 deletions
+59 -18
View File
@@ -3,7 +3,7 @@
import Image from "next/image";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { useMemo } from "react";
import { useMemo, useState, useCallback, useEffect } from "react";
import * as Icons from "lucide-react";
import { buildNavigation } from "@/config/navigation";
import { COMPANIES } from "@/config/companies";
@@ -64,24 +64,61 @@ function NavItem({
);
}
function SidebarLogo() {
const sdt = COMPANIES["studii-de-teren"];
const LOGO_COMPANIES = ["studii-de-teren", "urban-switch"] as const;
const logoSrc = sdt.logo?.light ?? null;
function SidebarLogos() {
const [clickCount, setClickCount] = useState(0);
const [shuffled, setShuffled] = useState(false);
if (!logoSrc) {
return <Icons.LayoutDashboard className="h-5 w-5 text-primary" />;
}
const handleLogoClick = useCallback(() => {
setClickCount((prev) => {
const next = prev + 1;
if (next >= 3) {
setShuffled((s) => !s);
return 0;
}
return next;
});
}, []);
// Reset click count after 2 seconds of inactivity
useEffect(() => {
if (clickCount === 0) return;
const timer = setTimeout(() => setClickCount(0), 2000);
return () => clearTimeout(timer);
}, [clickCount]);
const logos = shuffled ? [...LOGO_COMPANIES].reverse() : [...LOGO_COMPANIES];
return (
<Image
src={logoSrc}
alt={sdt.shortName}
width={28}
height={28}
className="h-7 w-7 shrink-0"
suppressHydrationWarning
/>
<div className="flex items-center gap-1.5">
{logos.map((companyId) => {
const company = COMPANIES[companyId];
const logoSrc = company?.logo?.light;
if (!logoSrc) return null;
return (
<button
key={companyId}
type="button"
onClick={handleLogoClick}
className={cn(
"relative shrink-0 rounded-md p-0.5 transition-all duration-300 hover:scale-110 focus:outline-none",
shuffled && "animate-pulse",
)}
title={company.shortName}
>
<Image
src={logoSrc}
alt={company.shortName}
width={36}
height={36}
className="h-9 w-9 object-contain"
suppressHydrationWarning
/>
</button>
);
})}
</div>
);
}
@@ -91,10 +128,14 @@ export function Sidebar() {
return (
<aside className="flex h-full w-64 shrink-0 flex-col border-r bg-card">
<div className="flex h-14 items-center gap-2 border-b px-4">
<SidebarLogo />
<Link
href="/"
className="flex h-14 items-center gap-2.5 border-b px-4 transition-colors hover:bg-accent/30"
title="Panou principal"
>
<SidebarLogos />
<span className="text-lg font-semibold">ArchiTools</span>
</div>
</Link>
<ScrollArea className="flex-1 px-3 py-3">
<Link