Загрузка данных
<!DOCTYPE html>
<html lang="ru">
<head>
<base target="_top">
<meta name="viewport"
content="width=device-width, initial-scale=1">
<style>
* { box-sizing: border-box; }
body {
margin: 0;
padding: 20px;
background: #f3f5f9;
color: #202124;
font-family: -apple-system, BlinkMacSystemFont,
"Segoe UI", Arial, sans-serif;
}
.app {
max-width: 440px;
margin: 20px auto;
padding: 24px;
border-radius: 20px;
background: white;
box-shadow: 0 5px 25px #00000010;
}
h1 { margin: 0 0 8px; font-size: 25px; }
.subtitle {
color: #777;
font-size: 14px;
margin-bottom: 25px;
}
label {
display: block;
margin: 18px 0 7px;
font-size: 14px;
font-weight: 600;
}
input, select {
width: 100%;
padding: 14px;
font-size: 17px;
border: 1px solid #ddd;
border-radius: 10px;
background: white;
}
input:focus, select:focus {
outline: 2px solid #4285f4;
}
.fixed {
margin-top: 24px;
padding: 16px;
background: #eef5ff;
border-radius: 12px;
display: flex;
justify-content: space-between;
}
.hint {
font-size: 12px;
color: #777;
margin-top: 7px;
}
button {
width: 100%;
padding: 16px;
margin-top: 24px;
border: none;
border-radius: 12px;
background: #2563eb;
color: white;
font-size: 16px;
font-weight: 600;
cursor: pointer;
}
button:disabled { opacity: .5; }
#status {
margin-top: 18px;
font-size: 14px;
white-space: pre-line;
}
.success { color: #16803c; }
.error { color: #c62828; }
</style>
</head>
<body>
<div class="app">
<h1>Мои счётчики</h1>
<div class="subtitle">
Коммунальные платежи · 2026
</div>
<label for="month">Месяц</label>
<select id="month" onchange="loadReadings()">
<option value="1">Январь</option>
<option value="2">Февраль</option>
<option value="3">Март</option>
<option value="4">Апрель</option>
<option value="5">Май</option>
<option value="6">Июнь</option>
<option value="7">Июль</option>
<option value="8">Август</option>
<option value="9">Сентябрь</option>
<option value="10">Октябрь</option>
<option value="11">Ноябрь</option>
<option value="12">Декабрь</option>
</select>
<label for="hot">Горячая вода, м³</label>
<input id="hot" type="text" inputmode="decimal"
placeholder="Сканировать показание">
<label for="cold">Холодная вода, м³</label>
<input id="cold" type="text" inputmode="decimal"
placeholder="Сканировать показание">
<label for="electric">Электроэнергия, кВт·ч</label>
<input id="electric" type="text" inputmode="decimal"
placeholder="Сканировать показание">
<p class="hint">
На iPhone используйте «Сканировать текст»
в меню поля ввода.
</p>
<label for="heating">Отопление, ₽</label>
<input id="heating" type="text" inputmode="decimal"
placeholder="Например, 850">
<p class="hint">
Если отопления нет, введите 0.
</p>
<div class="fixed">
<span>Фиксированный платёж</span>
<strong>1 100 ₽</strong>
</div>
<button id="save" onclick="saveData()">
Сохранить показания
</button>
<div id="status" role="status"></div>
</div>
<script>
const fields = ['hot', 'cold', 'electric', 'heating'];
const monthSelect = document.getElementById('month');
monthSelect.value = String(new Date().getMonth() + 1);
function setStatus(message, type = '') {
const element = document.getElementById('status');
element.textContent = message;
element.className = type;
}
function loadReadings() {
fields.forEach(id => {
document.getElementById(id).value = '';
});
setStatus('Загрузка данных...');
google.script.run
.withSuccessHandler(data => {
fields.forEach(id => {
document.getElementById(id).value = data[id];
});
setStatus('');
})
.withFailureHandler(error => {
setStatus(error.message, 'error');
})
.getReadings(monthSelect.value);
}
function saveData() {
const data = { month: monthSelect.value };
fields.forEach(id => {
data[id] = document.getElementById(id).value.trim();
});
if (fields.some(id => data[id] === '')) {
setStatus('Заполните все поля. Для отопления без начислений укажите 0.', 'error');
return;
}
if (!confirm('Сохранить показания за выбранный месяц?')) {
return;
}
const button = document.getElementById('save');
button.disabled = true;
setStatus('Сохраняем показания...');
google.script.run
.withSuccessHandler(result => {
button.disabled = false;
setStatus(
'Показания сохранены!\n' +
'Месяц: ' + result.month + '\n' +
'Итого к оплате: ' + result.total,
'success'
);
})
.withFailureHandler(error => {
button.disabled = false;
setStatus('Ошибка: ' + error.message, 'error');
})
.saveReadings(data);
}
loadReadings();
</script>
</body>
</html>