This commit is contained in:
2026-11-02 08:06:45 +02:00
parent e4f520092e
commit 2a4169162b
108 changed files with 3793 additions and 88 deletions
+26
View File
@@ -0,0 +1,26 @@
import React from 'react';
const sections = {
commercial:['services','billing','billing_support'], purchasing:['purchasing'], stock:['stock'],
workshop:['workshop'], finance:['receivables','costs'], accounting:['accounting'],
};
export function moduleGroups(groups, module) {
if(!sections[module])return [];
const own=groups.filter(g => sections[module].includes(g.id));
if(module==='commercial')return own;
const shared=groups.flatMap(g=>g.items).filter(i=>['clients','services','service_drafts','billing_drafts'].includes(i.id));
return shared.length?[...own,{id:'shared_records',label:'Cadastros e rascunhos do módulo',items:shared}]:own;
}
export default function ModuleNavigation({groups, context, page, navigate, changeModule, user, busy, logout}) {
const active=context?.modules?.find(m=>m.id===context.module_id);
const own=moduleGroups(groups,active?.id);
return <div className="module-navigation">
<div className="module-topbar"><button className="topbar-brand" onClick={()=>navigate('home')}>TEMPO <span>SGF</span></button>
<nav aria-label="Menu principal"><label>Módulo activo<select aria-label="Módulo activo" value={active?.id||''} disabled={busy} onChange={e=>changeModule(e.target.value||null)}><option value="">Escolher módulo</option>{context?.modules?.map(m=><option key={m.id} value={m.id}>{m.label}{m.development?' · desenvolvimento':''}</option>)}</select></label></nav>
<nav aria-label="Opções gerais"><button aria-current={page==='home'?'page':undefined} onClick={()=>navigate('home')}>Início</button>{groups.find(g=>g.id==='admin')?.items.map(i=><button key={i.id} aria-current={page===i.id?'page':undefined} onClick={()=>navigate(i.id)}>{i.label}</button>)}</nav>
<div className="topbar-account"><strong>{user.name}</strong><button disabled={busy} onClick={logout}>Sair</button></div>
</div>
<nav className="module-menu" aria-label={active?`Navegação de ${active.label}`:'Navegação do módulo'}><strong>{active?.label||'Nenhum módulo seleccionado'}</strong>{own.map(g=><details key={g.id}><summary>{g.label}</summary><div>{g.items.map(i=><button key={i.id} aria-current={page===i.id?'page':undefined} onClick={()=>navigate(i.id)}>{i.label}{i.informational?' · Em preparação':''}</button>)}</div></details>)}{active&&!own.length&&<span>Sem funcionalidades autorizadas neste contexto.</span>}</nav>
</div>;
}