wasrusgen1-crm/docs/mockup_admin.html

576 lines
37 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>@wasrusgen1 CRM — Администратор</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=Montserrat:wght@700;800&display=swap" rel="stylesheet">
<style>
*{box-sizing:border-box;margin:0;padding:0}
body{background:#C8CACD;min-height:100vh;display:flex;flex-direction:column;align-items:center;padding:20px;font-family:'Inter',sans-serif}
body{--accent:#003E7E;--accent2:#76BD22;--bg:#F5F6F8;--card:#FFFFFF;--ink:#1A1A2E;--muted:#8A94A6;--danger:#EF4444;--warn:#F59E0B;--success:#10B981}
body[data-theme="dark"]{--accent:#4338CA;--accent2:#6366F1;--bg:#111827;--card:#1F2937;--ink:#F9FAFB;--muted:#9CA3AF}
#controls{display:flex;align-items:center;gap:12px;margin-bottom:16px;flex-wrap:wrap;justify-content:center;width:100%;max-width:700px}
#controls label{color:#fff;font-size:13px;font-weight:600}
#screenSelect{padding:8px 12px;border-radius:10px;border:none;background:#fff;font-size:13px;color:#333;cursor:pointer;min-width:220px;box-shadow:0 2px 8px rgba(0,0,0,.15)}
#themeButtons{display:flex;gap:6px}
.theme-btn{padding:7px 14px;border-radius:9px;border:2px solid transparent;font-size:12px;font-weight:700;cursor:pointer;transition:all .2s}
.theme-btn.active{border-color:#fff}
.theme-btn[data-t="zov"]{background:#003E7E;color:#fff}
.theme-btn[data-t="dark"]{background:#111827;color:#6366F1}
#phoneFrame{width:390px;height:844px;background:var(--bg);border-radius:44px;overflow:hidden;box-shadow:0 24px 80px rgba(0,0,0,.4),inset 0 0 0 1px rgba(255,255,255,.15);position:relative;display:flex;flex-direction:column}
#statusBar{height:44px;background:var(--card);display:flex;align-items:center;justify-content:space-between;padding:0 24px;flex-shrink:0;font-size:13px;font-weight:600;color:var(--ink);z-index:10}
#screen{flex:1;overflow-y:auto;overflow-x:hidden;scrollbar-width:none;background:var(--bg)}
#screen::-webkit-scrollbar{display:none}
.bottom-nav{height:60px;background:rgba(255,255,255,.92);backdrop-filter:blur(12px);border-top:1px solid rgba(0,0,0,.06);display:flex;align-items:center;justify-content:space-around;flex-shrink:0;z-index:100}
.nav-item{display:flex;flex-direction:column;align-items:center;gap:2px;cursor:pointer;padding:6px 10px;border-radius:10px;transition:all .15s;flex:1}
.nav-item svg{width:22px;height:22px;color:var(--muted)}
.nav-item span{font-size:10px;color:var(--muted);font-weight:500}
.nav-item.active svg,.nav-item.active span{color:var(--accent)}
.page{padding:0 0 80px;min-height:100%}
.page-header{display:flex;align-items:center;gap:12px;padding:16px 16px 12px;background:var(--card);border-bottom:1px solid rgba(0,0,0,.06);position:sticky;top:0;z-index:50}
.page-header h2{font-size:17px;font-weight:700;color:var(--ink);flex:1}
.back-btn{width:32px;height:32px;border-radius:50%;background:var(--bg);display:flex;align-items:center;justify-content:center;cursor:pointer;border:none;flex-shrink:0}
.back-btn svg{color:var(--accent);width:18px;height:18px}
.header-action{width:32px;height:32px;border-radius:50%;background:var(--bg);display:flex;align-items:center;justify-content:center;cursor:pointer}
.header-action svg{width:18px;height:18px;color:var(--muted)}
.card{background:var(--card);border-radius:16px;box-shadow:0 2px 12px rgba(0,0,0,.07);padding:16px;margin-bottom:12px}
.card.warn-b{border-left:4px solid var(--warn)}
.card.ok-b{border-left:4px solid var(--success)}
.card.accent-b{border-left:4px solid var(--accent)}
.card.danger-b{border-left:4px solid var(--danger)}
.section-label{text-transform:uppercase;font-size:11px;letter-spacing:.06em;color:var(--muted);margin:20px 16px 8px;font-weight:600}
@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}
@keyframes btn-shimmer{0%{background-position:250% center}100%{background-position:-250% center}}
.btn-primary{width:100%;background:linear-gradient(135deg,#002450 0%,#003E7E 30%,#1560BD 60%,#0A4DA8 90%,#002450 100%);background-size:280% auto;color:#fff;border:none;border-radius:14px;padding:15px 20px;font-size:15px;font-weight:700;cursor:pointer;box-shadow:0 6px 20px rgba(0,62,126,.38);transition:transform .15s;animation:btn-shimmer 5s ease infinite}
.btn-primary:active{transform:scale(.97)}
.btn-secondary{width:100%;background:transparent;color:var(--accent);border:2px solid var(--accent);border-radius:14px;padding:13px;font-size:15px;font-weight:700;cursor:pointer;margin-top:8px}
.btn-sm{padding:8px 15px;font-size:12px;font-weight:700;border-radius:10px;cursor:pointer;border:none;background:linear-gradient(135deg,#003E7E,#1565C0);color:#fff}
.btn-pill{display:inline-flex;align-items:center;gap:5px;padding:4px 10px;border-radius:20px;font-size:11px;font-weight:700;cursor:pointer;border:none;white-space:nowrap}
.btn-pill.accent{background:rgba(0,62,126,.1);color:var(--accent);border:1px solid rgba(0,62,126,.2)}
.btn-pill.warn{background:#FEF3C7;color:#D97706;border:1px solid #FDE68A}
.btn-pill.success{background:rgba(16,185,129,.08);color:var(--success);border:1px solid rgba(16,185,129,.2)}
.btn-pill.danger{background:rgba(239,68,68,.08);color:var(--danger);border:1px solid rgba(239,68,68,.2)}
.btn-pill.muted{background:var(--bg);color:var(--muted);border:1px solid #E2E8F0}
.badge{display:inline-flex;align-items:center;padding:3px 9px;border-radius:20px;font-size:11px;font-weight:700}
.badge.yellow{background:#FEF3C7;color:#D97706}
.badge.green{background:#DCFCE7;color:#15803D}
.badge.blue{background:#DBEAFE;color:#1D4ED8}
.badge.red{background:#FEE2E2;color:#DC2626}
.badge.gray{background:#F1F5F9;color:#64748B}
.badge.orange{background:#FFF7ED;color:#EA580C}
.divider{height:1px;background:rgba(0,0,0,.07);margin:10px 0}
.row{display:flex;align-items:center;gap:10px}
.row.sb{justify-content:space-between}
.info-row{display:flex;justify-content:space-between;align-items:flex-start;padding:5px 0;border-bottom:1px solid rgba(0,0,0,.04)}
.info-row:last-child{border-bottom:none}
.info-label{font-size:13px;color:var(--muted)}
.info-val{font-size:13px;color:var(--ink);font-weight:600;text-align:right;max-width:60%}
/* Staff dot status */
.dot{width:9px;height:9px;border-radius:50%;flex-shrink:0}
.dot.green{background:#10B981}
.dot.yellow{background:#F59E0B}
.dot.gray{background:#CBD5E1}
.dot.red{background:#EF4444}
/* Stat tiles */
.stat-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:10px;margin:0 16px 4px}
.stat-tile{background:var(--card);border-radius:14px;padding:14px;box-shadow:0 2px 8px rgba(0,0,0,.07)}
.stat-tile .num{font-size:28px;font-weight:800;color:var(--ink);line-height:1}
.stat-tile .lbl{font-size:11px;color:var(--muted);margin-top:4px;font-weight:500}
.stat-tile .delta{font-size:11px;font-weight:700;margin-top:6px}
.stat-tile .delta.up{color:var(--success)}
.stat-tile .delta.down{color:var(--danger)}
/* Alert card */
.alert-card{border-radius:14px;padding:12px 14px;margin-bottom:10px;display:flex;align-items:flex-start;gap:10px}
.alert-card.warn{background:#FFFBEB;border:1.5px solid #FDE68A}
.alert-card.danger{background:#FEF2F2;border:1.5px solid #FECACA}
.alert-card.info{background:#EFF6FF;border:1.5px solid #BFDBFE}
.alert-card.success{background:#ECFDF5;border:1.5px solid #A7F3D0}
.alert-icon{font-size:20px;flex-shrink:0;margin-top:1px}
.alert-title{font-size:13px;font-weight:700;color:var(--ink);margin-bottom:2px}
.alert-sub{font-size:12px;color:var(--muted);line-height:1.4}
.alert-action{margin-top:8px}
/* Schedule row */
.sch-row{display:flex;align-items:center;gap:10px;padding:10px 0;border-bottom:1px solid rgba(0,0,0,.05)}
.sch-row:last-child{border-bottom:none}
.sch-avatar{width:36px;height:36px;border-radius:50%;background:linear-gradient(135deg,#003E7E,#1560BD);display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:700;color:#fff;flex-shrink:0}
.sch-avatar.msrr{background:linear-gradient(135deg,#0F766E,#059669)}
.sch-info{flex:1;min-width:0}
.sch-name{font-size:13px;font-weight:700;color:var(--ink)}
.sch-jobs{font-size:11px;color:var(--muted);margin-top:2px}
.sch-status{text-align:right;flex-shrink:0}
/* Order list item */
.order-item{background:var(--card);border-radius:14px;padding:13px 14px;margin-bottom:10px;box-shadow:0 2px 8px rgba(0,0,0,.06);cursor:pointer;position:relative;overflow:hidden}
.order-item::before{content:'';position:absolute;left:0;top:0;bottom:0;width:3px}
.order-item.new::before{background:var(--accent2)}
.order-item.progress::before{background:var(--warn)}
.order-item.done::before{background:var(--success)}
.order-item.problem::before{background:var(--danger)}
/* Filter tabs */
.filter-tabs{display:flex;gap:6px;overflow-x:auto;scrollbar-width:none;padding:0 16px 12px}
.filter-tabs::-webkit-scrollbar{display:none}
.ftab{padding:6px 14px;border-radius:20px;font-size:12px;font-weight:700;cursor:pointer;white-space:nowrap;border:1.5px solid #E2E8F0;background:var(--card);color:var(--muted)}
.ftab.active{background:var(--accent);color:#fff;border-color:var(--accent)}
</style>
</head>
<body>
<a href="index.html" style="position:fixed;top:16px;left:16px;color:#fff;font-size:12px;font-weight:700;text-decoration:none;background:rgba(0,0,0,.3);padding:6px 12px;border-radius:20px;z-index:9999">← Мокапы кабинетов</a>
<div id="controls">
<label>Экран:</label>
<select id="screenSelect" onchange="go(this.value)">
<option value="home">Главная</option>
<option value="schedule">Расписание</option>
<option value="orders">Заявки</option>
<option value="staff">Сотрудники</option>
<option value="order_detail">Детали заявки</option>
</select>
<div id="themeButtons">
<button class="theme-btn active" data-t="zov" onclick="setTheme('')">CRM</button>
<button class="theme-btn" data-t="dark" onclick="setTheme('dark')">Dark</button>
</div>
</div>
<div id="phoneFrame">
<div id="statusBar">
<span>9:41</span>
<div style="display:flex;align-items:center;gap:6px">
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M1.5 8.5a13 13 0 0 1 21 0M5 12a10 10 0 0 1 14 0M8.5 15.5a6 6 0 0 1 7 0M12 19h.01" stroke="currentColor" fill="none" stroke-width="2" stroke-linecap="round"/></svg>
<svg width="20" height="14" viewBox="0 0 23 14" fill="currentColor"><rect x="0" y="1" width="18" height="12" rx="2" fill="none" stroke="currentColor" stroke-width="1.5"/><rect x="1.5" y="2.5" width="13" height="9" rx="1" fill="currentColor"/><path d="M19.5 4.5v5a2.5 2.5 0 000-5z"/></svg>
</div>
</div>
<div id="screen"></div>
<nav class="bottom-nav" id="bottomNav">
<div class="nav-item" onclick="go('home')" id="nav-home">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
<span>Главная</span>
</div>
<div class="nav-item" onclick="go('schedule')" id="nav-schedule">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="4" width="18" height="18" rx="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg>
<span>Расписание</span>
</div>
<div class="nav-item" onclick="go('orders')" id="nav-orders">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="9" y1="13" x2="15" y2="13"/><line x1="9" y1="17" x2="13" y2="17"/></svg>
<span>Заявки</span>
</div>
<div class="nav-item" onclick="go('staff')" id="nav-staff">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 00-3-3.87"/><path d="M16 3.13a4 4 0 010 7.75"/></svg>
<span>Сотрудники</span>
</div>
</nav>
</div>
<script>
var _screen = 'home';
function setTheme(t){
document.body.dataset.theme = t;
document.querySelectorAll('.theme-btn').forEach(b=>b.classList.toggle('active', b.dataset.t===(t||'zov')));
}
function go(s){
_screen = s;
document.getElementById('screen').innerHTML = render(s);
document.getElementById('screenSelect').value = s;
document.querySelectorAll('.nav-item').forEach(n=>n.classList.remove('active'));
var map = {home:'nav-home',schedule:'nav-schedule',orders:'nav-orders',staff:'nav-staff'};
if(map[s]) document.getElementById(map[s]).classList.add('active');
}
function render(s){
if(s==='home') return screenHome();
if(s==='schedule') return screenSchedule();
if(s==='orders') return screenOrders();
if(s==='staff') return screenStaff();
if(s==='order_detail') return screenOrderDetail();
return screenHome();
}
/* ─── HOME ─── */
function screenHome(){
return `<div class="page">
<div style="background:linear-gradient(135deg,#002450,#003E7E,#1560BD);padding:20px 16px 24px">
<div style="font-size:11px;color:rgba(255,255,255,.65);font-weight:600;text-transform:uppercase;letter-spacing:.06em;margin-bottom:4px">ЧЕТВЕРГ, 29 МАЯ 2026</div>
<div style="font-size:22px;font-weight:800;color:#fff;margin-bottom:2px">Привет, Алина 👋</div>
<div style="font-size:13px;color:rgba(255,255,255,.75)">3 требуют внимания · 8 заявок сегодня</div>
</div>
<div class="stat-grid" style="margin-top:-14px;margin-bottom:0">
<div class="stat-tile" onclick="go('orders')">
<div class="num">8</div>
<div class="lbl">Заявок сегодня</div>
<div class="delta up">↑ +2 к вчера</div>
</div>
<div class="stat-tile" onclick="go('schedule')">
<div class="num" style="color:var(--warn)">3</div>
<div class="lbl">Не назначены</div>
<div class="delta down">⚠️ Срочно</div>
</div>
<div class="stat-tile" onclick="go('staff')">
<div class="num" style="color:var(--success)">5</div>
<div class="lbl">На выездах</div>
<div class="delta up">GPS активен</div>
</div>
<div class="stat-tile">
<div class="num" style="color:var(--accent2)">2</div>
<div class="lbl">Завершено</div>
<div class="delta" style="color:var(--muted)">из 8 на сегодня</div>
</div>
</div>
<div class="section-label">⚡ Требуют внимания</div>
<div style="padding:0 16px">
<div class="alert-card danger" onclick="go('order_detail')">
<div class="alert-icon">🚨</div>
<div style="flex:1">
<div class="alert-title">Заявка А-2855 — сборщик не назначен</div>
<div class="alert-sub">Сегодня 14:00 · Иванов Пётр · пр. Просвещения, 44<br>Осталось 4 часа до визита</div>
<div class="alert-action"><button class="btn-pill accent" onclick="event.stopPropagation();go('schedule')">Назначить →</button></div>
</div>
</div>
<div class="alert-card warn">
<div class="alert-icon">⏰</div>
<div style="flex:1">
<div class="alert-title">Замерщик Игорь опаздывает</div>
<div class="alert-sub">З-1043 · Корнилов Виктор · 13:00<br>GPS: выехал, но в 2.1 км от объекта</div>
<div class="alert-action">
<button class="btn-pill warn" onclick="alert('📞 Звонок Игорю…\\n+7 921 445-67-89')">📞 Позвонить</button>
</div>
</div>
</div>
<div class="alert-card info">
<div class="alert-icon">📋</div>
<div style="flex:1">
<div class="alert-title">Клиент просит перенести замер</div>
<div class="alert-sub">З-1044 · Лебедева Марина · сегодня 16:00<br>Сообщение: «Буду дома только после 18:00»</div>
<div class="alert-action" style="display:flex;gap:6px">
<button class="btn-pill accent" onclick="go('order_detail')">Открыть</button>
<button class="btn-pill muted" onclick="alert('Уведомление отложено')">Позже</button>
</div>
</div>
</div>
</div>
<div class="section-label">📅 Сегодня на выездах</div>
<div style="padding:0 16px">
<div class="card" style="padding:12px 14px">
${[
{name:'Игорь К.',role:'Замерщик',jobs:3,status:'В пути',sc:'msrr',dot:'yellow'},
{name:'Олег Р.',role:'Замерщик',jobs:2,status:'На объекте',sc:'msrr',dot:'green'},
{name:'Дмитрий В.',role:'Сборщик',jobs:1,status:'Завершил',sc:'',dot:'gray'},
{name:'Алексей М.',role:'Сборщик',jobs:2,status:'На объекте',sc:'',dot:'green'},
{name:'Сергей П.',role:'Сборщик',jobs:1,status:'Не выехал',sc:'',dot:'red'},
].map(e=>`
<div class="sch-row">
<div class="sch-avatar ${e.sc}">${e.name.split(' ').map(w=>w[0]).join('')}</div>
<div class="sch-info">
<div class="sch-name">${e.name}</div>
<div class="sch-jobs">${e.role} · ${e.jobs} зак.</div>
</div>
<div class="sch-status">
<div style="display:flex;align-items:center;gap:5px;justify-content:flex-end">
<div class="dot ${e.dot}"></div>
<span style="font-size:11px;font-weight:600;color:var(--muted)">${e.status}</span>
</div>
</div>
</div>`).join('')}
</div>
</div>
</div>`;
}
/* ─── SCHEDULE ─── */
function screenSchedule(){
return `<div class="page">
<div class="page-header">
<h2>Расписание · 29 мая</h2>
<div class="header-action" onclick="alert('Добавить заявку…')">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
</div>
</div>
<div style="display:flex;gap:0;border-bottom:1px solid rgba(0,0,0,.08);background:var(--card);padding:0 16px">
${['Сегодня','Завтра','30 мая','31 мая'].map((d,i)=>`
<div style="padding:10px 12px;font-size:13px;font-weight:700;cursor:pointer;border-bottom:2px solid ${i===0?'var(--accent)':'transparent'};color:${i===0?'var(--accent)':'var(--muted)'};">${d}</div>
`).join('')}
</div>
<div style="padding:12px 16px 0">
<div class="section-label" style="margin-top:8px;margin-left:0">🔲 Не назначены (3)</div>
${[
{id:'А-2855',client:'Иванов Пётр',addr:'пр. Просвещения, 44',time:'14:0017:00',type:'Сборка'},
{id:'А-2856',client:'Козлова Наталья',addr:'ул. Большая Пушкарская, 2',time:'15:0018:00',type:'Сборка'},
{id:'З-1045',client:'Фёдоров Антон',addr:'пр. Ветеранов, 120',time:'16:0017:00',type:'Замер'},
].map(o=>`
<div class="card warn-b" style="padding:12px">
<div class="row sb" style="margin-bottom:6px">
<span style="font-size:12px;font-weight:800;color:var(--accent)">${o.id}</span>
<span class="badge yellow">${o.type}</span>
</div>
<div style="font-size:14px;font-weight:700;color:var(--ink);margin-bottom:2px">${o.client}</div>
<div style="font-size:12px;color:var(--muted);margin-bottom:8px">📍 ${o.addr} · ${o.time}</div>
<button class="btn-sm" style="width:100%" onclick="alert('Выбор сотрудника для ${o.id}…')">Назначить сотрудника </button>
</div>
`).join('')}
<div class="section-label" style="margin-left:0">✅ Назначены (5)</div>
${[
{id:'З-1042',client:'Смирнова Ольга',addr:'ул. Рубинштейна, 7',time:'10:30',emp:'Игорь К.',status:'В процессе',dot:'yellow',sc:'msrr'},
{id:'З-1043',client:'Корнилов Виктор',addr:'пр. Невский, 120',time:'13:00',emp:'Игорь К.',status:'В пути',dot:'yellow',sc:'msrr'},
{id:'А-2847',client:'Петрова Светлана',addr:'ул. Ленина, 45',time:'09:00',emp:'Алексей М.',status:'На объекте',dot:'green',sc:''},
{id:'А-2851',client:'Громов Илья',addr:'пр. Победы, 88',time:'11:00',emp:'Дмитрий В.',status:'Завершил',dot:'gray',sc:''},
{id:'А-2853',client:'Шилова Ирина',addr:'ул. Савушкина, 14',time:'13:30',emp:'Алексей М.',status:'Назначен',dot:'gray',sc:''},
].map(o=>`
<div class="card" style="padding:12px" onclick="go('order_detail')">
<div class="row sb" style="margin-bottom:5px">
<span style="font-size:12px;font-weight:800;color:var(--accent)">${o.id}</span>
<div style="display:flex;align-items:center;gap:5px">
<div class="dot ${o.dot}"></div>
<span style="font-size:11px;color:var(--muted);font-weight:600">${o.status}</span>
</div>
</div>
<div style="font-size:13px;font-weight:700;color:var(--ink);margin-bottom:2px">${o.client}</div>
<div style="font-size:12px;color:var(--muted);margin-bottom:8px">📍 ${o.addr} · ${o.time}</div>
<div style="display:flex;align-items:center;gap:8px">
<div class="sch-avatar ${o.sc}" style="width:26px;height:26px;font-size:10px">${o.emp.split(' ').map(w=>w[0]).join('')}</div>
<span style="font-size:12px;font-weight:600;color:var(--ink)">${o.emp}</span>
<button class="btn-pill accent" style="margin-left:auto" onclick="event.stopPropagation();alert('Переназначить ${o.id}?')">Переназначить</button>
</div>
</div>
`).join('')}
</div>
</div>`;
}
/* ─── ORDERS ─── */
var _orderFilter = 'all';
function screenOrders(){
return `<div class="page">
<div class="page-header">
<h2>Заявки</h2>
<div class="header-action" onclick="alert('Фильтры…')">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="4" y1="6" x2="20" y2="6"/><line x1="8" y1="12" x2="16" y2="12"/><line x1="11" y1="18" x2="13" y2="18"/></svg>
</div>
</div>
<div class="filter-tabs">
${[['all','Все (12)'],['new','Новые'],['progress','В работе'],['done','Завершены'],['problem','Проблемы']].map(([v,l])=>`
<div class="ftab ${_orderFilter===v?'active':''}" onclick="_orderFilter='${v}';document.getElementById('screen').innerHTML=render('orders')">${l}</div>
`).join('')}
</div>
<div style="padding:0 16px">
${[
{id:'А-2855',client:'Иванов Пётр',type:'Сборка',status:'new',label:'Не назначен',badge:'red',time:'Сегодня 14:00',note:'Сборщик не определён'},
{id:'З-1044',client:'Лебедева Марина',type:'Замер',status:'problem',label:'Перенос',badge:'orange',time:'Сегодня 16:00',note:'Клиент просит после 18:00'},
{id:'З-1042',client:'Смирнова Ольга',type:'Замер',status:'progress',label:'В процессе',badge:'yellow',time:'Сегодня 10:30',note:'Шаг 2 из 4 · Игорь К.'},
{id:'А-2847',client:'Петрова Светлана',type:'Сборка',status:'progress',label:'На объекте',badge:'yellow',time:'Сегодня 09:00',note:'Алексей М. · GPS ✓'},
{id:'А-2851',client:'Громов Илья',type:'Сборка',status:'done',label:'Завершено',badge:'green',time:'Сегодня 11:00',note:'Сдано · подпись клиента'},
{id:'З-1040',client:'Новиков Кирилл',type:'Замер',status:'done',label:'Завершено',badge:'green',time:'Вчера 15:00',note:'Отчёт отправлен'},
{id:'А-2856',client:'Козлова Наталья',type:'Сборка',status:'new',label:'Не назначен',badge:'red',time:'Сегодня 15:00',note:'Ждёт назначения'},
{id:'З-1043',client:'Корнилов Виктор',type:'Замер',status:'progress',label:'В пути',badge:'yellow',time:'Сегодня 13:00',note:'Игорь К. · 2.1 км'},
].filter(o=>_orderFilter==='all'||o.status===_orderFilter).map(o=>`
<div class="order-item ${o.status}" onclick="go('order_detail')">
<div class="row sb" style="margin-bottom:5px">
<div style="display:flex;align-items:center;gap:7px">
<span style="font-size:12px;font-weight:800;color:var(--accent)">${o.id}</span>
<span class="badge gray" style="font-size:10px">${o.type}</span>
</div>
<span class="badge ${o.badge}">${o.label}</span>
</div>
<div style="font-size:15px;font-weight:700;color:var(--ink);margin-bottom:2px">${o.client}</div>
<div style="font-size:12px;color:var(--muted)">${o.time} · ${o.note}</div>
</div>
`).join('')}
</div>
</div>`;
}
/* ─── STAFF ─── */
function screenStaff(){
return `<div class="page">
<div class="page-header">
<h2>Сотрудники</h2>
</div>
<div class="section-label">📍 Замерщики (2)</div>
<div style="padding:0 16px">
${[
{name:'Игорь Краснов',phone:'+7 921 445-67-89',jobs:3,done:1,status:'В пути',dot:'yellow',detail:'З-1043 · Корнилов В. · 13:00 · 2.1 км от объекта',sc:'msrr',warn:true},
{name:'Олег Романов',phone:'+7 911 234-56-78',jobs:2,done:1,status:'На объекте',dot:'green',detail:'З-1042 · Смирнова О. · с 10:35 · GPS ✓',sc:'msrr',warn:false},
].map(e=>`
<div class="card${e.warn?' warn-b':''}">
<div class="row sb" style="margin-bottom:10px">
<div style="display:flex;align-items:center;gap:10px">
<div class="sch-avatar msrr" style="width:42px;height:42px;font-size:15px">${e.name.split(' ').map(w=>w[0]).join('')}</div>
<div>
<div style="font-size:14px;font-weight:700;color:var(--ink)">${e.name}</div>
<div style="font-size:12px;color:var(--accent)">${e.phone}</div>
</div>
</div>
<div style="text-align:right">
<div style="display:flex;align-items:center;gap:5px;justify-content:flex-end;margin-bottom:4px">
<div class="dot ${e.dot}"></div>
<span style="font-size:12px;font-weight:700;color:var(--muted)">${e.status}</span>
</div>
<div style="font-size:11px;color:var(--muted)">${e.done}/${e.jobs} зак.</div>
</div>
</div>
<div style="font-size:12px;color:var(--muted);background:var(--bg);padding:8px 10px;border-radius:8px;margin-bottom:10px">📍 ${e.detail}</div>
<div style="display:flex;gap:8px">
<button class="btn-pill accent" style="flex:1;justify-content:center" onclick="alert('📞 Звонок ${e.name}…')">📞 Позвонить</button>
<button class="btn-pill muted" style="flex:1;justify-content:center" onclick="alert('💬 Чат с ${e.name}…')">💬 Написать</button>
</div>
</div>
`).join('')}
</div>
<div class="section-label">🔧 Сборщики (3)</div>
<div style="padding:0 16px">
${[
{name:'Алексей Малинин',phone:'+7 981 876-54-32',jobs:2,done:0,status:'На объекте',dot:'green',detail:'А-2847 · Петрова С. · с 09:15 · GPS ✓',warn:false},
{name:'Дмитрий Власов',phone:'+7 965 321-44-55',jobs:1,done:1,status:'Завершил',dot:'gray',detail:'А-2851 · Громов И. · завершено в 13:40',warn:false},
{name:'Сергей Петров',phone:'+7 953 111-22-33',jobs:1,done:0,status:'Не выехал',dot:'red',detail:'А-2855 · НЕ НАЗНАЧЕН · сегодня 14:00',warn:true},
].map(e=>`
<div class="card${e.warn?' danger-b':''}">
<div class="row sb" style="margin-bottom:10px">
<div style="display:flex;align-items:center;gap:10px">
<div class="sch-avatar" style="width:42px;height:42px;font-size:15px">${e.name.split(' ').map(w=>w[0]).join('')}</div>
<div>
<div style="font-size:14px;font-weight:700;color:var(--ink)">${e.name}</div>
<div style="font-size:12px;color:var(--accent)">${e.phone}</div>
</div>
</div>
<div style="text-align:right">
<div style="display:flex;align-items:center;gap:5px;justify-content:flex-end;margin-bottom:4px">
<div class="dot ${e.dot}"></div>
<span style="font-size:12px;font-weight:700;color:var(--muted)">${e.status}</span>
</div>
<div style="font-size:11px;color:var(--muted)">${e.done}/${e.jobs} зак.</div>
</div>
</div>
<div style="font-size:12px;color:var(--muted);background:var(--bg);padding:8px 10px;border-radius:8px;margin-bottom:10px">${e.warn?'⚠️':'📍'} ${e.detail}</div>
<div style="display:flex;gap:8px">
<button class="btn-pill accent" style="flex:1;justify-content:center" onclick="alert('📞 Звонок ${e.name}…')">📞 Позвонить</button>
<button class="btn-pill muted" style="flex:1;justify-content:center" onclick="alert('💬 Чат с ${e.name}…')">💬 Написать</button>
</div>
</div>
`).join('')}
</div>
</div>`;
}
/* ─── ORDER DETAIL ─── */
function screenOrderDetail(){
return `<div class="page">
<div class="page-header">
<button class="back-btn" onclick="go('orders')"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="15 18 9 12 15 6"/></svg></button>
<h2>Заявка #А-2855</h2>
<div class="header-action" onclick="alert('История изменений…')">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="1"/><circle cx="19" cy="12" r="1"/><circle cx="5" cy="12" r="1"/></svg>
</div>
</div>
<div style="background:#FEF2F2;border-bottom:1.5px solid #FECACA;padding:12px 16px;display:flex;align-items:center;gap:10px">
<span style="font-size:18px">🚨</span>
<div>
<div style="font-size:13px;font-weight:700;color:#DC2626">Сборщик не назначен</div>
<div style="font-size:12px;color:#991B1B">Осталось 4 часа · Сегодня 14:0017:00</div>
</div>
</div>
<div style="padding:12px 16px 0">
<div class="card">
<div style="font-size:13px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.05em;margin-bottom:12px">Клиент</div>
<div class="info-row"><span class="info-label">Имя</span><span class="info-val">Иванов Пётр</span></div>
<div class="info-row"><span class="info-label">Телефон</span><span class="info-val" style="color:var(--accent)">+7 812 555-12-34</span></div>
<div class="info-row"><span class="info-label">Адрес</span><span class="info-val">пр. Просвещения, 44, кв. 7</span></div>
<div class="info-row"><span class="info-label">Время</span><span class="info-val">Сегодня 14:0017:00</span></div>
<div class="info-row"><span class="info-label">Менеджер</span><span class="info-val">Анна Смирнова</span></div>
<div style="margin-top:10px">
<a href="#" onclick="event.preventDefault();alert('📞 Звонок клиенту…')" style="display:inline-flex;align-items:center;gap:6px;background:#EFF6FF;padding:8px 14px;border-radius:10px;text-decoration:none;font-size:12px;font-weight:700;color:var(--accent);border:1px solid #BFDBFE">
📞 Позвонить клиенту
</a>
</div>
</div>
<div class="card">
<div style="font-size:13px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.05em;margin-bottom:12px">Объект сборки</div>
<div class="info-row"><span class="info-label">Тип</span><span class="info-val">Кухня угловая</span></div>
<div class="info-row"><span class="info-label">Размер</span><span class="info-val">2.8 × 3.8 м</span></div>
<div class="info-row"><span class="info-label">Корпуса</span><span class="info-val">14 ед.</span></div>
<div class="info-row"><span class="info-label">Фасады</span><span class="info-val">МДФ плёнка, белый</span></div>
<div class="info-row"><span class="info-label">Техника</span><span class="info-val">3 позиции</span></div>
</div>
<!-- Назначение сотрудника -->
<div class="card danger-b">
<div style="font-size:13px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.05em;margin-bottom:12px">Назначить сборщика</div>
${[
{name:'Сергей Петров',jobs:1,free:'С 12:00',avail:true},
{name:'Константин Лев.',jobs:0,free:'Свободен',avail:true},
{name:'Дмитрий Власов',jobs:1,free:'Занят до 16:00',avail:false},
].map(e=>`
<div style="display:flex;align-items:center;gap:10px;padding:9px 0;border-bottom:1px solid rgba(0,0,0,.05)">
<div class="sch-avatar" style="width:34px;height:34px;font-size:12px">${e.name.split(' ').map(w=>w[0]).join('')}</div>
<div style="flex:1">
<div style="font-size:13px;font-weight:700;color:var(--ink)">${e.name}</div>
<div style="font-size:11px;color:var(--muted)">${e.jobs} зак. · ${e.free}</div>
</div>
${e.avail
?`<button class="btn-sm" onclick="alert('Сборщик ${e.name} назначен на А-2855!')">Назначить</button>`
:`<span class="badge gray">Занят</span>`}
</div>
`).join('')}
</div>
<!-- Документы -->
<div class="card">
<div style="font-size:13px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.05em;margin-bottom:10px">Документы</div>
<div style="display:flex;gap:7px">
<a href="#" onclick="event.preventDefault();alert('📋 Договор А-2855…')" style="flex:1;display:flex;align-items:center;gap:6px;padding:9px 10px;background:#EFF6FF;border:1px solid #BFDBFE;border-radius:10px;text-decoration:none">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="#1D4ED8" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>
<div><div style="font-size:11px;font-weight:700;color:#1D4ED8">Договор</div><div style="font-size:10px;color:#93C5FD">PDF · 1.2 МБ</div></div>
</a>
<a href="#" onclick="event.preventDefault();alert('📐 Проект А-2855…')" style="flex:1;display:flex;align-items:center;gap:6px;padding:9px 10px;background:#F0FDF4;border:1px solid #BBF7D0;border-radius:10px;text-decoration:none">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="#15803D" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/><line x1="9" y1="3" x2="9" y2="21"/><line x1="3" y1="9" x2="21" y2="9"/></svg>
<div><div style="font-size:11px;font-weight:700;color:#15803D">Проект</div><div style="font-size:10px;color:#86EFAC">PDF · 4 листа</div></div>
</a>
<a href="#" onclick="event.preventDefault();alert('📸 Фото замера А-2855…')" style="flex:1;display:flex;align-items:center;gap:6px;padding:9px 10px;background:#FFF7ED;border:1px solid #FED7AA;border-radius:10px;text-decoration:none">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="#C2410C" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="5" width="18" height="14" rx="2"/><circle cx="12" cy="12" r="3"/></svg>
<div><div style="font-size:11px;font-weight:700;color:#C2410C">Фото</div><div style="font-size:10px;color:#FDBA74">8 фото</div></div>
</a>
</div>
</div>
<button class="btn-primary" onclick="alert('Сохранить изменения заявки А-2855?')">💾 Сохранить изменения</button>
<button class="btn-secondary" onclick="alert('Перенос заявки А-2855…')">🔄 Перенести визит</button>
</div>
</div>`;
}
// init
go('home');
</script>
</body>
</html>