feat(frontend): add frontend
This commit is contained in:
parent
aa57e6371d
commit
94fa6eb9be
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
build/
|
build/
|
||||||
sdkconfig
|
sdkconfig
|
||||||
|
main/frontend.h
|
||||||
|
|||||||
@ -5,6 +5,22 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
|
||||||
<title>IoT Pump controller</title>
|
<title>IoT Pump controller</title>
|
||||||
<style>
|
<style>
|
||||||
|
:root {
|
||||||
|
/* Min slider colors */
|
||||||
|
--min-slider-start: #e94f32;
|
||||||
|
--min-slider-end: #cb9085;
|
||||||
|
|
||||||
|
/* Max slider colors */
|
||||||
|
--max-slider-start: #fbbf24;
|
||||||
|
--max-slider-end: #c0bbad;
|
||||||
|
|
||||||
|
/* Common slider styles */
|
||||||
|
--slider-height: 6px;
|
||||||
|
--slider-radius: 12px;
|
||||||
|
--thumb-size: 24px;
|
||||||
|
--shadow-inset: inset 0 1px 2px #00000040;
|
||||||
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
@ -93,7 +109,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #e2eafc;
|
color: #e0eafc;
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
letter-spacing: 0.3px;
|
letter-spacing: 0.3px;
|
||||||
@ -110,28 +126,62 @@
|
|||||||
box-shadow: inset 0 1px 2px rgba(0,0,0,0.3), 0 1px 0 rgba(255,255,255,0.1);
|
box-shadow: inset 0 1px 2px rgba(0,0,0,0.3), 0 1px 0 rgba(255,255,255,0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="range"] {
|
.slider-base {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 6px;
|
height: 6px;
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
background: linear-gradient(90deg, #1e6f9f, #4aa3cf);
|
appearance: none;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
box-shadow: inset 0 1px 2px #00000040;
|
box-shadow: inset 0 1px 2px #00000040;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="range"]::-webkit-slider-thumb {
|
.min-slider {
|
||||||
|
width: 100%;
|
||||||
|
height: var(--slider-height);
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
width: 36px;
|
background: linear-gradient(90deg, var(--min-slider-start), var(--min-slider-end));
|
||||||
height: 36px;
|
border-radius: var(--slider-radius);
|
||||||
background: radial-gradient(circle, #6db3e0, #2c6c9e);
|
cursor: pointer;
|
||||||
|
box-shadow: var(--shadow-inset);
|
||||||
|
}
|
||||||
|
|
||||||
|
.max-slider {
|
||||||
|
width: 100%;
|
||||||
|
height: var(--slider-height);
|
||||||
|
-webkit-appearance: none;
|
||||||
|
background: linear-gradient(90deg, var(--max-slider-start), var(--max-slider-end));
|
||||||
|
border-radius: var(--slider-radius);
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: var(--shadow-inset);
|
||||||
|
}
|
||||||
|
|
||||||
|
.min-slider::-webkit-slider-thumb {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
width: var(--thumb-size);
|
||||||
|
height: var(--thumb-size);
|
||||||
|
background: radial-gradient(circle, var(--min-slider-start), var(--min-slider-end));
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(210, 230, 250, 0.7);
|
|
||||||
border: 1px solid #b8d0ff;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: transform 0.08s;
|
transition: transform 0.08s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.max-slider::-webkit-slider-thumb {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
width: var(--thumb-size);
|
||||||
|
height: var(--thumb-size);
|
||||||
|
background: radial-gradient(circle, var(--max-slider-start), var(--max-slider-end));
|
||||||
|
border-radius: 50%;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: transform 0.08s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Optional: Add hover effect for thumbs */
|
||||||
|
.min-slider::-webkit-slider-thumb:hover,
|
||||||
|
.max-slider::-webkit-slider-thumb:hover {
|
||||||
|
transform: scale(1.2);
|
||||||
|
}
|
||||||
|
|
||||||
input[type="range"]::-webkit-slider-thumb:active {
|
input[type="range"]::-webkit-slider-thumb:active {
|
||||||
transform: scale(1.15);
|
transform: scale(1.15);
|
||||||
}
|
}
|
||||||
@ -232,7 +282,7 @@
|
|||||||
Нижний порог (включение)
|
Нижний порог (включение)
|
||||||
<span id="minThresholdVal">1.40</span> атм
|
<span id="minThresholdVal">1.40</span> атм
|
||||||
</label>
|
</label>
|
||||||
<input type="range" id="minSlider" min="0" max="8" step="0.05" value="1.4">
|
<input type="range" class="min-slider" id="minSlider" min="0" max="8" step="0.05" value="1.4">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="slider-group">
|
<div class="slider-group">
|
||||||
@ -240,7 +290,7 @@
|
|||||||
Верхний порог (выключение)
|
Верхний порог (выключение)
|
||||||
<span id="maxThresholdVal">6.20</span> атм
|
<span id="maxThresholdVal">6.20</span> атм
|
||||||
</label>
|
</label>
|
||||||
<input type="range" id="maxSlider" min="0" max="8" step="0.05" value="6.2">
|
<input type="range" class="max-slider" id="maxSlider" min="0" max="8" step="0.05" value="6.2">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button class="save-btn" id="saveButton">💾 СОХРАНИТЬ УСТАНОВКИ</button>
|
<button class="save-btn" id="saveButton">💾 СОХРАНИТЬ УСТАНОВКИ</button>
|
||||||
@ -612,10 +662,10 @@
|
|||||||
if (corrected) {
|
if (corrected) {
|
||||||
// дополнительное уведомление о корректировке через тост, но уже показываем общий
|
// дополнительное уведомление о корректировке через тост, но уже показываем общий
|
||||||
toast.innerText = "✓ Корректные пороги сохранены";
|
toast.innerText = "✓ Корректные пороги сохранены";
|
||||||
setTimeout(() => { toast.innerText = "✓ Пороги успешно сохранены"; }, 1500);
|
// setTimeout(() => { toast.innerText = "✓ Пороги успешно сохранены"; }, 1500);
|
||||||
} else {
|
} else {
|
||||||
toast.innerText = "✓ Пороги сохранены";
|
toast.innerText = "✓ Пороги сохранены";
|
||||||
setTimeout(() => { toast.innerText = "✓ Пороги успешно сохранены"; }, 1400);
|
// setTimeout(() => { toast.innerText = "✓ Пороги успешно сохранены"; }, 1400);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
3
justfile
3
justfile
@ -12,7 +12,8 @@ init:
|
|||||||
build:
|
build:
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
. "{{ESPRESSIF}}/export.sh"
|
. "{{ESPRESSIF}}/export.sh"
|
||||||
idf.py
|
xxd -i assets/index.html > main/frontend.h
|
||||||
|
idf.py build
|
||||||
|
|
||||||
|
|
||||||
upload:
|
upload:
|
||||||
|
|||||||
@ -20,6 +20,7 @@
|
|||||||
#include "esp_adc/adc_oneshot.h"
|
#include "esp_adc/adc_oneshot.h"
|
||||||
#include "esp_adc/adc_cali.h"
|
#include "esp_adc/adc_cali.h"
|
||||||
#include "esp_adc/adc_cali_scheme.h"
|
#include "esp_adc/adc_cali_scheme.h"
|
||||||
|
#include "frontend.h"
|
||||||
|
|
||||||
// ==================== НАСТРОЙКИ ТОЧКИ ДОСТУПА ====================
|
// ==================== НАСТРОЙКИ ТОЧКИ ДОСТУПА ====================
|
||||||
#define AP_SSID "ESP32_Hotspot" // Имя Wi-Fi сети
|
#define AP_SSID "ESP32_Hotspot" // Имя Wi-Fi сети
|
||||||
@ -256,7 +257,7 @@ static esp_err_t root_get_handler(httpd_req_t *req)
|
|||||||
"</html>";
|
"</html>";
|
||||||
|
|
||||||
httpd_resp_set_type(req, "text/html; charset=utf-8");
|
httpd_resp_set_type(req, "text/html; charset=utf-8");
|
||||||
httpd_resp_send(req, response, HTTPD_RESP_USE_STRLEN);
|
httpd_resp_send(req, (const char*)assets_index_html, HTTPD_RESP_USE_STRLEN);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user