diff --git a/.gitignore b/.gitignore
index ea4d9e0..be55ec9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,6 +22,9 @@
go.work
go.work.sum
+# Generated templ code
+*_templ.go
+
# env file
.env
.idea
diff --git a/go.mod b/go.mod
index 050d73f..5ae13f9 100644
--- a/go.mod
+++ b/go.mod
@@ -1,5 +1,26 @@
module git.bronku.xyz/bronku/cake-order-tracker
-go 1.23.5
+go 1.25.0
require github.com/mattn/go-sqlite3 v1.14.24
+
+require github.com/a-h/templ v0.3.1020
+
+require (
+ github.com/a-h/parse v0.0.0-20250122154542-74294addb73e // indirect
+ github.com/andybalholm/brotli v1.1.0 // indirect
+ github.com/cenkalti/backoff/v4 v4.3.0 // indirect
+ github.com/cli/browser v1.3.0 // indirect
+ github.com/fatih/color v1.16.0 // indirect
+ github.com/fsnotify/fsnotify v1.7.0 // indirect
+ github.com/mattn/go-colorable v0.1.13 // indirect
+ github.com/mattn/go-isatty v0.0.20 // indirect
+ github.com/natefinch/atomic v1.0.1 // indirect
+ golang.org/x/mod v0.26.0 // indirect
+ golang.org/x/net v0.51.0 // indirect
+ golang.org/x/sync v0.16.0 // indirect
+ golang.org/x/sys v0.41.0 // indirect
+ golang.org/x/tools v0.35.0 // indirect
+)
+
+tool github.com/a-h/templ/cmd/templ
diff --git a/go.sum b/go.sum
index 9dcdc9b..e32de87 100644
--- a/go.sum
+++ b/go.sum
@@ -1,2 +1,45 @@
+github.com/a-h/parse v0.0.0-20250122154542-74294addb73e h1:HjVbSQHy+dnlS6C3XajZ69NYAb5jbGNfHanvm1+iYlo=
+github.com/a-h/parse v0.0.0-20250122154542-74294addb73e/go.mod h1:3mnrkvGpurZ4ZrTDbYU84xhwXW2TjTKShSwjRi2ihfQ=
+github.com/a-h/templ v0.3.1020 h1:ypAT/L5ySWEnZ6Zft/5yfoWXYYkhFNvEFOeeqecg4tw=
+github.com/a-h/templ v0.3.1020/go.mod h1:A2DlK61v+K+NRoGnhmYbNYVmtYHcFO5/AisMvBdDxTM=
+github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
+github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
+github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
+github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
+github.com/cli/browser v1.3.0 h1:LejqCrpWr+1pRqmEPDGnTZOjsMe7sehifLynZJuqJpo=
+github.com/cli/browser v1.3.0/go.mod h1:HH8s+fOAxjhQoBUAsKuPCbqUuxZDhQ2/aD+SzsEfBTk=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
+github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
+github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
+github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
+github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
+github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
+github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
+github.com/natefinch/atomic v1.0.1 h1:ZPYKxkqQOx3KZ+RsbnP/YsgvxWQPGxjC0oBt2AhwV0A=
+github.com/natefinch/atomic v1.0.1/go.mod h1:N/D/ELrljoqDyT3rZrsUmtsuzvHkeB/wWjHV22AZRbM=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
+github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=
+golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
+golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo=
+golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y=
+golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
+golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
+golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
+golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
+golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=
+golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/main.go b/main.go
index ec5a151..a422b1f 100644
--- a/main.go
+++ b/main.go
@@ -1,5 +1,7 @@
package main
+//go:generate go tool templ generate
+
import (
"log"
"net/http"
@@ -12,9 +14,9 @@ import (
func main() {
s := store.OpenStore("./foo.db")
defer s.Close()
- h := server.New(s)
- defer h.Close()
+ var h http.Handler = server.New(s)
+ h = logging.Middleware(h)
log.Println("starting server")
- log.Fatal(http.ListenAndServe(":8080", logging.Middleware(h)))
+ log.Fatal(http.ListenAndServe(":8080", h))
}
diff --git a/server/fetcher.go b/server/fetcher.go
index e30bd1a..f52b0aa 100644
--- a/server/fetcher.go
+++ b/server/fetcher.go
@@ -1,5 +1,9 @@
package server
-import "net/http"
+import (
+ "net/http"
-type fetcher func(r *http.Request) (any, int, error)
+ "github.com/a-h/templ"
+)
+
+type fetcher func(r *http.Request) (templ.Component, int, error)
diff --git a/server/get.go b/server/get.go
index ff3d3f3..ef9196c 100644
--- a/server/get.go
+++ b/server/get.go
@@ -1,13 +1,15 @@
package server
import (
- "fmt"
"net/http"
"strconv"
"strings"
"time"
+ "github.com/a-h/templ"
+
"git.bronku.xyz/bronku/cake-order-tracker/models"
+ "git.bronku.xyz/bronku/cake-order-tracker/server/templates"
)
func monthInterval(y int, m time.Month) (firstDay, lastDay time.Time) {
@@ -16,24 +18,18 @@ func monthInterval(y int, m time.Month) (firstDay, lastDay time.Time) {
return firstDay, lastDay
}
-func (h *Server) orders(_ *http.Request) (any, int, error) {
+func (h *Server) orders(_ *http.Request) (templ.Component, int, error) {
var (
y int
m time.Month
)
y, m, _ = time.Now().Date()
first, last := monthInterval(y, m)
- fmt.Println(first, last)
orders, err := h.s.GetOrders(first, last)
- data := struct {
- First string
- Last string
- Orders []models.Order
- }{first.Format("2006-01-02"), last.Format("2006-01-02"), orders}
- return data, http.StatusOK, err
+ return templates.OrdersPage(first.Format("2006-01-02"), last.Format("2006-01-02"), orders), http.StatusOK, err
}
-func (h *Server) ordersSearch(r *http.Request) (any, int, error) {
+func (h *Server) ordersSearch(r *http.Request) (templ.Component, int, error) {
from, err := time.Parse("2006-01-02", r.URL.Query().Get("from"))
if err != nil {
from = time.Time{}
@@ -42,20 +38,19 @@ func (h *Server) ordersSearch(r *http.Request) (any, int, error) {
if err != nil {
to = time.Time{}
}
- fmt.Println(from, to)
data, err := h.s.GetOrders(from, to)
- return data, http.StatusOK, err
+ return templates.OrdersTable(data), http.StatusOK, err
}
-func (h *Server) cakes(_ *http.Request) (any, int, error) {
+func (h *Server) cakes(_ *http.Request) (templ.Component, int, error) {
data, err := h.s.GetCakes()
- return data, http.StatusOK, err
+ return templates.CakesPage(data), http.StatusOK, err
}
-func (h *Server) cake(r *http.Request) (any, int, error) {
+func (h *Server) cake(r *http.Request) (templ.Component, int, error) {
url := strings.Split(r.URL.String(), "/")
if len(url) < 3 || url[2] == "" {
- return models.Cake{}, http.StatusOK, nil
+ return templates.CakePage(models.Cake{}), http.StatusOK, nil
}
id, err := strconv.Atoi(url[2])
@@ -68,26 +63,19 @@ func (h *Server) cake(r *http.Request) (any, int, error) {
return nil, http.StatusNotFound, err
}
- return data, http.StatusOK, nil
+ return templates.CakePage(data), http.StatusOK, nil
}
-func (h *Server) order(r *http.Request) (any, int, error) {
- type formData struct {
- Order models.Order
- Catalogue []models.Cake
- }
+func (h *Server) order(r *http.Request) (templ.Component, int, error) {
var err error
- var data formData
-
- data.Catalogue, err = h.s.GetCakes()
+ catalogue, err := h.s.GetCakes()
if err != nil {
return nil, http.StatusInternalServerError, err
}
url := strings.Split(r.URL.String(), "/")
if len(url) < 3 || url[2] == "" {
- data.Order.Date = time.Now()
- return data, http.StatusOK, nil
+ return templates.OrderPage(models.Order{Date: time.Now()}, catalogue), http.StatusOK, nil
}
id, err := strconv.Atoi(url[2])
@@ -95,10 +83,10 @@ func (h *Server) order(r *http.Request) (any, int, error) {
return nil, http.StatusBadRequest, err
}
- data.Order, err = h.s.GetOrder(id)
+ order, err := h.s.GetOrder(id)
if err != nil {
return nil, http.StatusNotFound, err
}
- return data, http.StatusOK, nil
+ return templates.OrderPage(order, catalogue), http.StatusOK, nil
}
diff --git a/server/post.go b/server/post.go
index 3bcc116..8e08547 100644
--- a/server/post.go
+++ b/server/post.go
@@ -7,10 +7,13 @@ import (
"strings"
"time"
+ "github.com/a-h/templ"
+
"git.bronku.xyz/bronku/cake-order-tracker/models"
+ "git.bronku.xyz/bronku/cake-order-tracker/server/templates"
)
-func (h *Server) postCake(r *http.Request) (any, int, error) {
+func (h *Server) postCake(r *http.Request) (templ.Component, int, error) {
err := r.ParseForm()
if err != nil {
return nil, http.StatusInternalServerError, err
@@ -28,10 +31,10 @@ func (h *Server) postCake(r *http.Request) (any, int, error) {
}
n.ID, err = h.s.SaveCake(n)
fmt.Println(err)
- return n, http.StatusAccepted, err
+ return templates.Confirmation("Potwierdzone", n.ID), http.StatusAccepted, err
}
-func (h *Server) postOrder(r *http.Request) (any, int, error) {
+func (h *Server) postOrder(r *http.Request) (templ.Component, int, error) {
cakes, err := h.s.GetCakes()
if err != nil {
return nil, http.StatusInternalServerError, err
@@ -75,5 +78,5 @@ func (h *Server) postOrder(r *http.Request) (any, int, error) {
n.ID, err = h.s.SaveOrder(n)
fmt.Println(n)
- return n, http.StatusAccepted, err
+ return templates.Confirmation("Potwierdzone", n.ID), http.StatusAccepted, err
}
diff --git a/server/server.go b/server/server.go
index 9b594dd..6b3ee3f 100644
--- a/server/server.go
+++ b/server/server.go
@@ -2,27 +2,19 @@ package server
import (
"embed"
- "html/template"
"net/http"
"git.bronku.xyz/bronku/cake-order-tracker/store"
)
type Server struct {
- tmpl map[string]*template.Template
s *store.Store
routes map[string]route
http.Handler
}
type route struct {
- function fetcher
- template string
- templateEntry string
-}
-
-func (h *Server) Close() {
- h.Close()
+ function fetcher
}
//go:embed static/*
@@ -32,7 +24,7 @@ func (h *Server) loadHandler() {
mux := http.NewServeMux()
for i, e := range h.routes {
- mux.HandleFunc(i, h.render(e.function, e.template, e.templateEntry))
+ mux.HandleFunc(i, h.render(e.function))
}
mux.HandleFunc("GET /", h.redirect("/orders", http.StatusSeeOther))
@@ -47,16 +39,15 @@ func New(store *store.Store) *Server {
var server Server
server.routes = map[string]route{
- "GET /order/": {server.order, "order", "layout"},
- "GET /orders": {server.orders, "orders", "layout"},
- "GET /orders/search/": {server.ordersSearch, "orders", "orders-table"},
- "GET /cake/": {server.cake, "cake", "layout"},
- "GET /cakes": {server.cakes, "cakes", "layout"},
- "POST /order/": {server.postOrder, "confirmation", "layout"},
- "POST /cake/": {server.postCake, "confirmation", "layout"},
+ "GET /order/": {server.order},
+ "GET /orders": {server.orders},
+ "GET /orders/search/": {server.ordersSearch},
+ "GET /cake/": {server.cake},
+ "GET /cakes": {server.cakes},
+ "POST /order/": {server.postOrder},
+ "POST /cake/": {server.postCake},
}
- server.loadTemplates()
server.s = store
server.loadHandler()
diff --git a/server/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa0ZL7SUc.woff2 b/server/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa0ZL7SUc.woff2
new file mode 100644
index 0000000..d750914
Binary files /dev/null and b/server/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa0ZL7SUc.woff2 differ
diff --git a/server/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1ZL7.woff2 b/server/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1ZL7.woff2
new file mode 100644
index 0000000..d15208d
Binary files /dev/null and b/server/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1ZL7.woff2 differ
diff --git a/server/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1pL7SUc.woff2 b/server/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1pL7SUc.woff2
new file mode 100644
index 0000000..024f077
Binary files /dev/null and b/server/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1pL7SUc.woff2 differ
diff --git a/server/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa25L7SUc.woff2 b/server/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa25L7SUc.woff2
new file mode 100644
index 0000000..479d010
Binary files /dev/null and b/server/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa25L7SUc.woff2 differ
diff --git a/server/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2JL7SUc.woff2 b/server/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2JL7SUc.woff2
new file mode 100644
index 0000000..de83a9c
Binary files /dev/null and b/server/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2JL7SUc.woff2 differ
diff --git a/server/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2ZL7SUc.woff2 b/server/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2ZL7SUc.woff2
new file mode 100644
index 0000000..6e7141f
Binary files /dev/null and b/server/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2ZL7SUc.woff2 differ
diff --git a/server/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2pL7SUc.woff2 b/server/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2pL7SUc.woff2
new file mode 100644
index 0000000..a40c469
Binary files /dev/null and b/server/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2pL7SUc.woff2 differ
diff --git a/server/static/fonts/inter.css b/server/static/fonts/inter.css
new file mode 100644
index 0000000..62697ea
--- /dev/null
+++ b/server/static/fonts/inter.css
@@ -0,0 +1,315 @@
+/* cyrillic-ext */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 400;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2JL7SUc.woff2) format('woff2');
+ unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
+}
+/* cyrillic */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 400;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa0ZL7SUc.woff2) format('woff2');
+ unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
+}
+/* greek-ext */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 400;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2ZL7SUc.woff2) format('woff2');
+ unicode-range: U+1F00-1FFF;
+}
+/* greek */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 400;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1pL7SUc.woff2) format('woff2');
+ unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
+}
+/* vietnamese */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 400;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2pL7SUc.woff2) format('woff2');
+ unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
+}
+/* latin-ext */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 400;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa25L7SUc.woff2) format('woff2');
+ unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
+}
+/* latin */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 400;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1ZL7.woff2) format('woff2');
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+/* cyrillic-ext */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 500;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2JL7SUc.woff2) format('woff2');
+ unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
+}
+/* cyrillic */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 500;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa0ZL7SUc.woff2) format('woff2');
+ unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
+}
+/* greek-ext */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 500;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2ZL7SUc.woff2) format('woff2');
+ unicode-range: U+1F00-1FFF;
+}
+/* greek */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 500;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1pL7SUc.woff2) format('woff2');
+ unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
+}
+/* vietnamese */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 500;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2pL7SUc.woff2) format('woff2');
+ unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
+}
+/* latin-ext */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 500;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa25L7SUc.woff2) format('woff2');
+ unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
+}
+/* latin */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 500;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1ZL7.woff2) format('woff2');
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+/* cyrillic-ext */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 600;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2JL7SUc.woff2) format('woff2');
+ unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
+}
+/* cyrillic */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 600;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa0ZL7SUc.woff2) format('woff2');
+ unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
+}
+/* greek-ext */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 600;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2ZL7SUc.woff2) format('woff2');
+ unicode-range: U+1F00-1FFF;
+}
+/* greek */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 600;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1pL7SUc.woff2) format('woff2');
+ unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
+}
+/* vietnamese */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 600;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2pL7SUc.woff2) format('woff2');
+ unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
+}
+/* latin-ext */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 600;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa25L7SUc.woff2) format('woff2');
+ unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
+}
+/* latin */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 600;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1ZL7.woff2) format('woff2');
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+/* cyrillic-ext */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 700;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2JL7SUc.woff2) format('woff2');
+ unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
+}
+/* cyrillic */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 700;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa0ZL7SUc.woff2) format('woff2');
+ unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
+}
+/* greek-ext */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 700;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2ZL7SUc.woff2) format('woff2');
+ unicode-range: U+1F00-1FFF;
+}
+/* greek */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 700;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1pL7SUc.woff2) format('woff2');
+ unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
+}
+/* vietnamese */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 700;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2pL7SUc.woff2) format('woff2');
+ unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
+}
+/* latin-ext */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 700;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa25L7SUc.woff2) format('woff2');
+ unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
+}
+/* latin */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 700;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1ZL7.woff2) format('woff2');
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+/* cyrillic-ext */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 800;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2JL7SUc.woff2) format('woff2');
+ unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
+}
+/* cyrillic */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 800;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa0ZL7SUc.woff2) format('woff2');
+ unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
+}
+/* greek-ext */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 800;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2ZL7SUc.woff2) format('woff2');
+ unicode-range: U+1F00-1FFF;
+}
+/* greek */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 800;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1pL7SUc.woff2) format('woff2');
+ unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
+}
+/* vietnamese */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 800;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2pL7SUc.woff2) format('woff2');
+ unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
+}
+/* latin-ext */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 800;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa25L7SUc.woff2) format('woff2');
+ unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
+}
+/* latin */
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 800;
+ font-display: swap;
+ src: url(/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1ZL7.woff2) format('woff2');
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
diff --git a/server/static/fonts/kJESBvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzBwG-RpA6RzaxHMO1W.woff2 b/server/static/fonts/kJESBvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzBwG-RpA6RzaxHMO1W.woff2
new file mode 100644
index 0000000..2d22eb4
Binary files /dev/null and b/server/static/fonts/kJESBvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzBwG-RpA6RzaxHMO1W.woff2 differ
diff --git a/server/static/fonts/material.css b/server/static/fonts/material.css
new file mode 100644
index 0000000..a38a17a
--- /dev/null
+++ b/server/static/fonts/material.css
@@ -0,0 +1,24 @@
+/* fallback */
+@font-face {
+ font-family: 'Material Symbols Outlined';
+ font-style: normal;
+ font-weight: 100 700;
+ font-display: swap;
+ src: url(/static/fonts/kJESBvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzBwG-RpA6RzaxHMO1W.woff2) format('woff2');
+}
+
+.material-symbols-outlined {
+ font-family: 'Material Symbols Outlined';
+ font-weight: normal;
+ font-style: normal;
+ font-size: 24px;
+ line-height: 1;
+ letter-spacing: normal;
+ text-transform: none;
+ display: inline-block;
+ white-space: nowrap;
+ word-wrap: normal;
+ direction: ltr;
+ -webkit-font-feature-settings: 'liga';
+ -webkit-font-smoothing: antialiased;
+}
diff --git a/server/template.go b/server/template.go
index adff311..e31b080 100644
--- a/server/template.go
+++ b/server/template.go
@@ -1,47 +1,23 @@
package server
import (
- "embed"
- "html/template"
- "log"
"net/http"
"git.bronku.xyz/bronku/cake-order-tracker/logging"
)
-//go:embed templates/*
-var templates embed.FS
-
-func (h *Server) loadTemplates() {
- h.tmpl = make(map[string]*template.Template)
- funcs := template.FuncMap{
- "add": func(a, b int) int { return a + b },
- "mult": func(a, b int) int { return a * b },
- }
- for _, page := range h.routes {
- tmpl, err := template.New("").Funcs(funcs).ParseFS(templates,
- "templates/layout/*.gohtml",
- "templates/"+page.template+".gohtml",
- )
- if err != nil {
- log.Fatal(err)
- }
- h.tmpl[page.template] = tmpl
- }
-}
-
-func (h *Server) render(fetch fetcher, templateFile string, templateEntry string) http.HandlerFunc {
+func (h *Server) render(fetch fetcher) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- data, code, err := fetch(r)
+ component, code, err := fetch(r)
if err != nil {
logging.ErrorPage(err, code).ServeHTTP(w, r)
return
}
- err = h.tmpl[templateFile].ExecuteTemplate(w, templateEntry, data)
+ w.Header().Set("content-type", "text/html")
+ err = component.Render(r.Context(), w)
if err != nil {
logging.ErrorPage(err, http.StatusInternalServerError).ServeHTTP(w, r)
return
}
- w.Header().Set("content-type", "text/html")
}
}
diff --git a/server/templates/cake.gohtml b/server/templates/cake.gohtml
deleted file mode 100644
index 81bb0e4..0000000
--- a/server/templates/cake.gohtml
+++ /dev/null
@@ -1,33 +0,0 @@
-{{define "title"}}
-Ciasto {{if .ID}}#{{.ID}}{{else}}nowe{{end}}
-{{end}}
-{{define "main"}}
-
-{{end}}
diff --git a/server/templates/cake.templ b/server/templates/cake.templ
new file mode 100644
index 0000000..83b6c46
--- /dev/null
+++ b/server/templates/cake.templ
@@ -0,0 +1,46 @@
+package templates
+
+import (
+ "strconv"
+
+ "git.bronku.xyz/bronku/cake-order-tracker/models"
+)
+
+templ CakePage(cake models.Cake) {
+ @Layout(cakeTitle(cake), CakeForm(cake))
+}
+
+templ CakeForm(cake models.Cake) {
+
+}
diff --git a/server/templates/cakes.gohtml b/server/templates/cakes.gohtml
deleted file mode 100644
index 04ac8f4..0000000
--- a/server/templates/cakes.gohtml
+++ /dev/null
@@ -1,61 +0,0 @@
-{{define "title"}}
-Katalog
-{{end}}
-{{define "main"}}
-
-
-
-
-
-
- |
- Nazwa |
- SKU |
- Cena bazowa |
- |
-
-
-
- {{range .}}
-
- |
-
- cake
-
- |
- {{.Name}} |
- #{{.ID}} |
- {{.Price}} PLN |
-
-
- edit
-
- |
-
- {{end}}
-
-
-
-
-
-{{end}}
diff --git a/server/templates/cakes.templ b/server/templates/cakes.templ
new file mode 100644
index 0000000..d931304
--- /dev/null
+++ b/server/templates/cakes.templ
@@ -0,0 +1,70 @@
+package templates
+
+import (
+ "strconv"
+
+ "git.bronku.xyz/bronku/cake-order-tracker/models"
+)
+
+templ CakesPage(cakes []models.Cake) {
+ @Layout("Katalog", CakesMain(cakes))
+}
+
+templ CakesMain(cakes []models.Cake) {
+
+
+
+
+
+
+ |
+ Nazwa |
+ SKU |
+ Cena bazowa |
+ |
+
+
+
+ for _, c := range cakes {
+
+ |
+
+ cake
+
+ |
+ { c.Name } |
+ #{ strconv.Itoa(c.ID) } |
+ { strconv.Itoa(c.Price) } PLN |
+
+
+ edit
+
+ |
+
+ }
+
+
+
+
+
+}
diff --git a/server/templates/confirmation.gohtml b/server/templates/confirmation.gohtml
deleted file mode 100644
index 9ed0444..0000000
--- a/server/templates/confirmation.gohtml
+++ /dev/null
@@ -1,13 +0,0 @@
-{{define "title"}}
-Potwierdzone
-{{end}}
-{{define "main"}}
-
-{{end}}
diff --git a/server/templates/confirmation.templ b/server/templates/confirmation.templ
new file mode 100644
index 0000000..2307ef0
--- /dev/null
+++ b/server/templates/confirmation.templ
@@ -0,0 +1,18 @@
+package templates
+
+import "strconv"
+
+templ Confirmation(title string, id int) {
+ @Layout(title, ConfirmationBody(id))
+}
+
+templ ConfirmationBody(id int) {
+
+}
diff --git a/server/templates/helpers.go b/server/templates/helpers.go
new file mode 100644
index 0000000..74f6c87
--- /dev/null
+++ b/server/templates/helpers.go
@@ -0,0 +1,84 @@
+package templates
+
+import (
+ "fmt"
+ "strconv"
+ "strings"
+
+ "git.bronku.xyz/bronku/cake-order-tracker/models"
+)
+
+func cakeTitle(cake models.Cake) string {
+ if cake.ID != 0 {
+ return "Ciasto #" + strconv.Itoa(cake.ID)
+ }
+ return "Ciasto nowe"
+}
+
+func orderTitle(order models.Order) string {
+ if order.ID != 0 {
+ return "Edytuj zamówienie #" + strconv.Itoa(order.ID)
+ }
+ return "Nowe zamówienie"
+}
+
+func orderSubtotal(order models.Order) int {
+ sub := 0
+ for _, c := range order.Cakes {
+ sub += c.Price * c.Amount
+ }
+ return sub
+}
+
+func countPending(orders []models.Order) int {
+ n := 0
+ for _, o := range orders {
+ if o.Status != "done" {
+ n++
+ }
+ }
+ return n
+}
+
+func countDone(orders []models.Order) int {
+ n := 0
+ for _, o := range orders {
+ if o.Status == "done" {
+ n++
+ }
+ }
+ return n
+}
+
+func estimateRevenue(orders []models.Order) int {
+ total := 0
+ for _, o := range orders {
+ for _, c := range o.Cakes {
+ total += c.Price * c.Amount
+ }
+ }
+ return total
+}
+
+func cakeItemsDesc(cakes []models.Cake) string {
+ desc := ""
+ for i, c := range cakes {
+ if i > 0 {
+ desc += ", "
+ }
+ desc += c.Name + " (x" + strconv.Itoa(c.Amount) + ")"
+ }
+ return desc
+}
+
+func orderScript(order models.Order) string {
+ var b strings.Builder
+ b.WriteString("")
+ return b.String()
+}
diff --git a/server/templates/layout.templ b/server/templates/layout.templ
new file mode 100644
index 0000000..2af9aca
--- /dev/null
+++ b/server/templates/layout.templ
@@ -0,0 +1,43 @@
+package templates
+
+templ Layout(title string, main templ.Component) {
+
+
+
+
+
+ { title } — Zamówienia ciast
+
+
+
+
+
+
+
+
+
+
+
+
+}
diff --git a/server/templates/layout/layout.gohtml b/server/templates/layout/layout.gohtml
deleted file mode 100644
index 44949c3..0000000
--- a/server/templates/layout/layout.gohtml
+++ /dev/null
@@ -1,43 +0,0 @@
-{{define "layout"}}
-
-
-
-
-
- {{template "title" .}} — Zamówienia ciast
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "main" .}}
-
-
-
-
-
-{{end}}
diff --git a/server/templates/layout/nav.gohtml b/server/templates/layout/nav.gohtml
deleted file mode 100644
index 2749d3f..0000000
--- a/server/templates/layout/nav.gohtml
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "nav"}}
-
-
-{{end}}
diff --git a/server/templates/nav.templ b/server/templates/nav.templ
new file mode 100644
index 0000000..aee619b
--- /dev/null
+++ b/server/templates/nav.templ
@@ -0,0 +1,18 @@
+package templates
+
+templ Nav() {
+
+
+}
diff --git a/server/templates/order.gohtml b/server/templates/order.gohtml
deleted file mode 100644
index 75ed842..0000000
--- a/server/templates/order.gohtml
+++ /dev/null
@@ -1,151 +0,0 @@
-{{define "title"}}
- {{if .Order.ID}}
- Edytuj zamówienie #{{.Order.ID}}
- {{else}}
- Nowe zamówienie
- {{end}}
-{{end}}
-{{define "main"}}
-
-
-{{end}}
diff --git a/server/templates/order.templ b/server/templates/order.templ
new file mode 100644
index 0000000..a12eb2e
--- /dev/null
+++ b/server/templates/order.templ
@@ -0,0 +1,144 @@
+package templates
+
+import (
+ "strconv"
+
+ "git.bronku.xyz/bronku/cake-order-tracker/models"
+)
+
+templ OrderPage(order models.Order, catalogue []models.Cake) {
+ @Layout(orderTitle(order), OrderForm(order, catalogue))
+}
+
+templ OrderForm(order models.Order, catalogue []models.Cake) {
+
+ @templ.Raw(orderScript(order))
+}
diff --git a/server/templates/orders.gohtml b/server/templates/orders.gohtml
deleted file mode 100644
index e837b70..0000000
--- a/server/templates/orders.gohtml
+++ /dev/null
@@ -1,126 +0,0 @@
-{{define "title"}}
-Panel główny
-{{end}}
-{{define "main"}}
-
-
-
- receipt_long
- Zamówienia dzisiaj
-
- {{len .Orders}}
-
- arrow_upward
- Wszystkie aktywne
-
-
-
-
- cake
- Do realizacji
-
-
- {{$pending := 0}}
- {{range .Orders}}{{if ne .Status "done"}}{{$pending = add $pending 1}}{{end}}{{end}}
- {{$pending}}
-
-
- priority_high
- Oczekujące
-
-
-
-
- check_circle
- Gotowe do odbioru
-
-
- {{$done := 0}}
- {{range .Orders}}{{if eq .Status "done"}}{{$done = add $done 1}}{{end}}{{end}}
- {{$done}}
-
- Zrealizowane
-
-
-
- payments
- Przychód (szac.)
-
-
- {{$total := 0}}
- {{range .Orders}}{{range .Cakes}}{{$total = add $total (mult .Price .Amount)}}{{end}}{{end}}
- {{$total}} PLN
-
-
- trending_up
- W bieżącym miesiącu
-
-
-
-
-
-
-
- {{template "orders-table" .Orders}}
-
-
-{{end}}
-{{define "orders-table"}}
-
-
-
- | ID zamówienia |
- Klient |
- Data odbioru |
- Pozycje |
- Suma |
- Status |
- |
-
-
-
- {{range .}}
-
- | #{{.ID}} |
- {{.Surname}} {{.Name}} {{.Phone}} |
- {{.Date.Format "2006-01-02 15:04"}} |
-
-
- {{range $i, $c := .Cakes}}{{if $i}}, {{end}}{{.Name}} (x{{.Amount}}){{end}}
-
- |
- {{.Total}} PLN |
-
-
- {{if eq .Status "accepted"}}Przyjęte
- {{else if eq .Status "done"}}Gotowe
- {{else}}Oczekujące{{end}}
-
- |
-
-
- edit
-
- |
-
- {{end}}
-
-
-{{end}}
diff --git a/server/templates/orders.templ b/server/templates/orders.templ
new file mode 100644
index 0000000..e76186f
--- /dev/null
+++ b/server/templates/orders.templ
@@ -0,0 +1,133 @@
+package templates
+
+import (
+ "strconv"
+
+ "git.bronku.xyz/bronku/cake-order-tracker/models"
+)
+
+templ OrdersPage(first, last string, orders []models.Order) {
+ @Layout("Panel główny", OrdersMain(first, last, orders))
+}
+
+templ OrdersMain(first, last string, orders []models.Order) {
+
+
+
+ receipt_long
+ Zamówienia dzisiaj
+
+ { len(orders) }
+
+ arrow_upward
+ Wszystkie aktywne
+
+
+
+
+ cake
+ Do realizacji
+
+ { strconv.Itoa(countPending(orders)) }
+
+ priority_high
+ Oczekujące
+
+
+
+
+ check_circle
+ Gotowe do odbioru
+
+ { strconv.Itoa(countDone(orders)) }
+ Zrealizowane
+
+
+
+ payments
+ Przychód (szac.)
+
+ { strconv.Itoa(estimateRevenue(orders)) } PLN
+
+ trending_up
+ W bieżącym miesiącu
+
+
+
+
+
+
+
+ @OrdersTable(orders)
+
+
+}
+
+templ OrdersTable(orders []models.Order) {
+
+
+
+ | ID zamówienia |
+ Klient |
+ Data odbioru |
+ Pozycje |
+ Suma |
+ Status |
+ |
+
+
+
+ for _, o := range orders {
+
+ | #{ strconv.Itoa(o.ID) } |
+ { o.Surname } { o.Name } { o.Phone } |
+ { o.Date.Format("2006-01-02 15:04") } |
+
+
+ for i, c := range o.Cakes {
+ if i > 0 {
+ { ", " }
+ }
+ { c.Name } (x{ strconv.Itoa(c.Amount) })
+ }
+
+ |
+ { strconv.Itoa(o.Total()) } PLN |
+
+
+ if o.Status == "accepted" {
+ Przyjęte
+ } else if o.Status == "done" {
+ Gotowe
+ } else {
+ Oczekujące
+ }
+
+ |
+
+
+ edit
+
+ |
+
+ }
+
+
+}