medicaments-spb/index.html
2026-01-13 18:29:50 +03:00

279 lines
8.8 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

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

<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Проверка наличия льготных препаратов</title>
<link rel="icon" type="image/png" href="/favicon.png">
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
background-color: #f5f5f5;
}
.container {
max-width: 700px;
margin: 0 auto;
background-color: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
h2 {
color: #333;
text-align: center;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
th, td {
border: 1px solid #ddd;
padding: 12px;
text-align: left;
}
th {
background-color: #195695;
color: white;
}
u {
border-bottom: 1px dashed #cccccc;
text-decoration: none;
cursor: help;
}
.name {
background-color: #e6f2ff;
text-align: center;
color: #195695;
}
.loading {
text-align: center;
padding: 20px;
font-style: italic;
color: #666;
}
.error {
color: red;
text-align: center;
padding: 20px;
}
.note {
margin-top: 10px;
font-size: small;
text-align: center;
}
.search-container {
display: flex;
gap: 10px;
justify-content: center;
}
#searchInput {
flex: 1;
min-width: 220px;
max-width: 280px;
padding: 10px;
font-size: 16px;
border: 1px solid #ccc;
border-radius: 4px;
}
#searchButton {
padding: 10px 20px;
font-size: 16px;
background-color: #6d4203;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
#searchButton:hover {
background-color: #8f6f3f;
}
/* Responsive behavior for smaller screens */
@media (max-width: 600px) {
.search-container {
display: flex;
flex-direction: column;
gap: 10px;
flex-wrap: wrap;
align-items: stretch;
}
#searchInput {
align-self: center;
margin-bottom: 10px;
}
#searchButton {
align-self: center;
width: 90%;
}
}
@media (hover: none) {
u {
border-bottom: none !important;
}
}
</style>
</head>
<body>
<div class="container">
<h2>Проверка наличия льготных препаратов<br/>в аптеках Санкт-Петербурга</h2>
<div class="search-container">
<input type="text" id="searchInput" placeholder="Введите название препарата">
<button id="searchButton">Найти</button>
</div>
<div id="content"></div>
</div>
<script>
function fetchData(name) {
document.getElementById('content').innerHTML = '<div class="loading">Загрузка данных...</div>';
name = name.replaceAll(' ', '_');
fetch(`/api-proxy?operation=getMedicament&filter=${name}`)
.then(response => response.json())
.then(data => displayData(processData(data)))
.catch(error => showError(error));
}
// Extract needed data from JSON
function processData(data) {
if (data['status'] !== "SUCCESS")
return data['errors'];
const results = data['model']['result'];
let processedData = [];
results.forEach(result => {
result['districts'].forEach(district => {
district['apothecaries'].forEach(apothecary => {
let address = apothecary['address'];
const regex = /\d*, [а-яА-Я\-. ]+, (.+) \*.+/;
let m;
if ((m = regex.exec(address)) !== null)
address = m[1];
else
address = address.substring(0, address.indexOf('*'));
processedData.push({
name: result['name'],
apothecary: apothecary['name'] + '<br/><i>' + address + '</i>',
countFederal: apothecary['ost1'],
countRegional: apothecary['ost2'],
timestamp: apothecary['date']
});
});
});
});
return processedData;
}
// Display the data in a table format
function displayData(data) {
let htmlContent;
if (typeof(data) === 'object') {
htmlContent = `
<table>
<thead>
<tr>
<th>Аптека</th>
<th style="width: 75px; text-align: center;">Остаток<br/>(<u title="региональная льгота">рег</u>/<u title="федеральная льгота">фед</u>)</th>
</tr>
</thead>
<tbody>
`;
// Group consecutive items with same name and generate merged cells
if (data.length > 0) {
let currentName = data[0].name;
let rowCount = 1;
let rowStartIndex = 0;
for (let i = 1; i <= data.length; i++) {
if (i < data.length && data[i].name === currentName) {
rowCount++;
} else {
// Generate rows for the current group
htmlContent += '<tr><td colspan="2"></td></tr>';
htmlContent += `<tr><td colspan="2" class="name"><b>${currentName}</b></td></tr>`;
for (let j = rowStartIndex; j < i; j++) {
const item = data[j];
htmlContent += `
<tr>
<td>${item.apothecary}</td>
<td style="text-align: center;">${item.countRegional} / ${item.countFederal}</td>
</tr>`;
}
// Reset for next group
if (i < data.length) {
currentName = data[i].name;
rowCount = 1;
rowStartIndex = i;
}
}
}
}
htmlContent += `
</tbody>
</table>
`;
htmlContent += '<div class="note">Информация получена через <a href="https://eservice.gu.spb.ru/portalFront/resources/portal.html#medicament" target="_blank" style="text-decoration: none;">портал госуслуг Санкт-Петербурга</a>.</div>'
}
else
htmlContent = `<div class="error">${data}</div>`;
document.getElementById('content').innerHTML = htmlContent;
}
function showError(error) {
document.getElementById('content').innerHTML = `<div class="error">Ошибка: ${error.message}</div>`;
}
function search() {
const name = document.getElementById('searchInput').value.trim();
if (name) {
saveInputValue();
fetchData(name);
}
}
// Save input value to localStorage
function saveInputValue() {
const name = document.getElementById('searchInput').value;
localStorage.setItem('medicamentName', name);
}
// Restore input value from localStorage
function restoreInputValue() {
const savedValue = localStorage.getItem('medicamentName');
if (savedValue) {
document.getElementById('searchInput').value = savedValue;
return savedValue;
}
return null;
}
window.addEventListener('load', () => {
let name = restoreInputValue();
if (name !== null)
fetchData(name);
});
document.getElementById('searchButton').addEventListener('click', search);
document.getElementById('searchInput').addEventListener('keypress', (e) => {
if (e.key === 'Enter')
search();
});
</script>
</body>
</html>