From 9467ff5f6b767ef240a9468843c901aa482972ce Mon Sep 17 00:00:00 2001 From: simon Date: Tue, 26 May 2026 17:47:54 +0200 Subject: [PATCH] Added Model Orders and Picture Upload --- internal/model/order.go | 21 ++ internal/paths/paths.go | 9 +- internal/server/admin/static/index.html | 399 +++++++++++++++++++++++- internal/server/api/api.go | 2 + internal/server/api/order.go | 213 +++++++++++++ internal/store/order.go | 218 +++++++++++++ 6 files changed, 856 insertions(+), 6 deletions(-) create mode 100644 internal/model/order.go create mode 100644 internal/server/api/order.go create mode 100644 internal/store/order.go diff --git a/internal/model/order.go b/internal/model/order.go new file mode 100644 index 0000000..9fd35da --- /dev/null +++ b/internal/model/order.go @@ -0,0 +1,21 @@ +package model + +import "time" + +// OrderImage is one uploaded image belonging to an order. +type OrderImage struct { + ID string `json:"id"` + OriginalName string `json:"original_name,omitempty"` + ContentType string `json:"content_type,omitempty"` + Filename string `json:"filename"` + CreatedAt time.Time `json:"created_at"` +} + +// Order groups an arbitrary number of customer images for printing. +type Order struct { + ID string `json:"id"` + Name string `json:"name,omitempty"` + Images []OrderImage `json:"images"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` +} diff --git a/internal/paths/paths.go b/internal/paths/paths.go index 8fb0007..816f31b 100644 --- a/internal/paths/paths.go +++ b/internal/paths/paths.go @@ -2,8 +2,9 @@ package paths // Runtime data directories (relative to process working directory). const ( - DataDir = "data" - PlatesDir = "data/plates" - SVGTemplateDir = "data/svg_template" - ConfigurationsDir = "data/configurations" + DataDir = "data" + PlatesDir = "data/plates" + SVGTemplateDir = "data/svg_template" + ConfigurationsDir = "data/configurations" + OrdersDir = "data/orders" ) diff --git a/internal/server/admin/static/index.html b/internal/server/admin/static/index.html index 37a52b6..0ecd151 100644 --- a/internal/server/admin/static/index.html +++ b/internal/server/admin/static/index.html @@ -245,6 +245,92 @@ padding: 2rem 0; text-align: center; } + .order-images { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); + gap: 1rem; + margin-top: 1.25rem; + } + .order-image-card { + background: var(--bg); + border: 1px solid var(--border); + border-radius: 8px; + overflow: hidden; + display: flex; + flex-direction: column; + } + .order-image-thumb { + display: block; + width: 100%; + padding: 0; + border: none; + background: #fff; + cursor: zoom-in; + } + .order-image-thumb img { + width: 100%; + aspect-ratio: 1; + object-fit: contain; + display: block; + background: #fff; + } + .order-lightbox { + position: fixed; + inset: 0; + z-index: 1000; + background: rgba(0, 0, 0, 0.88); + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 2rem; + cursor: zoom-out; + } + .order-lightbox img { + max-width: min(96vw, 1200px); + max-height: 82vh; + object-fit: contain; + background: #fff; + border-radius: 6px; + } + .order-lightbox-caption { + margin-top: 1rem; + color: var(--text); + font-size: 0.9rem; + text-align: center; + max-width: 90vw; + } + .order-lightbox-hint { + margin-top: 0.5rem; + color: var(--muted); + font-size: 0.8rem; + } + .order-image-meta { + padding: 0.5rem 0.65rem; + font-size: 0.75rem; + color: var(--muted); + flex: 1; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + .order-image-actions { + padding: 0 0.65rem 0.65rem; + display: flex; + flex-direction: column; + gap: 0.35rem; + } + .order-image-actions button { + width: 100%; + padding: 0.35rem 0.5rem; + font-size: 0.78rem; + } + [x-cloak] { display: none !important; } + input[type="file"].file-input { + margin-top: 0.75rem; + padding: 0.5rem; + font-size: 0.82rem; + } @media (max-width: 720px) { .app { flex-direction: column; } .sidebar { @@ -334,6 +420,29 @@ @click="newConfiguration()">+ Neu + + + + +
+
+

+

Order anlegen, danach Bilder hochladen.

+

Beliebig viele Bilder pro Order (PNG, JPEG, WebP, GIF).

+
+
+
+
+
+ + +
+
+
+ + +
+

+

+
+ +
+ + +

Lade hoch…

+

Lade Bilder…

+ +
+ +
+

+ Noch keine Bilder — Dateien oben auswählen. +

+
+
+
+ +
+ +