Add professional historian modal with realtime analytics
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import {
|
||||
ChevronLeft,
|
||||
ChevronRight,
|
||||
CloudSun,
|
||||
Droplet,
|
||||
Home,
|
||||
@@ -8,70 +10,99 @@ import {
|
||||
} from "lucide-react";
|
||||
|
||||
import logo from "../../assets/logo.png";
|
||||
import type { AppPage } from "../../app/App";
|
||||
|
||||
type SidebarProps = {
|
||||
theme: "dark" | "light";
|
||||
activePage: AppPage;
|
||||
collapsed: boolean;
|
||||
onNavigate: (page: AppPage) => void;
|
||||
onToggleCollapsed: () => void;
|
||||
};
|
||||
|
||||
const navigationItems = [
|
||||
{ label: "Painel Principal", icon: Home, active: true },
|
||||
{ label: "Meteorologia", icon: CloudSun },
|
||||
const navigationItems: {
|
||||
label: string;
|
||||
page: AppPage;
|
||||
icon: React.ElementType;
|
||||
}[] = [
|
||||
{ label: "Painel Principal", page: "dashboard", icon: Home },
|
||||
{ label: "Meteorologia", page: "meteo", icon: CloudSun },
|
||||
];
|
||||
|
||||
const disabledItems = [
|
||||
{ label: "Consola (VNC)", icon: TabletSmartphone },
|
||||
{ label: "Rega", icon: Droplet },
|
||||
{ label: "Clima", icon: Wind },
|
||||
{ label: "Configurações", icon: Settings },
|
||||
];
|
||||
|
||||
export function Sidebar({ theme }: SidebarProps) {
|
||||
export function Sidebar({
|
||||
theme,
|
||||
activePage,
|
||||
collapsed,
|
||||
onNavigate,
|
||||
onToggleCollapsed,
|
||||
}: SidebarProps) {
|
||||
const isDark = theme === "dark";
|
||||
|
||||
return (
|
||||
<aside
|
||||
className={
|
||||
isDark
|
||||
? "flex min-h-screen w-64 flex-col bg-[#0B1620] px-4 py-5 shadow-[inset_-1px_0_0_0_rgba(80,100,120,0.25),2px_0_12px_rgba(0,0,0,0.15)]"
|
||||
: "flex min-h-screen w-64 flex-col bg-[#EEF3F7] px-4 py-5 shadow-[inset_-1px_0_0_0_rgba(180,190,200,0.5)]"
|
||||
? `${collapsed ? "w-20" : "w-64"} flex h-full flex-col bg-[#0B1620] px-4 py-5 shadow-[inset_-1px_0_0_0_rgba(80,100,120,0.25),2px_0_12px_rgba(0,0,0,0.15)] transition-all duration-200`
|
||||
: `${collapsed ? "w-20" : "w-64"} flex h-full flex-col bg-[#EEF3F7] px-4 py-5 shadow-[inset_-1px_0_0_0_rgba(180,190,200,0.5)] transition-all duration-200`
|
||||
}
|
||||
>
|
||||
<div className="mb-10 flex items-center gap-3 px-2">
|
||||
<div
|
||||
className={
|
||||
collapsed
|
||||
? "mb-10 flex items-center justify-center"
|
||||
: "mb-10 flex items-center gap-3 px-2"
|
||||
}
|
||||
>
|
||||
<img
|
||||
src={logo}
|
||||
alt="LitoralRegas"
|
||||
className="h-12 w-12 shrink-0 object-contain"
|
||||
/>
|
||||
|
||||
<div className="min-w-0">
|
||||
<div
|
||||
className={
|
||||
isDark
|
||||
? "truncate text-[16px] font-bold tracking-wide text-white"
|
||||
: "truncate text-[16px] font-bold tracking-wide text-[#162434]"
|
||||
}
|
||||
>
|
||||
LITORAL CENTRAL
|
||||
</div>
|
||||
{!collapsed && (
|
||||
<div className="min-w-0">
|
||||
<div
|
||||
className={
|
||||
isDark
|
||||
? "truncate text-[16px] font-bold tracking-wide text-white"
|
||||
: "truncate text-[16px] font-bold tracking-wide text-[#162434]"
|
||||
}
|
||||
>
|
||||
LITORAL CENTRAL
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={
|
||||
isDark
|
||||
? "mt-0.5 text-[10px] uppercase tracking-[0.18em] text-[#8FA3B8]"
|
||||
: "mt-0.5 text-[10px] uppercase tracking-[0.18em] text-[#607284]"
|
||||
}
|
||||
>
|
||||
OPERAÇÕES AGRÍCOLAS
|
||||
<div
|
||||
className={
|
||||
isDark
|
||||
? "mt-0.5 text-[10px] uppercase tracking-[0.18em] text-[#8FA3B8]"
|
||||
: "mt-0.5 text-[10px] uppercase tracking-[0.18em] text-[#607284]"
|
||||
}
|
||||
>
|
||||
OPERAÇÕES AGRÍCOLAS
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<nav className="space-y-2">
|
||||
{navigationItems.map((item) => {
|
||||
const Icon = item.icon;
|
||||
const active = activePage === item.page;
|
||||
|
||||
return (
|
||||
<button
|
||||
key={item.label}
|
||||
onClick={() => onNavigate(item.page)}
|
||||
title={collapsed ? item.label : undefined}
|
||||
className={
|
||||
item.active
|
||||
active
|
||||
? isDark
|
||||
? "flex w-full items-center gap-3 rounded-xl bg-[#18304B] px-4 py-3 text-left text-sm font-semibold text-white"
|
||||
: "flex w-full items-center gap-3 rounded-xl bg-[#DCE8F5] px-4 py-3 text-left text-sm font-semibold text-[#162434]"
|
||||
@@ -80,22 +111,50 @@ export function Sidebar({ theme }: SidebarProps) {
|
||||
: "flex w-full items-center gap-3 rounded-xl px-4 py-3 text-left text-sm font-medium text-[#445569] hover:bg-[#E2E8F0] hover:text-[#162434]"
|
||||
}
|
||||
>
|
||||
<Icon className="h-5 w-5" />
|
||||
{item.label}
|
||||
<Icon className="h-5 w-5 shrink-0" />
|
||||
{!collapsed && <span>{item.label}</span>}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
|
||||
{disabledItems.map((item) => {
|
||||
const Icon = item.icon;
|
||||
|
||||
return (
|
||||
<button
|
||||
key={item.label}
|
||||
disabled
|
||||
title={collapsed ? item.label : undefined}
|
||||
className={
|
||||
isDark
|
||||
? "flex w-full cursor-not-allowed items-center gap-3 rounded-xl px-4 py-3 text-left text-sm font-medium text-[#607284] opacity-60"
|
||||
: "flex w-full cursor-not-allowed items-center gap-3 rounded-xl px-4 py-3 text-left text-sm font-medium text-[#8A9AAB] opacity-70"
|
||||
}
|
||||
>
|
||||
<Icon className="h-5 w-5 shrink-0" />
|
||||
{!collapsed && <span>{item.label}</span>}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</nav>
|
||||
|
||||
<div
|
||||
<button
|
||||
onClick={onToggleCollapsed}
|
||||
className={
|
||||
isDark
|
||||
? "mt-auto px-4 text-sm text-slate-400"
|
||||
: "mt-auto px-4 text-sm text-[#607284]"
|
||||
? "mt-auto flex items-center justify-center gap-2 rounded-xl px-4 py-3 text-sm text-slate-400 hover:bg-[#132434] hover:text-white"
|
||||
: "mt-auto flex items-center justify-center gap-2 rounded-xl px-4 py-3 text-sm text-[#607284] hover:bg-[#E2E8F0] hover:text-[#162434]"
|
||||
}
|
||||
>
|
||||
Recolher menu
|
||||
</div>
|
||||
{collapsed ? (
|
||||
<ChevronRight className="h-5 w-5" />
|
||||
) : (
|
||||
<>
|
||||
<ChevronLeft className="h-5 w-5" />
|
||||
<span>Recolher menu</span>
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user