wasrusgen1-crm/docs/mockup_measurer.html

1306 lines
85 KiB
HTML
Raw Permalink 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>
<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:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif}
body[data-theme="zov"] {--accent:#003E7E;--accent2:#76BD22;--bg:#F5F6F8;--card:#FFFFFF;--ink:#1A1A2E;--muted:#8A94A6;--danger:#EF4444;--warn:#F59E0B;--success:#10B981}
body[data-theme="radar"] {--accent:#4338CA;--accent2:#6366F1;--bg:#F9FAFB;--card:#FFFFFF;--ink:#111827;--muted:#6B7280;--danger:#EF4444;--warn:#F59E0B;--success:#10B981}
body[data-theme="dark"] {--accent:#4338CA;--accent2:#6366F1;--bg:#111827;--card:#1F2937;--ink:#F9FAFB;--muted:#9CA3AF;--danger:#EF4444;--warn:#F59E0B;--success:#10B981}
#controls{display:flex;align-items:center;gap:12px;margin-bottom:16px;flex-wrap:wrap;justify-content:center;width:100%;max-width:600px}
#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;transform:scale(1.05)}
.theme-btn[data-t="zov"] {background:#003E7E;color:#fff}
.theme-btn[data-t="radar"]{background:#4338CA;color:#fff}
.theme-btn[data-t="dark"] {background:#111827;color:#6366F1}
#phoneWrap{position:relative;width:390px;flex-shrink:0}
#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}
.sb-right{display:flex;align-items:center;gap:6px}
#screen{flex:1;overflow-y:auto;overflow-x:hidden;position:relative;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;position:relative;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{color:var(--accent)}
.nav-item.active span{color:var(--accent)}
.nav-fab{width:52px;height:52px;background:var(--accent);border-radius:50%;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 16px rgba(0,0,0,.25);cursor:pointer;margin-top:-18px;flex-shrink:0}
.nav-fab svg{color:#fff;width:24px;height:24px}
.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:36px;height:36px;border-radius:50%;background:var(--bg);display:flex;align-items:center;justify-content:center;cursor:pointer;border:none}
.header-action svg{color:var(--accent);width:20px;height:20px}
.card{background:var(--card);border-radius:16px;box-shadow:0 2px 12px rgba(0,0,0,.07);padding:16px;margin-bottom:12px}
.card.warn-border{border-left:3px solid var(--warn)}
.card.success-border{border-left:3px solid var(--success)}
.card.accent-border{border-left:3px solid var(--accent)}
.card.danger-border{border-left:3px solid var(--danger)}
.section-label{text-transform:uppercase;font-size:11px;letter-spacing:.06em;color:var(--muted);margin:20px 16px 8px;font-weight:600}
.btn-primary{width:100%;background:var(--accent);color:#fff;border:none;border-radius:12px;padding:14px;font-size:15px;font-weight:600;cursor:pointer;transition:opacity .2s}
.btn-primary:hover{opacity:.9}
.btn-secondary{width:100%;background:transparent;color:var(--accent);border:1.5px solid var(--accent);border-radius:12px;padding:13px;font-size:15px;font-weight:600;cursor:pointer;transition:all .2s;margin-top:8px}
.btn-sm{padding:8px 14px;font-size:13px;font-weight:600;border-radius:9px;cursor:pointer;border:none;background:var(--accent);color:#fff}
.btn-sm.outline{background:transparent;border:1.5px solid var(--accent);color:var(--accent)}
.btn-sm.success{background:var(--success);color:#fff}
.badge{display:inline-flex;align-items:center;padding:3px 10px;border-radius:20px;font-size:11px;font-weight:700;letter-spacing:.02em}
.badge.blue{background:#DBEAFE;color:#1D4ED8}
.badge.yellow{background:#FEF3C7;color:#D97706}
.badge.green{background:#DCFCE7;color:#15803D}
.badge.red{background:#FEE2E2;color:#DC2626}
.badge.gray{background:#F1F5F9;color:#64748B}
.form-group{margin-bottom:14px}
.form-group label{display:block;font-size:12px;font-weight:600;color:var(--muted);text-transform:uppercase;letter-spacing:.05em;margin-bottom:6px}
.form-input{width:100%;padding:12px 14px;border:1.5px solid #E2E8F0;border-radius:12px;font-size:15px;color:var(--ink);background:var(--card);outline:none}
.form-textarea{width:100%;padding:12px 14px;border:1.5px solid #E2E8F0;border-radius:12px;font-size:14px;color:var(--ink);background:var(--card);outline:none;resize:none;min-height:80px}
.row{display:flex;align-items:center;gap:10px}
.row.sb{justify-content:space-between}
.col{display:flex;flex-direction:column;gap:4px}
.avatar{width:40px;height:40px;border-radius:50%;background:var(--accent);display:flex;align-items:center;justify-content:center;color:#fff;font-size:15px;font-weight:700;flex-shrink:0}
.avatar.lg{width:64px;height:64px;font-size:22px}
.avatar.green{background:var(--success)}
.chip-row{display:flex;gap:8px;overflow-x:auto;padding:0 16px;margin-bottom:8px;scrollbar-width:none}
.chip-row::-webkit-scrollbar{display:none}
.chip{padding:6px 14px;border-radius:20px;font-size:13px;font-weight:600;cursor:pointer;white-space:nowrap;border:1.5px solid #E2E8F0;background:var(--card);color:var(--muted);transition:all .2s}
.chip.active{background:var(--accent);color:#fff;border-color:var(--accent)}
.progress-bar{height:6px;background:#E2E8F0;border-radius:3px;overflow:hidden;flex:1}
.progress-fill{height:100%;background:var(--accent);border-radius:3px}
.progress-fill.green{background:var(--success)}
.divider{height:1px;background:rgba(0,0,0,.07);margin:8px 0}
.photo-slot{width:80px;height:80px;border-radius:12px;background:#F1F5F9;border:2px dashed #CBD5E1;display:flex;align-items:center;justify-content:center;flex-shrink:0;cursor:pointer}
.photo-slot svg{color:var(--muted);width:24px;height:24px}
.photo-slot.filled{background:linear-gradient(135deg,#E2E8F0,#CBD5E1);border:none;font-size:28px}
.info-row{display:flex;gap:8px;padding:10px 0;border-bottom:1px solid rgba(0,0,0,.06)}
.info-row:last-child{border-bottom:none}
.info-label{font-size:12px;color:var(--muted);font-weight:500;width:100px;flex-shrink:0}
.info-val{font-size:13px;font-weight:600;color:var(--ink);flex:1}
.earnings-card{background:linear-gradient(135deg,var(--accent),var(--accent2));border-radius:16px;padding:20px;color:#fff;margin-bottom:12px}
/* measure-specific */
.dim-row{display:flex;align-items:center;gap:8px;margin-bottom:10px}
.dim-label{font-size:13px;font-weight:600;color:var(--ink);width:100px;flex-shrink:0}
.dim-input-wrap{display:flex;align-items:center;gap:6px;flex:1}
.dim-input{width:100%;padding:10px 12px;border:1.5px solid #E2E8F0;border-radius:10px;font-size:15px;color:var(--ink);background:var(--card);outline:none;text-align:right}
.dim-unit{font-size:12px;color:var(--muted);font-weight:600;white-space:nowrap}
.step-progress{display:flex;align-items:center;gap:0;padding:12px 16px;background:var(--card);border-bottom:1px solid rgba(0,0,0,.06)}
.step-item{display:flex;flex-direction:column;align-items:center;flex:1;position:relative}
.step-item:not(:last-child)::after{content:'';position:absolute;top:12px;left:50%;width:100%;height:2px;background:#E2E8F0;z-index:0}
.step-item.done:not(:last-child)::after{background:var(--accent)}
.step-dot{width:24px;height:24px;border-radius:50%;border:2px solid #E2E8F0;background:var(--card);display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700;color:var(--muted);position:relative;z-index:1}
.step-dot.active{border-color:var(--accent);background:var(--accent);color:#fff}
.step-dot.done{border-color:var(--accent);background:var(--accent);color:#fff}
.step-name{font-size:10px;color:var(--muted);margin-top:4px;text-align:center;font-weight:500}
.step-name.active{color:var(--accent);font-weight:700}
.grid-sketch{display:grid;grid-template-columns:repeat(5,1fr);gap:2px;background:#E2E8F0;border-radius:10px;overflow:hidden;border:2px solid #E2E8F0}
.grid-cell{aspect-ratio:1;background:var(--bg);display:flex;align-items:center;justify-content:center;font-size:9px;color:var(--muted)}
.grid-cell.wall{background:#CBD5E1}
.grid-cell.niche{background:#BFDBFE}
.grid-cell.door{background:#BBF7D0}
.grid-cell.dim-label-cell{font-size:8px;color:var(--accent);font-weight:700;background:transparent}
/* dark theme fixes */
body[data-theme="dark"] .form-input,body[data-theme="dark"] .form-textarea,body[data-theme="dark"] .dim-input{background:#374151;border-color:#4B5563;color:#F9FAFB}
body[data-theme="dark"] .chip{background:#1F2937;border-color:#374151;color:#9CA3AF}
body[data-theme="dark"] .progress-bar{background:#374151}
body[data-theme="dark"] .page-header{background:#1F2937;border-color:#374151}
body[data-theme="dark"] .bottom-nav{background:rgba(31,41,55,.95);border-color:#374151}
body[data-theme="dark"] #statusBar{background:#1F2937}
body[data-theme="dark"] .back-btn,body[data-theme="dark"] .header-action{background:#374151}
body[data-theme="dark"] .info-row{border-color:#374151}
body[data-theme="dark"] .step-progress{background:#1F2937;border-color:#374151}
body[data-theme="dark"] .step-dot{background:#1F2937;border-color:#374151}
body[data-theme="dark"] .grid-sketch{background:#374151;border-color:#374151}
body[data-theme="dark"] .grid-cell{background:#1F2937}
body[data-theme="dark"] .grid-cell.wall{background:#4B5563}
body[data-theme="dark"] .photo-slot{background:#374151;border-color:#4B5563}
@keyframes slideFade{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}
.page{animation:slideFade .18s ease-out}
</style>
</head>
<body data-theme="zov">
<div id="crm-back-nav" style="position:fixed;top:0;left:0;right:0;z-index:9999;background:rgba(255,255,255,0.92);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border-bottom:1px solid rgba(0,0,0,.08);padding:8px 16px;display:flex;align-items:center">
<a href="https://wasrusgen.github.io/wasrusgen1-crm/" style="display:inline-flex;align-items:center;gap:6px;font-family:Inter,system-ui,sans-serif;font-size:13px;font-weight:600;color:#003E7E;text-decoration:none;padding:4px 12px;border-radius:8px;background:#F0F4FF;transition:background .15s" onmouseover="this.style.background='#DDE8FF'" onmouseout="this.style.background='#F0F4FF'">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M19 12H5M12 5l-7 7 7 7"/></svg>
Все кабинеты
</a>
<span style="margin-left:12px;font-family:Inter,system-ui,sans-serif;font-size:12px;color:#8A94A6">@wasrusgen1 CRM</span>
</div>
<div style="height:40px"></div>
<div id="controls">
<label>Экран:</label>
<select id="screenSelect"></select>
<div id="themeButtons">
<button class="theme-btn active" data-t="zov" onclick="setTheme('zov')">CRM</button>
<button class="theme-btn" data-t="radar" onclick="setTheme('radar')">CRM</button>
<button class="theme-btn" data-t="dark" onclick="setTheme('dark')">Dark</button>
</div>
</div>
<div id="phoneWrap">
<div id="phoneFrame">
<a href="./index.html" id="in-frame-back" style="display:flex;align-items:center;gap:6px;padding:5px 14px;background:rgba(0,62,126,.06);border-bottom:1px solid rgba(0,62,126,.09);font-family:Inter,system-ui,sans-serif;font-size:11px;font-weight:700;color:#003E7E;text-decoration:none;flex-shrink:0;z-index:200"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M19 12H5M12 5l-7 7 7 7"/></svg>Мокапы кабинетов</a>
<div id="statusBar">
<span>9:41</span>
<div class="sb-right">
<svg width="16" height="12" viewBox="0 0 16 12" fill="currentColor" style="color:var(--ink)"><rect x="0" y="4" width="3" height="8" rx="1"/><rect x="4.5" y="2.5" width="3" height="9.5" rx="1"/><rect x="9" y="0.5" width="3" height="11.5" rx="1"/><rect x="13.5" y="0" width="2.5" height="12" rx="1" opacity=".3"/></svg>
<svg width="15" height="12" viewBox="0 0 15 12" fill="none" stroke="currentColor" stroke-width="1.5" style="color:var(--ink)"><path d="M7.5 3C9.5 3 11.3 3.8 12.7 5.1M2.3 5.1C3.7 3.8 5.5 3 7.5 3"/><path d="M7.5 6.5C8.7 6.5 9.8 7 10.6 7.8M4.4 7.8C5.2 7 6.3 6.5 7.5 6.5"/><circle cx="7.5" cy="10" r="1" fill="currentColor"/></svg>
<svg width="25" height="12" viewBox="0 0 25 12" fill="none" style="color:var(--ink)"><rect x="0.5" y="0.5" width="21" height="11" rx="3" stroke="currentColor" stroke-opacity=".35"/><rect x="1.5" y="1.5" width="17" height="9" rx="2" fill="currentColor"/><path d="M23 4v4a2 2 0 000-4z" fill="currentColor" fill-opacity=".4"/></svg>
</div>
</div>
<div id="screen"></div>
</div>
</div>
<script src="data.js"></script>
<script>
const SCREENS = {
home: 'Главная',
orders: 'Заявки на замер',
order_detail: 'Карточка заявки',
measure_form: 'Форма замера',
room_sketch: 'Схема помещения',
photo_room: 'Фото помещения',
report_preview: 'Предпросмотр отчёта',
report_send: 'Отправка менеджеру',
report_done: 'Успех отправки',
history: 'История замеров',
profile: 'Профиль замерщика',
my_questionnaire: 'Моя анкета',
schedule: 'Расписание',
accept_job: 'Входящая заявка',
};
let cur = 'home';
const sel = document.getElementById('screenSelect');
Object.entries(SCREENS).forEach(([k,v]) => {
const o = document.createElement('option');
o.value = k; o.textContent = v; sel.appendChild(o);
});
sel.addEventListener('change', e => go(e.target.value));
function go(id) {
cur = id; sel.value = id;
const s = document.getElementById('screen');
s.innerHTML = render(id);
s.scrollTop = 0;
}
function setTheme(t) {
document.body.dataset.theme = t;
document.querySelectorAll('.theme-btn').forEach(b => b.classList.toggle('active', b.dataset.t === t));
}
function nav(active) {
return `<div class="bottom-nav">
<div class="nav-item ${active==='home'?'active':''}" onclick="go('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 ${active==='orders'?'active':''}" onclick="go('orders')">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2"/><rect x="9" y="3" width="6" height="4" rx="1"/><line x1="9" y1="12" x2="15" y2="12"/><line x1="9" y1="16" x2="12" y2="16"/></svg>
<span>Заявки</span>
</div>
<div class="nav-item" style="flex:0">
<div class="nav-fab" onclick="go('accept_job')">
<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 class="nav-item ${active==='schedule'?'active':''}" onclick="go('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 ${active==='profile'?'active':''}" onclick="go('profile')">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 21v-2a4 4 0 00-4-4H8a4 4 0 00-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
<span>Профиль</span>
</div>
</div>`;
}
function stepBar(active) {
const steps = [{k:'order_detail',n:'Данные'},{k:'measure_form',n:'Размеры'},{k:'photo_room',n:'Фото'},{k:'report_preview',n:'Отчёт'}];
const idx = steps.findIndex(s => s.k === active);
return `<div class="step-progress">${steps.map((s,i) => `
<div class="step-item ${i<idx?'done':i===idx?'active':''}">
<div class="step-dot ${i<idx?'done':i===idx?'active':''}">${i<idx?'✓':(i+1)}</div>
<div class="step-name ${i===idx?'active':''}">${s.n}</div>
</div>
`).join('')}</div>`;
}
function render(id) {
switch(id) {
case 'home': return screenHome();
case 'orders': return screenOrders();
case 'order_detail': return screenOrderDetail();
case 'measure_form': return screenMeasureForm();
case 'room_sketch': return screenRoomSketch();
case 'photo_room': return screenPhotoRoom();
case 'report_preview': return screenReportPreview();
case 'report_send': return screenReportSend();
case 'report_done': return screenReportDone();
case 'history': return screenHistory();
case 'profile': return screenProfile();
case 'my_questionnaire': return screenMyQuestionnaire();
case 'accept_job': return screenAcceptJob();
case 'schedule': return screenSchedule();
default: return '<div style="padding:40px;text-align:center;color:var(--muted)">Экран в разработке</div>';
}
}
// ── GPS: прибытие на объект замера ────────────────────────────────────────────
var _MSR_GPS_RADIUS = 300; // метров
var _MSR_JOBS = {
'З-1042': {addr:'ул. Рубинштейна, 7, кв. 18', lat:59.9295, lng:30.3426}
};
window._MSR_GPS = {};
window._MSR_GPS_DEMO = 'near';
function _msrGpsDist(la1,lo1,la2,lo2){
var R=6371000,dL=(la2-la1)*Math.PI/180,dG=(lo2-lo1)*Math.PI/180;
var a=Math.sin(dL/2)*Math.sin(dL/2)+Math.cos(la1*Math.PI/180)*Math.cos(la2*Math.PI/180)*Math.sin(dG/2)*Math.sin(dG/2);
return Math.round(R*2*Math.atan2(Math.sqrt(a),Math.sqrt(1-a)));
}
function _msrFmt(m){ return m<1000?(m+' м'):(m/1000).toFixed(1)+' км'; }
function _msrGpsResult(jobId,dist){
var ok=dist<=_MSR_GPS_RADIUS;
window._MSR_GPS[jobId]={ok:ok,dist:dist};
document.getElementById('screen').innerHTML=render('order_detail');
}
function _msrGpsRequest(jobId){
window._MSR_GPS[jobId]='loading';
document.getElementById('screen').innerHTML=render('order_detail');
var job=_MSR_JOBS[jobId];
function onGot(lat,lng){ _msrGpsResult(jobId,_msrGpsDist(lat,lng,job.lat,job.lng)); }
function onFail(){ _msrGpsResult(jobId, window._MSR_GPS_DEMO==='near'?54:1510); }
var tg=window.Telegram&&Telegram.WebApp;
if(tg&&tg.LocationManager&&tg.LocationManager.isInited){
tg.LocationManager.getLocation(function(r){ r&&r.latitude?onGot(r.latitude,r.longitude):onFail(); });
} else if(navigator.geolocation){
navigator.geolocation.getCurrentPosition(
function(p){ onGot(p.coords.latitude,p.coords.longitude); },
onFail,{timeout:8000,maximumAge:15000}
);
} else { onFail(); }
}
function _msrGpsForce(jobId){
var prev=window._MSR_GPS[jobId];
window._MSR_GPS[jobId]={ok:false,dist:prev&&prev.dist||0,forced:true};
document.getElementById('screen').innerHTML=render('order_detail');
}
function _msrGpsCancelCheck(jobId){
window._MSR_GPS[jobId]=null;
document.getElementById('screen').innerHTML=render('order_detail');
}
/* ─── HOME ─── */
function screenHome() {
return `<div class="page">
<div style="background:linear-gradient(135deg,var(--accent) 0%,var(--accent2) 100%);padding:20px 16px 28px">
<div style="font-size:12px;color:rgba(255,255,255,.65);font-weight:600;text-transform:uppercase;letter-spacing:.05em;margin-bottom:4px">Четверг, 21 мая 2026</div>
<div style="font-size:22px;font-weight:800;color:#fff;margin-bottom:2px">Привет, Игорь 📐</div>
<div style="font-size:14px;color:rgba(255,255,255,.75)">3 замера сегодня · 1 активный</div>
<div style="display:flex;gap:12px;margin-top:16px">
<div style="background:rgba(255,255,255,.15);border-radius:12px;padding:10px 14px;flex:1;text-align:center">
<div style="font-size:22px;font-weight:800;color:#fff">3</div>
<div style="font-size:11px;color:rgba(255,255,255,.7)">Сегодня</div>
</div>
<div style="background:rgba(255,255,255,.15);border-radius:12px;padding:10px 14px;flex:1;text-align:center">
<div style="font-size:22px;font-weight:800;color:#fff">1</div>
<div style="font-size:11px;color:rgba(255,255,255,.7)">В процессе</div>
</div>
<div style="background:rgba(255,255,255,.15);border-radius:12px;padding:10px 14px;flex:1;text-align:center">
<div style="font-size:22px;font-weight:800;color:#fff">2</div>
<div style="font-size:11px;color:rgba(255,255,255,.7)">Ожидают</div>
</div>
</div>
</div>
<div style="padding:0 16px;margin-top:-14px">
<div class="card accent-border" onclick="go('order_detail')" style="cursor:pointer">
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:10px">
<span class="badge yellow">В процессе</span>
<span style="font-size:12px;color:var(--muted)">Замер #З-1042</span>
</div>
<div style="font-size:16px;font-weight:700;color:var(--ink);margin-bottom:4px">Смирнова Ольга</div>
<div style="font-size:13px;color:var(--muted);margin-bottom:12px">📍 ул. Рубинштейна, 7, кв. 18 · Сегодня, 10:30</div>
<div style="margin-bottom:12px">
<div style="display:flex;justify-content:space-between;margin-bottom:4px">
<span style="font-size:12px;color:var(--muted)">Прогресс замера</span>
<span style="font-size:12px;font-weight:700;color:var(--ink)">Шаг 2 / 4</span>
</div>
<div class="progress-bar"><div class="progress-fill" style="width:50%"></div></div>
</div>
<div style="display:flex;gap:8px">
<button class="btn-sm" onclick="event.stopPropagation();go('measure_form')">Продолжить замер</button>
<button class="btn-sm outline" onclick="event.stopPropagation();go('room_sketch')">Схема</button>
</div>
</div>
</div>
<div class="section-label">Расписание на сегодня</div>
<div style="padding:0 16px">
${[
{id:'З-1043',name:'Корнилов Виктор',addr:'пр. Невский, 120, кв. 5',time:'13:0014:00',type:'Гостиная + прихожая',badge:'blue',status:'Назначен'},
{id:'З-1044',name:'Лебедева Марина',addr:'ул. Восстания, 42, кв. 31',time:'16:0017:00',type:'Спальня + гардероб',badge:'blue',status:'Назначен'},
].map(o => `
<div class="card" onclick="go('order_detail')" style="cursor:pointer">
<div style="display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:8px">
<div>
<div style="font-size:15px;font-weight:700;color:var(--ink)">${o.name}</div>
<div style="font-size:12px;color:var(--muted);margin-top:2px">📍 ${o.addr}</div>
</div>
<span class="badge ${o.badge}">${o.status}</span>
</div>
<div style="display:flex;align-items:center;justify-content:space-between">
<span style="font-size:12px;color:var(--muted)"> ${o.time} · ${o.type}</span>
<span style="font-size:12px;color:var(--muted)">#${o.id}</span>
</div>
</div>
`).join('')}
</div>
<div class="section-label">Статистика месяца</div>
<div style="padding:0 16px">
<div class="earnings-card">
<div style="display:flex;justify-content:space-between;align-items:flex-start">
<div>
<div style="font-size:12px;color:rgba(255,255,255,.65);margin-bottom:4px">Май 2026</div>
<div style="font-size:28px;font-weight:800">18 600 ₽</div>
<div style="font-size:13px;color:rgba(255,255,255,.7);margin-top:4px">за 31 замер</div>
</div>
<div style="text-align:right">
<div style="font-size:12px;color:rgba(255,255,255,.65);margin-bottom:4px">Рейтинг</div>
<div style="font-size:28px;font-weight:800">4.8 ⭐</div>
<div style="font-size:13px;color:rgba(255,255,255,.7);margin-top:4px">из 5.0</div>
</div>
</div>
</div>
</div>
${nav('home')}</div>`;
}
/* ─── ORDERS ─── */
function screenOrders() {
return `<div class="page">
<div class="page-header">
<h2>Заявки на замер</h2>
<div class="header-action"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg></div>
</div>
<div class="chip-row" style="margin-top:12px">
<div class="chip active">Все (7)</div>
<div class="chip">Сегодня (3)</div>
<div class="chip">Новые (2)</div>
<div class="chip">Выполнены (4)</div>
</div>
<div style="padding:0 16px">
${[
{id:'З-1042',name:'Смирнова Ольга',addr:'ул. Рубинштейна, 7',time:'10:30',type:'Кухня + гостиная',badge:'yellow',status:'В процессе',date:'Сегодня'},
{id:'З-1043',name:'Корнилов Виктор',addr:'пр. Невский, 120',time:'13:00',type:'Гостиная + прихожая',badge:'blue',status:'Назначен',date:'Сегодня'},
{id:'З-1044',name:'Лебедева Марина',addr:'ул. Восстания, 42',time:'16:00',type:'Спальня + гардероб',badge:'blue',status:'Назначен',date:'Сегодня'},
{id:'З-1040',name:'Захаров Илья',addr:'пр. Литейный, 58',time:'11:00',type:'2-комнатная кв. полный',badge:'green',status:'Выполнен',date:'20.05'},
{id:'З-1038',name:'Фёдорова Анна',addr:'ул. Садовая, 33',time:'14:30',type:'Детская + спальня',badge:'green',status:'Выполнен',date:'19.05'},
{id:'З-1036',name:'Попов Сергей',addr:'пр. Просвещения, 14',time:'10:00',type:'Кухня студия',badge:'green',status:'Выполнен',date:'17.05'},
{id:'З-1045',name:'Новикова Тамара',addr:'Каменноостровский, 9',time:'—',type:'Кухня + 2 спальни',badge:'red',status:'Новая',date:'Завтра'},
].map(o => `
<div class="card" onclick="go('order_detail')" style="cursor:pointer">
<div style="display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:8px">
<div style="flex:1">
<div style="font-size:15px;font-weight:700;color:var(--ink)">${o.name}</div>
<div style="font-size:12px;color:var(--muted);margin-top:2px">📍 ${o.addr}</div>
</div>
<span class="badge ${o.badge}">${o.status}</span>
</div>
<div style="display:flex;align-items:center;justify-content:space-between">
<span style="font-size:12px;color:var(--muted)">${o.date}${o.time!=='—'?' · ⏰ '+o.time:''} · ${o.type}</span>
<span style="font-size:11px;color:var(--muted)">#${o.id}</span>
</div>
</div>
`).join('')}
</div>
${nav('orders')}</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>Заявка #З-1042</h2>
<div class="header-action"><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>
${stepBar('order_detail')}
${(function(){
var jobId='З-1042';
var gst=window._MSR_GPS[jobId];
if(!gst){
return '<div style="background:#F0FDF4;border-bottom:1.5px solid #86EFAC;padding:12px 16px">'
+'<div style="font-size:12px;color:#059669;font-weight:700;margin-bottom:6px">📍 Подтвердите прибытие на объект</div>'
+'<div style="font-size:12px;color:var(--muted);margin-bottom:10px">ул. Рубинштейна, 7, кв. 18 · Смирнова Ольга</div>'
+'<button onclick="_msrGpsRequest(\'З-1042\')" style="width:100%;padding:10px;border-radius:10px;border:none;background:#16A34A;color:#fff;font-size:13px;font-weight:700;cursor:pointer">📍 Я на месте</button>'
+'<div style="margin-top:7px;font-size:10px;color:#94A3B8">Демо: '
+'<span onclick="window._MSR_GPS_DEMO=\'near\';document.getElementById(\'screen\').innerHTML=render(\'order_detail\')" style="cursor:pointer;font-weight:700;color:'+(window._MSR_GPS_DEMO==='near'?'#16A34A':'#94A3B8')+'">Рядом</span> · '
+'<span onclick="window._MSR_GPS_DEMO=\'far\';document.getElementById(\'screen\').innerHTML=render(\'order_detail\')" style="cursor:pointer;font-weight:700;color:'+(window._MSR_GPS_DEMO==='far'?'#DC2626':'#94A3B8')+'">Далеко</span></div>'
+'</div>';
} else if(gst==='loading'){
return '<div style="background:#F8FAFC;border-bottom:1px solid #E2E8F0;padding:14px 16px;text-align:center;font-size:14px;color:var(--muted);font-weight:600">'
+'<span style="display:inline-block;animation:spin 1s linear infinite;margin-right:8px">⏱</span>Определяем местоположение…</div>';
} else if(gst&&!gst.ok&&!gst.forced){
return '<div style="background:rgba(245,158,11,.1);border-bottom:1.5px solid rgba(245,158,11,.4);padding:13px 16px">'
+'<div style="font-size:13px;font-weight:700;color:var(--warn);margin-bottom:4px">⚠️ Вы в '+_msrFmt(gst.dist)+' от объекта</div>'
+'<div style="font-size:12px;color:var(--muted);margin-bottom:10px">ул. Рубинштейна, 7 · Допустимый радиус: 300 м</div>'
+'<div style="display:flex;gap:8px">'
+'<button onclick="_msrGpsForce(\'З-1042\')" style="flex:1;padding:9px;border-radius:10px;border:none;background:#F59E0B;color:#fff;font-size:13px;font-weight:700;cursor:pointer">Отметить всё равно</button>'
+'<button onclick="_msrGpsCancelCheck(\'З-1042\')" style="padding:9px 14px;border-radius:10px;border:1px solid #E2E8F0;background:transparent;font-size:13px;font-weight:600;color:var(--muted);cursor:pointer">Отмена</button>'
+'</div></div>';
} else {
var chip=gst.forced
?'<span style="font-size:10px;background:rgba(245,158,11,.2);color:#D97706;border-radius:6px;padding:1px 6px;font-weight:700;margin-left:6px">⚡ вручную</span>'
:'<span style="font-size:10px;background:rgba(22,163,74,.15);color:#16A34A;border-radius:6px;padding:1px 6px;font-weight:700;margin-left:6px">GPS ✓</span>';
return '<div style="background:var(--warn);padding:10px 16px;display:flex;align-items:center;gap:8px">'
+'<span style="font-size:18px">⏱</span>'
+'<div><div style="font-size:13px;font-weight:700;color:#fff;display:flex;align-items:center">В процессе · начато в 10:35'+chip+'</div>'
+'<div style="font-size:12px;color:rgba(255,255,255,.8)">Прошло 47 минут</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 921 312-45-67</span></div>
<div class="info-row"><span class="info-label">Адрес</span><span class="info-val">ул. Рубинштейна, 7, кв. 18</span></div>
<div class="info-row"><span class="info-label">Время</span><span class="info-val">Сегодня 10:3012:00</span></div>
<div class="info-row"><span class="info-label">Менеджер</span><span class="info-val">Елена Морозова</span></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">Кухня + гостиная</span></div>
<div class="info-row"><span class="info-label">Этаж</span><span class="info-val">4 из 6</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">После ремонта</span></div>
</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('📋 Бриф клиента…\\nВ продакшне — открытие из облака')" 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 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="9" y1="13" x2="15" y2="13"/><line x1="9" y1="17" x2="13" y2="17"/></svg>
<div><div style="font-size:11px;font-weight:700;color:#1D4ED8">Бриф клиента</div><div style="font-size:10px;color:#93C5FD">PDF · 0.8 МБ</div></div>
</a>
<a href="#" onclick="event.preventDefault();alert('📐 Планировка квартиры…\\nВ продакшне — открытие из облака')" 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 · 3 листа</div></div>
</a>
</div>
</div>
<div class="card" style="background:var(--bg)">
<div style="font-size:13px;color:var(--muted);margin-bottom:4px;font-weight:600">Примечание менеджера</div>
<div style="font-size:14px;color:var(--ink);line-height:1.5">Клиент хочет угловую кухню 2,8×3,8 м. Уточнить расположение розеток и вентиляции. Есть ниша под холодильник — обязательно замерить.</div>
</div>
<button class="btn-primary" onclick="go('measure_form')">📐 Начать замер</button>
<button class="btn-secondary" onclick="go('room_sketch')">🗺 Схема помещения</button>
</div>
${nav('orders')}</div>`;
}
/* ─── MEASURE FORM ─── */
function screenMeasureForm() {
return `<div class="page">
<div class="page-header">
<button class="back-btn" onclick="go('order_detail')"><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>Форма замера</h2>
</div>
${stepBar('measure_form')}
<div style="padding:12px 16px 0">
<div style="font-size:13px;color:var(--muted);margin-bottom:16px">Замер #З-1042 · Смирнова · Кухня</div>
<div class="card">
<div style="font-size:13px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.05em;margin-bottom:14px">Стены</div>
${[
{label:'Стена A (фасад)', w:'3850', note:''},
{label:'Стена B (правая)', w:'4200', note:''},
{label:'Стена C (задняя)', w:'3850', note:''},
{label:'Стена D (левая)', w:'4200', note:''},
].map(s => `
<div style="margin-bottom:14px;padding-bottom:14px;border-bottom:1px solid rgba(0,0,0,.06)">
<div style="font-size:13px;font-weight:700;color:var(--ink);margin-bottom:8px">${s.label}</div>
<div class="dim-row">
<span class="dim-label">Длина</span>
<div class="dim-input-wrap">
<input type="number" class="dim-input" value="${s.w}" placeholder="0">
<span class="dim-unit">мм</span>
</div>
</div>
<div class="dim-row">
<span class="dim-label">Высота</span>
<div class="dim-input-wrap">
<input type="number" class="dim-input" value="2680" placeholder="0">
<span class="dim-unit">мм</span>
</div>
</div>
</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:14px">Входная группа</div>
<div class="dim-row">
<span class="dim-label">Ширина дверного проёма</span>
<div class="dim-input-wrap">
<input type="number" class="dim-input" value="900" placeholder="0">
<span class="dim-unit">мм</span>
</div>
</div>
<div class="dim-row">
<span class="dim-label">Высота проёма</span>
<div class="dim-input-wrap">
<input type="number" class="dim-input" value="2100" placeholder="0">
<span class="dim-unit">мм</span>
</div>
</div>
<div class="dim-row">
<span class="dim-label">Откос (толщина стены)</span>
<div class="dim-input-wrap">
<input type="number" class="dim-input" value="180" placeholder="0">
<span class="dim-unit">мм</span>
</div>
</div>
</div>
<div class="card">
<div style="font-size:13px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.05em;margin-bottom:14px">Особенности</div>
${[
{name:'Ниша под холодильник', dims:'650 × 680 × 2100', active:true},
{name:'Вентиляционный короб', dims:'300 × 250', active:true},
{name:'Трубы (диаметр / вынос)', dims:'50 мм / 80 мм', active:false},
{name:'Подоконник', dims:'1200 × 320', active:false},
].map(f => `
<div style="display:flex;align-items:center;gap:10px;margin-bottom:12px">
<div style="width:20px;height:20px;border-radius:5px;${f.active?'background:var(--accent)':'border:2px solid #CBD5E1'};display:flex;align-items:center;justify-content:center;flex-shrink:0;cursor:pointer">
${f.active?'<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="3"><polyline points="20 6 9 17 4 12"/></svg>':''}
</div>
<div style="flex:1">
<div style="font-size:14px;font-weight:600;color:var(--ink)">${f.name}</div>
${f.active?`<div style="font-size:12px;color:var(--muted)">${f.dims}</div>`:''}
</div>
</div>
`).join('')}
</div>
<div class="form-group">
<label>Комментарий замерщика</label>
<textarea class="form-textarea" placeholder="Особенности, которые важно учесть при проектировании...">Ниша под холодильник нестандартная — 650 мм. Вентиляция выходит в угол, короб придётся обходить.</textarea>
</div>
<button class="btn-primary" onclick="go('room_sketch')">Далее: Схема →</button>
</div>
${nav('orders')}</div>`;
}
/* ─── ROOM SKETCH ─── */
function screenRoomSketch() {
return `<div class="page">
<div class="page-header">
<button class="back-btn" onclick="go('measure_form')"><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>Схема помещения</h2>
</div>
${stepBar('measure_form')}
<div style="padding:12px 16px 0">
<div style="font-size:13px;color:var(--muted);margin-bottom:12px">Кухня · З-1042 · Смирнова</div>
<div class="card">
<div style="font-size:13px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.05em;margin-bottom:12px">Схема 5×5 (план)</div>
<!-- dimension labels top -->
<div style="display:grid;grid-template-columns:20px repeat(5,1fr);gap:2px;margin-bottom:2px">
<div></div>
<div style="text-align:center;font-size:9px;color:var(--accent);font-weight:700">770</div>
<div style="text-align:center;font-size:9px;color:var(--accent);font-weight:700">770</div>
<div style="text-align:center;font-size:9px;color:var(--accent);font-weight:700">770</div>
<div style="text-align:center;font-size:9px;color:var(--accent);font-weight:700">770</div>
<div style="text-align:center;font-size:9px;color:var(--accent);font-weight:700">770</div>
</div>
<div style="display:grid;grid-template-columns:20px repeat(5,1fr);gap:2px">
<!-- row labels -->
<div style="display:flex;flex-direction:column;gap:2px;justify-content:space-around">
${['840','840','840','840','840'].map(v=>`<div style="font-size:9px;color:var(--accent);font-weight:700;text-align:right;padding-right:2px">${v}</div>`).join('')}
</div>
<!-- grid cells -->
${(() => {
const grid = [
['wall','wall','wall','wall','wall'],
['wall','','','niche','wall'],
['wall','','','niche','wall'],
['wall','','','','wall'],
['wall','door','door','wall','wall'],
];
const labels = {
'0,0':'┌','0,4':'┐','4,0':'└','4,3':'🚪','1,3':'Ниша','2,3':''};
return grid.map((row,ri) =>
row.map((cell,ci) => {
const lbl = labels[ri+','+ci]||'';
return `<div class="grid-cell ${cell}" style="border-radius:${ri===0&&ci===0?'8px 0 0 0':ri===0&&ci===4?'0 8px 0 0':ri===4&&ci===0?'0 0 0 8px':ri===4&&ci===4?'0 0 8px 0':''}0">${lbl}</div>`;
}).join('')
).join('');
})()}
</div>
<div style="display:flex;gap:8px;margin-top:12px;flex-wrap:wrap">
<div style="display:flex;align-items:center;gap:4px"><div style="width:12px;height:12px;background:#CBD5E1;border-radius:2px"></div><span style="font-size:11px;color:var(--muted)">Стена</span></div>
<div style="display:flex;align-items:center;gap:4px"><div style="width:12px;height:12px;background:#BFDBFE;border-radius:2px"></div><span style="font-size:11px;color:var(--muted)">Ниша</span></div>
<div style="display:flex;align-items:center;gap:4px"><div style="width:12px;height:12px;background:#BBF7D0;border-radius:2px"></div><span style="font-size:11px;color:var(--muted)">Дверь</span></div>
</div>
</div>
<div style="display:flex;gap:8px;margin-bottom:12px">
<button class="btn-sm outline" style="flex:1">+ Ниша</button>
<button class="btn-sm outline" style="flex:1">+ Колонна</button>
<button class="btn-sm outline" style="flex:1">+ Окно</button>
</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>
${[
['Стена A','3 850 мм'],['Стена B','4 200 мм'],['Стена C','3 850 мм'],['Стена D','4 200 мм'],
['Высота','2 680 мм'],['Ниша Ш×Г','650 × 680 мм'],['Дверной проём','900 мм'],
].map(([l,v])=>`<div class="info-row"><span class="info-label">${l}</span><span class="info-val" style="color:var(--accent);font-weight:700">${v}</span></div>`).join('')}
</div>
<button class="btn-primary" onclick="go('photo_room')">Далее: Фото </button>
</div>
${nav('orders')}</div>`;
}
/* ─── PHOTO ROOM ─── */
function screenPhotoRoom() {
return `<div class="page">
<div class="page-header">
<button class="back-btn" onclick="go('room_sketch')"><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>Фото помещения</h2>
</div>
${stepBar('photo_room')}
<div style="padding:12px 16px 0">
<div style="font-size:13px;color:var(--muted);margin-bottom:16px">Кухня · З-1042 · Сфотографируйте все зоны</div>
${[
{zone:'🚪 Входная группа', slots:[{emoji:'📷',filled:false},{emoji:'📷',filled:false}]},
{zone:'🧱 Основная стена (А)', slots:[{emoji:'🏠',filled:true},{emoji:'📷',filled:false}]},
{zone:'🪟 Окна / световой проём', slots:[{emoji:'🪟',filled:true},{emoji:'📷',filled:false}]},
{zone:'🟫 Пол и плинтус', slots:[{emoji:'📷',filled:false},{emoji:'📷',filled:false}]},
{zone:'🔍 Детали (ниша, вентиляция)', slots:[{emoji:'📦',filled:true},{emoji:'🔧',filled:true}]},
].map(s => `
<div style="margin-bottom:16px">
<div style="font-size:13px;font-weight:700;color:var(--ink);margin-bottom:8px">${s.zone}</div>
<div style="display:flex;gap:10px;align-items:center">
${s.slots.map(sl => `
<div class="photo-slot ${sl.filled?'filled':''}" onclick="">
${sl.filled
? `<span style="font-size:28px">${sl.emoji}</span>`
: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M23 19a2 2 0 01-2 2H3a2 2 0 01-2-2V8a2 2 0 012-2h4l2-3h6l2 3h4a2 2 0 012 2z"/><circle cx="12" cy="13" r="4"/></svg>`}
</div>
`).join('')}
<div style="flex:1">
<div style="font-size:12px;color:var(--muted)">${s.slots.filter(x=>x.filled).length} из ${s.slots.length} фото</div>
<div class="progress-bar" style="margin-top:4px;width:80px"><div class="progress-fill ${s.slots.filter(x=>x.filled).length===s.slots.length?'green':''}" style="width:${s.slots.filter(x=>x.filled).length/s.slots.length*100}%"></div></div>
</div>
</div>
</div>
`).join('')}
<div class="form-group" style="margin-top:8px">
<label>Комментарий к фото</label>
<textarea class="form-textarea" placeholder="Пояснения к снимкам...">Ниша сфотографирована с рулеткой для масштаба. Вентиляционный короб — угол левой стены.</textarea>
</div>
<button class="btn-primary" onclick="go('report_preview')">Далее: Отчёт →</button>
</div>
${nav('orders')}</div>`;
}
/* ─── REPORT PREVIEW ─── */
function screenReportPreview() {
return `<div class="page">
<div class="page-header">
<button class="back-btn" onclick="go('photo_room')"><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>Предпросмотр отчёта</h2>
</div>
${stepBar('report_preview')}
<div style="padding:12px 16px 0">
<div class="card" style="background:linear-gradient(135deg,var(--accent),var(--accent2));color:#fff">
<div style="font-size:12px;color:rgba(255,255,255,.7);margin-bottom:4px">Отчёт по замеру</div>
<div style="font-size:18px;font-weight:800">З-1042 · Смирнова Ольга</div>
<div style="font-size:13px;color:rgba(255,255,255,.75);margin-top:4px">ул. Рубинштейна, 7, кв. 18 · 21.05.2026</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>
${[
['Стена A','3 850 мм'],['Стена B','4 200 мм'],['Стена C','3 850 мм'],['Стена D','4 200 мм'],
['Высота потолка','2 680 мм'],['Пл. пола (расчётная)','16,2 м²'],
].map(([l,v])=>`<div class="info-row"><span class="info-label">${l}</span><span class="info-val">${v}</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:12px">Особенности</div>
${[
['Ниша Ш×Г×В','650 × 680 × 2 100 мм'],
['Вентиляционный короб','300 × 250 мм · угол стены B'],
['Дверной проём','900 × 2 100 мм · откос 180 мм'],
['Подоконник','—'],
].map(([l,v])=>`<div class="info-row"><span class="info-label">${l}</span><span class="info-val">${v}</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>
${[
['Периметр рабочей зоны','14,5 п.м.'],
['Верхние шкафы (до ниши)','11,3 п.м.'],
['Нижние шкафы','9,8 п.м.'],
['Столешница','4,0 п.м.'],
].map(([l,v])=>`
<div style="display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px solid rgba(0,0,0,.06)">
<span style="font-size:13px;color:var(--ink)">${l}</span>
<span style="font-size:14px;font-weight:800;color:var(--accent)">${v}</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">Фото (5 снимков)</div>
<div style="display:flex;gap:8px;overflow-x:auto;padding-bottom:4px">
${['🏠','🪟','📦','🔧','📷'].map((e,i) => `
<div style="width:68px;height:68px;border-radius:10px;background:linear-gradient(135deg,#E2E8F0,#CBD5E1);flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:24px">${e}</div>
`).join('')}
</div>
</div>
<div class="form-group">
<label>Примечания замерщика</label>
<div style="background:var(--bg);padding:12px;border-radius:12px;font-size:14px;color:var(--ink);line-height:1.5">Ниша под холодильник 650 мм (нестандарт). Вентиляция в угол — короб обходить. Трубы под окном — вынос 80 мм.</div>
</div>
<button class="btn-primary" onclick="go('report_send')">Отправить менеджеру →</button>
<button class="btn-secondary" onclick="go('measure_form')">← Редактировать размеры</button>
</div>
${nav('orders')}</div>`;
}
/* ─── REPORT SEND ─── */
function screenReportSend() {
return `<div class="page">
<div class="page-header">
<button class="back-btn" onclick="go('report_preview')"><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>Отправка менеджеру</h2>
</div>
${stepBar('report_preview')}
<div style="padding:16px">
<div class="form-group">
<label>Кому отправить</label>
${[
{name:'Елена Морозова',role:'Менеджер заявки',active:true},
{name:'Дизайн-отдел',role:'Проектировщики',active:false},
{name:'Директор',role:'Контроль качества',active:false},
].map(r => `
<div style="display:flex;align-items:center;gap:12px;padding:12px;border-radius:12px;border:1.5px solid ${r.active?'var(--accent)':'#E2E8F0'};background:${r.active?'#EFF6FF':'transparent'};margin-bottom:8px;cursor:pointer">
<div style="width:36px;height:36px;border-radius:50%;background:var(--accent);display:flex;align-items:center;justify-content:center;color:#fff;font-size:14px;font-weight:700">${r.name[0]}</div>
<div style="flex:1">
<div style="font-size:14px;font-weight:700;color:var(--ink)">${r.name}</div>
<div style="font-size:12px;color:var(--muted)">${r.role}</div>
</div>
<div style="width:20px;height:20px;border-radius:50%;border:2px solid ${r.active?'var(--accent)':'#CBD5E1'};background:${r.active?'var(--accent)':'transparent'};display:flex;align-items:center;justify-content:center">
${r.active?'<svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="3"><polyline points="20 6 9 17 4 12"/></svg>':''}
</div>
</div>
`).join('')}
</div>
<div class="form-group">
<label>Комментарий к отправке</label>
<textarea class="form-textarea" placeholder="Дополнительное сообщение менеджеру...">Замер выполнен. Обратите внимание на нишу под холодильник 650 мм — нестандартный размер. Все размеры и фото прикреплены.</textarea>
</div>
<div class="card" style="background:var(--bg);margin-bottom:16px">
<div style="display:flex;align-items:center;gap:10px">
<span style="font-size:20px">📎</span>
<div style="flex:1">
<div style="font-size:14px;font-weight:600;color:var(--ink)">Отчёт З-1042</div>
<div style="font-size:12px;color:var(--muted)">PDF · размеры + схема + 5 фото · ~2.4 МБ</div>
</div>
<span class="badge green">Готов</span>
</div>
</div>
<button class="btn-primary" style="background:var(--success)" onclick="go('report_done')">📤 Отправить отчёт</button>
<button class="btn-secondary" onclick="go('report_preview')">← Предпросмотр</button>
</div>
${nav('orders')}</div>`;
}
/* ─── REPORT DONE ─── */
function screenReportDone() {
return `<div class="page">
<div style="padding:60px 24px 24px;text-align:center">
<div style="width:84px;height:84px;background:#DCFCE7;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:44px;margin:0 auto 20px">✅</div>
<div style="font-size:24px;font-weight:800;color:var(--ink);margin-bottom:8px">Отчёт отправлен!</div>
<div style="font-size:15px;color:var(--muted);line-height:1.5;margin-bottom:32px">Менеджер <b style="color:var(--ink)">Елена Морозова</b> уведомлена. Замер #З-1042 завершён.</div>
<div class="card" style="text-align:left;margin-bottom:24px">
<div class="info-row"><span class="info-label">Заявка</span><span class="info-val">#З-1042</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">Кухня · 16,2 м²</span></div>
<div class="info-row"><span class="info-label">Отправлено</span><span class="info-val" style="color:var(--success);font-weight:800">21.05.2026, 11:22</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">5 снимков</span></div>
</div>
<button class="btn-primary" onclick="go('orders')">← К списку заявок</button>
<button class="btn-secondary" onclick="go('home')">На главную</button>
</div>
${nav('orders')}</div>`;
}
/* ─── HISTORY ─── */
function screenHistory() {
return `<div class="page">
<div class="page-header">
<h2>История замеров</h2>
<div class="header-action"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg></div>
</div>
<div style="padding:12px 16px 0">
<div style="position:relative;margin-bottom:12px">
<svg style="position:absolute;left:12px;top:50%;transform:translateY(-50%);color:var(--muted)" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
<input class="form-input" style="padding-left:38px" placeholder="Поиск по клиенту или адресу...">
</div>
</div>
<div class="chip-row">
<div class="chip active">Все (47)</div>
<div class="chip">Май (31)</div>
<div class="chip">Апрель (16)</div>
</div>
<div style="padding:0 16px">
<div class="section-label" style="margin-top:4px">21 мая 2026</div>
${[
{id:'З-1042',name:'Смирнова Ольга',addr:'ул. Рубинштейна, 7',type:'Кухня',pog:'14,5 п.м.',time:'10:30'},
].map(h => `
<div class="card success-border" onclick="go('report_preview')" style="cursor:pointer">
<div style="display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:8px">
<div>
<div style="font-size:15px;font-weight:700;color:var(--ink)">${h.name}</div>
<div style="font-size:12px;color:var(--muted);margin-top:2px">📍 ${h.addr} · ${h.time}</div>
</div>
<span class="badge green">Выполнен</span>
</div>
<div style="display:flex;justify-content:space-between;align-items:center">
<span style="font-size:12px;color:var(--muted)">${h.type} · #${h.id}</span>
<span style="font-size:13px;font-weight:700;color:var(--accent)">${h.pog}</span>
</div>
</div>
`).join('')}
<div class="section-label">20 мая 2026</div>
${[
{id:'З-1040',name:'Захаров Илья',addr:'пр. Литейный, 58',type:'2-комн. кв.',pog:'38,4 п.м.',time:'11:00'},
{id:'З-1039',name:'Попова Светлана',addr:'ул. Некрасова, 22',type:'Спальня + гардероб',pog:'12,1 п.м.',time:'14:00'},
].map(h => `
<div class="card success-border" onclick="go('report_preview')" style="cursor:pointer">
<div style="display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:8px">
<div>
<div style="font-size:15px;font-weight:700;color:var(--ink)">${h.name}</div>
<div style="font-size:12px;color:var(--muted);margin-top:2px">📍 ${h.addr} · ${h.time}</div>
</div>
<span class="badge green">Выполнен</span>
</div>
<div style="display:flex;justify-content:space-between;align-items:center">
<span style="font-size:12px;color:var(--muted)">${h.type} · #${h.id}</span>
<span style="font-size:13px;font-weight:700;color:var(--accent)">${h.pog}</span>
</div>
</div>
`).join('')}
<div class="section-label">19 мая 2026</div>
${[
{id:'З-1038',name:'Фёдорова Анна',addr:'ул. Садовая, 33',type:'Детская + спальня',pog:'22,6 п.м.',time:'14:30'},
{id:'З-1037',name:'Кузнецов Роман',addr:'Каменноостровский, 67',type:'Кухня-гостиная',pog:'16,8 п.м.',time:'10:00'},
].map(h => `
<div class="card success-border" onclick="go('report_preview')" style="cursor:pointer">
<div style="display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:8px">
<div>
<div style="font-size:15px;font-weight:700;color:var(--ink)">${h.name}</div>
<div style="font-size:12px;color:var(--muted);margin-top:2px">📍 ${h.addr} · ${h.time}</div>
</div>
<span class="badge green">Выполнен</span>
</div>
<div style="display:flex;justify-content:space-between;align-items:center">
<span style="font-size:12px;color:var(--muted)">${h.type} · #${h.id}</span>
<span style="font-size:13px;font-weight:700;color:var(--accent)">${h.pog}</span>
</div>
</div>
`).join('')}
</div>
${nav('history')}</div>`;
}
/* ─── PROFILE ─── */
function screenProfile() {
return `<div class="page">
<div class="page-header">
<h2>Профиль</h2>
<div class="header-action"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z"/></svg></div>
</div>
<div style="padding:20px 16px 0">
<div style="display:flex;align-items:center;gap:16px;margin-bottom:20px">
<div class="avatar lg" style="background:var(--accent2);color:var(--ink);font-size:24px">ИС</div>
<div>
<div style="font-size:20px;font-weight:800;color:var(--ink)">Игорь Соколов</div>
<div style="font-size:14px;color:var(--muted)">Замерщик · Старший</div>
<div style="margin-top:6px;display:flex;gap:6px">
<span class="badge green">Активен</span>
<span class="badge blue">Опыт 4 года</span>
</div>
</div>
</div>
<!-- Категория и загрузка -->
<div class="card" style="padding:14px 16px;margin-bottom:12px">
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:10px">
<div style="display:flex;align-items:center;gap:8px">
<span style="background:#4338CA;color:#fff;font-size:11px;font-weight:800;padding:3px 10px;border-radius:20px;letter-spacing:.03em">Кат.А</span>
<span style="font-size:12px;color:var(--muted)">Присвоена 15.01.2026</span>
</div>
<button onclick="go('my_questionnaire')" style="font-size:12px;font-weight:700;color:var(--accent);background:rgba(0,62,126,.07);border:none;border-radius:8px;padding:5px 10px;cursor:pointer">Анкета →</button>
</div>
<div style="display:flex;gap:8px;margin-bottom:10px">
<div style="flex:1;background:rgba(67,56,202,.07);border-radius:8px;padding:8px 10px;text-align:center">
<div style="font-size:18px;font-weight:800;color:#4338CA">79%</div>
<div style="font-size:10px;color:var(--muted);font-weight:600;margin-top:1px">загрузка</div>
</div>
<div style="flex:1;background:rgba(0,62,126,.07);border-radius:8px;padding:8px 10px;text-align:center">
<div style="font-size:18px;font-weight:800;color:var(--accent)">600 ₽</div>
<div style="font-size:10px;color:var(--muted);font-weight:600;margin-top:1px">ставка/замер</div>
</div>
<div style="flex:1;background:rgba(16,185,129,.07);border-radius:8px;padding:8px 10px;text-align:center">
<div style="font-size:18px;font-weight:800;color:#059669">4/д</div>
<div style="font-size:10px;color:var(--muted);font-weight:600;margin-top:1px">макс. замеров</div>
</div>
</div>
<div style="height:6px;border-radius:99px;background:rgba(0,0,0,.07);overflow:hidden">
<div style="height:100%;width:79%;border-radius:99px;background:linear-gradient(90deg,#4338CA,#6366F1)"></div>
</div>
</div>
<div class="earnings-card">
<div style="display:flex;justify-content:space-between">
<div>
<div style="font-size:12px;color:rgba(255,255,255,.65);margin-bottom:4px">Май 2026</div>
<div style="font-size:28px;font-weight:800">18 600 ₽</div>
</div>
<div style="text-align:right">
<div style="font-size:12px;color:rgba(255,255,255,.65);margin-bottom:4px">Рейтинг</div>
<div style="font-size:28px;font-weight:800">4.8 ⭐</div>
</div>
</div>
<div style="display:flex;gap:16px;margin-top:14px;padding-top:14px;border-top:1px solid rgba(255,255,255,.2)">
<div><div style="font-size:11px;color:rgba(255,255,255,.6)">Замеров</div><div style="font-size:16px;font-weight:700">31</div></div>
<div><div style="font-size:11px;color:rgba(255,255,255,.6)">Отчётов</div><div style="font-size:16px;font-weight:700">29</div></div>
<div><div style="font-size:11px;color:rgba(255,255,255,.6)">Всего п.м.</div><div style="font-size:16px;font-weight:700">412 п.м.</div></div>
</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" style="color:var(--accent)">+7 921 567-89-01</span></div>
<div class="info-row"><span class="info-label">Telegram</span><span class="info-val">@sokolov_msr</span></div>
<div class="info-row"><span class="info-label">Менеджер</span><span class="info-val">Елена Морозова</span></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">247 замеров</span></div>
<div class="info-row"><span class="info-label">Ср. время замера</span><span class="info-val">48 минут</span></div>
<div class="info-row"><span class="info-label">Точность</span><span class="info-val" style="color:var(--success)">98,4%</span></div>
<div class="info-row"><span class="info-label">Отчёты вовремя</span><span class="info-val" style="color:var(--success)">97,1%</span></div>
<div class="info-row"><span class="info-label">С нами с</span><span class="info-val">Июнь 2022</span></div>
</div>
<button class="btn-secondary" style="margin-bottom:8px">🚪 Выйти</button>
</div>
${nav('profile')}</div>`;
}
/* ─── MY QUESTIONNAIRE (Measurer) ─── */
function screenMyQuestionnaire() {
if (!window._qSaved) window._qSaved = false;
if (!window._qCar) window._qCar = 'yes';
if (!window._qEquip) window._qEquip = {laser:true,tape:true,level:true,digital:false,theodolite:false,photo360:false};
if (!window._qTypes) window._qTypes = {flat:true,house:false,office:true,commercial:false,newbuild:true};
if (!window._qZones) window._qZones = {center:true,north:true,south:false,east:false,west:false};
function chk(key, store, label, note) {
var on = window[store][key];
return '<label style="display:flex;align-items:flex-start;gap:10px;padding:9px 0;border-bottom:1px solid rgba(0,0,0,.05);cursor:pointer">'
+'<div onclick="(function(){window[\''+store+'\'][\''+key+'\']=!window[\''+store+'\'][\''+key+'\'];'
+'document.getElementById(\'screen\').innerHTML=renderScreen(\'my_questionnaire\')})()"'
+' style="width:20px;height:20px;border-radius:5px;border:2px solid '+(on?'var(--accent)':'#D1D5DB')+';background:'+(on?'var(--accent)':'transparent')+';flex-shrink:0;margin-top:1px;display:flex;align-items:center;justify-content:center">'
+(on?'<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="3"><polyline points="20 6 9 17 4 12"/></svg>':'')
+'</div>'
+'<div><div style="font-size:13px;color:var(--ink);font-weight:500">'+label+'</div>'
+(note?'<div style="font-size:11px;color:var(--muted);margin-top:1px">'+note+'</div>':'')
+'</div></label>';
}
var saved = window._qSaved;
return '<div class="page">'
+'<div class="page-header">'
+'<button class="back-btn" onclick="go(\'profile\')"><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>Моя анкета</h2>'
+'</div>'
+'<div style="padding:0 16px 20px">'
// Info banner
+'<div style="background:rgba(0,62,126,.06);border:1px solid rgba(0,62,126,.15);border-radius:10px;padding:10px 14px;margin:12px 0;display:flex;gap:8px;align-items:flex-start">'
+'<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="var(--accent)" stroke-width="2" style="flex-shrink:0;margin-top:1px"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>'
+'<div style="font-size:12px;color:var(--ink);line-height:1.5">Данные видны директору. При изменениях (новое оборудование, зона, тип объекта) — директор получит уведомление.</div>'
+'</div>'
// Equipment
+'<div class="card" style="padding:14px 16px;margin-bottom:10px">'
+'<div style="font-size:11px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.05em;margin-bottom:4px">Измерительное оборудование</div>'
+'<div style="font-size:11px;color:var(--muted);margin-bottom:10px">Что есть в наличии</div>'
+ chk('laser', '_qEquip', 'Лазерный дальномер', 'основной инструмент')
+ chk('tape', '_qEquip', 'Рулетка 510 м', null)
+ chk('level', '_qEquip', 'Нивелир / уровень', null)
+ chk('digital', '_qEquip', 'Цифровой угломер', 'для нестандартных углов')
+ chk('theodolite', '_qEquip', 'Теодолит / тахеометр', 'для больших объектов')
+ chk('photo360', '_qEquip', '360° камера', 'для фиксации помещения')
+'</div>'
// Object types
+'<div class="card" style="padding:14px 16px;margin-bottom:10px">'
+'<div style="font-size:11px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.05em;margin-bottom:10px">Типы объектов</div>'
+ chk('flat', '_qTypes', 'Квартиры', null)
+ chk('house', '_qTypes', 'Частные дома / коттеджи', null)
+ chk('office', '_qTypes', 'Офисы', null)
+ chk('commercial', '_qTypes', 'Коммерция (магазины, кафе)', null)
+ chk('newbuild', '_qTypes', 'Новостройки (без отделки)', 'сложные объекты')
+'</div>'
// Transport
+'<div class="card" style="padding:14px 16px;margin-bottom:10px">'
+'<div style="font-size:11px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.05em;margin-bottom:10px">Личный автомобиль</div>'
+'<div style="display:flex;gap:8px">'
+'<button onclick="(function(){window._qCar=\'yes\';document.getElementById(\'screen\').innerHTML=renderScreen(\'my_questionnaire\')})()"'
+' style="flex:1;padding:12px;border-radius:10px;border:2px solid '+(window._qCar==='yes'?'var(--accent)':'rgba(0,0,0,.1)')+';background:'+(window._qCar==='yes'?'rgba(0,62,126,.07)':'transparent')+';cursor:pointer;font-size:13px;font-weight:700;color:'+(window._qCar==='yes'?'var(--accent)':'var(--muted)')+'">'
+'🚗 Есть авто</button>'
+'<button onclick="(function(){window._qCar=\'no\';document.getElementById(\'screen\').innerHTML=renderScreen(\'my_questionnaire\')})()"'
+' style="flex:1;padding:12px;border-radius:10px;border:2px solid '+(window._qCar==='no'?'var(--accent)':'rgba(0,0,0,.1)')+';background:'+(window._qCar==='no'?'rgba(0,62,126,.07)':'transparent')+';cursor:pointer;font-size:13px;font-weight:700;color:'+(window._qCar==='no'?'var(--accent)':'var(--muted)')+'">'
+'🚌 Без авто</button>'
+'</div>'
+'</div>'
// Work zones
+'<div class="card" style="padding:14px 16px;margin-bottom:16px">'
+'<div style="font-size:11px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.05em;margin-bottom:4px">Зона работы</div>'
+'<div style="font-size:11px;color:var(--muted);margin-bottom:10px">Комфортные районы</div>'
+ chk('center', '_qZones', 'Центр города', null)
+ chk('north', '_qZones', 'Север', null)
+ chk('south', '_qZones', 'Юг', null)
+ chk('east', '_qZones', 'Восток', null)
+ chk('west', '_qZones', 'Запад / ЗАД', null)
+'</div>'
// Save
+(saved
? '<div style="background:rgba(16,185,129,.1);border:1px solid rgba(16,185,129,.3);border-radius:12px;padding:14px;text-align:center;font-size:14px;font-weight:700;color:#065f46">✓ Сохранено · Директор уведомлён</div>'
: '<button onclick="(function(){window._qSaved=true;document.getElementById(\'screen\').innerHTML=renderScreen(\'my_questionnaire\')})()"'
+' style="width:100%;padding:16px;background:var(--accent);color:#fff;border:none;border-radius:12px;font-size:15px;font-weight:700;cursor:pointer">Сохранить изменения</button>'
)
+'<div style="text-align:center;font-size:11px;color:var(--muted);margin-top:8px">Последнее обновление: 20.05.2026 · 09:30</div>'
+'</div>'
+ nav('profile')
+'</div>';
}
/* ─── ACCEPT JOB ─── */
function screenAcceptJob() {
const bk = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M15 18l-6-6 6-6"/></svg>';
return `<div class="page">
<div class="page-header">
<button class="back-btn" onclick="go('schedule')">${bk}</button>
<h2>Новая заявка</h2>
<span class="badge yellow" style="font-size:11px">Требует ответа</span>
</div>
<div style="padding:16px">
<div class="card accent-border">
<div style="font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);margin-bottom:6px">Клиент</div>
<div style="font-size:20px;font-weight:800;color:var(--ink);margin-bottom:4px">Петрова Ирина Николаевна</div>
<div style="font-size:13px;color:var(--muted)">📍 ул. Бассейная, 12, кв. 7 · 3 этаж</div>
<div style="font-size:13px;color:var(--muted);margin-top:2px">📞 +7 921 876-54-32</div>
</div>
<div class="card">
<div class="info-row"><span class="info-label">Тип</span><span class="info-val">Кухня-гостиная · ~22 м²</span></div>
<div class="info-row"><span class="info-label">Дата/время</span><span class="info-val" style="color:var(--accent);font-weight:700">22 мая (завтра) · 14:0015:30</span></div>
<div class="info-row"><span class="info-label">До объекта</span><span class="info-val">~25 мин · 8 км</span></div>
<div class="info-row"><span class="info-label">Заказ</span><span class="info-val">#З-1045</span></div>
<div class="info-row"><span class="info-label">Менеджер</span><span class="info-val">Елена Морозова</span></div>
</div>
<div class="card warn-border">
<div style="font-size:12px;font-weight:700;color:var(--warn);text-transform:uppercase;letter-spacing:.05em;margin-bottom:6px">⚠️ Примечание</div>
<div style="font-size:13px;color:var(--ink);line-height:1.5">Стеклопакеты нестандартные — мансардный тип. Взять удлинённые дюбели и угловые адаптеры.</div>
</div>
<div style="background:linear-gradient(135deg,#E2E8F0,#F1F5F9);border-radius:14px;height:120px;display:flex;align-items:center;justify-content:center;margin-bottom:16px;position:relative;overflow:hidden;cursor:pointer">
<div style="font-size:36px">🗺️</div>
<div style="position:absolute;bottom:10px;left:12px;background:#fff;border-radius:8px;padding:4px 10px;font-size:12px;font-weight:700;color:var(--ink);box-shadow:0 2px 8px rgba(0,0,0,.15)">📍 ул. Бассейная, 12</div>
<div style="position:absolute;top:10px;right:12px;background:#fff;border-radius:8px;padding:4px 10px;font-size:11px;font-weight:600;color:var(--muted)">8 км · ~25 мин</div>
</div>
<button class="btn-primary" style="background:var(--success);margin-bottom:8px" onclick="go('schedule')">✅ Принять заявку</button>
<button class="btn-secondary" style="border-color:var(--danger);color:var(--danger)" onclick="go('schedule')">✕ Не смогу выехать</button>
</div>
${nav('')}</div>`;
}
/* ─── SCHEDULE ─── */
function screenSchedule() {
const days = [
{d:'Пн',n:19,count:2},{d:'Вт',n:20,count:3},{d:'Ср',n:21,active:true,count:3},
{d:'Чт',n:22,count:1,new:true},{d:'Пт',n:23,count:2},{d:'Сб',n:24,count:0},{d:'Вс',n:25,count:0}
];
const today = [
{time:'09:00','end':'10:30',name:'Корнилов Виктор',addr:'пр. Невский, 120, кв. 5',type:'Гостиная + прихожая',status:'done'},
{time:'13:00','end':'14:30',name:'Смирнова Ольга',addr:'ул. Рубинштейна, 7, кв. 18',type:'Кухня',status:'active'},
{time:'16:00','end':'17:30',name:'Лебедева Марина',addr:'ул. Восстания, 42, кв. 31',type:'Спальня + гардероб',status:'upcoming'},
];
return `<div class="page">
<div class="page-header">
<h2>Расписание</h2>
<span style="font-size:13px;color:var(--muted);font-weight:500">Май 2026</span>
</div>
<div style="background:var(--card);padding:12px 16px 14px;border-bottom:1px solid rgba(0,0,0,.06);display:flex;gap:4px">
${days.map(d => `
<div style="display:flex;flex-direction:column;align-items:center;gap:4px;flex:1;cursor:pointer">
<div style="font-size:10px;color:var(--muted);font-weight:600">${d.d}</div>
<div style="width:34px;height:34px;border-radius:50%;display:flex;align-items:center;justify-content:center;background:${d.active?'var(--accent)':'transparent'}">
<span style="font-size:13px;font-weight:700;color:${d.active?'#fff':'var(--ink)'}">${d.n}</span>
</div>
${d.count>0?`<div style="width:6px;height:6px;border-radius:50%;background:${d.new?'var(--warn)':d.active?'rgba(255,255,255,.6)':'var(--accent)'}"></div>`:'<div style="height:6px"></div>'}
</div>
`).join('')}
</div>
<div class="section-label">Среда, 21 мая · 3 замера</div>
<div style="padding:0 16px">
${today.map(s => `
<div class="card ${s.status==='done'?'success-border':s.status==='active'?'accent-border':''}" onclick="go('order_detail')" style="cursor:pointer">
<div style="display:flex;gap:12px;align-items:flex-start">
<div style="min-width:58px;text-align:center">
<div style="font-size:12px;font-weight:700;color:${s.status==='active'?'var(--accent)':s.status==='done'?'var(--success)':'var(--muted)'}">${s.time}</div>
<div style="width:2px;height:18px;background:${s.status==='done'?'var(--success)':s.status==='active'?'var(--accent)':'#E2E8F0'};margin:4px auto"></div>
<div style="font-size:10px;color:var(--muted)">${s.end}</div>
</div>
<div style="flex:1">
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:3px">
<div style="font-size:15px;font-weight:700;color:var(--ink)">${s.name}</div>
<span class="badge ${s.status==='done'?'green':s.status==='active'?'blue':'gray'}">${s.status==='done'?'Выполнен':s.status==='active'?'Активный':'Назначен'}</span>
</div>
<div style="font-size:12px;color:var(--muted)">📍 ${s.addr}</div>
<div style="font-size:12px;color:var(--muted);margin-top:1px">🏠 ${s.type}</div>
</div>
</div>
</div>
`).join('')}
</div>
<div class="section-label">Четверг, 22 мая · 1 замер <span class="badge yellow" style="font-size:10px;margin-left:4px">Новая</span></div>
<div style="padding:0 16px">
<div class="card warn-border" onclick="go('accept_job')" style="cursor:pointer">
<div style="display:flex;gap:12px;align-items:flex-start">
<div style="min-width:58px;text-align:center">
<div style="font-size:12px;font-weight:700;color:var(--warn)">14:00</div>
</div>
<div style="flex:1">
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:3px">
<div style="font-size:15px;font-weight:700;color:var(--ink)">Петрова Ирина</div>
<span class="badge yellow">Требует ответа</span>
</div>
<div style="font-size:12px;color:var(--muted)">📍 ул. Бассейная, 12, кв. 7</div>
<div style="font-size:12px;color:var(--muted);margin-top:1px">🏠 Кухня-гостиная · ~22 м²</div>
</div>
</div>
</div>
</div>
<div class="section-label">Статистика недели</div>
<div style="padding:0 16px 8px">
<div class="card">
<div style="display:flex;justify-content:space-around;text-align:center">
<div><div style="font-size:22px;font-weight:800;color:var(--ink)">11</div><div style="font-size:11px;color:var(--muted)">Замеров</div></div>
<div><div style="font-size:22px;font-weight:800;color:var(--ink)">6 600 ₽</div><div style="font-size:11px;color:var(--muted)">Заработано</div></div>
<div><div style="font-size:22px;font-weight:800;color:var(--success)">4.9 ⭐</div><div style="font-size:11px;color:var(--muted)">Рейтинг</div></div>
</div>
</div>
</div>
${nav('schedule')}</div>`;
}
// init
go('home');
</script>
</body>
</html>