1520 lines
88 KiB
HTML
1520 lines
88 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="cs">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>BOHA Automation – Platforma</title>
|
||
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;0,9..40,700;1,9..40,400&family=DM+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||
<style>
|
||
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
|
||
:root{
|
||
--red:#D63031;--red-dark:#B52626;--red-soft:#FFF0F0;--red-mid:#FDDCDC;
|
||
--sidebar-bg:#141414;--bg:#F5F4F2;--card:#FFFFFF;--border:#E8E6E1;
|
||
--text:#1A1A1A;--muted:#888;--muted2:#BBB;
|
||
--green:#00B894;--green-soft:#E8FBF7;
|
||
--amber:#F39C12;--amber-soft:#FEF9EC;
|
||
--blue:#2D80E4;--blue-soft:#EBF3FD;
|
||
--purple:#7C3AED;--purple-soft:#EDE9FE;
|
||
--shadow:0 1px 3px rgba(0,0,0,.06),0 4px 16px rgba(0,0,0,.04);
|
||
--shadow-md:0 2px 8px rgba(0,0,0,.08),0 8px 32px rgba(0,0,0,.06);
|
||
--r:10px;
|
||
}
|
||
body{font-family:'DM Sans',sans-serif;background:var(--bg);color:var(--text);display:flex;height:100vh;overflow:hidden;font-size:14px}
|
||
|
||
/* ─── SIDEBAR ─── */
|
||
aside{width:220px;flex-shrink:0;background:var(--sidebar-bg);display:flex;flex-direction:column;height:100vh;overflow-y:auto}
|
||
.sidebar-logo{padding:20px 18px 16px;border-bottom:1px solid #2a2a2a;display:flex;align-items:center;gap:10px;flex-shrink:0}
|
||
.logo-mark{width:32px;height:32px;background:var(--red);border-radius:6px;display:flex;align-items:center;justify-content:center;font-weight:700;color:#fff;font-size:13px;letter-spacing:-0.5px}
|
||
.sidebar-logo span{color:#fff;font-weight:600;font-size:15px;letter-spacing:-0.3px}
|
||
.sb-section{padding:14px 10px 6px}
|
||
.sb-label{font-size:10px;font-weight:600;letter-spacing:1px;text-transform:uppercase;color:#444;padding:0 8px;margin-bottom:4px}
|
||
.nav-item{display:flex;align-items:center;gap:9px;padding:7px 10px;border-radius:7px;color:#A0A0A0;cursor:pointer;transition:all .15s;font-size:13px;font-weight:450;margin-bottom:1px;user-select:none}
|
||
.nav-item:hover{background:#1f1f1f;color:#ddd}
|
||
.nav-item.active{background:#fff;color:#141414;font-weight:600}
|
||
.nav-item.active svg{color:var(--red)}
|
||
.nav-item svg{width:14px;height:14px;flex-shrink:0}
|
||
.nav-badge{margin-left:auto;background:var(--red);color:#fff;font-size:10px;font-weight:700;border-radius:20px;padding:1px 6px;min-width:18px;text-align:center}
|
||
.nav-badge.g{background:var(--green)}
|
||
.nav-badge.b{background:var(--blue)}
|
||
.sb-footer{margin-top:auto;border-top:1px solid #222;padding:14px 10px;flex-shrink:0}
|
||
.user-chip{display:flex;align-items:center;gap:10px;padding:8px;border-radius:8px;cursor:pointer;transition:background .15s}
|
||
.user-chip:hover{background:#1f1f1f}
|
||
.avatar{width:32px;height:32px;border-radius:50%;background:var(--red);display:flex;align-items:center;justify-content:center;font-weight:700;color:#fff;font-size:12px;flex-shrink:0}
|
||
.u-name{color:#ddd;font-size:13px;font-weight:500}
|
||
.u-role{color:#555;font-size:11px}
|
||
|
||
/* ─── MAIN ─── */
|
||
main{flex:1;overflow-y:auto;display:flex;flex-direction:column}
|
||
.page{padding:28px 32px;display:flex;flex-direction:column;gap:22px;animation:fadeIn .2s ease}
|
||
@keyframes fadeIn{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}
|
||
|
||
/* ─── TOPBAR ─── */
|
||
.topbar{display:flex;align-items:flex-start;justify-content:space-between;gap:16px}
|
||
.topbar h1{font-size:22px;font-weight:700;letter-spacing:-0.5px;color:#111}
|
||
.topbar-sub{color:var(--muted);font-size:13px;margin-top:3px}
|
||
.topbar-actions{display:flex;gap:8px;align-items:center;flex-shrink:0}
|
||
|
||
/* ─── BUTTONS ─── */
|
||
.btn{display:inline-flex;align-items:center;gap:6px;padding:8px 14px;border-radius:8px;cursor:pointer;font-family:inherit;font-size:13px;font-weight:550;border:none;transition:all .15s;white-space:nowrap}
|
||
.btn-primary{background:var(--red);color:#fff}
|
||
.btn-primary:hover{background:var(--red-dark)}
|
||
.btn-ghost{background:#fff;color:var(--text);border:1px solid var(--border)}
|
||
.btn-ghost:hover{background:#f0eeea}
|
||
.btn-sm{padding:6px 11px;font-size:12px;border-radius:7px}
|
||
.btn svg{width:13px;height:13px}
|
||
.btn-icon{width:32px;height:32px;padding:0;display:inline-flex;align-items:center;justify-content:center;border-radius:7px}
|
||
|
||
/* ─── CARDS ─── */
|
||
.card{background:var(--card);border-radius:var(--r);box-shadow:var(--shadow);overflow:hidden}
|
||
.card-header{padding:14px 18px;border-bottom:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;gap:12px}
|
||
.card-title{font-size:14px;font-weight:650;color:#111}
|
||
.card-link{font-size:12px;color:var(--red);font-weight:550;cursor:pointer}
|
||
.card-body{padding:18px}
|
||
|
||
/* ─── KPI ─── */
|
||
.kpi-grid{display:grid;gap:14px}
|
||
.kpi-4{grid-template-columns:repeat(4,1fr)}
|
||
.kpi-3{grid-template-columns:repeat(3,1fr)}
|
||
.kpi-2{grid-template-columns:repeat(2,1fr)}
|
||
.kpi-card{background:var(--card);border-radius:var(--r);padding:18px 20px;box-shadow:var(--shadow);display:flex;flex-direction:column;gap:10px;position:relative;overflow:hidden}
|
||
.kpi-card::after{content:'';position:absolute;top:0;left:0;right:0;height:3px;border-radius:var(--r) var(--r) 0 0;background:var(--accent,var(--border))}
|
||
.kpi-card.red{--accent:var(--red)}.kpi-card.green{--accent:var(--green)}.kpi-card.amber{--accent:var(--amber)}.kpi-card.blue{--accent:var(--blue)}.kpi-card.purple{--accent:var(--purple)}
|
||
.kpi-lbl{font-size:11px;font-weight:600;color:var(--muted);text-transform:uppercase;letter-spacing:.5px}
|
||
.kpi-val{font-size:28px;font-weight:700;letter-spacing:-1px;line-height:1;color:#111}
|
||
.kpi-val small{font-size:13px;font-weight:500;color:var(--muted);margin-left:2px}
|
||
.kpi-foot{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--muted)}
|
||
|
||
/* ─── PILLS / TAGS ─── */
|
||
.pill{display:inline-flex;align-items:center;gap:4px;padding:3px 9px;border-radius:20px;font-size:11.5px;font-weight:600;white-space:nowrap}
|
||
.pill.g{background:var(--green-soft);color:var(--green)}
|
||
.pill.a{background:var(--amber-soft);color:var(--amber)}
|
||
.pill.r{background:var(--red-soft);color:var(--red)}
|
||
.pill.b{background:var(--blue-soft);color:var(--blue)}
|
||
.pill.p{background:var(--purple-soft);color:var(--purple)}
|
||
.pill.n{background:#F3F4F6;color:#6B7280}
|
||
.tag-up{background:var(--green-soft);color:var(--green);font-size:11px;font-weight:600;padding:2px 7px;border-radius:20px}
|
||
.tag-dn{background:var(--red-soft);color:var(--red);font-size:11px;font-weight:600;padding:2px 7px;border-radius:20px}
|
||
.tag-neu{background:var(--amber-soft);color:var(--amber);font-size:11px;font-weight:600;padding:2px 7px;border-radius:20px}
|
||
|
||
/* ─── TABLE ─── */
|
||
.tbl-wrap{overflow-x:auto}
|
||
table{width:100%;border-collapse:collapse}
|
||
thead th{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(--muted);padding:10px 16px;text-align:left;border-bottom:2px solid var(--border);white-space:nowrap}
|
||
tbody tr{border-bottom:1px solid var(--border);transition:background .1s}
|
||
tbody tr:last-child{border-bottom:none}
|
||
tbody tr:hover{background:#FAFAF8}
|
||
tbody td{padding:11px 16px;font-size:13px;color:#333;vertical-align:middle}
|
||
tbody td strong{font-weight:600;color:#111}
|
||
.mono{font-family:'DM Mono',monospace;font-size:12px}
|
||
|
||
/* ─── FILTER BAR ─── */
|
||
.filter-bar{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
|
||
.filter-input{background:#fff;border:1px solid var(--border);border-radius:8px;padding:7px 12px;font-family:inherit;font-size:13px;color:var(--text);outline:none;transition:border .15s;min-width:160px}
|
||
.filter-input:focus{border-color:var(--red)}
|
||
.filter-select{background:#fff;border:1px solid var(--border);border-radius:8px;padding:7px 12px;font-family:inherit;font-size:13px;color:var(--text);outline:none;cursor:pointer;appearance:none;padding-right:28px;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' fill='none'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23888' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 10px center}
|
||
|
||
/* ─── TABS ─── */
|
||
.tabs{display:flex;gap:2px;background:#EEECEA;border-radius:9px;padding:3px}
|
||
.tab{padding:6px 14px;border-radius:7px;font-size:13px;font-weight:500;cursor:pointer;color:var(--muted);transition:all .15s;white-space:nowrap}
|
||
.tab.active{background:#fff;color:#111;font-weight:600;box-shadow:0 1px 3px rgba(0,0,0,.08)}
|
||
|
||
/* ─── GRID LAYOUTS ─── */
|
||
.two-col{display:grid;grid-template-columns:1fr 1fr;gap:16px}
|
||
.three-col{display:grid;grid-template-columns:1.4fr 1fr 1fr;gap:16px}
|
||
.col-32{display:grid;grid-template-columns:3fr 2fr;gap:16px}
|
||
.col-23{display:grid;grid-template-columns:2fr 3fr;gap:16px}
|
||
|
||
/* ─── ACTIVITY / LIST ROWS ─── */
|
||
.list-row{display:flex;align-items:center;gap:12px;padding:11px 18px;border-bottom:1px solid var(--border);transition:background .1s}
|
||
.list-row:last-child{border-bottom:none}
|
||
.list-row:hover{background:#FAFAF8}
|
||
.row-icon{width:34px;height:34px;border-radius:8px;display:flex;align-items:center;justify-content:center;flex-shrink:0}
|
||
.row-icon svg{width:15px;height:15px}
|
||
.row-icon.r{background:var(--red-soft);color:var(--red)}
|
||
.row-icon.g{background:var(--green-soft);color:var(--green)}
|
||
.row-icon.b{background:var(--blue-soft);color:var(--blue)}
|
||
.row-icon.a{background:var(--amber-soft);color:var(--amber)}
|
||
.row-icon.p{background:var(--purple-soft);color:var(--purple)}
|
||
.row-main{flex:1;min-width:0}
|
||
.row-title{font-size:13px;font-weight:500;color:#222}
|
||
.row-sub{font-size:12px;color:var(--muted);margin-top:1px}
|
||
.row-end{display:flex;flex-direction:column;align-items:flex-end;gap:3px;flex-shrink:0}
|
||
|
||
/* ─── PRESENCE ─── */
|
||
.status-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}
|
||
.status-dot.in{background:var(--green)}
|
||
.status-dot.out{background:#ddd}
|
||
.status-dot.away{background:var(--amber)}
|
||
.status-label.in{color:var(--green)}
|
||
.status-label.out{color:#bbb}
|
||
.status-label.away{color:var(--amber)}
|
||
.status-label{font-size:11.5px;font-weight:550}
|
||
|
||
/* ─── PROGRESS ─── */
|
||
.prog-bar-bg{height:6px;background:var(--border);border-radius:99px;overflow:hidden}
|
||
.prog-bar-fill{height:100%;border-radius:99px}
|
||
|
||
/* ─── FORM ─── */
|
||
.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px}
|
||
.form-group{display:flex;flex-direction:column;gap:6px}
|
||
.form-group.full{grid-column:1/-1}
|
||
.form-label{font-size:12px;font-weight:600;color:#555;letter-spacing:.2px}
|
||
.form-input,.form-textarea,.form-sel{background:#fff;border:1.5px solid var(--border);border-radius:8px;padding:9px 12px;font-family:inherit;font-size:13px;color:var(--text);outline:none;transition:border .15s;width:100%}
|
||
.form-input:focus,.form-textarea:focus,.form-sel:focus{border-color:var(--red)}
|
||
.form-textarea{resize:vertical;min-height:80px}
|
||
.form-sel{cursor:pointer;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' fill='none'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23888' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 12px center;padding-right:32px}
|
||
|
||
/* ─── CALENDAR ─── */
|
||
.cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:3px}
|
||
.cal-head{text-align:center;font-size:11px;font-weight:600;color:var(--muted);padding:6px 0;text-transform:uppercase;letter-spacing:.5px}
|
||
.cal-day{aspect-ratio:1;display:flex;align-items:center;justify-content:center;border-radius:8px;font-size:13px;cursor:pointer;transition:all .15s;position:relative;flex-direction:column;gap:2px}
|
||
.cal-day:hover{background:#F0EEEA}
|
||
.cal-day.today{background:var(--red);color:#fff;font-weight:700}
|
||
.cal-day.has-data::after{content:'';width:4px;height:4px;border-radius:50%;background:var(--green);position:absolute;bottom:4px;left:50%;transform:translateX(-50%)}
|
||
.cal-day.today.has-data::after{background:rgba(255,255,255,.7)}
|
||
.cal-day.other-month{color:#ccc}
|
||
.cal-day.weekend{color:var(--muted)}
|
||
|
||
/* ─── VEHICLE CARDS ─── */
|
||
.vehicle-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
|
||
.vehicle-card{background:var(--card);border-radius:var(--r);padding:18px;box-shadow:var(--shadow);display:flex;flex-direction:column;gap:12px;transition:box-shadow .15s}
|
||
.vehicle-card:hover{box-shadow:var(--shadow-md)}
|
||
.vehicle-plate{font-family:'DM Mono',monospace;font-size:15px;font-weight:500;background:#141414;color:#fff;padding:4px 10px;border-radius:6px;display:inline-block;letter-spacing:2px}
|
||
.vehicle-name{font-size:15px;font-weight:650;color:#111;margin-top:4px}
|
||
.vehicle-stats{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:4px}
|
||
.v-stat{display:flex;flex-direction:column;gap:2px}
|
||
.v-stat-lbl{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(--muted)}
|
||
.v-stat-val{font-size:14px;font-weight:650;color:#111}
|
||
|
||
/* ─── PROJECT KANBAN ─── */
|
||
.kanban{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;align-items:start}
|
||
.kanban-col{display:flex;flex-direction:column;gap:8px}
|
||
.kanban-header{display:flex;align-items:center;justify-content:space-between;padding:8px 2px;margin-bottom:2px}
|
||
.kanban-title{font-size:12px;font-weight:650;text-transform:uppercase;letter-spacing:.5px}
|
||
.kanban-count{font-size:11px;font-weight:600;background:var(--border);color:var(--muted);padding:2px 7px;border-radius:99px}
|
||
.kanban-card{background:var(--card);border-radius:9px;padding:14px;box-shadow:var(--shadow);display:flex;flex-direction:column;gap:8px;cursor:pointer;transition:all .15s;border-left:3px solid transparent}
|
||
.kanban-card:hover{box-shadow:var(--shadow-md);transform:translateY(-1px)}
|
||
.kanban-card.kred{border-left-color:var(--red)}
|
||
.kanban-card.kblue{border-left-color:var(--blue)}
|
||
.kanban-card.kamber{border-left-color:var(--amber)}
|
||
.kanban-card.kgreen{border-left-color:var(--green)}
|
||
.kc-title{font-size:13px;font-weight:600;color:#111;line-height:1.3}
|
||
.kc-client{font-size:11.5px;color:var(--muted)}
|
||
.kc-foot{display:flex;align-items:center;justify-content:space-between;margin-top:2px}
|
||
.kc-date{font-size:11px;color:var(--muted2);font-family:'DM Mono',monospace}
|
||
.kc-avatar{width:22px;height:22px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:9px;font-weight:700;color:#fff}
|
||
|
||
/* ─── CUSTOMER CARDS ─── */
|
||
.customer-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
|
||
.customer-card{background:var(--card);border-radius:var(--r);padding:18px;box-shadow:var(--shadow);display:flex;flex-direction:column;gap:10px;transition:box-shadow .15s;cursor:pointer}
|
||
.customer-card:hover{box-shadow:var(--shadow-md)}
|
||
.cc-logo{width:40px;height:40px;border-radius:10px;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:14px;color:#fff;flex-shrink:0}
|
||
.cc-name{font-size:14px;font-weight:650;color:#111}
|
||
.cc-sub{font-size:12px;color:var(--muted)}
|
||
.cc-stats{display:flex;gap:16px}
|
||
.cc-s{display:flex;flex-direction:column;gap:1px}
|
||
.cc-s-val{font-size:15px;font-weight:700;color:#111}
|
||
.cc-s-lbl{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.4px;color:var(--muted)}
|
||
|
||
/* ─── SETTINGS ─── */
|
||
.settings-tabs{display:flex;gap:0;border-bottom:2px solid var(--border);margin-bottom:0}
|
||
.settings-tab{padding:10px 20px;font-size:13.5px;font-weight:500;color:var(--muted);cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-2px;transition:all .15s}
|
||
.settings-tab.active{color:var(--red);border-bottom-color:var(--red);font-weight:650}
|
||
.settings-section{display:flex;flex-direction:column;gap:0}
|
||
.settings-row{display:flex;align-items:center;justify-content:space-between;padding:16px 0;border-bottom:1px solid var(--border);gap:20px}
|
||
.settings-row:last-child{border-bottom:none}
|
||
.settings-info{display:flex;flex-direction:column;gap:3px}
|
||
.settings-lbl{font-size:13.5px;font-weight:550;color:#111}
|
||
.settings-desc{font-size:12px;color:var(--muted)}
|
||
.toggle{width:42px;height:24px;border-radius:99px;cursor:pointer;transition:background .2s;flex-shrink:0;position:relative;border:none}
|
||
.toggle::after{content:'';width:18px;height:18px;border-radius:50%;background:#fff;position:absolute;top:3px;left:3px;transition:transform .2s;box-shadow:0 1px 3px rgba(0,0,0,.2)}
|
||
.toggle.on{background:var(--green)}.toggle.on::after{transform:translateX(18px)}
|
||
.toggle.off{background:#ddd}
|
||
|
||
/* ─── USER CARDS ─── */
|
||
.user-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
|
||
.user-card{background:var(--card);border-radius:var(--r);padding:18px;box-shadow:var(--shadow);display:flex;align-items:center;gap:14px;transition:box-shadow .15s}
|
||
.user-card:hover{box-shadow:var(--shadow-md)}
|
||
.ua-info{flex:1;min-width:0}
|
||
.ua-name{font-size:14px;font-weight:650;color:#111}
|
||
.ua-email{font-size:12px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
||
.ua-meta{display:flex;align-items:center;gap:8px;margin-top:6px}
|
||
|
||
/* ─── FIRMA ─── */
|
||
.firma-header{background:linear-gradient(135deg,#141414 0%,#2a2a2a 100%);border-radius:var(--r);padding:28px;display:flex;align-items:center;gap:20px;color:#fff}
|
||
.firma-logo{width:64px;height:64px;border-radius:12px;background:var(--red);display:flex;align-items:center;justify-content:center;font-weight:700;font-size:24px;flex-shrink:0}
|
||
|
||
/* Scrollbar */
|
||
::-webkit-scrollbar{width:5px}
|
||
::-webkit-scrollbar-track{background:transparent}
|
||
::-webkit-scrollbar-thumb{background:#ddd;border-radius:99px}
|
||
aside::-webkit-scrollbar-thumb{background:#333}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<!-- ══════════════ SIDEBAR ══════════════ -->
|
||
<aside>
|
||
<div class="sidebar-logo">
|
||
<div class="logo-mark">B</div>
|
||
<span>BOHA</span>
|
||
</div>
|
||
|
||
<div class="sb-section">
|
||
<div class="sb-label">Přehled</div>
|
||
<div class="nav-item" data-page="dashboard">
|
||
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></svg>
|
||
Přehled
|
||
</div>
|
||
</div>
|
||
|
||
<div class="sb-section">
|
||
<div class="sb-label">Docházka</div>
|
||
<div class="nav-item" data-page="doc-zaznam">
|
||
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="9"/><polyline points="12 7 12 12 15 15"/></svg>
|
||
Záznam <span class="nav-badge g">3</span>
|
||
</div>
|
||
<div class="nav-item" data-page="doc-historie">
|
||
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><polyline points="12 8 12 12 14 14"/><path d="M3.05 11a9 9 0 1 1 .5 4m-.5 5v-5h5"/></svg>
|
||
Historie
|
||
</div>
|
||
<div class="nav-item" data-page="doc-zadosti">
|
||
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="12" y1="18" x2="12" y2="12"/><line x1="9" y1="15" x2="15" y2="15"/></svg>
|
||
Žádosti
|
||
</div>
|
||
<div class="nav-item" data-page="doc-schvalovani">
|
||
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path d="M9 12l2 2 4-4"/><path d="M21 12c-1 4.5-5 8-9 8s-8-3.5-9-8 5-8 9-8 8 3.5 9 8z"/></svg>
|
||
Schvalování <span class="nav-badge">2</span>
|
||
</div>
|
||
<div class="nav-item" data-page="doc-bilance">
|
||
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><line x1="18" y1="20" x2="18" y2="10"/><line x1="12" y1="20" x2="12" y2="4"/><line x1="6" y1="20" x2="6" y2="14"/></svg>
|
||
Správa bilancí
|
||
</div>
|
||
</div>
|
||
|
||
<div class="sb-section">
|
||
<div class="sb-label">Kniha jízd</div>
|
||
<div class="nav-item" data-page="kj-zaznam">
|
||
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><circle cx="5" cy="18" r="3"/><circle cx="19" cy="18" r="3"/><path d="M10 18H14"/><path d="M5 18V12L8 5h8l3 7v6"/><path d="M8 5h8"/></svg>
|
||
Záznam
|
||
</div>
|
||
<div class="nav-item" data-page="kj-historie">
|
||
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><polyline points="12 8 12 12 14 14"/><path d="M3.05 11a9 9 0 1 1 .5 4m-.5 5v-5h5"/></svg>
|
||
Historie
|
||
</div>
|
||
<div class="nav-item" data-page="kj-vozidla">
|
||
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><rect x="1" y="3" width="15" height="13" rx="2"/><path d="M16 8h4l3 3v5h-7V8z"/><circle cx="5.5" cy="18.5" r="2.5"/><circle cx="18.5" cy="18.5" r="2.5"/></svg>
|
||
Vozidla
|
||
</div>
|
||
</div>
|
||
|
||
<div class="sb-section">
|
||
<div class="sb-label">Administrativa</div>
|
||
<div class="nav-item" data-page="adm-nabidky">
|
||
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>
|
||
Nabídky <span class="nav-badge b">5</span>
|
||
</div>
|
||
<div class="nav-item" data-page="adm-objednavky">
|
||
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path d="M6 2L3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z"/><line x1="3" y1="6" x2="21" y2="6"/><path d="M16 10a4 4 0 0 1-8 0"/></svg>
|
||
Objednávky
|
||
</div>
|
||
<div class="nav-item" data-page="adm-projekty">
|
||
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><rect x="2" y="3" width="20" height="14" rx="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg>
|
||
Projekty
|
||
</div>
|
||
<div class="nav-item" data-page="adm-faktury">
|
||
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><line x1="12" y1="1" x2="12" y2="23"/><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/></svg>
|
||
Faktury
|
||
</div>
|
||
<div class="nav-item" data-page="adm-zakaznici">
|
||
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
|
||
Zákazníci
|
||
</div>
|
||
<div class="nav-item" data-page="adm-firma">
|
||
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||
Firma
|
||
</div>
|
||
</div>
|
||
|
||
<div class="sb-section">
|
||
<div class="sb-label">Systém</div>
|
||
<div class="nav-item" data-page="uzivatele">
|
||
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
|
||
Uživatelé
|
||
</div>
|
||
<div class="nav-item" data-page="nastaveni">
|
||
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"/><path d="M19.07 4.93a10 10 0 0 1 0 14.14M4.93 4.93a10 10 0 0 0 0 14.14"/></svg>
|
||
Nastavení
|
||
</div>
|
||
</div>
|
||
|
||
<div class="sb-footer">
|
||
<div class="user-chip">
|
||
<div class="avatar">ŠH</div>
|
||
<div>
|
||
<div class="u-name">Šimon Haas</div>
|
||
<div class="u-role">Administrátor</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
|
||
<!-- ══════════════ MAIN ══════════════ -->
|
||
<main id="main-content"></main>
|
||
|
||
<script>
|
||
// ══════════════════════════════════════════
|
||
// PAGE RENDERERS
|
||
// ══════════════════════════════════════════
|
||
|
||
const pages = {
|
||
|
||
// ── DASHBOARD ──────────────────────────────
|
||
dashboard: () => `
|
||
<div class="page">
|
||
<div class="topbar">
|
||
<div><h1>Dobrý den, Šimone 👋</h1><div class="topbar-sub">Neděle, 8. března 2026 · Týden 10</div></div>
|
||
<div class="topbar-actions">
|
||
<button class="btn btn-ghost">
|
||
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" style="width:13px;height:13px"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></svg>
|
||
Notifikace <span style="background:var(--red);color:#fff;border-radius:99px;padding:0 5px;font-size:10px;font-weight:700;margin-left:4px">7</span>
|
||
</button>
|
||
<button class="btn btn-primary">+ Nová nabídka</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="kpi-grid kpi-4">
|
||
<div class="kpi-card green"><div class="kpi-lbl">Přítomní dnes</div><div class="kpi-val">7<small> / 9</small></div><div class="kpi-foot"><span class="tag-up">↑ +1</span> oproti včerejšku</div></div>
|
||
<div class="kpi-card blue"><div class="kpi-lbl">Otevřené nabídky</div><div class="kpi-val">5</div><div class="kpi-foot"><span class="tag-neu">2 čekají</span> na schválení</div></div>
|
||
<div class="kpi-card amber"><div class="kpi-lbl">Tržby (březen)</div><div class="kpi-val">148<small>k Kč</small></div><div class="kpi-foot"><span class="tag-up">↑ 12 %</span> vs. únor</div></div>
|
||
<div class="kpi-card red"><div class="kpi-lbl">Čeká schválení</div><div class="kpi-val">2</div><div class="kpi-foot"><span class="tag-dn">! urgentní</span> vyžaduje akci</div></div>
|
||
</div>
|
||
|
||
<div style="display:grid;grid-template-columns:repeat(4,1fr);gap:10px">
|
||
${qaBtn('green','M9 12l2 2 4-4','Zaznamenat příchod')}
|
||
${qaBtn('blue','M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z','Nová nabídka')}
|
||
${qaBtn('amber','M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z','Přidat jízdu')}
|
||
${qaBtn('red','M12 1v22M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6','Vystavit fakturu')}
|
||
</div>
|
||
|
||
<div class="three-col">
|
||
<div class="card">
|
||
<div class="card-header"><span class="card-title">Poslední aktivita</span><span class="card-link">Vše →</span></div>
|
||
${actRow('b','M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z','Nabídka <strong>VW-2026-047</strong> odeslána','Volkswagen Group of America','09:14')}
|
||
${actRow('g','M9 12l2 2 4-4','<strong>Jan Novák</strong> příchod zaznamenán','Docházka · 08:52','08:52')}
|
||
${actRow('a','M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z','Žádost o <strong>dovolenou</strong> čeká','Pavel Kratochvíl · 15.–19.3.','Včera')}
|
||
${actRow('r','M12 1v22M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6','Faktura <strong>#2026-018</strong> uhrazena','+42 500 Kč · ŠKODA AUTO','Včera')}
|
||
${actRow('b','M2 3h20M2 3v14h20V3','Projekt <strong>TIA Migration</strong> aktualizován','75 % hotovo','6.3.')}
|
||
</div>
|
||
<div class="card">
|
||
<div class="card-header"><span class="card-title">Docházka dnes</span><span class="card-link">Detail →</span></div>
|
||
${presRow('JN','#DBEAFE','#2D80E4','Jan Novák','in','Přítomen','08:52')}
|
||
${presRow('MK','#D1FAE5','#00B894','Marie Kučerová','in','Přítomna','07:45')}
|
||
${presRow('PK','#FEF3C7','#F39C12','Pavel Kratochvíl','away','Home office','09:00')}
|
||
${presRow('LP','#FCE7F3','#DB2777','Lucie Procházková','in','Přítomna','08:10')}
|
||
${presRow('TO','#F3F4F6','#9CA3AF','Tomáš Ondřej','out','Nepřihlášen','—')}
|
||
${presRow('RB','#EDE9FE','#7C3AED','Radka Bílá','in','Přítomna','08:30')}
|
||
</div>
|
||
<div style="display:flex;flex-direction:column;gap:14px">
|
||
<div class="card">
|
||
<div class="card-header"><span class="card-title">Projekty – průběh</span><span class="card-link">Vše →</span></div>
|
||
<div style="padding:8px 0">
|
||
${progRow('TIA Migration S7-300','75','var(--blue)')}
|
||
${progRow('CIMPLICITY HMI Update','40','var(--amber)')}
|
||
${progRow('Web Platform BOHA','90','var(--green)')}
|
||
</div>
|
||
</div>
|
||
<div class="card">
|
||
<div class="card-header"><span class="card-title">Nabídky – status</span><span class="card-link">Zobrazit →</span></div>
|
||
${miniStatRow('Čeká na odeslání','3','a')}
|
||
${miniStatRow('Odesláno, čeká odezvu','2','b')}
|
||
${miniStatRow('Schváleno (březen)','4','g')}
|
||
${miniStatRow('Zamítnuto','1','r')}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>`,
|
||
|
||
// ── DOCHÁZKA – ZÁZNAM ──────────────────────
|
||
'doc-zaznam': () => `
|
||
<div class="page">
|
||
<div class="topbar">
|
||
<div><h1>Docházka – Záznamy</h1><div class="topbar-sub">Dnešní přehled příchodů a odchodů</div></div>
|
||
<div class="topbar-actions">
|
||
<button class="btn btn-ghost btn-sm">Export CSV</button>
|
||
<button class="btn btn-primary">+ Ruční záznam</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="kpi-grid kpi-4">
|
||
<div class="kpi-card green"><div class="kpi-lbl">Přítomno</div><div class="kpi-val">7</div><div class="kpi-foot">z 9 zaměstnanců</div></div>
|
||
<div class="kpi-card amber"><div class="kpi-lbl">Home office</div><div class="kpi-val">1</div><div class="kpi-foot">Pavel Kratochvíl</div></div>
|
||
<div class="kpi-card red"><div class="kpi-lbl">Nepřítomno</div><div class="kpi-val">1</div><div class="kpi-foot">Bez záznamu</div></div>
|
||
<div class="kpi-card blue"><div class="kpi-lbl">Průměr příchodu</div><div class="kpi-val">08:24</div><div class="kpi-foot">dnes</div></div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<span class="card-title">Záznamy – dnes, 8. března 2026</span>
|
||
<div style="display:flex;gap:8px">
|
||
<input class="filter-input" style="width:180px" placeholder="Hledat jméno…">
|
||
<select class="filter-select" style="width:140px"><option>Všichni</option><option>Přítomní</option><option>Nepřítomní</option></select>
|
||
</div>
|
||
</div>
|
||
<div class="tbl-wrap">
|
||
<table>
|
||
<thead><tr><th>Zaměstnanec</th><th>Příchod</th><th>Odchod</th><th>Přestávky</th><th>Celkem</th><th>Typ</th><th>Status</th><th></th></tr></thead>
|
||
<tbody>
|
||
${docRow('JN','#DBEAFE','#2D80E4','Jan Novák','08:52','—','0:30','7:23','Kancelář','in','Přítomen')}
|
||
${docRow('MK','#D1FAE5','#00B894','Marie Kučerová','07:45','—','0:30','8:00','Kancelář','in','Přítomna')}
|
||
${docRow('PK','#FEF3C7','#F39C12','Pavel Kratochvíl','09:00','—','0:00','6:45','Home office','away','HO')}
|
||
${docRow('LP','#FCE7F3','#DB2777','Lucie Procházková','08:10','—','1:00','7:35','Kancelář','in','Přítomna')}
|
||
${docRow('TO','#F3F4F6','#9CA3AF','Tomáš Ondřej','—','—','—','—','—','out','Nepřihlášen')}
|
||
${docRow('RB','#EDE9FE','#7C3AED','Radka Bílá','08:30','—','0:30','7:15','Kancelář','in','Přítomna')}
|
||
${docRow('JK','#FEE2E2','#DC2626','Jiří Kratochvíl','07:30','15:30','0:45','7:15','Kancelář','g','Odešel')}
|
||
${docRow('AH','#DBEAFE','#1D4ED8','Anna Horáčková','08:05','—','0:30','7:30','Kancelář','in','Přítomna')}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>`,
|
||
|
||
// ── DOCHÁZKA – HISTORIE ─────────────────────
|
||
'doc-historie': () => `
|
||
<div class="page">
|
||
<div class="topbar">
|
||
<div><h1>Docházka – Historie</h1><div class="topbar-sub">Přehled docházky za vybrané období</div></div>
|
||
<div class="topbar-actions">
|
||
<input class="filter-input" type="month" value="2026-03">
|
||
<select class="filter-select"><option>Všichni zaměstnanci</option><option>Jan Novák</option><option>Marie Kučerová</option></select>
|
||
<button class="btn btn-ghost btn-sm">Export</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="col-32">
|
||
<div class="card">
|
||
<div class="card-header"><span class="card-title">Kalendář – Březen 2026</span></div>
|
||
<div style="padding:16px">
|
||
<div class="cal-grid">
|
||
${['Po','Út','St','Čt','Pá','So','Ne'].map(d=>`<div class="cal-head">${d}</div>`).join('')}
|
||
${Array.from({length:6},(_,i)=>'<div class="cal-day other-month">'+(23+i)+'</div>').join('')}
|
||
${Array.from({length:31},(_,i)=>{
|
||
const d=i+1,isToday=d===8,isWe=((5+i)%7>=5),hasData=d<8&&!isWe;
|
||
return `<div class="cal-day${isToday?' today':''}${hasData?' has-data':''}${isWe&&!isToday?' weekend':''}">${d}</div>`;
|
||
}).join('')}
|
||
${Array.from({length:3},(_,i)=>'<div class="cal-day other-month">'+(i+1)+'</div>').join('')}
|
||
</div>
|
||
<div style="display:flex;gap:16px;margin-top:14px;font-size:11.5px;color:var(--muted)">
|
||
<span style="display:flex;align-items:center;gap:5px"><span style="width:8px;height:8px;border-radius:50%;background:var(--green);display:inline-block"></span>Pracovní den</span>
|
||
<span style="display:flex;align-items:center;gap:5px"><span style="width:8px;height:8px;border-radius:50%;background:var(--amber);display:inline-block"></span>Dovolená / HO</span>
|
||
<span style="display:flex;align-items:center;gap:5px"><span style="width:8px;height:8px;border-radius:50%;background:var(--red);display:inline-block"></span>Nepřítomnost</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div style="display:flex;flex-direction:column;gap:14px">
|
||
<div class="card">
|
||
<div class="card-header"><span class="card-title">Souhrn – Březen 2026</span></div>
|
||
${miniStatRow('Pracovní dny v měsíci','21','n')}
|
||
${miniStatRow('Odpracováno dní','7','g')}
|
||
${miniStatRow('Dovolená','0','a')}
|
||
${miniStatRow('Přesčasy','3h 20min','b')}
|
||
${miniStatRow('Nemocenská','0','n')}
|
||
${miniStatRow('Zbývá dovolené','18 dní','g')}
|
||
</div>
|
||
<div class="card">
|
||
<div class="card-header"><span class="card-title">Rychlé porovnání</span></div>
|
||
${miniStatRow('Únor 2026','160h 45min','n')}
|
||
${miniStatRow('Leden 2026','158h 30min','n')}
|
||
${miniStatRow('Prosinec 2025','148h 00min','n')}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header"><span class="card-title">Detail záznamů</span></div>
|
||
<div class="tbl-wrap">
|
||
<table>
|
||
<thead><tr><th>Datum</th><th>Den</th><th>Příchod</th><th>Odchod</th><th>Přestávka</th><th>Odpracováno</th><th>Přesčas</th><th>Typ</th></tr></thead>
|
||
<tbody>
|
||
${histRow('3.3.2026','Úterý','08:45','17:30','0:30','8:15','+0:15','Kancelář','g')}
|
||
${histRow('4.3.2026','Středa','08:12','17:45','0:45','8:48','+0:48','Kancelář','g')}
|
||
${histRow('5.3.2026','Čtvrtek','08:55','17:00','0:30','7:35','0:00','Kancelář','g')}
|
||
${histRow('6.3.2026','Pátek','08:30','16:30','0:30','7:30','0:00','Kancelář','g')}
|
||
${histRow('7.3.2026','Sobota','—','—','—','—','—','Víkend','n')}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>`,
|
||
|
||
// ── DOCHÁZKA – ŽÁDOSTI ─────────────────────
|
||
'doc-zadosti': () => `
|
||
<div class="page">
|
||
<div class="topbar">
|
||
<div><h1>Žádosti</h1><div class="topbar-sub">Dovolené, sick days, home office, přesčasy</div></div>
|
||
<div class="topbar-actions">
|
||
<button class="btn btn-primary">+ Nová žádost</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="display:flex;gap:12px;align-items:center">
|
||
<div class="tabs">
|
||
<div class="tab active">Vše (8)</div>
|
||
<div class="tab">Čeká (2)</div>
|
||
<div class="tab">Schváleno (5)</div>
|
||
<div class="tab">Zamítnuto (1)</div>
|
||
</div>
|
||
<div style="margin-left:auto;display:flex;gap:8px">
|
||
<input class="filter-input" placeholder="Hledat…" style="width:160px">
|
||
<select class="filter-select" style="width:140px"><option>Všichni</option></select>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="tbl-wrap">
|
||
<table>
|
||
<thead><tr><th>Žadatel</th><th>Typ</th><th>Od</th><th>Do</th><th>Dní</th><th>Poznámka</th><th>Podáno</th><th>Stav</th><th></th></tr></thead>
|
||
<tbody>
|
||
${zadostRow('PK','#FEF3C7','#F39C12','Pavel Kratochvíl','Dovolená','15.3.2026','19.3.2026','5','Rodinná dovolená','4.3.2026','a','Čeká')}
|
||
${zadostRow('TO','#F3F4F6','#9CA3AF','Tomáš Ondřej','Sick day','8.3.2026','8.3.2026','1','Nachlazení','8.3.2026','a','Čeká')}
|
||
${zadostRow('MK','#D1FAE5','#00B894','Marie Kučerová','Dovolená','24.3.2026','28.3.2026','5','Jarní prázdniny','2.3.2026','g','Schváleno')}
|
||
${zadostRow('JN','#DBEAFE','#2D80E4','Jan Novák','Home office','10.3.2026','12.3.2026','3','Práce z domova','1.3.2026','g','Schváleno')}
|
||
${zadostRow('LP','#FCE7F3','#DB2777','Lucie Procházková','Dovolená','1.4.2026','3.4.2026','3','','28.2.2026','g','Schváleno')}
|
||
${zadostRow('RB','#EDE9FE','#7C3AED','Radka Bílá','Přesčas','5.3.2026','5.3.2026','1','Dokončení projektu','5.3.2026','g','Schváleno')}
|
||
${zadostRow('JK','#FEE2E2','#DC2626','Jiří Kratochvíl','Dovolená','20.3.2026','21.3.2026','2','','25.2.2026','r','Zamítnuto')}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>`,
|
||
|
||
// ── DOCHÁZKA – SCHVALOVÁNÍ ─────────────────
|
||
'doc-schvalovani': () => `
|
||
<div class="page">
|
||
<div class="topbar">
|
||
<div><h1>Schvalování</h1><div class="topbar-sub">Žádosti čekající na váš podpis</div></div>
|
||
<div class="topbar-actions">
|
||
<button class="btn btn-ghost btn-sm">Schválit vše</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="kpi-grid kpi-3">
|
||
<div class="kpi-card red"><div class="kpi-lbl">Čeká schválení</div><div class="kpi-val">2</div><div class="kpi-foot"><span class="tag-dn">urgentní</span></div></div>
|
||
<div class="kpi-card green"><div class="kpi-lbl">Schváleno tento měsíc</div><div class="kpi-val">9</div><div class="kpi-foot">z 10 žádostí</div></div>
|
||
<div class="kpi-card amber"><div class="kpi-lbl">Zamítnuto</div><div class="kpi-val">1</div><div class="kpi-foot">v březnu</div></div>
|
||
</div>
|
||
|
||
<div style="display:flex;flex-direction:column;gap:12px">
|
||
<div style="font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.8px;color:var(--muted)">Čeká na schválení</div>
|
||
${schvalCard('PK','#FEF3C7','#F39C12','Pavel Kratochvíl','Dovolená','15.3.2026 – 19.3.2026','5 pracovních dní','Rodinná dovolená v Alpách. Záskok zajistí kolega Novák.','4.3.2026')}
|
||
${schvalCard('TO','#F3F4F6','#9CA3AF','Tomáš Ondřej','Sick day','8.3.2026','1 den','Nachlazení, doloženo potvrzením od lékaře.','8.3.2026')}
|
||
</div>
|
||
|
||
<div style="display:flex;flex-direction:column;gap:12px">
|
||
<div style="font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.8px;color:var(--muted)">Nedávno vyřešené</div>
|
||
<div class="card">
|
||
<div class="tbl-wrap">
|
||
<table>
|
||
<thead><tr><th>Žadatel</th><th>Typ</th><th>Datum</th><th>Vyřídil</th><th>Dne</th><th>Stav</th></tr></thead>
|
||
<tbody>
|
||
${histRow2('Marie Kučerová','Dovolená','24.–28.3.','Šimon Haas','2.3.','g','Schváleno')}
|
||
${histRow2('Jan Novák','Home office','10.–12.3.','Šimon Haas','1.3.','g','Schváleno')}
|
||
${histRow2('Jiří Kratochvíl','Dovolená','20.–21.3.','Šimon Haas','26.2.','r','Zamítnuto')}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>`,
|
||
|
||
// ── DOCHÁZKA – BILANCE ─────────────────────
|
||
'doc-bilance': () => `
|
||
<div class="page">
|
||
<div class="topbar">
|
||
<div><h1>Správa bilancí</h1><div class="topbar-sub">Přehled dovolených, přesčasů a sick days na rok 2026</div></div>
|
||
<div class="topbar-actions">
|
||
<button class="btn btn-ghost btn-sm">Export XLSX</button>
|
||
<button class="btn btn-primary">Hromadná úprava</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="kpi-grid kpi-4">
|
||
<div class="kpi-card blue"><div class="kpi-lbl">Průměr dovolené zbývá</div><div class="kpi-val">17.4<small>dní</small></div><div class="kpi-foot">na zaměstnance</div></div>
|
||
<div class="kpi-card green"><div class="kpi-lbl">Dovolená čerpána</div><div class="kpi-val">2.6<small>dní</small></div><div class="kpi-foot">průměr, Q1 2026</div></div>
|
||
<div class="kpi-card amber"><div class="kpi-lbl">Celkem přesčasy</div><div class="kpi-val">24<small>h</small></div><div class="kpi-foot">nevyčerpáno</div></div>
|
||
<div class="kpi-card red"><div class="kpi-lbl">Sick days použito</div><div class="kpi-val">3</div><div class="kpi-foot">z 30 dostupných</div></div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header"><span class="card-title">Bilance zaměstnanců – 2026</span></div>
|
||
<div class="tbl-wrap">
|
||
<table>
|
||
<thead><tr><th>Zaměstnanec</th><th>Dovolená nárok</th><th>Čerpáno</th><th>Zbývá</th><th>Přesčas (h)</th><th>Sick days</th><th>HO (dní)</th><th>Stav</th></tr></thead>
|
||
<tbody>
|
||
${bilanceRow('JN','#DBEAFE','#2D80E4','Jan Novák','25','3','22','12','1','8','g')}
|
||
${bilanceRow('MK','#D1FAE5','#00B894','Marie Kučerová','25','5','20','4','2','12','g')}
|
||
${bilanceRow('PK','#FEF3C7','#F39C12','Pavel Kratochvíl','25','0','25','8','0','3','a')}
|
||
${bilanceRow('LP','#FCE7F3','#DB2777','Lucie Procházková','20','3','17','6','0','5','g')}
|
||
${bilanceRow('TO','#F3F4F6','#9CA3AF','Tomáš Ondřej','20','1','19','0','1','2','g')}
|
||
${bilanceRow('RB','#EDE9FE','#7C3AED','Radka Bílá','25','2','23','0','0','0','g')}
|
||
${bilanceRow('JK','#FEE2E2','#DC2626','Jiří Kratochvíl','25','5','20','-4','0','0','r')}
|
||
${bilanceRow('AH','#DBEAFE','#1D4ED8','Anna Horáčková','25','2','23','2','0','4','g')}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>`,
|
||
|
||
// ── KNIHA JÍZD – ZÁZNAM ────────────────────
|
||
'kj-zaznam': () => `
|
||
<div class="page">
|
||
<div class="topbar">
|
||
<div><h1>Záznam jízdy</h1><div class="topbar-sub">Nová nebo aktivní jízda</div></div>
|
||
<div class="topbar-actions">
|
||
<button class="btn btn-ghost btn-sm">Uložit jako koncept</button>
|
||
<button class="btn btn-primary">Uložit jízdu</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="two-col">
|
||
<div class="card">
|
||
<div class="card-header"><span class="card-title">Detail jízdy</span></div>
|
||
<div class="card-body">
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Datum</label>
|
||
<input class="form-input" type="date" value="2026-03-08">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Vozidlo</label>
|
||
<select class="form-sel"><option>1AX 1234 – Škoda Octavia</option><option>2BC 5678 – VW Passat</option><option>3CD 9012 – Renault Trafic</option></select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Řidič</label>
|
||
<select class="form-sel"><option>Šimon Haas</option><option>Jan Novák</option><option>Marie Kučerová</option></select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Účel jízdy</label>
|
||
<select class="form-sel"><option>Služební</option><option>Soukromá</option></select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Odkud</label>
|
||
<input class="form-input" placeholder="Výchozí místo" value="Mladá Boleslav, závod">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Kam</label>
|
||
<input class="form-input" placeholder="Cílové místo" value="Volkswagen, Chattanooga TN">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Stav km – začátek</label>
|
||
<input class="form-input" type="number" placeholder="km" value="48230">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Stav km – konec</label>
|
||
<input class="form-input" type="number" placeholder="km">
|
||
</div>
|
||
<div class="form-group full">
|
||
<label class="form-label">Popis / poznámka</label>
|
||
<textarea class="form-textarea" placeholder="Popis cesty, zákazník, projekt…">Servisní návštěva VW Chattanooga – komisionování enkodéru</textarea>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="display:flex;flex-direction:column;gap:14px">
|
||
<div class="card">
|
||
<div class="card-header"><span class="card-title">Shrnutí jízdy</span></div>
|
||
<div class="card-body">
|
||
<div style="display:flex;flex-direction:column;gap:12px">
|
||
${sumRow('Vzdálenost','— km','b')}
|
||
${sumRow('Vozidlo','Škoda Octavia · 1AX 1234','n')}
|
||
${sumRow('Řidič','Šimon Haas','g')}
|
||
${sumRow('Datum','8.3.2026','n')}
|
||
${sumRow('Typ','Služební','b')}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header"><span class="card-title">Dnešní jízdy vozidla</span></div>
|
||
<div style="padding:12px 0">
|
||
<div style="text-align:center;padding:20px;color:var(--muted);font-size:13px">Zatím žádné záznamy dnes</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header"><span class="card-title">Nejčastější trasy</span></div>
|
||
${actRow('b','M9 17H7A5 5 0 0 1 7 7h2','MB závod → Praha','42 km · 87x použita','nejčastější')}
|
||
${actRow('g','M9 17H7A5 5 0 0 1 7 7h2','MB závod → Volkswagen CZ','18 km · 34x použita','')}
|
||
${actRow('a','M9 17H7A5 5 0 0 1 7 7h2','Praha → Brno','210 km · 12x použita','')}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>`,
|
||
|
||
// ── KNIHA JÍZD – HISTORIE ──────────────────
|
||
'kj-historie': () => `
|
||
<div class="page">
|
||
<div class="topbar">
|
||
<div><h1>Kniha jízd – Historie</h1><div class="topbar-sub">Kompletní přehled zaznamenaných jízd</div></div>
|
||
<div class="topbar-actions">
|
||
<input class="filter-input" type="month" value="2026-03">
|
||
<button class="btn btn-ghost btn-sm">Export PDF</button>
|
||
<button class="btn btn-primary">+ Nová jízda</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="kpi-grid kpi-4">
|
||
<div class="kpi-card blue"><div class="kpi-lbl">Celkem km (březen)</div><div class="kpi-val">2 840<small>km</small></div><div class="kpi-foot"><span class="tag-up">↑ 8 %</span> vs únor</div></div>
|
||
<div class="kpi-card green"><div class="kpi-lbl">Jízd celkem</div><div class="kpi-val">47</div><div class="kpi-foot">v tomto měsíci</div></div>
|
||
<div class="kpi-card amber"><div class="kpi-lbl">Průměr km / jízda</div><div class="kpi-val">60.4<small>km</small></div><div class="kpi-foot"></div></div>
|
||
<div class="kpi-card red"><div class="kpi-lbl">Soukromé jízdy</div><div class="kpi-val">3</div><div class="kpi-foot">6.4 % z celku</div></div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<span class="card-title">Záznamy</span>
|
||
<div style="display:flex;gap:8px">
|
||
<input class="filter-input" placeholder="Hledat trasu…" style="width:180px">
|
||
<select class="filter-select" style="width:160px"><option>Všechna vozidla</option><option>1AX 1234</option><option>2BC 5678</option></select>
|
||
<select class="filter-select" style="width:140px"><option>Všichni řidiči</option></select>
|
||
</div>
|
||
</div>
|
||
<div class="tbl-wrap">
|
||
<table>
|
||
<thead><tr><th>Datum</th><th>Vozidlo</th><th>Řidič</th><th>Odkud</th><th>Kam</th><th>km</th><th>Účel</th><th>Typ</th><th></th></tr></thead>
|
||
<tbody>
|
||
${jizdaRow('8.3.2026','1AX 1234','Šimon Haas','MB závod','VW Chattanooga','18','Komisionování enkodéru','Služební','b')}
|
||
${jizdaRow('7.3.2026','2BC 5678','Jan Novák','Praha','Mladá Boleslav','58','Zákazník ŠKODA','Služební','b')}
|
||
${jizdaRow('6.3.2026','1AX 1234','Šimon Haas','MB závod','Praha, zákazník','120','Obchodní jednání','Služební','b')}
|
||
${jizdaRow('6.3.2026','1AX 1234','Šimon Haas','Praha','MB závod','120','Zpáteční cesta','Služební','b')}
|
||
${jizdaRow('5.3.2026','3CD 9012','Pavel Kratochvíl','MB','Liberec','85','Servis klienta','Služební','b')}
|
||
${jizdaRow('4.3.2026','2BC 5678','Marie Kučerová','MB závod','Nymburk','34','Dodávka dokumentů','Služební','b')}
|
||
${jizdaRow('4.3.2026','1AX 1234','Jan Novák','MB','Praha','60','Osobní','Soukromá','n')}
|
||
${jizdaRow('3.3.2026','3CD 9012','Šimon Haas','MB','Brno','210','Výstava AMPER','Služební','b')}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>`,
|
||
|
||
// ── KNIHA JÍZD – VOZIDLA ───────────────────
|
||
'kj-vozidla': () => `
|
||
<div class="page">
|
||
<div class="topbar">
|
||
<div><h1>Vozidla</h1><div class="topbar-sub">Správa firemního vozového parku</div></div>
|
||
<div class="topbar-actions">
|
||
<button class="btn btn-primary">+ Přidat vozidlo</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="kpi-grid kpi-4">
|
||
<div class="kpi-card green"><div class="kpi-lbl">Vozidel celkem</div><div class="kpi-val">3</div><div class="kpi-foot">v provozu</div></div>
|
||
<div class="kpi-card blue"><div class="kpi-lbl">Km celkem (rok)</div><div class="kpi-val">34 820<small>km</small></div><div class="kpi-foot">2026</div></div>
|
||
<div class="kpi-card amber"><div class="kpi-lbl">Nejbližší STK</div><div class="kpi-val">48<small>dní</small></div><div class="kpi-foot">Škoda Octavia</div></div>
|
||
<div class="kpi-card red"><div class="kpi-lbl">Servis potřeba</div><div class="kpi-val">1</div><div class="kpi-foot">Renault Trafic</div></div>
|
||
</div>
|
||
|
||
<div class="vehicle-grid">
|
||
${vehicleCard('1AX 1234','Škoda Octavia','2021','Benzín','48 230','8.3.2026','dostupné','g','Dostupné','25.4.2026')}
|
||
${vehicleCard('2BC 5678','VW Passat','2020','Diesel','92 450','7.3.2026','dostupné','g','Dostupné','12.9.2026')}
|
||
${vehicleCard('3CD 9012','Renault Trafic','2019','Diesel','124 780','5.3.2026','servis','r','Servis potřeba','2.2.2026')}
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header"><span class="card-title">Vytíženost vozidel – Březen 2026</span></div>
|
||
<div style="padding:16px;display:flex;flex-direction:column;gap:14px">
|
||
${progRow2('Škoda Octavia (1AX 1234)','1 240 km','var(--blue)','62')}
|
||
${progRow2('VW Passat (2BC 5678)','980 km','var(--green)','49')}
|
||
${progRow2('Renault Trafic (3CD 9012)','620 km','var(--amber)','31')}
|
||
</div>
|
||
</div>
|
||
</div>`,
|
||
|
||
// ── ADMINISTRATIVA – NABÍDKY ───────────────
|
||
'adm-nabidky': () => `
|
||
<div class="page">
|
||
<div class="topbar">
|
||
<div><h1>Nabídky</h1><div class="topbar-sub">Cenové nabídky a kalkulace</div></div>
|
||
<div class="topbar-actions">
|
||
<button class="btn btn-ghost btn-sm">Import</button>
|
||
<button class="btn btn-primary">+ Nová nabídka</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="kpi-grid kpi-4">
|
||
<div class="kpi-card blue"><div class="kpi-lbl">Otevřené</div><div class="kpi-val">5</div><div class="kpi-foot">2 čekají na odezvu</div></div>
|
||
<div class="kpi-card green"><div class="kpi-lbl">Schváleno (březen)</div><div class="kpi-val">4</div><div class="kpi-foot"><span class="tag-up">480 000 Kč</span></div></div>
|
||
<div class="kpi-card amber"><div class="kpi-lbl">Úspěšnost</div><div class="kpi-val">72<small>%</small></div><div class="kpi-foot">za posledních 90 dní</div></div>
|
||
<div class="kpi-card red"><div class="kpi-lbl">Zamítnuto</div><div class="kpi-val">1</div><div class="kpi-foot">v březnu</div></div>
|
||
</div>
|
||
|
||
<div style="display:flex;gap:10px;align-items:center">
|
||
<div class="tabs">
|
||
<div class="tab active">Vše (12)</div>
|
||
<div class="tab">Koncept (3)</div>
|
||
<div class="tab">Odesláno (2)</div>
|
||
<div class="tab">Schváleno (4)</div>
|
||
<div class="tab">Zamítnuto (1)</div>
|
||
</div>
|
||
<div style="margin-left:auto;display:flex;gap:8px">
|
||
<input class="filter-input" placeholder="Číslo nebo zákazník…" style="width:200px">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="tbl-wrap">
|
||
<table>
|
||
<thead><tr><th>Číslo</th><th>Zákazník</th><th>Předmět</th><th>Hodnota</th><th>Vytvořeno</th><th>Platnost</th><th>Stav</th><th></th></tr></thead>
|
||
<tbody>
|
||
${nabidkaRow('VW-2026-047','Volkswagen Group of America','TIA Portal S7-1500 Migration','185 000 Kč','4.3.2026','4.4.2026','b','Odesláno')}
|
||
${nabidkaRow('SK-2026-031','ŠKODA AUTO a.s.','CIMPLICITY SCADA Update','92 500 Kč','1.3.2026','1.4.2026','b','Odesláno')}
|
||
${nabidkaRow('BO-2026-028','BOSCH CZ s.r.o.','PLC Programming S7-300→1500','340 000 Kč','25.2.2026','25.3.2026','g','Schváleno')}
|
||
${nabidkaRow('SI-2026-021','Siemens s.r.o.','HMI Panel Replacement','76 000 Kč','20.2.2026','20.3.2026','g','Schváleno')}
|
||
${nabidkaRow('AU-2026-019','AutoCont CZ a.s.','Web Platform Development','125 000 Kč','15.2.2026','15.3.2026','g','Schváleno')}
|
||
${nabidkaRow('SE-2026-014','SEW-Eurodrive','Drive Commissioning','48 000 Kč','10.2.2026','10.3.2026','r','Zamítnuto')}
|
||
${nabidkaRow('VW-2026-052','Volkswagen Group of America','SICK Sensor Integration','28 000 Kč','6.3.2026','—','n','Koncept')}
|
||
${nabidkaRow('AB-2026-053','ABB s.r.o.','Electro Documentation','55 000 Kč','7.3.2026','—','n','Koncept')}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>`,
|
||
|
||
// ── ADMINISTRATIVA – OBJEDNÁVKY ────────────
|
||
'adm-objednavky': () => `
|
||
<div class="page">
|
||
<div class="topbar">
|
||
<div><h1>Objednávky</h1><div class="topbar-sub">Přijaté i vystavené objednávky</div></div>
|
||
<div class="topbar-actions">
|
||
<button class="btn btn-primary">+ Nová objednávka</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="display:flex;gap:10px;margin-bottom:0">
|
||
<div class="tabs">
|
||
<div class="tab active">Přijaté (8)</div>
|
||
<div class="tab">Vystavené (5)</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="kpi-grid kpi-3">
|
||
<div class="kpi-card green"><div class="kpi-lbl">Splněno</div><div class="kpi-val">5</div><div class="kpi-foot">tento měsíc</div></div>
|
||
<div class="kpi-card amber"><div class="kpi-lbl">V řešení</div><div class="kpi-val">2</div><div class="kpi-foot">probíhá</div></div>
|
||
<div class="kpi-card blue"><div class="kpi-lbl">Hodnota (březen)</div><div class="kpi-val">720<small>k Kč</small></div><div class="kpi-foot">přijaté objednávky</div></div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="tbl-wrap">
|
||
<table>
|
||
<thead><tr><th>Číslo OBJ</th><th>Zákazník / Dodavatel</th><th>Předmět</th><th>Hodnota</th><th>Datum</th><th>Termín</th><th>Stav</th><th></th></tr></thead>
|
||
<tbody>
|
||
${objednavkaRow('OBJ-2026-038','Volkswagen Group of America','TIA Portal Migration Phase 2','185 000 Kč','5.3.2026','30.6.2026','b','V řešení')}
|
||
${objednavkaRow('OBJ-2026-035','ŠKODA AUTO a.s.','SCADA Update – Linka B','92 500 Kč','1.3.2026','31.5.2026','b','V řešení')}
|
||
${objednavkaRow('OBJ-2026-029','BOSCH CZ s.r.o.','PLC Programming','340 000 Kč','22.2.2026','30.4.2026','g','Splněno')}
|
||
${objednavkaRow('OBJ-2026-022','Siemens s.r.o.','HMI Replacement','76 000 Kč','18.2.2026','28.2.2026','g','Splněno')}
|
||
${objednavkaRow('OBJ-2026-017','AutoCont CZ a.s.','Web Platform','125 000 Kč','10.2.2026','31.3.2026','a','Čeká')}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>`,
|
||
|
||
// ── ADMINISTRATIVA – PROJEKTY ──────────────
|
||
'adm-projekty': () => `
|
||
<div class="page">
|
||
<div class="topbar">
|
||
<div><h1>Projekty</h1><div class="topbar-sub">Přehled všech aktivních projektů</div></div>
|
||
<div class="topbar-actions">
|
||
<div class="tabs" style="background:transparent;padding:0;gap:6px">
|
||
<div class="tab active" style="background:#fff;border:1px solid var(--border);box-shadow:none">Kanban</div>
|
||
<div class="tab" style="background:transparent">Seznam</div>
|
||
</div>
|
||
<button class="btn btn-primary">+ Nový projekt</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="kpi-grid kpi-4">
|
||
<div class="kpi-card blue"><div class="kpi-lbl">Aktivní projekty</div><div class="kpi-val">7</div><div class="kpi-foot"></div></div>
|
||
<div class="kpi-card amber"><div class="kpi-lbl">Blíží se deadline</div><div class="kpi-val">2</div><div class="kpi-foot">do 30 dní</div></div>
|
||
<div class="kpi-card green"><div class="kpi-lbl">Dokončeno (2026)</div><div class="kpi-val">3</div><div class="kpi-foot"></div></div>
|
||
<div class="kpi-card red"><div class="kpi-lbl">Po termínu</div><div class="kpi-val">0</div><div class="kpi-foot">vše v pořádku ✓</div></div>
|
||
</div>
|
||
|
||
<div class="kanban">
|
||
<div class="kanban-col">
|
||
<div class="kanban-header"><span class="kanban-title" style="color:var(--muted)">📋 Plánování</span><span class="kanban-count">2</span></div>
|
||
${kanbanCard('kblue','Web Platform v2.0','BOHA Automation','15.6.2026','ŠH','#D63031')}
|
||
${kanbanCard('kblue','Dokumentace TIA','Interní','30.4.2026','JN','#2D80E4')}
|
||
</div>
|
||
<div class="kanban-col">
|
||
<div class="kanban-header"><span class="kanban-title" style="color:var(--amber)">⚙️ V realizaci</span><span class="kanban-count">3</span></div>
|
||
${kanbanCard('kamber','TIA Migration S7-300→1500','Volkswagen Group of America','30.6.2026','ŠH','#D63031')}
|
||
${kanbanCard('kamber','CIMPLICITY HMI Update','ŠKODA AUTO a.s.','31.5.2026','MK','#00B894')}
|
||
${kanbanCard('kamber','SICK Sensor FB Migration','ABB s.r.o.','15.4.2026','JN','#2D80E4')}
|
||
</div>
|
||
<div class="kanban-col">
|
||
<div class="kanban-header"><span class="kanban-title" style="color:var(--blue)">🔍 Review</span><span class="kanban-count">1</span></div>
|
||
${kanbanCard('kred','SSI Encoder Commissioning','Pepperl+Fuchs','20.3.2026','ŠH','#D63031')}
|
||
</div>
|
||
<div class="kanban-col">
|
||
<div class="kanban-header"><span class="kanban-title" style="color:var(--green)">✅ Hotovo</span><span class="kanban-count">2</span></div>
|
||
${kanbanCard('kgreen','PLC Library Standard','BOSCH CZ','28.2.2026','JK','#DC2626')}
|
||
${kanbanCard('kgreen','G120 Drive Commissioning','SEW-Eurodrive','15.2.2026','ŠH','#D63031')}
|
||
</div>
|
||
</div>
|
||
</div>`,
|
||
|
||
// ── ADMINISTRATIVA – FAKTURY ───────────────
|
||
'adm-faktury': () => `
|
||
<div class="page">
|
||
<div class="topbar">
|
||
<div><h1>Faktury</h1><div class="topbar-sub">Vydané faktury a přehled pohledávek</div></div>
|
||
<div class="topbar-actions">
|
||
<button class="btn btn-ghost btn-sm">Export účetnictví</button>
|
||
<button class="btn btn-primary">+ Vystavit fakturu</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="kpi-grid kpi-4">
|
||
<div class="kpi-card green"><div class="kpi-lbl">Uhrazeno (březen)</div><div class="kpi-val">148<small>k Kč</small></div><div class="kpi-foot"><span class="tag-up">+3 faktury</span></div></div>
|
||
<div class="kpi-card amber"><div class="kpi-lbl">Čeká úhrada</div><div class="kpi-val">277<small>k Kč</small></div><div class="kpi-foot">4 faktury</div></div>
|
||
<div class="kpi-card red"><div class="kpi-lbl">Po splatnosti</div><div class="kpi-val">0<small>Kč</small></div><div class="kpi-foot">vše v pořádku ✓</div></div>
|
||
<div class="kpi-card blue"><div class="kpi-lbl">DPH (březen)</div><div class="kpi-val">29.4<small>k Kč</small></div><div class="kpi-foot">21 %</div></div>
|
||
</div>
|
||
|
||
<div style="display:flex;gap:8px;align-items:center">
|
||
<div class="tabs">
|
||
<div class="tab active">Vše (11)</div>
|
||
<div class="tab">Čeká (4)</div>
|
||
<div class="tab">Uhrazeno (6)</div>
|
||
<div class="tab">Po splatnosti (0)</div>
|
||
</div>
|
||
<input class="filter-input" placeholder="Číslo faktury nebo zákazník…" style="margin-left:auto;width:220px">
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="tbl-wrap">
|
||
<table>
|
||
<thead><tr><th>Číslo</th><th>Zákazník</th><th>Předmět</th><th>Základ</th><th>DPH</th><th>Celkem</th><th>Vystaveno</th><th>Splatnost</th><th>Stav</th><th></th></tr></thead>
|
||
<tbody>
|
||
${fakturaRow('2026-021','ŠKODA AUTO a.s.','CIMPLICITY Update','42 500','8 925','51 425 Kč','1.3.2026','15.3.2026','g','Uhrazeno')}
|
||
${fakturaRow('2026-020','BOSCH CZ s.r.o.','PLC Programming','180 000','37 800','217 800 Kč','25.2.2026','25.3.2026','a','Čeká')}
|
||
${fakturaRow('2026-019','Siemens s.r.o.','HMI Replacement','76 000','15 960','91 960 Kč','20.2.2026','20.3.2026','a','Čeká')}
|
||
${fakturaRow('2026-018','Volkswagen Group of America','TIA Consultation','35 000','7 350','42 350 Kč','15.2.2026','1.3.2026','g','Uhrazeno')}
|
||
${fakturaRow('2026-017','AutoCont CZ a.s.','Web Development','68 000','14 280','82 280 Kč','10.2.2026','10.3.2026','a','Čeká')}
|
||
${fakturaRow('2026-016','ABB s.r.o.','Sensor Integration','28 000','5 880','33 880 Kč','5.2.2026','5.3.2026','g','Uhrazeno')}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>`,
|
||
|
||
// ── ADMINISTRATIVA – ZÁKAZNÍCI ─────────────
|
||
'adm-zakaznici': () => `
|
||
<div class="page">
|
||
<div class="topbar">
|
||
<div><h1>Zákazníci</h1><div class="topbar-sub">Přehled klientů a firem</div></div>
|
||
<div class="topbar-actions">
|
||
<div style="display:flex;gap:8px">
|
||
<input class="filter-input" placeholder="Hledat zákazníka…" style="width:200px">
|
||
<button class="btn btn-ghost">
|
||
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" style="width:13px;height:13px"><line x1="4" y1="6" x2="20" y2="6"/><line x1="8" y1="12" x2="16" y2="12"/><line x1="12" y1="18" x2="12" y2="18"/></svg>
|
||
Filtr
|
||
</button>
|
||
<button class="btn btn-primary">+ Přidat zákazníka</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="kpi-grid kpi-3">
|
||
<div class="kpi-card blue"><div class="kpi-lbl">Celkem zákazníků</div><div class="kpi-val">18</div><div class="kpi-foot">aktivní klienti</div></div>
|
||
<div class="kpi-card green"><div class="kpi-lbl">Nových (2026)</div><div class="kpi-val">3</div><div class="kpi-foot"></div></div>
|
||
<div class="kpi-card amber"><div class="kpi-lbl">Obrát top 5 (rok)</div><div class="kpi-val">2.4<small>M Kč</small></div><div class="kpi-foot"></div></div>
|
||
</div>
|
||
|
||
<div class="customer-grid">
|
||
${customerCard('#1e3a5f','VW','Volkswagen Group of America','Automobilový průmysl, USA','4 jízdy · 6 projektů','1 240 000 Kč')}
|
||
${customerCard('#1b5e20','SK','ŠKODA AUTO a.s.','Automobilový průmysl, CZ','12 faktur · 4 projekty','840 000 Kč')}
|
||
${customerCard('#7f1d1d','BO','BOSCH CZ s.r.o.','Automotive / Electronics','8 faktur · 3 projekty','620 000 Kč')}
|
||
${customerCard('#1a237e','SI','Siemens s.r.o.','Průmyslová automatizace','5 faktur · 2 projekty','310 000 Kč')}
|
||
${customerCard('#4a148c','AB','ABB s.r.o.','Průmyslová automatizace','3 faktury · 1 projekt','185 000 Kč')}
|
||
${customerCard('#e65100','AU','AutoCont CZ a.s.','IT & automatizace','2 faktury · 1 projekt','125 000 Kč')}
|
||
</div>
|
||
</div>`,
|
||
|
||
// ── ADMINISTRATIVA – FIRMA ─────────────────
|
||
'adm-firma': () => `
|
||
<div class="page">
|
||
<div class="topbar">
|
||
<div><h1>Profil firmy</h1><div class="topbar-sub">Základní informace a nastavení společnosti</div></div>
|
||
<div class="topbar-actions">
|
||
<button class="btn btn-primary">Uložit změny</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="firma-header">
|
||
<div class="firma-logo">B</div>
|
||
<div>
|
||
<div style="font-size:22px;font-weight:700;letter-spacing:-0.5px">BOHA Automation s.r.o.</div>
|
||
<div style="color:#888;font-size:14px;margin-top:4px">IČO: 12345678 · DIČ: CZ12345678 · Plátce DPH</div>
|
||
<div style="display:flex;gap:8px;margin-top:10px">
|
||
<span class="pill g">Aktivní</span>
|
||
<span class="pill b">Plátce DPH</span>
|
||
<span class="pill n">s.r.o.</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="two-col">
|
||
<div class="card">
|
||
<div class="card-header"><span class="card-title">Základní údaje</span></div>
|
||
<div class="card-body">
|
||
<div class="form-grid">
|
||
<div class="form-group full"><label class="form-label">Název společnosti</label><input class="form-input" value="BOHA Automation s.r.o."></div>
|
||
<div class="form-group"><label class="form-label">IČO</label><input class="form-input" value="12345678"></div>
|
||
<div class="form-group"><label class="form-label">DIČ</label><input class="form-input" value="CZ12345678"></div>
|
||
<div class="form-group full"><label class="form-label">Sídlo</label><input class="form-input" value="Mladá Boleslav, Česká republika"></div>
|
||
<div class="form-group"><label class="form-label">Telefon</label><input class="form-input" value="+420 xxx xxx xxx"></div>
|
||
<div class="form-group"><label class="form-label">E-mail</label><input class="form-input" value="info@boha-automation.cz"></div>
|
||
<div class="form-group full"><label class="form-label">Web</label><input class="form-input" value="www.boha-automation.cz"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div style="display:flex;flex-direction:column;gap:14px">
|
||
<div class="card">
|
||
<div class="card-header"><span class="card-title">Bankovní údaje</span></div>
|
||
<div class="card-body">
|
||
<div class="form-grid">
|
||
<div class="form-group full"><label class="form-label">Banka</label><input class="form-input" value="Komerční banka"></div>
|
||
<div class="form-group"><label class="form-label">Číslo účtu</label><input class="form-input" value="123456789/0100"></div>
|
||
<div class="form-group"><label class="form-label">IBAN</label><input class="form-input" value="CZ65 0100 0000 0012 3456 7890"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="card">
|
||
<div class="card-header"><span class="card-title">Fakturační nastavení</span></div>
|
||
<div class="card-body">
|
||
<div class="form-grid">
|
||
<div class="form-group"><label class="form-label">Splatnost (dní)</label><input class="form-input" value="14" type="number"></div>
|
||
<div class="form-group"><label class="form-label">DPH sazba</label><select class="form-sel"><option>21 %</option><option>12 %</option><option>0 %</option></select></div>
|
||
<div class="form-group full"><label class="form-label">Způsob platby</label><select class="form-sel"><option>Bankovní převod</option><option>Hotovost</option></select></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>`,
|
||
|
||
// ── UŽIVATELÉ ──────────────────────────────
|
||
uzivatele: () => `
|
||
<div class="page">
|
||
<div class="topbar">
|
||
<div><h1>Uživatelé</h1><div class="topbar-sub">Správa účtů a přístupových práv</div></div>
|
||
<div class="topbar-actions">
|
||
<input class="filter-input" placeholder="Hledat uživatele…" style="width:200px">
|
||
<button class="btn btn-primary">+ Přidat uživatele</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="kpi-grid kpi-4">
|
||
<div class="kpi-card blue"><div class="kpi-lbl">Celkem uživatelů</div><div class="kpi-val">9</div><div class="kpi-foot"></div></div>
|
||
<div class="kpi-card green"><div class="kpi-lbl">Aktivní dnes</div><div class="kpi-val">7</div><div class="kpi-foot"></div></div>
|
||
<div class="kpi-card red"><div class="kpi-lbl">Administrátoři</div><div class="kpi-val">1</div><div class="kpi-foot"></div></div>
|
||
<div class="kpi-card amber"><div class="kpi-lbl">2FA aktivní</div><div class="kpi-val">3</div><div class="kpi-foot">z 9 uživatelů</div></div>
|
||
</div>
|
||
|
||
<div class="user-grid">
|
||
${userCard('ŠH','#D63031','Šimon Haas','simon.haas@boha-automation.cz','Administrátor','Před 5 min','g','Aktivní',true)}
|
||
${userCard('JN','#2D80E4','Jan Novák','jan.novak@boha-automation.cz','Zaměstnanec','Dnes 08:52','g','Aktivní',true)}
|
||
${userCard('MK','#00B894','Marie Kučerová','marie.kucerova@boha-automation.cz','Zaměstnanec','Dnes 07:45','g','Aktivní',true)}
|
||
${userCard('PK','#F39C12','Pavel Kratochvíl','pavel.kratochvil@boha-automation.cz','Zaměstnanec','Dnes 09:00','a','HO',false)}
|
||
${userCard('LP','#DB2777','Lucie Procházková','lucie.prochazkova@boha-automation.cz','Manažer','Dnes 08:10','g','Aktivní',false)}
|
||
${userCard('TO','#9CA3AF','Tomáš Ondřej','tomas.ondrej@boha-automation.cz','Zaměstnanec','Včera 17:22','n','Offline',false)}
|
||
${userCard('RB','#7C3AED','Radka Bílá','radka.bila@boha-automation.cz','Zaměstnanec','Dnes 08:30','g','Aktivní',false)}
|
||
${userCard('JK','#DC2626','Jiří Kratochvíl','jiri.kratochvil@boha-automation.cz','Zaměstnanec','Dnes 07:30','g','Aktivní',false)}
|
||
${userCard('AH','#1D4ED8','Anna Horáčková','anna.horackova@boha-automation.cz','Zaměstnanec','Dnes 08:05','g','Aktivní',false)}
|
||
</div>
|
||
</div>`,
|
||
|
||
// ── NASTAVENÍ ──────────────────────────────
|
||
nastaveni: () => `
|
||
<div class="page">
|
||
<div class="topbar">
|
||
<div><h1>Nastavení</h1><div class="topbar-sub">Konfigurace systému a vašeho účtu</div></div>
|
||
<div class="topbar-actions">
|
||
<button class="btn btn-primary">Uložit změny</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="two-col">
|
||
<div style="display:flex;flex-direction:column;gap:14px">
|
||
<div class="card">
|
||
<div class="card-header"><span class="card-title">Váš účet</span></div>
|
||
<div class="card-body">
|
||
<div style="display:flex;align-items:center;gap:16px;margin-bottom:18px">
|
||
<div class="avatar" style="width:56px;height:56px;font-size:18px;border-radius:12px">ŠH</div>
|
||
<div>
|
||
<div style="font-size:16px;font-weight:650">Šimon Haas</div>
|
||
<div style="font-size:13px;color:var(--muted)">simon.haas@boha-automation.cz</div>
|
||
<div style="margin-top:6px"><span class="pill r">Administrátor</span></div>
|
||
</div>
|
||
</div>
|
||
<div class="form-grid">
|
||
<div class="form-group"><label class="form-label">Jméno</label><input class="form-input" value="Šimon"></div>
|
||
<div class="form-group"><label class="form-label">Příjmení</label><input class="form-input" value="Haas"></div>
|
||
<div class="form-group full"><label class="form-label">E-mail</label><input class="form-input" value="simon.haas@boha-automation.cz"></div>
|
||
<div class="form-group full"><label class="form-label">Nové heslo</label><input class="form-input" type="password" placeholder="Ponechte prázdné pro zachování"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header"><span class="card-title">Zabezpečení</span></div>
|
||
<div class="card-body" style="padding:0">
|
||
<div class="settings-section">
|
||
${settingsRow('Dvoufaktorové ověření (2FA)','Přidat extra vrstvu ochrany','off')}
|
||
${settingsRow('Přihlašovací notifikace','E-mail při každém novém přihlášení','on')}
|
||
${settingsRow('Automatické odhlášení','Po 8 hodinách nečinnosti','on')}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="display:flex;flex-direction:column;gap:14px">
|
||
<div class="card">
|
||
<div class="card-header"><span class="card-title">Notifikace</span></div>
|
||
<div class="card-body" style="padding:0">
|
||
<div class="settings-section">
|
||
${settingsRow('E-mail – nová žádost','Při podání žádosti zaměstnancem','on')}
|
||
${settingsRow('E-mail – splatnost faktury','3 dny před splatností','on')}
|
||
${settingsRow('E-mail – schválená nabídka','Potvrzení od zákazníka','on')}
|
||
${settingsRow('Push notifikace','V prohlížeči (pokud povoleno)','off')}
|
||
${settingsRow('Týdenní report','Souhrn aktivit každé pondělí','on')}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header"><span class="card-title">Systém</span></div>
|
||
<div class="card-body" style="padding:0">
|
||
<div class="settings-section">
|
||
${settingsRow('Tmavý režim','Přepnout na tmavé rozhraní','off')}
|
||
${settingsRow('Kompaktní zobrazení','Menší řádky v tabulkách','off')}
|
||
${settingsRow('Česky jako výchozí jazyk','Lokalizace rozhraní','on')}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header"><span class="card-title">Přihlášená zařízení</span></div>
|
||
<div style="padding:0">
|
||
<div class="list-row">
|
||
<div class="row-icon g"><svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><rect x="2" y="3" width="20" height="14" rx="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg></div>
|
||
<div class="row-main"><div class="row-title">Google Chrome na Windows 10/11</div><div class="row-sub">Mladá Boleslav, CZ · 8.3.2026 13:04</div></div>
|
||
<div><span class="pill g">Aktuální</span></div>
|
||
</div>
|
||
<div class="list-row">
|
||
<div class="row-icon b"><svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><rect x="2" y="3" width="20" height="14" rx="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg></div>
|
||
<div class="row-main"><div class="row-title">Google Chrome na Windows 10/11</div><div class="row-sub">Mladá Boleslav, CZ · 6.3.2026 20:56</div></div>
|
||
<div><button class="btn btn-ghost btn-sm" style="font-size:11px;color:var(--red)">Odhlásit</button></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>`,
|
||
};
|
||
|
||
// ══════════════════════════════════════════
|
||
// COMPONENT HELPERS
|
||
// ══════════════════════════════════════════
|
||
function qaBtn(color,path,label){
|
||
const colors={green:'#00B894',blue:'#2D80E4',amber:'#F39C12',red:'#D63031'};
|
||
const bgs={green:'var(--green-soft)',blue:'var(--blue-soft)',amber:'var(--amber-soft)',red:'var(--red-soft)'};
|
||
return `<div class="qa-btn" style="background:#fff;border:1.5px solid var(--border);border-radius:10px;padding:14px;cursor:pointer;text-align:center;display:flex;flex-direction:column;align-items:center;gap:8px;transition:all .15s">
|
||
<div style="width:36px;height:36px;border-radius:9px;background:${bgs[color]};display:flex;align-items:center;justify-content:center">
|
||
<svg fill="none" viewBox="0 0 24 24" stroke="${colors[color]}" stroke-width="2" style="width:18px;height:18px"><path d="${path}"/></svg>
|
||
</div>
|
||
<span style="font-size:12px;font-weight:550">${label}</span>
|
||
</div>`;
|
||
}
|
||
function actRow(c,path,title,sub,time){
|
||
return `<div class="list-row">
|
||
<div class="row-icon ${c}"><svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path d="${path}"/></svg></div>
|
||
<div class="row-main"><div class="row-title">${title}</div><div class="row-sub">${sub}</div></div>
|
||
<div class="activity-time" style="font-size:11px;color:#bbb;font-family:'DM Mono',monospace;margin-top:3px;flex-shrink:0">${time}</div>
|
||
</div>`;
|
||
}
|
||
function presRow(initials,bg,color,name,cls,label,time){
|
||
return `<div class="list-row">
|
||
<div class="presence-avatar" style="width:28px;height:28px;border-radius:50%;background:${bg};color:${color};display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;flex-shrink:0">${initials}</div>
|
||
<span style="font-size:13px;font-weight:500;flex:1">${name}</span>
|
||
<div class="status-dot ${cls}"></div>
|
||
<span class="status-label ${cls}">${label}</span>
|
||
<span class="mono" style="color:var(--muted2);margin-left:8px">${time}</span>
|
||
</div>`;
|
||
}
|
||
function progRow(name,pct,color){
|
||
return `<div style="padding:10px 18px;border-bottom:1px solid var(--border)">
|
||
<div style="display:flex;justify-content:space-between;margin-bottom:6px">
|
||
<span style="font-size:13px;font-weight:500">${name}</span>
|
||
<span class="mono" style="font-size:12px;color:var(--muted)">${pct} %</span>
|
||
</div>
|
||
<div class="prog-bar-bg"><div class="prog-bar-fill" style="width:${pct}%;background:${color}"></div></div>
|
||
</div>`;
|
||
}
|
||
function miniStatRow(label,val,c){
|
||
return `<div style="display:flex;align-items:center;justify-content:space-between;padding:11px 18px;border-bottom:1px solid var(--border)">
|
||
<span style="font-size:13px;color:#444">${label}</span>
|
||
<span class="pill ${c}">${val}</span>
|
||
</div>`;
|
||
}
|
||
function docRow(i,bg,c,name,inn,out,br,tot,type,sc,sl){
|
||
return `<tr>
|
||
<td><div style="display:flex;align-items:center;gap:8px">
|
||
<div style="width:26px;height:26px;border-radius:50%;background:${bg};color:${c};display:flex;align-items:center;justify-content:center;font-size:9px;font-weight:700;flex-shrink:0">${i}</div>
|
||
<strong>${name}</strong>
|
||
</div></td>
|
||
<td class="mono">${inn}</td><td class="mono">${out}</td><td class="mono">${br}</td>
|
||
<td class="mono"><strong>${tot}</strong></td>
|
||
<td><span class="pill n">${type}</span></td>
|
||
<td><div style="display:flex;align-items:center;gap:5px"><div class="status-dot ${sc}"></div><span class="status-label ${sc}" style="font-size:12px">${sl}</span></div></td>
|
||
<td><button class="btn btn-ghost btn-sm">Detail</button></td>
|
||
</tr>`;
|
||
}
|
||
function histRow(date,day,inn,out,br,tot,over,type,c){
|
||
return `<tr>
|
||
<td class="mono"><strong>${date}</strong></td><td>${day}</td>
|
||
<td class="mono">${inn}</td><td class="mono">${out}</td><td class="mono">${br}</td>
|
||
<td class="mono"><strong>${tot}</strong></td>
|
||
<td class="mono"><span class="pill ${over==='+0:00'||over==='0:00'?'n':'g'}">${over}</span></td>
|
||
<td><span class="pill ${c}">${type}</span></td>
|
||
</tr>`;
|
||
}
|
||
function histRow2(name,type,date,who,when,c,label){
|
||
return `<tr>
|
||
<td><strong>${name}</strong></td><td>${type}</td><td class="mono">${date}</td>
|
||
<td>${who}</td><td class="mono">${when}</td>
|
||
<td><span class="pill ${c}">${label}</span></td>
|
||
</tr>`;
|
||
}
|
||
function zadostRow(i,bg,c,name,type,from,to,days,note,sub,sc,sl){
|
||
return `<tr>
|
||
<td><div style="display:flex;align-items:center;gap:8px">
|
||
<div style="width:26px;height:26px;border-radius:50%;background:${bg};color:${c};display:flex;align-items:center;justify-content:center;font-size:9px;font-weight:700;flex-shrink:0">${i}</div>
|
||
<strong>${name}</strong>
|
||
</div></td>
|
||
<td><span class="pill b">${type}</span></td>
|
||
<td class="mono">${from}</td><td class="mono">${to}</td>
|
||
<td style="font-weight:600;color:#111">${days}</td>
|
||
<td style="color:var(--muted);font-size:12px;max-width:120px">${note||'—'}</td>
|
||
<td class="mono">${sub}</td>
|
||
<td><span class="pill ${sc}">${sl}</span></td>
|
||
<td style="display:flex;gap:4px;padding-right:12px">
|
||
${sc==='a'?`<button class="btn btn-ghost btn-sm" style="color:var(--green)">✓</button><button class="btn btn-ghost btn-sm" style="color:var(--red)">✗</button>`:''}
|
||
</td>
|
||
</tr>`;
|
||
}
|
||
function schvalCard(i,bg,c,name,type,date,days,note,sub){
|
||
return `<div class="card" style="border-left:3px solid var(--amber)">
|
||
<div style="padding:16px 20px">
|
||
<div style="display:flex;align-items:flex-start;justify-content:space-between;gap:12px">
|
||
<div style="display:flex;align-items:center;gap:12px">
|
||
<div style="width:40px;height:40px;border-radius:50%;background:${bg};color:${c};display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:700;flex-shrink:0">${i}</div>
|
||
<div>
|
||
<div style="font-size:14px;font-weight:650">${name}</div>
|
||
<div style="font-size:12px;color:var(--muted)">Podáno ${sub}</div>
|
||
</div>
|
||
</div>
|
||
<div style="display:flex;gap:8px">
|
||
<button class="btn btn-ghost btn-sm" style="color:var(--red)">✗ Zamítnout</button>
|
||
<button class="btn btn-primary btn-sm">✓ Schválit</button>
|
||
</div>
|
||
</div>
|
||
<div style="margin-top:14px;background:var(--bg);border-radius:8px;padding:12px;display:grid;grid-template-columns:repeat(3,1fr);gap:12px">
|
||
${sumRow('Typ',type,'b')}${sumRow('Datum',date,'n')}${sumRow('Délka',days,'a')}
|
||
</div>
|
||
<div style="margin-top:10px;font-size:13px;color:#555;line-height:1.5">${note}</div>
|
||
</div>
|
||
</div>`;
|
||
}
|
||
function bilanceRow(i,bg,c,name,nar,cer,zby,over,sick,ho,sc){
|
||
return `<tr>
|
||
<td><div style="display:flex;align-items:center;gap:8px">
|
||
<div style="width:26px;height:26px;border-radius:50%;background:${bg};color:${c};display:flex;align-items:center;justify-content:center;font-size:9px;font-weight:700;flex-shrink:0">${i}</div>
|
||
<strong>${name}</strong>
|
||
</div></td>
|
||
<td class="mono">${nar} dní</td><td class="mono">${cer} dní</td>
|
||
<td class="mono"><strong style="color:${parseInt(zby)<5?'var(--red)':'var(--text)'}">${zby} dní</strong></td>
|
||
<td class="mono"><span class="pill ${parseInt(over)<0?'r':parseInt(over)>0?'g':'n'}">${over}h</span></td>
|
||
<td class="mono">${sick}</td><td class="mono">${ho}</td>
|
||
<td><span class="pill ${sc}">OK</span></td>
|
||
</tr>`;
|
||
}
|
||
function jizdaRow(date,vehicle,driver,from,to,km,purpose,type,c){
|
||
return `<tr>
|
||
<td class="mono">${date}</td>
|
||
<td><span class="mono" style="background:#141414;color:#fff;padding:2px 7px;border-radius:4px;font-size:11px">${vehicle}</span></td>
|
||
<td>${driver}</td><td>${from}</td><td><strong>${to}</strong></td>
|
||
<td class="mono"><strong>${km}</strong></td>
|
||
<td style="max-width:140px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--muted)">${purpose}</td>
|
||
<td><span class="pill ${c}">${type}</span></td>
|
||
<td><button class="btn btn-ghost btn-sm">Detail</button></td>
|
||
</tr>`;
|
||
}
|
||
function vehicleCard(plate,name,year,fuel,km,lastTrip,status,sc,sl,stk){
|
||
return `<div class="vehicle-card">
|
||
<div>
|
||
<div class="vehicle-plate">${plate}</div>
|
||
<div class="vehicle-name">${name} <span style="font-weight:400;color:var(--muted);font-size:13px">${year}</span></div>
|
||
</div>
|
||
<div style="display:flex;justify-content:space-between;align-items:center">
|
||
<span class="pill ${sc}">${sl}</span>
|
||
<span style="font-size:12px;color:var(--muted)">${fuel}</span>
|
||
</div>
|
||
<div class="vehicle-stats">
|
||
<div class="v-stat"><div class="v-stat-lbl">Celkem km</div><div class="v-stat-val">${parseInt(km).toLocaleString('cs')}</div></div>
|
||
<div class="v-stat"><div class="v-stat-lbl">Poslední jízda</div><div class="v-stat-val">${lastTrip}</div></div>
|
||
<div class="v-stat"><div class="v-stat-lbl">STK do</div><div class="v-stat-val" style="font-size:12px">${stk}</div></div>
|
||
</div>
|
||
<div style="display:flex;gap:6px">
|
||
<button class="btn btn-ghost btn-sm" style="flex:1">Historie</button>
|
||
<button class="btn btn-ghost btn-sm" style="flex:1">Detail</button>
|
||
</div>
|
||
</div>`;
|
||
}
|
||
function progRow2(name,km,color,pct){
|
||
return `<div>
|
||
<div style="display:flex;justify-content:space-between;margin-bottom:6px">
|
||
<span style="font-size:13px;font-weight:500">${name}</span>
|
||
<span style="font-size:13px;font-weight:650;color:#111">${km}</span>
|
||
</div>
|
||
<div class="prog-bar-bg"><div class="prog-bar-fill" style="width:${pct}%;background:${color}"></div></div>
|
||
</div>`;
|
||
}
|
||
function nabidkaRow(num,client,subject,val,created,valid,sc,sl){
|
||
return `<tr>
|
||
<td class="mono"><strong>${num}</strong></td>
|
||
<td>${client}</td>
|
||
<td style="max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">${subject}</td>
|
||
<td style="font-weight:650;color:#111">${val}</td>
|
||
<td class="mono">${created}</td>
|
||
<td class="mono">${valid}</td>
|
||
<td><span class="pill ${sc}">${sl}</span></td>
|
||
<td style="display:flex;gap:4px">
|
||
<button class="btn btn-ghost btn-sm">PDF</button>
|
||
<button class="btn btn-ghost btn-sm">Detail</button>
|
||
</td>
|
||
</tr>`;
|
||
}
|
||
function objednavkaRow(num,client,subject,val,date,deadline,sc,sl){
|
||
return `<tr>
|
||
<td class="mono"><strong>${num}</strong></td>
|
||
<td>${client}</td>
|
||
<td>${subject}</td>
|
||
<td style="font-weight:650;color:#111">${val}</td>
|
||
<td class="mono">${date}</td>
|
||
<td class="mono">${deadline}</td>
|
||
<td><span class="pill ${sc}">${sl}</span></td>
|
||
<td><button class="btn btn-ghost btn-sm">Detail</button></td>
|
||
</tr>`;
|
||
}
|
||
function kanbanCard(cls,title,client,deadline,initials,color){
|
||
return `<div class="kanban-card ${cls}">
|
||
<div class="kc-title">${title}</div>
|
||
<div class="kc-client">${client}</div>
|
||
<div class="kc-foot">
|
||
<span class="kc-date">${deadline}</span>
|
||
<div class="kc-avatar" style="background:${color}">${initials}</div>
|
||
</div>
|
||
</div>`;
|
||
}
|
||
function fakturaRow(num,client,subject,base,dph,total,created,due,sc,sl){
|
||
return `<tr>
|
||
<td class="mono"><strong>${num}</strong></td>
|
||
<td>${client}</td>
|
||
<td style="color:var(--muted);font-size:12px">${subject}</td>
|
||
<td class="mono">${base} Kč</td>
|
||
<td class="mono">${dph} Kč</td>
|
||
<td style="font-weight:700;color:#111">${total}</td>
|
||
<td class="mono">${created}</td>
|
||
<td class="mono">${due}</td>
|
||
<td><span class="pill ${sc}">${sl}</span></td>
|
||
<td style="display:flex;gap:4px">
|
||
<button class="btn btn-ghost btn-sm">PDF</button>
|
||
<button class="btn btn-ghost btn-sm">Detail</button>
|
||
</td>
|
||
</tr>`;
|
||
}
|
||
function customerCard(bg,initials,name,sector,activity,revenue){
|
||
return `<div class="customer-card">
|
||
<div style="display:flex;align-items:center;gap:12px">
|
||
<div class="cc-logo" style="background:${bg}">${initials}</div>
|
||
<div><div class="cc-name">${name}</div><div class="cc-sub">${sector}</div></div>
|
||
</div>
|
||
<div class="cc-stats">
|
||
<div class="cc-s"><div class="cc-s-val">${revenue}</div><div class="cc-s-lbl">Celk. obrat</div></div>
|
||
<div class="cc-s"><div class="cc-s-val" style="font-size:12px;color:var(--muted)">${activity}</div><div class="cc-s-lbl">Aktivita</div></div>
|
||
</div>
|
||
<div style="display:flex;gap:6px;margin-top:4px">
|
||
<button class="btn btn-ghost btn-sm" style="flex:1">Faktury</button>
|
||
<button class="btn btn-ghost btn-sm" style="flex:1">Projekty</button>
|
||
</div>
|
||
</div>`;
|
||
}
|
||
function userCard(i,color,name,email,role,lastLogin,sc,sl,twofa){
|
||
return `<div class="user-card">
|
||
<div class="avatar" style="background:${color};width:42px;height:42px;border-radius:10px;font-size:13px;flex-shrink:0">${i}</div>
|
||
<div class="ua-info">
|
||
<div class="ua-name">${name}</div>
|
||
<div class="ua-email">${email}</div>
|
||
<div class="ua-meta">
|
||
<span class="pill ${sc}" style="font-size:10px;padding:1px 6px">${sl}</span>
|
||
<span class="pill n" style="font-size:10px;padding:1px 6px">${role}</span>
|
||
${twofa?'<span class="pill g" style="font-size:10px;padding:1px 6px">2FA ✓</span>':''}
|
||
</div>
|
||
<div style="font-size:11px;color:var(--muted);margin-top:4px">${lastLogin}</div>
|
||
</div>
|
||
<button class="btn btn-ghost btn-icon">
|
||
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" style="width:14px;height:14px"><circle cx="12" cy="12" r="1"/><circle cx="12" cy="5" r="1"/><circle cx="12" cy="19" r="1"/></svg>
|
||
</button>
|
||
</div>`;
|
||
}
|
||
function settingsRow(label,desc,state){
|
||
return `<div class="settings-row">
|
||
<div class="settings-info">
|
||
<div class="settings-lbl">${label}</div>
|
||
<div class="settings-desc">${desc}</div>
|
||
</div>
|
||
<button class="toggle ${state}" onclick="this.classList.toggle('on');this.classList.toggle('off')"></button>
|
||
</div>`;
|
||
}
|
||
function sumRow(label,val,c){
|
||
return `<div style="display:flex;flex-direction:column;gap:3px">
|
||
<div style="font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.4px;color:var(--muted)">${label}</div>
|
||
<div style="font-size:13px;font-weight:600;color:#111">${val}</div>
|
||
</div>`;
|
||
}
|
||
|
||
// ══════════════════════════════════════════
|
||
// ROUTER
|
||
// ══════════════════════════════════════════
|
||
function navigate(pageId){
|
||
document.querySelectorAll('.nav-item').forEach(el=>{
|
||
el.classList.toggle('active', el.dataset.page===pageId);
|
||
});
|
||
const content = document.getElementById('main-content');
|
||
content.innerHTML = pages[pageId] ? pages[pageId]() : `<div class="page"><h2>Stránka nenalezena</h2></div>`;
|
||
content.scrollTop = 0;
|
||
}
|
||
|
||
document.querySelectorAll('.nav-item[data-page]').forEach(el=>{
|
||
el.addEventListener('click', ()=>navigate(el.dataset.page));
|
||
});
|
||
|
||
navigate('dashboard');
|
||
</script>
|
||
</body>
|
||
</html>
|