Pulse/frontend-modern/src/components/Proxmox/ProxmoxSectionNav.tsx
2025-10-22 16:10:15 +00:00

79 lines
2.3 KiB
TypeScript

import type { Component } from 'solid-js';
import { createMemo, For } from 'solid-js';
import { useNavigate } from '@solidjs/router';
import { useWebSocket } from '@/App';
type ProxmoxSection = 'overview' | 'storage' | 'replication' | 'backups' | 'mail';
interface ProxmoxSectionNavProps {
current: ProxmoxSection;
class?: string;
}
const allSections: Array<{
id: ProxmoxSection;
label: string;
path: string;
}> = [
{
id: 'overview',
label: 'Overview',
path: '/proxmox/overview',
},
{
id: 'storage',
label: 'Storage',
path: '/proxmox/storage',
},
{
id: 'replication',
label: 'Replication',
path: '/proxmox/replication',
},
{
id: 'mail',
label: 'Mail Gateway',
path: '/proxmox/mail',
},
{
id: 'backups',
label: 'Backups',
path: '/proxmox/backups',
},
];
export const ProxmoxSectionNav: Component<ProxmoxSectionNavProps> = (props) => {
const navigate = useNavigate();
const { state } = useWebSocket();
// Only show Mail Gateway tab if PMG instances are configured
const sections = createMemo(() => {
const hasPMG = state.pmg && state.pmg.length > 0;
return allSections.filter((section) => section.id !== 'mail' || hasPMG);
});
const baseClasses =
'inline-flex items-center px-2 sm:px-3 py-1 text-xs sm:text-sm font-medium border-b-2 border-transparent text-gray-600 dark:text-gray-400 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-400/60 focus-visible:ring-offset-2 focus-visible:ring-offset-white dark:focus-visible:ring-offset-gray-900';
return (
<div class={`flex flex-wrap items-center gap-3 sm:gap-4 ${props.class ?? ''}`} aria-label="Proxmox sections">
<For each={sections()}>{(section) => {
const isActive = section.id === props.current;
const classes = isActive
? `${baseClasses} text-blue-600 dark:text-blue-300 border-blue-500 dark:border-blue-400`
: `${baseClasses} hover:text-blue-500 dark:hover:text-blue-300 hover:border-blue-300/70 dark:hover:border-blue-500/50`;
return (
<button
type="button"
class={classes}
onClick={() => navigate(section.path)}
aria-pressed={isActive}
>
<span>{section.label}</span>
</button>
);
}}</For>
</div>
);
};