added static page
This commit is contained in:
parent
45b565a672
commit
c7057d7853
37
main.go
37
main.go
|
|
@ -2,6 +2,7 @@ package main
|
|||
|
||||
import (
|
||||
"database/sql"
|
||||
"embed"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
|
@ -21,6 +22,9 @@ import (
|
|||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
//go:embed static
|
||||
var staticFiles embed.FS
|
||||
|
||||
type Config struct {
|
||||
Server ServerConfig `yaml:"server"`
|
||||
PLC PLCConfig `yaml:"plc"`
|
||||
|
|
@ -849,6 +853,8 @@ func main() {
|
|||
go startDBCleanup(db)
|
||||
go startPLCPoller()
|
||||
|
||||
// Serve embedded static assets (tailwind.min.js, chart.umd.min.js)
|
||||
http.Handle("/static/", http.FileServer(http.FS(staticFiles)))
|
||||
http.HandleFunc("/", serveUI)
|
||||
http.HandleFunc("/api/data", apiData)
|
||||
http.HandleFunc("/api/history", apiHistory)
|
||||
|
|
@ -865,11 +871,9 @@ const uiHTML = `<!DOCTYPE html>
|
|||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{.Title}}</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js"></script>
|
||||
<script src="/static/tailwind.min.js"></script>
|
||||
<script src="/static/chart.umd.min.js"></script>
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Space+Grotesk:wght@500;600;700&display=swap');
|
||||
|
||||
:root {
|
||||
--bg1: #050816;
|
||||
--bg2: #0b1224;
|
||||
|
|
@ -879,7 +883,7 @@ const uiHTML = `<!DOCTYPE html>
|
|||
* { box-sizing: border-box; }
|
||||
|
||||
body {
|
||||
font-family: 'Inter', system-ui, sans-serif;
|
||||
font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
|
||||
background:
|
||||
radial-gradient(circle at 10% 10%, rgba(34,211,238,0.12), transparent 18%),
|
||||
radial-gradient(circle at 90% 10%, rgba(168,85,247,0.14), transparent 18%),
|
||||
|
|
@ -887,8 +891,6 @@ const uiHTML = `<!DOCTYPE html>
|
|||
color: #f4f4f5;
|
||||
}
|
||||
|
||||
.title { font-family: 'Space Grotesk', sans-serif; }
|
||||
|
||||
.glass {
|
||||
background: var(--panel);
|
||||
backdrop-filter: blur(14px);
|
||||
|
|
@ -993,14 +995,14 @@ const uiHTML = `<!DOCTYPE html>
|
|||
<div class="w-[92vw] max-w-[1800px] mx-auto p-4 md:p-8 min-h-screen">
|
||||
<div id="alarm-banner" class="hidden mb-6 bg-red-600/90 border border-red-500 text-white px-8 py-4 rounded-2xl flex items-center justify-between text-lg font-medium">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="text-2xl">⚠️</span>
|
||||
<span class="text-2xl">⚠️</span>
|
||||
<span id="alarm-text">CRITICAL ALARM ACTIVE</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-6 xl:flex-row xl:items-center xl:justify-between mb-8">
|
||||
<div>
|
||||
<h1 class="title text-4xl md:text-5xl xl:text-6xl font-semibold tracking-tighter bg-gradient-to-r from-sky-300 to-violet-300 bg-clip-text text-transparent">{{.Title}}</h1>
|
||||
<h1 class="text-4xl md:text-5xl xl:text-6xl font-semibold tracking-tighter bg-gradient-to-r from-sky-300 to-violet-300 bg-clip-text text-transparent">{{.Title}}</h1>
|
||||
<p class="text-zinc-400 mt-2 text-base md:text-lg">{{.Subtitle}}</p>
|
||||
<p class="text-zinc-500 mt-1 text-sm font-mono">MAX_TONNAGE = {{printf "%.1f" .MaxTonnage}} {{.UnitForce}}</p>
|
||||
</div>
|
||||
|
|
@ -1195,7 +1197,8 @@ const uiHTML = `<!DOCTYPE html>
|
|||
};
|
||||
}
|
||||
|
||||
function colorToCss(c, a = 1) {
|
||||
function colorToCss(c, a) {
|
||||
a = a === undefined ? 1 : a;
|
||||
return 'rgba(' + c.r + ',' + c.g + ',' + c.b + ',' + a + ')';
|
||||
}
|
||||
|
||||
|
|
@ -1241,7 +1244,8 @@ const uiHTML = `<!DOCTYPE html>
|
|||
return colorMix(yellow, red, t);
|
||||
}
|
||||
|
||||
function drawArc(ctx, cx, cy, r, a1, a2, stroke, width, shadowBlur = 0) {
|
||||
function drawArc(ctx, cx, cy, r, a1, a2, stroke, width, shadowBlur) {
|
||||
shadowBlur = shadowBlur || 0;
|
||||
ctx.save();
|
||||
ctx.beginPath();
|
||||
ctx.arc(cx, cy, r, a1, a2, false);
|
||||
|
|
@ -1292,7 +1296,6 @@ const uiHTML = `<!DOCTYPE html>
|
|||
|
||||
drawArc(ctx, cx, cy, radius, START_ANGLE, END_ANGLE, 'rgba(255,255,255,0.06)', trackWidth + 10, 0);
|
||||
drawColoredBand(ctx, cx, cy, radius, trackWidth);
|
||||
|
||||
drawArc(ctx, cx, cy, radius, valueAngle, END_ANGLE, 'rgba(9,9,11,0.60)', trackWidth - 1, 0);
|
||||
drawArc(ctx, cx, cy, radius, START_ANGLE, valueAngle, 'rgba(255,255,255,0.04)', trackWidth - 1, 10);
|
||||
|
||||
|
|
@ -1328,7 +1331,7 @@ const uiHTML = `<!DOCTYPE html>
|
|||
ctx.textAlign = 'center';
|
||||
ctx.textBaseline = 'middle';
|
||||
ctx.fillStyle = 'rgba(244,244,245,0.96)';
|
||||
ctx.font = '700 18px Inter, sans-serif';
|
||||
ctx.font = '700 18px system-ui, sans-serif';
|
||||
|
||||
for (const v of labels) {
|
||||
const a = valueToAngle(v);
|
||||
|
|
@ -1386,15 +1389,15 @@ const uiHTML = `<!DOCTYPE html>
|
|||
ctx.textBaseline = 'middle';
|
||||
|
||||
ctx.fillStyle = '#ffffff';
|
||||
ctx.font = '700 ' + valueFontPx + 'px Space Grotesk, Inter, sans-serif';
|
||||
ctx.font = '700 ' + valueFontPx + 'px system-ui, sans-serif';
|
||||
ctx.fillText(valueText, cx, cy - 6);
|
||||
|
||||
ctx.fillStyle = sideAccent;
|
||||
ctx.font = '700 18px Inter, sans-serif';
|
||||
ctx.font = '700 18px system-ui, sans-serif';
|
||||
ctx.fillText(UNIT_PCT, cx, cy + 28);
|
||||
|
||||
ctx.fillStyle = '#a1a1aa';
|
||||
ctx.font = '600 16px Inter, sans-serif';
|
||||
ctx.font = '600 16px system-ui, sans-serif';
|
||||
ctx.fillText((Number(knValue) || 0).toFixed(1) + ' ' + UNIT_FORCE, cx, cy + 54);
|
||||
}
|
||||
|
||||
|
|
@ -1529,7 +1532,7 @@ const uiHTML = `<!DOCTYPE html>
|
|||
parts.push('IMBALANCE');
|
||||
}
|
||||
|
||||
text.textContent = 'CRITICAL ALARM ACTIVE • ' + parts.join(' • ');
|
||||
text.textContent = 'CRITICAL ALARM ACTIVE \u2022 ' + parts.join(' \u2022 ');
|
||||
banner.classList.remove('hidden');
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue