mirror of
https://github.com/RGJorge/ContainerFlow.git
synced 2026-08-03 07:21:42 +02:00
v0.0.24
This commit is contained in:
@@ -5,6 +5,7 @@ import {
|
||||
Play, Square, RotateCcw,
|
||||
} from "lucide-react";
|
||||
import type { Service, DockerEvent } from "../../shared/types";
|
||||
import { useT } from "../i18n";
|
||||
|
||||
export type Page = "dashboard" | "monitoring" | "settings";
|
||||
|
||||
@@ -53,6 +54,7 @@ interface NotificationBellProps {
|
||||
}
|
||||
|
||||
function NotificationBell({ events }: NotificationBellProps) {
|
||||
const { t } = useT();
|
||||
const [open, setOpen] = useState(false);
|
||||
const [lastSeen, setLastSeen] = useState(events.length);
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
@@ -93,10 +95,10 @@ function NotificationBell({ events }: NotificationBellProps) {
|
||||
{open && (
|
||||
<div className="absolute top-full right-0 mt-1.5 bg-slate-800 border border-slate-700 rounded-lg shadow-xl shadow-black/40 w-72 max-h-80 overflow-auto z-[9999]">
|
||||
<div className="px-3 py-2 border-b border-slate-700/60 text-xs font-semibold text-slate-400 uppercase tracking-wider">
|
||||
Recent Events
|
||||
{t("header.recentEvents")}
|
||||
</div>
|
||||
{recent.length === 0 ? (
|
||||
<div className="px-3 py-6 text-center text-sm text-slate-500">No events yet</div>
|
||||
<div className="px-3 py-6 text-center text-sm text-slate-500">{t("header.noEvents")}</div>
|
||||
) : (
|
||||
recent.map((ev, i) => (
|
||||
<div key={`${ev.service}-${ev.time}-${i}`} className="flex items-center gap-2.5 px-3 py-2 hover:bg-slate-700/40 transition-colors">
|
||||
@@ -133,14 +135,15 @@ export function HeaderBar({
|
||||
onPageChange,
|
||||
events,
|
||||
}: HeaderBarProps) {
|
||||
const { t, lang, setLang } = useT();
|
||||
|
||||
return (
|
||||
<div className="flex items-center justify-between px-5 py-1 bg-slate-900/90 backdrop-blur-sm relative z-[9999]">
|
||||
{/* Left: Navigation */}
|
||||
<nav className="flex items-center gap-1">
|
||||
<NavButton icon={LayoutDashboard} label="Dashboard" active={activePage === "dashboard"} onClick={() => onPageChange("dashboard")} />
|
||||
<NavButton icon={Activity} label="Monitoring" active={activePage === "monitoring"} onClick={() => onPageChange("monitoring")} />
|
||||
<NavButton icon={Settings} label="Settings" active={activePage === "settings"} onClick={() => onPageChange("settings")} />
|
||||
<NavButton icon={LayoutDashboard} label={t("header.dashboard")} active={activePage === "dashboard"} onClick={() => onPageChange("dashboard")} />
|
||||
<NavButton icon={Activity} label={t("header.monitoring")} active={activePage === "monitoring"} onClick={() => onPageChange("monitoring")} />
|
||||
<NavButton icon={Settings} label={t("header.settings")} active={activePage === "settings"} onClick={() => onPageChange("settings")} />
|
||||
</nav>
|
||||
|
||||
{/* Center: Logo */}
|
||||
@@ -175,6 +178,27 @@ export function HeaderBar({
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Language toggle */}
|
||||
<div className="flex items-center bg-slate-800 rounded-md border border-slate-700/50 overflow-hidden">
|
||||
<button
|
||||
onClick={() => setLang("en")}
|
||||
className={`px-2 py-1 text-[11px] font-semibold transition-colors ${
|
||||
lang === "en" ? "bg-cyan-500/20 text-cyan-400" : "text-slate-500 hover:text-slate-300"
|
||||
}`}
|
||||
>
|
||||
EN
|
||||
</button>
|
||||
<div className="w-px h-4 bg-slate-700/50" />
|
||||
<button
|
||||
onClick={() => setLang("es")}
|
||||
className={`px-2 py-1 text-[11px] font-semibold transition-colors ${
|
||||
lang === "es" ? "bg-cyan-500/20 text-cyan-400" : "text-slate-500 hover:text-slate-300"
|
||||
}`}
|
||||
>
|
||||
ES
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<NotificationBell events={events} />
|
||||
|
||||
{/* Logout (only if auth is active) */}
|
||||
|
||||
Reference in New Issue
Block a user