date presets

This commit is contained in:
bronkuu 2026-06-15 17:39:22 +02:00
parent 8d81940faf
commit e8ea70d61e
5 changed files with 101 additions and 71 deletions

View file

@ -13,34 +13,33 @@ import (
"git.bronku.xyz/bronku/cake-order-tracker/server/templates" "git.bronku.xyz/bronku/cake-order-tracker/server/templates"
) )
func monthInterval(y int, m time.Month) (firstDay, lastDay time.Time) { func weekInterval(t time.Time) (firstDay, lastDay time.Time) {
firstDay = time.Date(y, m, 1, 0, 0, 0, 0, time.UTC) monday := t.AddDate(0, 0, -((int(t.Weekday()) + 6) % 7))
lastDay = time.Date(y, m+1, 1, 0, 0, 0, -1, time.UTC) sunday := monday.AddDate(0, 0, 6)
return firstDay, lastDay return monday, sunday
} }
func (h *Server) orders(_ *http.Request) (templ.Component, int, error) { func (h *Server) orders(r *http.Request) (templ.Component, int, error) {
var ( now := time.Now()
y int weekFirst, weekLast := weekInterval(now)
m time.Month
) first, last := weekFirst, weekLast
y, m, _ = time.Now().Date() if from := r.URL.Query().Get("from"); from != "" {
first, last := monthInterval(y, m) if t, err := time.Parse(config.DateFormat, from); err == nil {
first = t
}
}
if to := r.URL.Query().Get("to"); to != "" {
if t, err := time.Parse(config.DateFormat, to); err == nil {
last = t
}
}
today := now.Format(config.DateFormat)
tomorrow := now.AddDate(0, 0, 1).Format(config.DateFormat)
orders, err := h.s.GetOrders(first, last) orders, err := h.s.GetOrders(first, last)
return templates.OrdersPage(first.Format(config.DateFormat), last.Format(config.DateFormat), orders), http.StatusOK, err return templates.OrdersPage(first.Format(config.DateFormat), last.Format(config.DateFormat), today, tomorrow, orders), http.StatusOK, err
}
func (h *Server) ordersSearch(r *http.Request) (templ.Component, int, error) {
from, err := time.Parse(config.DateFormat, r.URL.Query().Get("from"))
if err != nil {
from = time.Time{}
}
to, err := time.Parse(config.DateFormat, r.URL.Query().Get("to"))
if err != nil {
to = time.Time{}
}
data, err := h.s.GetOrders(from, to)
return templates.OrdersTable(data), http.StatusOK, err
} }
func (h *Server) cakes(_ *http.Request) (templ.Component, int, error) { func (h *Server) cakes(_ *http.Request) (templ.Component, int, error) {

View file

@ -33,7 +33,6 @@ func New(store *store.Store) *Server {
mux.HandleFunc("GET /", redirect("/orders", http.StatusSeeOther)) mux.HandleFunc("GET /", redirect("/orders", http.StatusSeeOther))
mux.HandleFunc("GET /order/", server.render(server.order)) mux.HandleFunc("GET /order/", server.render(server.order))
mux.HandleFunc("GET /orders", server.render(server.orders)) mux.HandleFunc("GET /orders", server.render(server.orders))
mux.HandleFunc("GET /orders/search/", server.render(server.ordersSearch))
mux.HandleFunc("GET /cake/", server.render(server.cake)) mux.HandleFunc("GET /cake/", server.render(server.cake))
mux.HandleFunc("GET /cakes", server.render(server.cakes)) mux.HandleFunc("GET /cakes", server.render(server.cakes))
mux.HandleFunc("POST /order/", server.render(server.postOrder)) mux.HandleFunc("POST /order/", server.render(server.postOrder))

View file

@ -118,6 +118,26 @@
} }
} }
/* ========== PRESET BUTTONS ========== */
.preset-group {
display: flex;
}
.preset-btn {
padding: 0.375rem 0.625rem;
font-size: 0.8125rem;
font-weight: 600;
color: var(--on-surface-variant);
text-decoration: none;
display: inline-flex;
align-items: center;
&:hover,
&.active {
color: var(--primary);
}
}
/* ========== PAGINATION ========== */ /* ========== PAGINATION ========== */
.pagination { .pagination {
display: flex; display: flex;

View file

@ -17,49 +17,58 @@
} }
} }
.form-group { .form-group,
.horizontal-group {
display: flex; display: flex;
flex-direction: column;
gap: 0.25rem; gap: 0.25rem;
&.form-group {
flex-direction: column;
}
&.horizontal-group {
align-items: center;
}
}
label { form {
& label {
font-size: 0.75rem; font-size: 0.75rem;
font-weight: 600; font-weight: 600;
color: var(--on-surface-variant); color: var(--on-surface-variant);
letter-spacing: 0.02em; letter-spacing: 0.02em;
} }
} & input,
& select,
& textarea {
height: 2rem;
padding: 0 0.5rem;
border: 1px solid var(--outline-variant);
border-radius: var(--border-radius-sm);
background: var(--surface-container-lowest);
font-size: 0.75rem;
color: var(--on-surface);
outline: none;
transition: border-color var(--transition);
width: 100%;
.form-input { &:focus {
height: 2rem; border-color: var(--primary);
padding: 0 0.5rem; }
border: 1px solid var(--outline-variant);
border-radius: var(--border-radius-sm);
background: var(--surface-container-lowest);
font-size: 0.75rem;
color: var(--on-surface);
outline: none;
transition: border-color var(--transition);
width: 100%;
&:focus { &::placeholder {
border-color: var(--primary); color: var(--on-surface-variant);
opacity: 0.6;
}
&:is(textarea) {
height: auto;
padding: 0.5rem;
resize: vertical;
}
&:is(select) {
appearance: auto;
}
} }
&::placeholder {
color: var(--on-surface-variant);
opacity: 0.6;
}
}
textarea.form-input {
height: auto;
padding: 0.5rem;
resize: vertical;
}
select.form-input {
appearance: auto;
} }
.form-card { .form-card {
@ -80,3 +89,4 @@ select.form-input {
border-top: 1px solid var(--outline-variant); border-top: 1px solid var(--outline-variant);
margin-top: 0.5rem; margin-top: 0.5rem;
} }

View file

@ -6,21 +6,23 @@ import (
"git.bronku.xyz/bronku/cake-order-tracker/models" "git.bronku.xyz/bronku/cake-order-tracker/models"
) )
templ OrdersPage(first, last string, orders []models.Order) { templ OrdersPage(first, last, today, tomorrow string, orders []models.Order) {
@Layout("Panel główny", DateForm(first, last), OrdersMain(orders)) @Layout("Panel główny", DateForm(first, last, today, tomorrow), OrdersMain(orders))
} }
templ DateForm(first, last string) { templ DateForm(first, last, today, tomorrow string) {
<div style="display:flex;align-items:center;gap:0.5rem"> <div class="horizontal-group" style="gap:0.5rem;flex-wrap:wrap">
<form hx-get="/orders/search" hx-target="#results-table" hx-trigger="keyup delay:500ms, change" style="display:flex;align-items:center;gap:0.5rem"> <div class="preset-group">
<div class="form-group" style="flex-direction:row;align-items:center;gap:0.25rem"> <a href={ templ.URL("/orders?from=" + today + "&to=" + today) } class="preset-btn">Dzisiaj</a>
<label style="font-size:0.75rem;white-space:nowrap">Od</label> <a href={ templ.URL("/orders?from=" + tomorrow + "&to=" + tomorrow) } class="preset-btn">Jutro</a>
<input class="form-input" style="width:8.75rem" type="date" value={ first } name="from"/> <a href="/orders" class="preset-btn">W tym tygodniu</a>
</div> </div>
<div class="form-group" style="flex-direction:row;align-items:center;gap:0.25rem"> <form method="GET" action="/orders" class="horizontal-group" style="align-items:center;gap:0.25rem">
<label style="font-size:0.75rem;white-space:nowrap">Do</label> <label>Od</label>
<input class="form-input" style="width:8.75rem" type="date" value={ last } name="to"/> <input type="date" name="from" value={ first }/>
</div> <label>Do</label>
<input type="date" name="to" value={ last }/>
<button type="submit" class="btn primary sm">Filtruj</button>
</form> </form>
</div> </div>
} }