Blog

bash

cat > /home/claude/dosar-horeca.html << 'HTMLEOF'
<!DOCTYPE html>
<html lang="ro">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dosar HoReCa — Control Documente</title>
<script src="https://cdn.jsdelivr.net/npm/@supabase/supabase-js@2"></script>
<style>
@import url('https://fonts.googleapis.com/css2?family=DM+Sans:wght@300;400;500;600&family=DM+Mono:wght@400;500&display=swap');

:root {
  --bg: #0F0F0F;
  --bg2: #181818;
  --bg3: #212121;
  --bg4: #2A2A2A;
  --border: #2E2E2E;
  --border2: #3A3A3A;
  --text: #F0EEE8;
  --text2: #9A9890;
  --text3: #6A6860;
  --accent: #E8C547;
  --accent2: #C9A830;
  --red: #E24B4A;
  --red-bg: #2A1818;
  --orange: #EF9F27;
  --orange-bg: #2A2010;
  --green: #5CB85C;
  --green-bg: #152015;
  --blue: #4A9EE8;
  --blue-bg: #101E2A;
  --radius: 10px;
  --radius-sm: 6px;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

body {
  font-family: 'DM Sans', sans-serif;
  background: var(--bg);
  color: var(--text);
  min-height: 100vh;
  font-size: 14px;
}

/* LAYOUT */
.layout { display: flex; min-height: 100vh; }

.sidebar {
  width: 220px;
  background: var(--bg2);
  border-right: 0.5px solid var(--border);
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  position: fixed;
  top: 0; left: 0; bottom: 0;
  z-index: 10;
}

.sidebar-logo {
  padding: 20px 18px 16px;
  border-bottom: 0.5px solid var(--border);
}
.sidebar-logo-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--accent);
  letter-spacing: -0.02em;
}
.sidebar-logo-sub {
  font-size: 11px;
  color: var(--text3);
  margin-top: 2px;
  font-family: 'DM Mono', monospace;
}

.sidebar-nav { padding: 10px 10px; flex: 1; }

.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-size: 13px;
  color: var(--text2);
  margin-bottom: 2px;
  transition: all 0.15s;
  border: none;
  background: none;
  width: 100%;
  text-align: left;
  font-family: 'DM Sans', sans-serif;
}
.nav-item:hover { background: var(--bg3); color: var(--text); }
.nav-item.active { background: var(--bg3); color: var(--text); font-weight: 500; }
.nav-item.active .nav-icon { color: var(--accent); }
.nav-icon { font-size: 15px; flex-shrink: 0; }
.nav-badge {
  margin-left: auto;
  background: var(--red-bg);
  color: var(--red);
  font-size: 10px;
  font-weight: 600;
  padding: 1px 6px;
  border-radius: 10px;
  font-family: 'DM Mono', monospace;
}
.nav-badge.warn { background: var(--orange-bg); color: var(--orange); }

.sidebar-footer {
  padding: 12px 14px;
  border-top: 0.5px solid var(--border);
  font-size: 11px;
  color: var(--text3);
  font-family: 'DM Mono', monospace;
}

.main {
  margin-left: 220px;
  flex: 1;
  min-height: 100vh;
}

.topbar {
  background: var(--bg2);
  border-bottom: 0.5px solid var(--border);
  padding: 14px 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  position: sticky;
  top: 0;
  z-index: 5;
}
.topbar-title { font-size: 16px; font-weight: 500; }
.topbar-sub { font-size: 12px; color: var(--text3); margin-top: 1px; }

.content { padding: 20px 24px; }

/* ALERTS */
.alert {
  border-radius: var(--radius-sm);
  padding: 10px 14px;
  font-size: 12px;
  margin-bottom: 8px;
  border: 0.5px solid;
  line-height: 1.5;
}
.al-red { background: var(--red-bg); color: #F08080; border-color: #5A2020; }
.al-orange { background: var(--orange-bg); color: #F0B060; border-color: #5A4010; }
.al-green { background: var(--green-bg); color: #80C880; border-color: #1A4A1A; }

/* STATS */
.stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
  margin-bottom: 20px;
}
.stat {
  background: var(--bg2);
  border: 0.5px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 16px;
}
.stat-n { font-size: 28px; font-weight: 600; line-height: 1; font-family: 'DM Mono', monospace; }
.stat-l { font-size: 11px; color: var(--text3); margin-top: 5px; text-transform: uppercase; letter-spacing: 0.06em; }
.stat-exp .stat-n { color: var(--red); }
.stat-sn .stat-n { color: var(--orange); }
.stat-ok .stat-n { color: var(--green); }
.stat-acc .stat-n { color: var(--accent); }

/* BUTTONS */
.btn {
  padding: 7px 14px;
  border-radius: var(--radius-sm);
  font-size: 12px;
  cursor: pointer;
  border: 0.5px solid var(--border2);
  background: var(--bg3);
  color: var(--text2);
  font-family: 'DM Sans', sans-serif;
  transition: all 0.15s;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.btn:hover { background: var(--bg4); color: var(--text); }
.btn-primary { background: var(--accent); color: #0F0F0F; border-color: var(--accent); font-weight: 600; }
.btn-primary:hover { background: var(--accent2); border-color: var(--accent2); }
.btn-danger { background: var(--red-bg); color: var(--red); border-color: #5A2020; }
.btn-info { background: var(--blue-bg); color: var(--blue); border-color: #1A3A5A; }
.btn-sm { padding: 4px 9px; font-size: 11px; }

/* TOOLBAR */
.toolbar {
  display: flex;
  gap: 8px;
  margin-bottom: 14px;
  flex-wrap: wrap;
  align-items: center;
}
.toolbar input, .toolbar select {
  padding: 7px 11px;
  border: 0.5px solid var(--border2);
  border-radius: var(--radius-sm);
  font-size: 12px;
  background: var(--bg2);
  color: var(--text);
  font-family: 'DM Sans', sans-serif;
}
.toolbar input { flex: 1; min-width: 160px; }
.toolbar input::placeholder { color: var(--text3); }

/* SUBTABS */
.subtabs {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}
.stab {
  padding: 5px 12px;
  border: 0.5px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: 12px;
  cursor: pointer;
  background: var(--bg2);
  color: var(--text2);
  display: flex;
  align-items: center;
  gap: 6px;
  transition: all 0.12s;
  font-family: 'DM Sans', sans-serif;
}
.stab.active { border-color: var(--accent); color: var(--accent); background: rgba(232,197,71,0.08); }
.stab:hover { color: var(--text); border-color: var(--border2); }

/* CARDS */
.card {
  background: var(--bg2);
  border: 0.5px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: 8px;
  overflow: hidden;
  transition: border-color 0.15s;
}
.card:hover { border-color: var(--border2); }
.card.st-exp { border-left: 2px solid var(--red); }
.card.st-sn { border-left: 2px solid var(--orange); }
.card.st-ok { border-left: 2px solid var(--green); }
.card.st-nd { border-left: 2px solid var(--border2); }
.card.st-lip { border-left: 2px solid var(--orange); }

.card-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
}
.card-head.clickable { cursor: pointer; }
.avatar {
  width: 36px; height: 36px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 600;
  flex-shrink: 0;
  font-family: 'DM Mono', monospace;
}
.card-info { flex: 1; min-width: 0; }
.card-name { font-size: 13px; font-weight: 500; margin-bottom: 3px; }
.card-sub { font-size: 11px; color: var(--text2); }
.card-badges { display: flex; gap: 4px; flex-wrap: wrap; margin-top: 5px; }
.card-actions { display: flex; gap: 5px; flex-shrink: 0; }

/* BADGES */
.badge {
  display: inline-block;
  padding: 2px 7px;
  border-radius: 4px;
  font-size: 10px;
  font-weight: 500;
  font-family: 'DM Mono', monospace;
}
.b-exp { background: var(--red-bg); color: #F08080; }
.b-sn { background: var(--orange-bg); color: #F0B060; }
.b-ok { background: var(--green-bg); color: #80C880; }
.b-nd { background: var(--bg3); color: var(--text3); }
.b-info { background: var(--blue-bg); color: var(--blue); }
.b-acc { background: rgba(232,197,71,0.12); color: var(--accent); }

/* INST TAGS */
.inst-tags { display: flex; flex-wrap: wrap; gap: 3px; margin-top: 5px; }
.itag { font-size: 10px; padding: 2px 7px; border-radius: 4px; font-weight: 500; font-family: 'DM Mono', monospace; }

/* CARD BODY */
.card-body { padding: 0 14px 12px; border-top: 0.5px solid var(--border); }
.sec-lbl {
  font-size: 10px;
  font-weight: 500;
  color: var(--text3);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 8px 0 4px;
}
.doc-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 0;
  border-bottom: 0.5px solid var(--border);
  font-size: 12px;
}
.doc-row:last-child { border-bottom: none; }
.doc-dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; }
.doc-name { flex: 1; min-width: 0; }
.doc-date { font-size: 11px; color: var(--text3); flex-shrink: 0; font-family: 'DM Mono', monospace; }
.missing-row {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 0;
  font-size: 11px;
  color: #F08080;
  border-bottom: 0.5px solid var(--border);
}
.missing-row:last-child { border-bottom: none; }
.notes-t { font-size: 11px; color: var(--text3); font-style: italic; margin-top: 3px; }

/* EXPAND ARROW */
.exp-arrow { font-size: 10px; color: var(--text3); transition: transform 0.2s; flex-shrink: 0; }
.expanded .exp-arrow { transform: rotate(180deg); }

/* CAT HEADER */
.cat-hdr {
  font-size: 10px;
  font-weight: 600;
  color: var(--text3);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin: 16px 0 8px;
  padding-bottom: 6px;
  border-bottom: 0.5px solid var(--border);
  font-family: 'DM Mono', monospace;
}

/* CONTROL CARD */
.ctrl-card {
  background: var(--bg2);
  border: 0.5px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: 10px;
  overflow: hidden;
}
.ctrl-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border-bottom: 0.5px solid var(--border);
}
.ctrl-name { font-size: 14px; font-weight: 500; }
.ctrl-desc { font-size: 11px; color: var(--text3); margin-top: 1px; }
.ctrl-body { padding: 8px 14px; }
.ctrl-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 5px 0;
  border-bottom: 0.5px solid var(--border);
  gap: 8px;
  font-size: 12px;
}
.ctrl-row:last-child { border-bottom: none; }
.ctrl-miss {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 0;
  font-size: 11px;
  color: #F08080;
  border-bottom: 0.5px solid var(--border);
}
.ctrl-miss:last-child { border-bottom: none; }

/* EMPTY */
.empty {
  text-align: center;
  padding: 3rem;
  color: var(--text3);
  font-size: 13px;
}

/* LOADING */
.loading {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3rem;
  color: var(--text3);
  gap: 10px;
  font-size: 13px;
}
.spinner {
  width: 18px; height: 18px;
  border: 2px solid var(--border2);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* MODAL */
.modal-bg {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.7);
  display: flex; align-items: center; justify-content: center;
  z-index: 100;
  backdrop-filter: blur(3px);
}
.modal {
  background: var(--bg2);
  border: 0.5px solid var(--border2);
  border-radius: var(--radius);
  padding: 20px;
  width: 480px;
  max-width: 96vw;
  max-height: 88vh;
  overflow-y: auto;
}
.modal h2 { font-size: 15px; font-weight: 500; margin-bottom: 16px; color: var(--text); }
.fg { margin-bottom: 12px; }
.fg label { display: block; font-size: 11px; color: var(--text3); margin-bottom: 4px; text-transform: uppercase; letter-spacing: 0.06em; font-family: 'DM Mono', monospace; }
.fg input, .fg select, .fg textarea {
  width: 100%;
  padding: 8px 11px;
  border: 0.5px solid var(--border2);
  border-radius: var(--radius-sm);
  font-size: 12px;
  background: var(--bg3);
  color: var(--text);
  font-family: 'DM Sans', sans-serif;
}
.fg input:focus, .fg select:focus, .fg textarea:focus {
  outline: none;
  border-color: var(--accent);
}
.fg textarea { min-height: 60px; resize: vertical; }
.fr2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.mf {
  display: flex; justify-content: flex-end; gap: 8px;
  margin-top: 16px; padding-top: 16px;
  border-top: 0.5px solid var(--border);
}

/* INST CHECKBOXES */
.inst-cbs { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
.icb {
  display: flex; align-items: center; gap: 5px;
  padding: 4px 10px;
  border: 0.5px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-size: 11px;
  transition: all 0.12s;
  font-family: 'DM Mono', monospace;
  color: var(--text2);
}
.icb:hover { border-color: var(--border2); }
.icb.on { font-weight: 500; }

/* COLOR STRIP */
.color-strip { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 4px; }
.color-opt {
  width: 24px; height: 24px;
  border-radius: 50%;
  cursor: pointer;
  border: 2px solid transparent;
  transition: all 0.12s;
}
.color-opt.selected { border-color: var(--text); transform: scale(1.15); }

/* SCROLLBAR */
::-webkit-scrollbar { width: 5px; }
::-webkit-scrollbar-track { background: var(--bg2); }
::-webkit-scrollbar-thumb { background: var(--border2); border-radius: 3px; }

select option { background: var(--bg3); }
</style>
</head>
<body>
<div class="layout">

<!-- SIDEBAR -->
<div class="sidebar">
  <div class="sidebar-logo">
    <div class="sidebar-logo-title">Dosar HoReCa</div>
    <div class="sidebar-logo-sub">v1.0 · Supabase</div>
  </div>
  <div class="sidebar-nav">
    <button class="nav-item active" onclick="goPage('dashboard')" id="nav-dashboard">
      <span class="nav-icon">◈</span> Rezumat
    </button>
    <button class="nav-item" onclick="goPage('docs')" id="nav-docs">
      <span class="nav-icon">◉</span> Documente firmă
    </button>
    <button class="nav-item" onclick="goPage('angajati')" id="nav-angajati">
      <span class="nav-icon">◎</span> Angajați
    </button>
    <button class="nav-item" onclick="goPage('controale')" id="nav-controale">
      <span class="nav-icon">◫</span> Pe instituții
    </button>
  </div>
  <div class="sidebar-footer" id="sidebar-footer">Se încarcă...</div>
</div>

<!-- MAIN -->
<div class="main">
  <div class="topbar">
    <div>
      <div class="topbar-title" id="topbar-title">Rezumat</div>
      <div class="topbar-sub" id="topbar-sub">DSP · ANPC · ITM · ISU · DSVSA · Primărie · Poliție</div>
    </div>
    <div id="topbar-actions"></div>
  </div>
  <div class="content">
    <div id="alerts-box" style="margin-bottom:14px"></div>
    <div id="stats-box"></div>
    <div id="page-content">
      <div class="loading"><div class="spinner"></div> Se conectează la baza de date...</div>
    </div>
  </div>
</div>

</div>
<div id="modal" style="display:none"></div>

<script>
// ─── SUPABASE CONFIG ───────────────────────────────────────────────
const SUPA_URL = 'https://rzsyqgvodwkrkaappole.supabase.co';
const SUPA_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InJ6c3lxZ3ZvZHdrcmthYXBwb2xlIiwicm9sZSI6ImFub24iLCJpYXQiOjE3Nzc0Njk0MjQsImV4cCI6MjA5MzA0NTQyNH0.dPAd16RG47E8IF0oJkylvHzQ9SbLi-SHIjR2IHc9VP8';
const { createClient } = supabase;
const db = createClient(SUPA_URL, SUPA_KEY);

// ─── CONSTANTE ────────────────────────────────────────────────────
const INST = [
  {id:'DSP',   label:'DSP',      color:'#E24B4A', bg:'rgba(226,75,74,0.15)', desc:'Sănătate Publică'},
  {id:'ANPC',  label:'ANPC',     color:'#EF9F27', bg:'rgba(239,159,39,0.15)', desc:'Protecția Consumatorului'},
  {id:'ITM',   label:'ITM',      color:'#4A9EE8', bg:'rgba(74,158,232,0.15)', desc:'Inspecția Muncii'},
  {id:'ISU',   label:'ISU',      color:'#9F77DD', bg:'rgba(159,119,221,0.15)', desc:'Situații Urgență'},
  {id:'DSVSA', label:'DSVSA',    color:'#3DC495', bg:'rgba(61,196,149,0.15)', desc:'Sanitar-Veterinar'},
  {id:'PRM',   label:'Primărie', color:'#A8A098', bg:'rgba(168,160,152,0.15)', desc:'Primărie'},
  {id:'POL',   label:'Poliție',  color:'#4A9EE8', bg:'rgba(74,158,232,0.12)', desc:'Poliție Locală'},
];
const CTRL_OBL = {
  DSP:   ['Autorizație sanitară de funcționare','Contract DDD','Fișe aptitudine angajați','Analize medicale personal','Plan igienizare + grafic curățenie','Proceduri HACCP','Dovadă apă potabilă','Contract colectare deșeuri'],
  ANPC:  ['Autorizație de funcționare (primărie)','Certificat înregistrare firmă (CUI)','Afișare prețuri (meniu/bar)','Gramaje și informații produse','Politică reclamații + registru reclamații','Bon fiscal (casă de marcat)'],
  ITM:   ['Contracte individuale de muncă (CIM)','Revisal','Fișe de post','Pontaj','Dosar personal angajat','Medicină muncii — contract + fișe','SSM — instruiri + fișe semnate'],
  ISU:   ['Autorizație ISU / Scenariu securitate incendiu','Plan evacuare','Contract mentenanță stingătoare','Verificare instalații electrice','Instruiri PSI angajați'],
  DSVSA: ['Autorizație sanitar-veterinară','Contract DDD','Facturi proveniență marfă','HACCP complet','Fișe temperaturi depozitare','Trasabilitate produse'],
  PRM:   ['Autorizație de funcționare','Contract salubritate','Contract utilități (apă, curent)'],
  POL:   ['Autorizație funcționare','Contract muzică UCMR-ADA','Casă de marcat fiscalizată'],
};
const DOC_CATS = [
  {id:'autorizatii',label:'Autorizații & Avize'},
  {id:'haccp',label:'HACCP & Igienă'},
  {id:'contracte',label:'Contracte'},
  {id:'securitate',label:'Securitate & ISU'},
  {id:'fiscal',label:'Fiscal & Registre'},
  {id:'altele',label:'Altele'},
];
const DOC_TYPES_BY_CAT = {
  autorizatii:['Autorizație sanitară de funcționare','Autorizație sanitar-veterinară (DSVSA)','Autorizație ISU / Scenariu securitate incendiu','Autorizație de funcționare (primărie)','Certificat înregistrare firmă (CUI)','Licență OANC','Autorizație vânzare alcool'],
  haccp:['Proceduri HACCP','Plan igienizare + grafic curățenie','Dovadă apă potabilă (buletin analiză)','Registru temperaturi frigidere','Registru curățenie','Fișe temperaturi depozitare','Trasabilitate produse'],
  contracte:['Contract DDD (dezinsecție/deratizare)','Contract colectare deșeuri / salubritate','Contract muzică UCMR-ADA','Contract utilități (apă)','Contract utilități (curent)','Contract mentenanță stingătoare','Contract chirie','Contract pază / alarmare'],
  securitate:['Plan evacuare','Verificare instalații electrice','Stingătoare — buletin verificare','Marcaje evacuare','Iluminat de siguranță'],
  fiscal:['Casă de marcat fiscalizată','Revisal','Pontaj','Registru reclamații','Politică reclamații'],
  altele:['Afișare prețuri (meniu/bar)','Gramaje și informații produse','Acord vecini','Aviz urbanism / mediu','Altul'],
};
const EMP_DOC_TYPES = [
  {id:'cim',    label:'Contract individual de muncă (CIM)', inst:['ITM'],       obl:true},
  {id:'med',    label:'Fișă aptitudine — medicină muncii',  inst:['DSP','ITM'], obl:true},
  {id:'analize',label:'Analize medicale (coprocultură)',     inst:['DSP'],       obl:true},
  {id:'ssm',    label:'Fișă instruire SSM',                  inst:['ITM'],       obl:true},
  {id:'psi',    label:'Fișă instruire PSI',                  inst:['ISU'],       obl:true},
  {id:'post',   label:'Fișă de post (semnată)',              inst:['ITM'],       obl:true},
  {id:'gdpr',   label:'Acord GDPR',                          inst:['ITM'],       obl:false},
  {id:'ri',     label:'Regulament intern (semnat)',          inst:['ITM'],       obl:false},
];
const POSTURI = ['Barman','Ospătar','Ajutor bucătar','Bucătar','Casier','Manager tură','Îngrijitor','Paznic','Altul'];
const TURE    = ['Dimineață','Seară','Noapte','Split','Flexibil'];
const COLORS  = [
  {id:'blue',  bg:'#1A3A5A', fg:'#4A9EE8'},
  {id:'teal',  bg:'#103A28', fg:'#3DC495'},
  {id:'coral', bg:'#3A1A10', fg:'#E87050'},
  {id:'purple',bg:'#2A1A4A', fg:'#9F77DD'},
  {id:'amber', bg:'#3A2A08', fg:'#E8C547'},
  {id:'pink',  bg:'#3A1030', fg:'#E870A8'},
  {id:'green', bg:'#1A3A10', fg:'#70C840'},
  {id:'gray',  bg:'#2A2A2A', fg:'#A8A098'},
];

// ─── STATE ────────────────────────────────────────────────────────
let docs  = [];
let emps  = [];
let empDocs = {};
let page  = 'dashboard';
let subCtrl   = 'all';
let subDocTab = 'all';
let subEmpTab = 'activi';
let expanded  = {};
let _selColor = 'blue';
let _cbInst   = [];
let _editDid  = null;
let _editEid  = null;
let _addDocEid= null;
let _editEdid = null;

// ─── HELPERS ──────────────────────────────────────────────────────
function days(s){ if(!s)return null; const d=new Date(s),n=new Date(); n.setHours(0,0,0,0); return Math.round((d-n)/86400000); }
function dst(s){ if(!s)return 'nd'; const d=days(s); return d<0?'exp':d<=30?'sn':'ok'; }
function fdt(s){ if(!s)return '—'; const[y,m,d]=s.split('-'); return `${d}.${m}.${y}`; }
function ini(n){ return n.split(' ').map(w=>w[0]).join('').substring(0,2).toUpperCase(); }
function colOf(id){ return COLORS.find(c=>c.id===id)||COLORS[0]; }
function iInf(id){ return INST.find(i=>i.id===id)||{label:id,color:'#888',bg:'rgba(128,128,128,0.15)'}; }
function badge(s,d){
  if(s==='nd') return '<span class="badge b-nd">Fără exp.</span>';
  if(s==='exp') return `<span class="badge b-exp">Expirat ${Math.abs(d)}z</span>`;
  if(s==='sn')  return `<span class="badge b-sn">${d}z</span>`;
  return `<span class="badge b-ok">${d}z</span>`;
}
function docSt(doc){ return dst(doc.expiry); }
function empSt(emp){
  const edocs = empDocs[emp.id]||[];
  const ss = edocs.map(d=>dst(d.expiry));
  if(ss.includes('exp')) return 'exp';
  if(ss.includes('sn'))  return 'sn';
  const obl = EMP_DOC_TYPES.filter(t=>t.obl).map(t=>t.id);
  if(obl.some(t=>!edocs.find(d=>d.type===t))) return 'lip';
  return 'ok';
}
function missingEmp(emp){
  const edocs = empDocs[emp.id]||[];
  return EMP_DOC_TYPES.filter(t=>t.obl && !edocs.find(d=>d.type===t.id));
}
function loading(){ return '<div class="loading"><div class="spinner"></div> Se încarcă...</div>'; }

// ─── SUPABASE CRUD ────────────────────────────────────────────────
async function loadAll(){
  const [{ data: d }, { data: e }, { data: ed }] = await Promise.all([
    db.from('documente').select('*').order('created_at'),
    db.from('angajati').select('*').order('created_at'),
    db.from('angajat_documente').select('*').order('created_at'),
  ]);
  docs = d||[];
  emps = e||[];
  empDocs = {};
  (ed||[]).forEach(x=>{ if(!empDocs[x.angajat_id]) empDocs[x.angajat_id]=[]; empDocs[x.angajat_id].push(x); });
  updateSidebar();
}

async function addDoc(obj){
  const {data,error} = await db.from('documente').insert([obj]).select();
  if(error) return alert('Eroare: '+error.message);
  docs.push(data[0]); renderAll();
}
async function updDoc(id,obj){
  const {error} = await db.from('documente').update(obj).eq('id',id);
  if(error) return alert('Eroare: '+error.message);
  docs = docs.map(d=>d.id===id?{...d,...obj}:d); renderAll();
}
async function delDocDB(id){
  const {error} = await db.from('documente').delete().eq('id',id);
  if(error) return alert('Eroare: '+error.message);
  docs = docs.filter(d=>d.id!==id); renderAll();
}

async function addEmp(obj){
  const {data,error} = await db.from('angajati').insert([obj]).select();
  if(error) return alert('Eroare: '+error.message);
  emps.push(data[0]); empDocs[data[0].id]=[]; expanded['e'+data[0].id]=true; renderAll();
}
async function updEmp(id,obj){
  const {error} = await db.from('angajati').update(obj).eq('id',id);
  if(error) return alert('Eroare: '+error.message);
  emps = emps.map(e=>e.id===id?{...e,...obj}:e); renderAll();
}
async function delEmpDB(id){
  const {error} = await db.from('angajati').delete().eq('id',id);
  if(error) return alert('Eroare: '+error.message);
  emps = emps.filter(e=>e.id!==id); delete empDocs[id]; renderAll();
}

async function addEmpDoc(obj){
  const {data,error} = await db.from('angajat_documente').insert([obj]).select();
  if(error) return alert('Eroare: '+error.message);
  if(!empDocs[obj.angajat_id]) empDocs[obj.angajat_id]=[];
  empDocs[obj.angajat_id].push(data[0]); renderAll();
}
async function updEmpDoc(id,obj,eid){
  const {error} = await db.from('angajat_documente').update(obj).eq('id',id);
  if(error) return alert('Eroare: '+error.message);
  empDocs[eid] = (empDocs[eid]||[]).map(d=>d.id===id?{...d,...obj}:d); renderAll();
}
async function delEmpDocDB(id,eid){
  const {error} = await db.from('angajat_documente').delete().eq('id',id);
  if(error) return alert('Eroare: '+error.message);
  empDocs[eid] = (empDocs[eid]||[]).filter(d=>d.id!==id); renderAll();
}

// ─── SIDEBAR UPDATE ───────────────────────────────────────────────
function updateSidebar(){
  const expD = docs.filter(d=>docSt(d)==='exp').length;
  const snD  = docs.filter(d=>docSt(d)==='sn').length;
  const expE = emps.filter(e=>e.status==='activ'&&empSt(e)==='exp').length;
  const snE  = emps.filter(e=>e.status==='activ'&&(empSt(e)==='sn'||empSt(e)==='lip')).length;
  const prob = expD+snD+expE+snE;
  document.getElementById('sidebar-footer').innerHTML =
    `${emps.filter(e=>e.status==='activ').length} angajați · ${docs.length} doc.<br>` +
    (prob ? `<span style="color:var(--orange)">${prob} necesită atenție</span>` : '<span style="color:var(--green)">Totul ok</span>');
  // update nav badges
  const dBadge = document.querySelector('#nav-docs .nav-badge');
  if(dBadge) dBadge.remove();
  if(expD+snD>0){
    const b=document.createElement('span');
    b.className='nav-badge'+(expD>0?'':' warn');
    b.textContent=expD+snD;
    document.getElementById('nav-docs').appendChild(b);
  }
  const eBadge = document.querySelector('#nav-angajati .nav-badge');
  if(eBadge) eBadge.remove();
  if(expE+snE>0){
    const b=document.createElement('span');
    b.className='nav-badge'+(expE>0?'':' warn');
    b.textContent=expE+snE;
    document.getElementById('nav-angajati').appendChild(b);
  }
}

// ─── NAV ──────────────────────────────────────────────────────────
function goPage(p){
  page = p;
  ['dashboard','docs','angajati','controale'].forEach(x=>{
    document.getElementById('nav-'+x).className='nav-item'+(x===p?' active':'');
  });
  const titles = {dashboard:'Rezumat',docs:'Documente firmă',angajati:'Angajați',controale:'Pe instituții de control'};
  document.getElementById('topbar-title').textContent = titles[p];
  const addBtns = {
    docs:'<button class="btn btn-primary" onclick="openAddDoc()">+ Document</button>',
    angajati:'<button class="btn btn-primary" onclick="openAddEmp()">+ Angajat</button>',
    dashboard:'', controale:'',
  };
  document.getElementById('topbar-actions').innerHTML = addBtns[p]||'';
  renderAll();
}

// ─── ALERTS + STATS ───────────────────────────────────────────────
function renderAlerts(){
  const expD = docs.filter(d=>docSt(d)==='exp');
  const snD  = docs.filter(d=>docSt(d)==='sn');
  const expE = emps.filter(e=>e.status==='activ'&&empSt(e)==='exp');
  const snE  = emps.filter(e=>e.status==='activ'&&empSt(e)==='sn');
  const lipE = emps.filter(e=>e.status==='activ'&&empSt(e)==='lip');
  let h='';
  if(expD.length||expE.length) h+=`<div class="alert al-red"><strong>Expirate:</strong> ${[...expD.map(d=>d.name),...expE.map(e=>e.nume)].join(' · ')}</div>`;
  if(snD.length||snE.length||lipE.length) h+=`<div class="alert al-orange">${snD.length?`<strong>Doc. expiră curând:</strong> ${snD.map(d=>d.name).join(', ')}<br>`:''}${snE.length?`<strong>Angajați — expiră curând:</strong> ${snE.map(e=>e.nume).join(', ')}<br>`:''}${lipE.length?`<strong>Doc. lipsă la:</strong> ${lipE.map(e=>e.nume).join(', ')}`:''}</div>`;
  if(!h) h='<div class="alert al-green">Toate documentele și dosarele angajaților sunt în regulă.</div>';
  document.getElementById('alerts-box').innerHTML = h;
}

function renderStats(){
  let h='';
  if(page==='docs'){
    const t=docs.length,e=docs.filter(d=>docSt(d)==='exp').length,s=docs.filter(d=>docSt(d)==='sn').length,o=docs.filter(d=>docSt(d)==='ok').length;
    h=`<div class="stats"><div class="stat stat-acc"><div class="stat-n">${t}</div><div class="stat-l">Total doc.</div></div><div class="stat stat-exp"><div class="stat-n">${e}</div><div class="stat-l">Expirate</div></div><div class="stat stat-sn"><div class="stat-n">${s}</div><div class="stat-l">Expiră curând</div></div><div class="stat stat-ok"><div class="stat-n">${o}</div><div class="stat-l">În regulă</div></div></div>`;
  } else if(page==='angajati'){
    const ac=emps.filter(e=>e.status==='activ');
    const t=ac.length,e=ac.filter(x=>empSt(x)==='exp').length,s=ac.filter(x=>empSt(x)==='sn'||empSt(x)==='lip').length,o=ac.filter(x=>empSt(x)==='ok').length;
    h=`<div class="stats"><div class="stat stat-acc"><div class="stat-n">${t}</div><div class="stat-l">Angajați activi</div></div><div class="stat stat-exp"><div class="stat-n">${e}</div><div class="stat-l">Doc. expirate</div></div><div class="stat stat-sn"><div class="stat-n">${s}</div><div class="stat-l">Atenție</div></div><div class="stat stat-ok"><div class="stat-n">${o}</div><div class="stat-l">Complet ok</div></div></div>`;
  } else if(page==='dashboard'){
    const td=docs.length,te=emps.filter(e=>e.status==='activ').length;
    const prob=docs.filter(d=>docSt(d)==='exp'||docSt(d)==='sn').length+emps.filter(e=>e.status==='activ'&&(empSt(e)==='exp'||empSt(e)==='sn'||empSt(e)==='lip')).length;
    h=`<div class="stats"><div class="stat stat-acc"><div class="stat-n">${td}</div><div class="stat-l">Doc. firmă</div></div><div class="stat stat-acc"><div class="stat-n">${te}</div><div class="stat-l">Angajați activi</div></div><div class="stat stat-exp"><div class="stat-n">${prob}</div><div class="stat-l">Necesită atenție</div></div><div class="stat stat-ok"><div class="stat-n">${td+te-prob}</div><div class="stat-l">În regulă</div></div></div>`;
  }
  document.getElementById('stats-box').innerHTML = h;
}

// ─── PAGE RENDERS ─────────────────────────────────────────────────
function renderAll(){ renderAlerts(); renderStats(); updateSidebar();
  if(page==='dashboard') renderDashboard();
  else if(page==='docs') renderDocs();
  else if(page==='angajati') renderAngajati();
  else if(page==='controale') renderControale();
}

function renderDashboard(){
  const expD=docs.filter(d=>docSt(d)==='exp'), snD=docs.filter(d=>docSt(d)==='sn');
  const expE=emps.filter(e=>e.status==='activ'&&empSt(e)==='exp'), snE=emps.filter(e=>e.status==='activ'&&(empSt(e)==='sn'||empSt(e)==='lip'));
  let h='';
  if(expD.length||snD.length){
    h+=`<div class="cat-hdr">Documente firmă — acțiune necesară</div>`;
    [...expD,...snD].forEach(doc=>{
      const s=docSt(doc),d=days(doc.expiry);
      const itags=(doc.inst||[]).map(i=>{const inf=iInf(i);return `<span class="itag" style="background:${inf.bg};color:${inf.color}">${inf.label}</span>`;}).join('');
      h+=`<div class="card st-${s}"><div class="card-head"><div class="card-info"><div class="card-name">${doc.name}</div><div class="card-sub">${doc.type||''}</div><div class="inst-tags">${itags}</div><div class="card-badges" style="margin-top:5px">${badge(s,d)}</div></div><div class="card-actions"><button class="btn btn-sm" onclick="goPage('docs')">Vezi</button></div></div></div>`;
    });
  }
  if(expE.length||snE.length){
    h+=`<div class="cat-hdr">Angajați — acțiune necesară</div>`;
    [...expE,...snE].forEach(emp=>{
      const es=empSt(emp),c=colOf(emp.color);
      h+=`<div class="card st-${es}"><div class="card-head"><div class="avatar" style="background:${c.bg};color:${c.fg}">${ini(emp.nume)}</div><div class="card-info"><div class="card-name">${emp.nume}</div><div class="card-sub">${emp.post} · ${emp.tura}</div><div class="card-badges"><span class="badge ${es==='exp'?'b-exp':'b-sn'}">${es==='exp'?'Doc. expirate':es==='lip'?'Lipsă doc.':'Expiră curând'}</span></div></div><div class="card-actions"><button class="btn btn-sm" onclick="goPage('angajati')">Dosar</button></div></div></div>`;
    });
  }
  if(!expD.length&&!snD.length&&!expE.length&&!snE.length) h='<div class="empty">◈<br><br>Totul în regulă.</div>';
  document.getElementById('page-content').innerHTML = h;
}

function renderDocs(){
  const insts=[{id:'all',label:'Toate'},...INST];
  let h=`<div class="subtabs">${insts.map(i=>`<button class="stab ${subDocTab===i.id?'active':''}" onclick="setSubDoc('${i.id}')">${i.id!=='all'?`<span style="width:8px;height:8px;border-radius:50%;background:${i.color};display:inline-block"></span>`:''}${i.label||i.id}</button>`).join('')}</div>`;
  h+=`<div class="toolbar"><input type="text" id="docQ" placeholder="Caută document..." oninput="filterDocs()"><select id="docSf" onchange="filterDocs()"><option value="">Toate statusurile</option><option value="exp">Expirate</option><option value="sn">Expiră curând</option><option value="ok">Ok</option></select></div><div id="doc-items"></div>`;
  document.getElementById('page-content').innerHTML = h;
  filterDocs();
}
function setSubDoc(id){ subDocTab=id; renderDocs(); }
function filterDocs(){
  const q=(document.getElementById('docQ')||{value:''}).value.toLowerCase();
  const sf=(document.getElementById('docSf')||{value:''}).value;
  let filtered=docs.filter(d=>{
    if(subDocTab!=='all'&&!(d.inst||[]).includes(subDocTab)) return false;
    if(sf&&docSt(d)!==sf) return false;
    if(q&&!((d.name+d.type+(d.inst||[]).join('')+(d.notes||'')).toLowerCase().includes(q))) return false;
    return true;
  });
  filtered.sort((a,b)=>{const sv={exp:0,sn:1,ok:2,nd:3};return sv[docSt(a)]-sv[docSt(b)];});
  if(!filtered.length){document.getElementById('doc-items').innerHTML='<div class="empty">Niciun document.</div>';return;}
  const byCat={};
  filtered.forEach(d=>{if(!byCat[d.cat])byCat[d.cat]=[];byCat[d.cat].push(d);});
  let dh='';
  DOC_CATS.forEach(({id,label})=>{
    if(!byCat[id]) return;
    dh+=`<div class="cat-hdr">${label}</div>`;
    byCat[id].forEach(doc=>{
      const s=docSt(doc),d=days(doc.expiry);
      const itags=(doc.inst||[]).map(ii=>{const inf=iInf(ii);return `<span class="itag" style="background:${inf.bg};color:${inf.color}">${inf.label}</span>`;}).join('');
      dh+=`<div class="card st-${s}"><div class="card-head">
        <div class="card-info">
          <div class="card-name">${doc.name}</div>
          <div class="card-sub">${doc.type||''}${doc.issued_by?' · '+doc.issued_by:''}${doc.expiry?' · exp: '+fdt(doc.expiry):''}</div>
          <div class="inst-tags">${itags}</div>
          ${doc.notes?`<div class="notes-t">${doc.notes}</div>`:''}
          <div class="card-badges" style="margin-top:5px">${badge(s,d)}</div>
        </div>
        <div class="card-actions">
          <button class="btn btn-sm" onclick="openEditDoc(${doc.id})">Edit</button>
          <button class="btn btn-sm btn-danger" onclick="confirmDelDoc(${doc.id})">×</button>
        </div>
      </div></div>`;
    });
  });
  document.getElementById('doc-items').innerHTML = dh;
}

function renderAngajati(){
  const tabs=[{id:'activi',l:'Activi'},{id:'inactivi',l:'Ieșiți'},{id:'toate',l:'Toți'}];
  let h=`<div class="subtabs">${tabs.map(t=>`<button class="stab ${subEmpTab===t.id?'active':''}" onclick="setSubEmp('${t.id}')">${t.l}</button>`).join('')}</div>`;
  h+=`<div class="toolbar"><input type="text" id="empQ" placeholder="Caută angajat..." oninput="filterEmps()"></div><div id="emp-items"></div>`;
  document.getElementById('page-content').innerHTML = h;
  filterEmps();
}
function setSubEmp(t){ subEmpTab=t; renderAngajati(); }
function filterEmps(){
  const q=(document.getElementById('empQ')||{value:''}).value.toLowerCase();
  let filtered=emps.filter(e=>{
    if(subEmpTab==='activi'&&e.status!=='activ') return false;
    if(subEmpTab==='inactivi'&&e.status==='activ') return false;
    if(q&&!((e.nume+e.post+e.tura).toLowerCase().includes(q))) return false;
    return true;
  });
  if(!filtered.length){document.getElementById('emp-items').innerHTML='<div class="empty">Niciun angajat.</div>';return;}
  let eh='';
  filtered.forEach(emp=>{
    const es=empSt(emp),c=colOf(emp.color),miss=missingEmp(emp),isExp=expanded['e'+emp.id];
    const edocs=empDocs[emp.id]||[];
    const stLbl={exp:'Doc. expirate',sn:'Expiră curând',ok:'Complet ok',lip:`${miss.length} doc. lipsă`,nd:'—'}[es];
    const stCl={exp:'b-exp',sn:'b-sn',ok:'b-ok',lip:'b-sn',nd:'b-nd'}[es];
    eh+=`<div class="card st-${es} ${isExp?'expanded':''}">
      <div class="card-head clickable" onclick="toggleEmp(${emp.id})">
        <div class="avatar" style="background:${c.bg};color:${c.fg}">${ini(emp.nume)}</div>
        <div class="card-info">
          <div class="card-name">${emp.nume}</div>
          <div class="card-sub">${emp.post} · ${emp.tura}${emp.angajat?' · din '+fdt(emp.angajat):''}</div>
          <div class="card-badges"><span class="badge ${stCl}">${stLbl}</span><span class="badge b-nd">${edocs.length} doc.</span></div>
        </div>
        <div class="card-actions" onclick="event.stopPropagation()">
          <button class="btn btn-sm btn-info" onclick="openAddEmpDoc(${emp.id})">+ Doc</button>
          <button class="btn btn-sm" onclick="openEditEmp(${emp.id})">Edit</button>
          <button class="btn btn-sm btn-danger" onclick="confirmDelEmp(${emp.id})">×</button>
        </div>
        <span class="exp-arrow">▼</span>
      </div>`;
    if(isExp){
      eh+=`<div class="card-body">`;
      if(edocs.length){
        eh+=`<div class="sec-lbl">Documente</div>`;
        edocs.forEach(doc=>{
          const s=dst(doc.expiry),d=days(doc.expiry);
          const dotC={exp:'var(--red)',sn:'var(--orange)',ok:'var(--green)',nd:'var(--text3)'}[s];
          eh+=`<div class="doc-row"><span class="doc-dot" style="background:${dotC}"></span><span class="doc-name">${doc.label||doc.type}${doc.note?` <span style="color:var(--text3);font-style:italic">— ${doc.note}</span>`:''}</span><span class="doc-date">${doc.expiry?fdt(doc.expiry):'—'}</span>${badge(s,d)}<button class="btn btn-sm" onclick="openEditEmpDoc(${emp.id},${doc.id})" style="font-size:10px">Edit</button><button class="btn btn-sm btn-danger" onclick="confirmDelEmpDoc(${emp.id},${doc.id})" style="font-size:10px">×</button></div>`;
        });
      }
      if(miss.length){
        eh+=`<div class="sec-lbl" style="color:var(--red)">Lipsă obligatorii</div>`;
        miss.forEach(dt=>{eh+=`<div class="missing-row">⚠ ${dt.label}<button class="btn btn-sm btn-info" style="margin-left:auto" onclick="openAddEmpDoc(${emp.id},'${dt.id}')">Adaugă</button></div>`;});
      }
      eh+=`</div>`;
    }
    eh+=`</div>`;
  });
  document.getElementById('emp-items').innerHTML = eh;
}
function toggleEmp(id){ expanded['e'+id]=!expanded['e'+id]; filterEmps(); }

function renderControale(){
  const insts2=[{id:'all',label:'Toate',color:'var(--text3)'},...INST];
  let h=`<div class="subtabs">${insts2.map(i=>`<button class="stab ${subCtrl===i.id?'active':''}" onclick="setSubCtrl('${i.id}')">${i.id!=='all'?`<span style="width:8px;height:8px;border-radius:50%;background:${i.color};display:inline-block"></span>`:''}${i.label}</button>`).join('')}</div><div id="ctrl-items"></div>`;
  document.getElementById('page-content').innerHTML = h;
  const show = subCtrl==='all'?INST:INST.filter(i=>i.id===subCtrl);
  let ch='';
  show.forEach(inst=>{
    const obl=CTRL_OBL[inst.id]||[];
    let rows='',miss=[];
    obl.forEach(docName=>{
      const found=docs.find(d=>(d.inst||[]).includes(inst.id)&&(d.type===docName||d.name.toLowerCase().includes(docName.toLowerCase().substring(0,14))));
      if(found){const s=docSt(found),d=days(found.expiry);rows+=`<div class="ctrl-row"><span style="flex:1">${docName}</span><div style="display:flex;gap:5px;align-items:center">${badge(s,d)}<span class="badge b-info">Obligatoriu</span></div></div>`;}
      else miss.push(docName);
    });
    const typeMap={DSP:['med','analize'],ITM:['cim','med','ssm','post'],ISU:['psi']};
    const needed=typeMap[inst.id]||[];
    if(needed.length){
      const ac=emps.filter(e=>e.status==='activ');
      let er='';
      ac.forEach(emp=>{
        needed.forEach(t=>{
          const edt=EMP_DOC_TYPES.find(x=>x.id===t);
          const fd=(empDocs[emp.id]||[]).find(d=>d.type===t);
          if(fd){const s=dst(fd.expiry),d=days(fd.expiry);er+=`<div class="ctrl-row"><span style="flex:1">${emp.nume} — ${edt.label}</span>${badge(s,d)}</div>`;}
          else if(edt.obl) er+=`<div class="ctrl-miss">⚠ ${emp.nume} — ${edt.label} lipsă</div>`;
        });
      });
      if(er) rows+=`<div class="sec-lbl">Documente angajați</div>`+er;
    }
    const misH=miss.map(m=>`<div class="ctrl-miss">⚠ Lipsă: ${m}</div>`).join('');
    ch+=`<div class="ctrl-card">
      <div class="ctrl-head">
        <span style="width:12px;height:12px;border-radius:50%;background:${inst.color};display:inline-block;flex-shrink:0"></span>
        <div style="flex:1"><div class="ctrl-name">${inst.label}</div><div class="ctrl-desc">${inst.desc}</div></div>
        <div style="font-size:11px;font-weight:500;color:${miss.length?'var(--red)':'var(--green)'};">${miss.length?miss.length+' doc. lipsă':'Complet'}</div>
      </div>
      <div class="ctrl-body">${rows}${misH}${!rows&&!misH?'<div style="font-size:12px;color:var(--text3);padding:6px 0">Niciun document înregistrat.</div>':''}</div>
    </div>`;
  });
  document.getElementById('ctrl-items').innerHTML = ch;
}
function setSubCtrl(id){ subCtrl=id; renderControale(); }

// ─── MODALS DOCS ──────────────────────────────────────────────────
function openAddDoc(){ _editDid=null; _cbInst=[]; showDocModal(); }
function openEditDoc(id){
  _editDid=id;
  const doc=docs.find(d=>d.id===id);
  _cbInst=[...(doc.inst||[])];
  showDocModal(doc);
}
function showDocModal(doc){
  const d=doc||{};
  const catOpts=DOC_CATS.map(c=>`<option value="${c.id}" ${c.id===(d.cat||'')?'selected':''}>${c.label}</option>`).join('');
  const typeOpts=Object.entries(DOC_TYPES_BY_CAT).map(([cat,types])=>`<optgroup label="${DOC_CATS.find(c=>c.id===cat)?.label||cat}">${types.map(t=>`<option value="${t}" ${t===(d.type||'')?'selected':''}>${t}</option>`).join('')}</optgroup>`).join('');
  const icbs=INST.map(i=>{const on=_cbInst.includes(i.id);return `<div class="icb ${on?'on':''}" id="icb-${i.id}" style="${on?`background:${i.bg};border-color:${i.color};color:${i.color}`:''}" onclick="toggleInst('${i.id}','${i.color}','${i.bg.replace(/'/g,'"')}')"><span style="width:7px;height:7px;border-radius:50%;background:${i.color};display:inline-block"></span>${i.label}</div>`;}).join('');
  showM(`<h2>${_editDid?'Editează document':'Document nou'}</h2>
    <div class="fr2"><div class="fg"><label>Categorie</label><select id="f-cat">${catOpts}</select></div><div class="fg"><label>Tip</label><select id="f-type">${typeOpts}</select></div></div>
    <div class="fg"><label>Denumire</label><input id="f-name" value="${d.name||''}" placeholder="ex: Autorizație sanitară DSP 2025"></div>
    <div class="fr2"><div class="fg"><label>Data emiterii</label><input type="date" id="f-issued" value="${d.issued||''}"></div><div class="fg"><label>Data expirării</label><input type="date" id="f-expiry" value="${d.expiry||''}"></div></div>
    <div class="fg"><label>Emis de</label><input id="f-issby" value="${d.issued_by||''}" placeholder="DSP, ISU, ANAF..."></div>
    <div class="fg"><label>Cerut la control de</label><div class="inst-cbs">${icbs}</div></div>
    <div class="fg"><label>Note</label><textarea id="f-notes">${d.notes||''}</textarea></div>
    <div class="mf"><button class="btn" onclick="closeModal()">Anulează</button><button class="btn btn-primary" onclick="saveDocF()">Salvează</button></div>`);
}
function toggleInst(id,color,bg){
  const el=document.getElementById('icb-'+id);
  if(_cbInst.includes(id)){_cbInst=_cbInst.filter(x=>x!==id);el.className='icb';el.removeAttribute('style');}
  else{_cbInst.push(id);el.className='icb on';el.style=`background:${bg};border-color:${color};color:${color}`;}
}
async function saveDocF(){
  const name=document.getElementById('f-name').value.trim();
  if(!name){alert('Completați denumirea.');return;}
  const obj={name,cat:document.getElementById('f-cat').value,type:document.getElementById('f-type').value,issued:document.getElementById('f-issued').value||null,expiry:document.getElementById('f-expiry').value||null,issued_by:document.getElementById('f-issby').value.trim()||null,inst:_cbInst,notes:document.getElementById('f-notes').value.trim()||null};
  closeModal();
  if(_editDid) await updDoc(_editDid,obj);
  else await addDoc(obj);
}
async function confirmDelDoc(id){
  const doc=docs.find(d=>d.id===id);
  if(!confirm(`Ștergi "${doc?.name}"?`)) return;
  await delDocDB(id);
}

// ─── MODALS ANGAJAȚI ──────────────────────────────────────────────
function openAddEmp(){ _editEid=null; _selColor='blue'; showEmpModal(); }
function openEditEmp(id){ _editEid=id; const e=emps.find(x=>x.id===id); _selColor=e.color; showEmpModal(e); }
function showEmpModal(e){
  const d=e||{};
  const cps=COLORS.map(c=>`<div class="color-opt ${c.id===(d.color||'blue')?'selected':''}" id="cp-${c.id}" style="background:${c.fg};border-color:${c.id===(d.color||'blue')?'var(--text)':'transparent'}" onclick="pickCol('${c.id}')"></div>`).join('');
  showM(`<h2>${_editEid?'Editează angajat':'Angajat nou'}</h2>
    <div class="fr2"><div class="fg"><label>Nume complet</label><input id="f-enume" value="${d.nume||''}" placeholder="Ionescu Maria"></div><div class="fg"><label>Post</label><select id="f-epost">${POSTURI.map(p=>`<option ${p===(d.post||'')?'selected':''}>${p}</option>`).join('')}</select></div></div>
    <div class="fr2"><div class="fg"><label>Tură</label><select id="f-etura">${TURE.map(t=>`<option ${t===(d.tura||'')?'selected':''}>${t}</option>`).join('')}</select></div><div class="fg"><label>Status</label><select id="f-estat"><option value="activ" ${(d.status||'activ')==='activ'?'selected':''}>Activ</option><option value="inactiv" ${d.status==='inactiv'?'selected':''}>Ieșit</option></select></div></div>
    <div class="fr2"><div class="fg"><label>Data angajării</label><input type="date" id="f-eang" value="${d.angajat||''}"></div><div class="fg"><label>Telefon</label><input id="f-etel" value="${d.tel||''}" placeholder="07xx..."></div></div>
    <div class="fg"><label>Culoare identificare</label><div class="color-strip">${cps}</div></div>
    <div class="fg"><label>Note</label><textarea id="f-enote">${d.note||''}</textarea></div>
    <div class="mf"><button class="btn" onclick="closeModal()">Anulează</button><button class="btn btn-primary" onclick="saveEmpF()">Salvează</button></div>`);
}
function pickCol(id){
  _selColor=id;
  COLORS.forEach(c=>{const el=document.getElementById('cp-'+c.id);if(!el)return;el.className='color-opt'+(c.id===id?' selected':'');el.style.borderColor=c.id===id?'var(--text)':'transparent';});
}
async function saveEmpF(){
  const nume=document.getElementById('f-enume').value.trim();
  if(!nume){alert('Completați numele.');return;}
  const obj={nume,post:document.getElementById('f-epost').value,tura:document.getElementById('f-etura').value,status:document.getElementById('f-estat').value,angajat:document.getElementById('f-eang').value||null,tel:document.getElementById('f-etel').value.trim()||null,color:_selColor,note:document.getElementById('f-enote').value.trim()||null};
  closeModal();
  if(_editEid) await updEmp(_editEid,obj);
  else await addEmp(obj);
}
async function confirmDelEmp(id){
  const e=emps.find(x=>x.id===id);
  if(!confirm(`Ștergi angajatul "${e?.nume}" și toate documentele sale?`)) return;
  await delEmpDB(id);
}

// ─── MODALS DOC ANGAJAT ───────────────────────────────────────────
function openAddEmpDoc(eid,prefillType){
  _addDocEid=eid; _editEdid=null; showEmpDocModal(null,prefillType);
}
function openEditEmpDoc(eid,did){
  _addDocEid=eid; _editEdid=did;
  const doc=(empDocs[eid]||[]).find(d=>d.id===did);
  showEmpDocModal(doc);
}
function showEmpDocModal(doc,prefillType){
  const d=doc||{};
  const typeOpts=EMP_DOC_TYPES.map(t=>`<option value="${t.id}" ${(t.id===(d.type||prefillType||''))?'selected':''}>${t.label}${t.obl?' ✓':''}</option>`).join('');
  showM(`<h2>${_editEdid?'Editează document':'Document angajat'}</h2>
    <div class="fg"><label>Tip document</label><select id="f-etype">${typeOpts}</select></div>
    <div class="fg"><label>Denumire (opțional)</label><input id="f-elabel" value="${d.label||''}" placeholder="Lasă gol pentru titlu automat"></div>
    <div class="fr2"><div class="fg"><label>Data emiterii</label><input type="date" id="f-eissued" value="${d.issued||''}"></div><div class="fg"><label>Data expirării</label><input type="date" id="f-eexpiry" value="${d.expiry||''}"></div></div>
    <div class="fg"><label>Note</label><textarea id="f-enote2">${d.note||''}</textarea></div>
    <div class="mf"><button class="btn" onclick="closeModal()">Anulează</button><button class="btn btn-primary" onclick="saveEmpDocF()">Salvează</button></div>`);
}
async function saveEmpDocF(){
  const tid=document.getElementById('f-etype').value;
  const ti=EMP_DOC_TYPES.find(t=>t.id===tid);
  const label=document.getElementById('f-elabel').value.trim()||ti.label;
  const obj={angajat_id:_addDocEid,type:tid,label,issued:document.getElementById('f-eissued').value||null,expiry:document.getElementById('f-eexpiry').value||null,note:document.getElementById('f-enote2').value.trim()||null};
  closeModal();
  if(_editEdid) await updEmpDoc(_editEdid,obj,_addDocEid);
  else await addEmpDoc(obj);
  expanded['e'+_addDocEid]=true;
}
async function confirmDelEmpDoc(eid,did){
  const doc=(empDocs[eid]||[]).find(d=>d.id===did);
  if(!confirm(`Ștergi "${doc?.label||doc?.type}"?`)) return;
  await delEmpDocDB(did,eid);
}

// ─── MODAL UTILS ──────────────────────────────────────────────────
function showM(html){ document.getElementById('modal').style.display='flex'; document.getElementById('modal').innerHTML=`<div class="modal-bg" onclick="if(event.target===this)closeModal()"><div class="modal">${html}</div></div>`; }
function closeModal(){ document.getElementById('modal').style.display='none'; }

// ─── INIT ─────────────────────────────────────────────────────────
(async()=>{
  await loadAll();
  goPage('dashboard');
})();
</script>
</body>
</html>
HTMLEOF
echo "Done"
Output

Done

Sorry, but nothing was found. Please try a search with different keywords.