import React, { useMemo, useState, useEffect } from 'react'; import { Modal, Text, ActionIcon } from '@mantine/core'; import { useMediaQuery } from '@mantine/hooks'; import LocalIcon from './LocalIcon'; import Overview from './config/configSections/Overview'; import { createConfigNavSections } from './config/configNavSections'; import { NavKey } from './config/types'; import './AppConfigModal.css'; import { Z_INDEX_OVER_FULLSCREEN_SURFACE } from '../../styles/zIndex'; interface AppConfigModalProps { opened: boolean; onClose: () => void; } const AppConfigModal: React.FC = ({ opened, onClose }) => { const [active, setActive] = useState('overview'); const isMobile = useMediaQuery("(max-width: 1024px)"); useEffect(() => { const handler = (ev: Event) => { const detail = (ev as CustomEvent).detail as { key?: NavKey } | undefined; if (detail?.key) { setActive(detail.key); } }; window.addEventListener('appConfig:navigate', handler as EventListener); return () => window.removeEventListener('appConfig:navigate', handler as EventListener); }, []); const colors = useMemo(() => ({ navBg: 'var(--modal-nav-bg)', sectionTitle: 'var(--modal-nav-section-title)', navItem: 'var(--modal-nav-item)', navItemActive: 'var(--modal-nav-item-active)', navItemActiveBg: 'var(--modal-nav-item-active-bg)', contentBg: 'var(--modal-content-bg)', headerBorder: 'var(--modal-header-border)', }), []); // Placeholder logout handler (not needed in open-source but keeps SaaS compatibility) const handleLogout = () => { // In SaaS this would sign out, in open-source it does nothing console.log('Logout placeholder for SaaS compatibility'); }; // Left navigation structure and icons const configNavSections = useMemo(() => createConfigNavSections( Overview, handleLogout ), [] ); const activeLabel = useMemo(() => { for (const section of configNavSections) { const found = section.items.find(i => i.key === active); if (found) return found.label; } return ''; }, [configNavSections, active]); const activeComponent = useMemo(() => { for (const section of configNavSections) { const found = section.items.find(i => i.key === active); if (found) return found.component; } return null; }, [configNavSections, active]); return (
{/* Left navigation */}
{configNavSections.map(section => (
{!isMobile && ( {section.title} )}
{section.items.map(item => { const isActive = active === item.key; const color = isActive ? colors.navItemActive : colors.navItem; const iconSize = isMobile ? 28 : 18; return (
setActive(item.key)} className={`modal-nav-item ${isMobile ? 'mobile' : ''}`} style={{ background: isActive ? colors.navItemActiveBg : 'transparent', }} > {!isMobile && ( {item.label} )}
); })}
))}
{/* Right content */}
{/* Sticky header with section title and small close button */}
{activeLabel}
{activeComponent}
); }; export default AppConfigModal;