527 lines
16 KiB
HTML
527 lines
16 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="ru">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||
<title>Прототип</title>
|
||
<style>
|
||
@import url('https://fonts.googleapis.com/css2?family=Manrope:wght@400;600;700&display=swap');
|
||
|
||
* {
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
html,
|
||
body {
|
||
margin: 0;
|
||
padding: 0;
|
||
height: 100%;
|
||
font-family: 'Manrope', system-ui, sans-serif;
|
||
color: #1b1f23;
|
||
background: #eef1f4;
|
||
}
|
||
|
||
.app {
|
||
height: 100%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 12px;
|
||
padding: 72px 16px 18px;
|
||
background: #eef1f4;
|
||
}
|
||
|
||
.screen-title {
|
||
font-size: 20px;
|
||
font-weight: 800;
|
||
letter-spacing: -0.02em;
|
||
color: #14171c;
|
||
}
|
||
|
||
.screen-subtitle {
|
||
margin-top: 6px;
|
||
font-size: 12px;
|
||
color: rgba(27, 31, 35, 0.65);
|
||
}
|
||
|
||
.analysis-hero {
|
||
height: 100%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
text-align: center;
|
||
gap: 10px;
|
||
padding: 8px 12px;
|
||
}
|
||
|
||
.analysis-sub {
|
||
font-size: 12px;
|
||
color: rgba(27, 31, 35, 0.6);
|
||
}
|
||
|
||
.card {
|
||
background: transparent;
|
||
border-radius: 12px;
|
||
border: none;
|
||
padding: 0;
|
||
box-shadow: none;
|
||
}
|
||
|
||
.card.main {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 10px;
|
||
}
|
||
|
||
.section-title {
|
||
font-size: 11px;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.12em;
|
||
color: rgba(27, 31, 35, 0.45);
|
||
}
|
||
|
||
.media-count {
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
color: rgba(27, 31, 35, 0.7);
|
||
}
|
||
|
||
.media-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(3, 1fr);
|
||
gap: 6px;
|
||
margin-top: 12px;
|
||
}
|
||
|
||
.thumb {
|
||
position: relative;
|
||
height: 64px;
|
||
border-radius: 10px;
|
||
background-size: cover;
|
||
background-position: center;
|
||
overflow: hidden;
|
||
border: 1px solid rgba(27, 31, 35, 0.08);
|
||
}
|
||
|
||
.thumb::after {
|
||
content: '';
|
||
position: absolute;
|
||
inset: 0;
|
||
background: linear-gradient(180deg, rgba(0, 0, 0, 0) 40%, rgba(0, 0, 0, 0.35));
|
||
}
|
||
|
||
.thumb.video::before {
|
||
content: '▶';
|
||
position: absolute;
|
||
top: 8px;
|
||
left: 8px;
|
||
width: 20px;
|
||
height: 20px;
|
||
border-radius: 999px;
|
||
background: rgba(0, 0, 0, 0.5);
|
||
color: #fff;
|
||
font-size: 10px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
z-index: 1;
|
||
}
|
||
|
||
.thumb span {
|
||
position: absolute;
|
||
bottom: 6px;
|
||
left: 6px;
|
||
font-size: 10px;
|
||
font-weight: 600;
|
||
color: #fff;
|
||
z-index: 1;
|
||
}
|
||
|
||
.loader {
|
||
height: 8px;
|
||
background: rgba(15, 76, 129, 0.12);
|
||
border-radius: 999px;
|
||
overflow: hidden;
|
||
width: 140px;
|
||
}
|
||
|
||
.loader__bar {
|
||
height: 100%;
|
||
width: 0;
|
||
background: linear-gradient(90deg, #0f4c81, #4f8fc7);
|
||
border-radius: inherit;
|
||
transition: width 0.4s ease;
|
||
}
|
||
|
||
.hint {
|
||
font-size: 11px;
|
||
color: rgba(27, 31, 35, 0.55);
|
||
}
|
||
|
||
.table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
font-size: 11px;
|
||
margin-top: 12px;
|
||
}
|
||
|
||
.table th,
|
||
.table td {
|
||
padding: 6px 6px;
|
||
text-align: left;
|
||
border-bottom: 1px solid rgba(27, 31, 35, 0.08);
|
||
}
|
||
|
||
.table th {
|
||
color: rgba(27, 31, 35, 0.55);
|
||
font-weight: 600;
|
||
}
|
||
|
||
.total {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 8px 10px;
|
||
border-radius: 10px;
|
||
background: #f0f2f4;
|
||
font-size: 12px;
|
||
font-weight: 700;
|
||
}
|
||
|
||
.q {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 14px;
|
||
height: 14px;
|
||
margin-left: 4px;
|
||
border-radius: 999px;
|
||
background: rgba(15, 76, 129, 0.12);
|
||
color: #0f4c81;
|
||
font-size: 10px;
|
||
font-weight: 700;
|
||
}
|
||
|
||
.accept-card {
|
||
display: grid;
|
||
grid-template-columns: 54px 1fr;
|
||
gap: 10px;
|
||
align-items: center;
|
||
margin-top: 12px;
|
||
padding: 10px;
|
||
border-radius: 12px;
|
||
background: #f0f2f4;
|
||
}
|
||
|
||
.accept-photo {
|
||
width: 54px;
|
||
height: 54px;
|
||
border-radius: 10px;
|
||
background-size: cover;
|
||
background-position: center;
|
||
border: 1px solid rgba(27, 31, 35, 0.08);
|
||
}
|
||
|
||
.accept-title {
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.accept-meta {
|
||
font-size: 11px;
|
||
color: rgba(27, 31, 35, 0.6);
|
||
}
|
||
|
||
.accept-note {
|
||
margin-top: 8px;
|
||
font-size: 11px;
|
||
color: rgba(27, 31, 35, 0.6);
|
||
}
|
||
|
||
.tag {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
padding: 2px 8px;
|
||
border-radius: 999px;
|
||
font-size: 10px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.tag.success {
|
||
background: rgba(31, 129, 84, 0.14);
|
||
color: #1f8154;
|
||
}
|
||
|
||
.tag.pending {
|
||
background: rgba(211, 135, 32, 0.15);
|
||
color: #b7741c;
|
||
}
|
||
|
||
.tag.info {
|
||
background: rgba(26, 77, 122, 0.14);
|
||
color: #1a4d7a;
|
||
}
|
||
|
||
.toggle-row {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-top: 12px;
|
||
padding: 8px 10px;
|
||
border-radius: 10px;
|
||
background: #f0f2f4;
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.switch {
|
||
position: relative;
|
||
width: 42px;
|
||
height: 22px;
|
||
}
|
||
|
||
.switch input {
|
||
opacity: 0;
|
||
width: 0;
|
||
height: 0;
|
||
}
|
||
|
||
.slider {
|
||
position: absolute;
|
||
cursor: pointer;
|
||
inset: 0;
|
||
background-color: #c7ced6;
|
||
transition: 0.2s;
|
||
border-radius: 999px;
|
||
}
|
||
|
||
.slider:before {
|
||
position: absolute;
|
||
content: '';
|
||
height: 18px;
|
||
width: 18px;
|
||
left: 2px;
|
||
top: 2px;
|
||
background-color: white;
|
||
transition: 0.2s;
|
||
border-radius: 50%;
|
||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
||
}
|
||
|
||
.switch input:checked + .slider {
|
||
background-color: #0f4c81;
|
||
}
|
||
|
||
.switch input:checked + .slider:before {
|
||
transform: translateX(20px);
|
||
}
|
||
|
||
.list {
|
||
display: grid;
|
||
gap: 8px;
|
||
margin-top: 12px;
|
||
}
|
||
|
||
.item {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 8px 10px;
|
||
border-radius: 10px;
|
||
background: #f0f2f4;
|
||
font-size: 12px;
|
||
}
|
||
|
||
.action {
|
||
border: none;
|
||
border-radius: 12px;
|
||
padding: 12px 14px;
|
||
font-size: 18px;
|
||
font-weight: 700;
|
||
cursor: pointer;
|
||
background: #0f4c81;
|
||
color: #fff;
|
||
box-shadow: 0 10px 20px rgba(15, 76, 129, 0.25);
|
||
transition: transform 0.2s ease, box-shadow 0.2s ease, opacity 0.2s ease;
|
||
}
|
||
|
||
.action:active {
|
||
transform: scale(0.98);
|
||
}
|
||
|
||
.action[disabled] {
|
||
opacity: 0.5;
|
||
cursor: not-allowed;
|
||
box-shadow: none;
|
||
transform: none;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="app">
|
||
<div class="card main">
|
||
<div id="screenContent"></div>
|
||
</div>
|
||
<button class="action" id="actionButton" aria-label="Дальше">›</button>
|
||
</div>
|
||
<script>
|
||
(function () {
|
||
var state = {
|
||
screen: 0,
|
||
loadingTimer: null,
|
||
loadingProgress: 0,
|
||
accepted: false
|
||
};
|
||
|
||
var screens = [
|
||
{
|
||
content: function () {
|
||
return (
|
||
'<div class="screen-title">Добавление объекта</div>' +
|
||
'<div class="media-grid">' +
|
||
'<div class="thumb" style="background-image:url(https://images.unsplash.com/photo-1502005097973-6a7082348e28?auto=format&fit=crop&w=600&q=60)"></div>' +
|
||
'<div class="thumb" style="background-image:url(https://images.unsplash.com/photo-1484154218962-a197022b5858?auto=format&fit=crop&w=600&q=60)"></div>' +
|
||
'<div class="thumb" style="background-image:url(https://images.unsplash.com/photo-1493809842364-78817add7ffb?auto=format&fit=crop&w=600&q=60)"></div>' +
|
||
'<div class="thumb" style="background-image:url(https://images.unsplash.com/photo-1502005097973-6a7082348e28?auto=format&fit=crop&w=600&q=60)"></div>' +
|
||
'<div class="thumb" style="background-image:url(https://images.unsplash.com/photo-1484154218962-a197022b5858?auto=format&fit=crop&w=600&q=60)"></div>' +
|
||
'<div class="thumb" style="background-image:url(https://images.unsplash.com/photo-1493809842364-78817add7ffb?auto=format&fit=crop&w=600&q=60)"></div>' +
|
||
'<div class="thumb video" style="background-image:url(https://images.unsplash.com/photo-1484154218962-a197022b5858?auto=format&fit=crop&w=600&q=60)"><span>Видео</span></div>' +
|
||
'<div class="thumb video" style="background-image:url(https://images.unsplash.com/photo-1502005097973-6a7082348e28?auto=format&fit=crop&w=600&q=60)"><span>Видео</span></div>' +
|
||
'<div class="thumb" style="background-image:url(https://images.unsplash.com/photo-1493809842364-78817add7ffb?auto=format&fit=crop&w=600&q=60)"></div>' +
|
||
'</div>'
|
||
);
|
||
},
|
||
onEnter: function () {},
|
||
onAction: function () {
|
||
state.screen = 1;
|
||
render();
|
||
}
|
||
},
|
||
{
|
||
content: function () {
|
||
return (
|
||
'<div class="analysis-hero">' +
|
||
'<div class="screen-title">Анализируем объект</div>' +
|
||
'<div class="analysis-sub">Формируем смету, этапы и критерии приемки</div>' +
|
||
'<div class="loader"><div class="loader__bar" id="loaderBar"></div></div>' +
|
||
'</div>'
|
||
);
|
||
},
|
||
onEnter: function () {
|
||
var bar = document.getElementById('loaderBar');
|
||
state.loadingProgress = 0;
|
||
if (state.loadingTimer) {
|
||
clearInterval(state.loadingTimer);
|
||
}
|
||
state.loadingTimer = setInterval(function () {
|
||
state.loadingProgress += 20;
|
||
if (bar) {
|
||
bar.style.width = state.loadingProgress + '%';
|
||
}
|
||
if (state.loadingProgress >= 100) {
|
||
clearInterval(state.loadingTimer);
|
||
state.loadingTimer = null;
|
||
state.screen = 2;
|
||
render();
|
||
}
|
||
}, 1000);
|
||
},
|
||
onAction: function () {}
|
||
},
|
||
{
|
||
content: function () {
|
||
return (
|
||
'<div class="screen-title">Готовая смета по вашему объекту</div>' +
|
||
'<div class="screen-subtitle">Ознакомьтесь с этапами работ и итоговой стоимостью.</div>' +
|
||
'<table class="table">' +
|
||
'<thead><tr><th>Работы</th><th>Старт</th><th>Финиш</th><th>Сумма</th></tr></thead>' +
|
||
'<tbody>' +
|
||
'<tr><td>Демонтаж<span class="q" title="Стены чистые, мусор вывезен">?</span></td><td>12.03</td><td>15.03</td><td>120 000 ₽</td></tr>' +
|
||
'<tr><td>Черновые работы<span class="q" title="Геометрия в допуске">?</span></td><td>16.03</td><td>24.03</td><td>340 000 ₽</td></tr>' +
|
||
'<tr><td>Электрика<span class="q" title="Маркировка и линии">?</span></td><td>25.03</td><td>28.03</td><td>180 000 ₽</td></tr>' +
|
||
'<tr><td>Чистовая отделка<span class="q" title="Без дефектов">?</span></td><td>29.03</td><td>08.04</td><td>410 000 ₽</td></tr>' +
|
||
'</tbody>' +
|
||
'</table>' +
|
||
'<div class="section-title" style="margin-top:8px;">Материалы</div>' +
|
||
'<table class="table">' +
|
||
'<thead><tr><th>Позиция</th><th>Объём</th><th>Сумма</th></tr></thead>' +
|
||
'<tbody>' +
|
||
'<tr><td>Штукатурка</td><td>120 м²</td><td>94 000 ₽</td></tr>' +
|
||
'<tr><td>Кабель</td><td>320 м</td><td>52 000 ₽</td></tr>' +
|
||
'<tr><td>Плитка</td><td>34 м²</td><td>126 000 ₽</td></tr>' +
|
||
'<tr><td>Смеси</td><td>48 меш.</td><td>37 000 ₽</td></tr>' +
|
||
'</tbody>' +
|
||
'</table>' +
|
||
'<div class="total" style="margin-top:8px;"><span>Итого</span><span>1 359 000 ₽</span></div>'
|
||
);
|
||
},
|
||
onEnter: function () {},
|
||
onAction: function () {
|
||
state.screen = 3;
|
||
render();
|
||
}
|
||
},
|
||
{
|
||
content: function () {
|
||
return (
|
||
'<div class="screen-title">Подтвердите выполнение этапа работ</div>' +
|
||
'<div class="accept-card">' +
|
||
'<div class="accept-photo" style="background-image:url(https://images.unsplash.com/photo-1484154218962-a197022b5858?auto=format&fit=crop&w=600&q=60)"></div>' +
|
||
'<div>' +
|
||
'<div class="accept-title">Черновые работы</div>' +
|
||
'<div class="accept-meta">Исполнитель: Смирнов А. · Фотоотчет загружен</div>' +
|
||
'</div>' +
|
||
'</div>' +
|
||
'<div class="toggle-row">' +
|
||
'<span>Подтвердить приемку</span>' +
|
||
'<label class="switch">' +
|
||
'<input type="checkbox" id="acceptToggle" ' + (state.accepted ? 'checked' : '') + ' />' +
|
||
'<span class="slider"></span>' +
|
||
'</label>' +
|
||
'</div>' +
|
||
'<div class="accept-note">Подтверждая приемку работ, вы переводите оплату исполнителю.</div>'
|
||
);
|
||
},
|
||
onEnter: function () {
|
||
var toggle = document.getElementById('acceptToggle');
|
||
if (toggle) {
|
||
toggle.addEventListener('change', function (event) {
|
||
state.accepted = event.target.checked;
|
||
render();
|
||
});
|
||
}
|
||
},
|
||
onAction: function () {
|
||
state.screen = 0;
|
||
state.accepted = false;
|
||
render();
|
||
}
|
||
}
|
||
];
|
||
|
||
var screenContent = document.getElementById('screenContent');
|
||
var actionButton = document.getElementById('actionButton');
|
||
|
||
function render() {
|
||
var screen = screens[state.screen];
|
||
screenContent.innerHTML = screen.content();
|
||
actionButton.disabled = state.screen === 1;
|
||
if (screen.onEnter) {
|
||
screen.onEnter();
|
||
}
|
||
}
|
||
|
||
actionButton.addEventListener('click', function () {
|
||
var screen = screens[state.screen];
|
||
if (screen.onAction) {
|
||
screen.onAction();
|
||
}
|
||
});
|
||
|
||
render();
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|