ва поисковых поля (Google и Яндекс) с логотипами, адаптивные, крупный шрифт, занимают всю ширину

This commit is contained in:
Vlad 2025-07-11 12:33:44 +03:00
parent a4f6dd4d93
commit c3b0c19758
2 changed files with 61 additions and 5 deletions

View File

@ -12,6 +12,7 @@
- Поддержка настройки времени кэширования погоды через weather.cache_ttl (минуты, по умолчанию 60) - Поддержка настройки времени кэширования погоды через weather.cache_ttl (минуты, по умолчанию 60)
- В шапке вместо приветствия теперь крупно текущее время, дата на русском - В шапке вместо приветствия теперь крупно текущее время, дата на русском
- Дата и время теперь на одной строке, одинакового размера и цвета, хорошо видны на тёмном фоне - Дата и время теперь на одной строке, одинакового размера и цвета, хорошо видны на тёмном фоне
- Два поисковых поля (Google и Яндекс) с логотипами, адаптивные, крупный шрифт, занимают всю ширину
## [init] Стартовая инициализация структуры Flask-приложения ## [init] Стартовая инициализация структуры Flask-приложения
- Создана структура каталогов: templates/, static/ - Создана структура каталогов: templates/, static/

View File

@ -14,15 +14,30 @@
<body style="--color-primary: #FFFDEA; --color-accent: #5c5c5c; --color-background: #1a1a1a;"> <body style="--color-primary: #FFFDEA; --color-accent: #5c5c5c; --color-background: #1a1a1a;">
<div id="root"> <div id="root">
<div class="Layout_Container__HIHX7"> <div class="Layout_Container__HIHX7">
<div><input type="text" class="SearchBar_SearchBar__MQiwu" placeholder="Поиск..."></div> <div style="display:flex; flex-direction:row; align-items:center; gap:18px; margin-bottom:12px; width:100%;">
<form id="google-search" style="display:flex; align-items:center; gap:6px; flex:1 1 0;" onsubmit="event.preventDefault(); window.open('https://www.google.com/search?q='+encodeURIComponent(this.elements.q.value),'_blank');">
<img src="https://www.google.com/favicon.ico" alt="Google" width="24" height="24"/>
<input type="text" name="q" class="SearchBar_SearchBar__MQiwu" placeholder="Поиск Google..." autocomplete="off" style="width:100%; min-width:0; font-size:1.2em;"/>
</form>
<form id="yandex-search" style="display:flex; align-items:center; gap:6px; flex:1 1 0;" onsubmit="event.preventDefault(); window.open('https://yandex.ru/search/?text='+encodeURIComponent(this.elements.q.value),'_blank');">
<img src="https://yandex.ru/favicon.ico" alt="Yandex" width="24" height="24"/>
<input type="text" name="q" class="SearchBar_SearchBar__MQiwu" placeholder="Поиск Яндекс..." autocomplete="off" style="width:100%; min-width:0; font-size:1.2em;"/>
</form>
</div>
<header class="Header_Header__GCJdR"> <header class="Header_Header__GCJdR">
<span class="Header_HeaderMain__oLoBB"> <span class="Header_HeaderMain__oLoBB">
<div style="display:flex; flex-direction:row; align-items:center; gap:12px;"> <div style="display:flex; flex-direction:row; align-items:center; gap:12px;">
<span style="font-size:1.1em; color: var(--color-primary);">{{ current_time }}</span> <span style="font-size:1.6em; color: var(--color-primary);">{{ current_time }}</span>
<span style="font-size:1.1em; color: var(--color-primary);">{{ now }}</span> <span style="font-size:1.6em; color: var(--color-primary);">{{ now }}</span>
</div> </div>
<div class="WeatherWidget_WeatherWidget__3XlYt"> <div class="WeatherWidget_WeatherWidget__3XlYt" id="weather-area" style="cursor:pointer;">
<div><canvas id="weather-icon" width="50" height="50"></canvas></div> <div>
{% if weather and weather.icon %}
<img src="{{ weather.icon if not weather.icon.startswith('//') else 'https:' + weather.icon }}" width="50" height="50" alt="icon"/>
{% else %}
<canvas id="weather-icon" width="50" height="50"></canvas>
{% endif %}
</div>
<div class="WeatherWidget_WeatherDetails__1y3CA"> <div class="WeatherWidget_WeatherDetails__1y3CA">
{% if weather %} {% if weather %}
<span>{{ weather.temp }}°C</span> <span>{{ weather.temp }}°C</span>
@ -85,6 +100,13 @@
<div id="config-error" style="color:red;"></div> <div id="config-error" style="color:red;"></div>
</div> </div>
</div> </div>
<div id="forecast-modal" style="display:none; position:fixed; z-index:2000; left:0; top:0; width:100vw; height:100vh; background:rgba(0,0,0,0.7); align-items:center; justify-content:center;">
<div style="background:#fff; color:#222; padding:24px; border-radius:8px; min-width:320px; max-width:90vw; max-height:90vh; display:flex; flex-direction:column; gap:12px;">
<h2 id="forecast-title">Прогноз</h2>
<div id="forecast-content" style="overflow-y:auto; max-height:60vh;"></div>
<button id="close-forecast-btn" style="padding:10px 24px; font-size:1.1em; align-self:flex-end;">Закрыть</button>
</div>
</div>
<div class="NotificationCenter_NotificationCenter__Tfgzh" style="height: 0px;"></div> <div class="NotificationCenter_NotificationCenter__Tfgzh" style="height: 0px;"></div>
</div> </div>
<script src="https://cdn.jsdelivr.net/npm/monaco-editor@0.44.0/min/vs/loader.js"></script> <script src="https://cdn.jsdelivr.net/npm/monaco-editor@0.44.0/min/vs/loader.js"></script>
@ -166,6 +188,39 @@ let resizeObserver = new ResizeObserver(() => {
resizeMonaco(); resizeMonaco();
}); });
resizeObserver.observe(document.getElementById('config-modal-content')); resizeObserver.observe(document.getElementById('config-modal-content'));
const weatherArea = document.getElementById('weather-area');
const forecastModal = document.getElementById('forecast-modal');
const forecastContent = document.getElementById('forecast-content');
const closeForecastBtn = document.getElementById('close-forecast-btn');
const forecastTitle = document.getElementById('forecast-title');
weatherArea.onclick = function() {
forecastContent.innerHTML = 'Загрузка...';
forecastModal.style.display = 'flex';
fetch('/api/weather-forecast').then(r => r.json()).then(data => {
if(data.error) {
forecastContent.innerHTML = '<span style="color:red;">'+data.error+'</span>';
forecastTitle.textContent = 'Прогноз';
return;
}
let days = data.forecast.length;
forecastTitle.textContent = `Прогноз на ${days} ${days === 1 ? 'день' : (days < 5 ? 'дня' : 'дней')}`;
let html = '<table style="width:100%; border-collapse:collapse;">';
html += '<tr><th style="text-align:left; padding:4px;">Дата</th><th style="text-align:left; padding:4px;">Температура</th><th style="text-align:left; padding:4px;">Облачность</th><th style="text-align:left; padding:4px;">Состояние</th><th></th></tr>';
for(const day of data.forecast) {
html += `<tr><td style="padding:4px;">${day.date}</td><td style="padding:4px;">${day.temp}°C</td><td style="padding:4px;">${day.cloud}%</td><td style="padding:4px;">${day.text||''}</td><td>${day.icon ? `<img src='${day.icon.startsWith('//') ? 'https:' + day.icon : day.icon}' width='32' height='32'/>` : ''}</td></tr>`;
}
html += '</table>';
forecastContent.innerHTML = html;
}).catch(() => {
forecastContent.innerHTML = '<span style="color:red;">Ошибка загрузки прогноза</span>';
forecastTitle.textContent = 'Прогноз';
});
};
closeForecastBtn.onclick = function() {
forecastModal.style.display = 'none';
};
</script> </script>
</body> </body>
</html> </html>