cake-order-tracker/server/templates/order.templ
2026-06-15 19:48:40 +02:00

205 lines
7.3 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package templates
import (
"encoding/json"
"strconv"
"git.bronku.xyz/bronku/cake-order-tracker/models"
)
templ OrderPage(order models.Order, catalogue []models.Cake, allTags []models.Tag, blockedDates []models.BlockedDate) {
@Layout(OrderTitle(order), templ.NopComponent, OrderForm(order, catalogue, allTags, blockedDates))
}
templ OrderForm(order models.Order, catalogue []models.Cake, allTags []models.Tag, blockedDates []models.BlockedDate) {
<form method="post" class="split-pane order-form" onsubmit="return confirmBlockedDate(this)" data-blocked-dates={ blockedDatesJSON(blockedDates) } data-state={ orderStateJSON(order) }>
<input type="hidden" name="id" value={ strconv.Itoa(order.ID) }/>
<div class="order-left">
<section class="card">
<header>
<h2>
<span class="material-symbols-outlined">person_add</span>
Dane klienta
</h2>
</header>
<div>
<div class="form-grid">
<div>
<label>Imię *</label>
<input type="text" name="name" value={ order.Name } placeholder="Jan"/>
</div>
<div>
<label>Nazwisko *</label>
<input type="text" name="surname" value={ order.Surname } placeholder="Kowalski"/>
</div>
<div>
<label>Telefon</label>
<input type="tel" name="phone" value={ order.Phone } placeholder="+48 123 456 789"/>
</div>
<div>
<label>Lokalizacja</label>
<div class="toggle-group">
<input type="hidden" name="location" value={ order.Location }/>
<button type="button" class={ "toggle-btn", templ.KV("active", order.Location == "Kartuzy") } onclick="setLocation(this, 'Kartuzy')">Kartuzy</button>
<button type="button" class={ "toggle-btn", templ.KV("active", order.Location == "Somonino") } onclick="setLocation(this, 'Somonino')">Somonino</button>
</div>
</div>
<div>
<label>Data dostawy *</label>
<input type="date" name="date" value={ order.Date.Format("2006-01-02") }/>
</div>
<div>
<label>Zaliczka</label>
<input type="number" name="paid" min="0" step="0.01" value={ order.Paid.String() } oninput={ templ.JSFuncCall("updatePrepaid") }/>
</div>
</div>
</div>
</section>
<section class="card">
<header>
<h2>
<span class="material-symbols-outlined">cake_add</span>
Torty specjalne
</h2>
</header>
<div class="button-center">
<button type="button" class="btn btn-outline" onclick="openSpecialCakeOverlay()">
<span class="material-symbols-outlined">add</span>
Dodaj tort specjalny
</button>
</div>
</section>
<section class="card card-catalogue">
<header>
<h2>
<span class="material-symbols-outlined">inventory_2</span>
Katalog produktów
</h2>
<div class="search">
<span class="material-symbols-outlined">search</span>
<input type="text" placeholder="Filtruj produkty..." oninput="filterCatalogue(this)"/>
</div>
</header>
if len(allTags) > 0 {
<div class="tag-row">
for _, t := range allTags {
<button type="button" class="tag-chip" data-tag={ t.Name } onclick="toggleCatalogueTagFilter(this)">{ t.Name }</button>
}
</div>
}
<div class="catalogue-scroll">
<ul id="catalogue-grid">
for _, c := range catalogue {
<li data-name={ c.Name } data-tags={ tagNames(c.Tags) }>
<div>
<div class="icon cake">
<span class="material-symbols-outlined">cake</span>
</div>
<div>
<div class="name">{ c.Name }</div>
<div class="price">{ c.Price.String() } PLN</div>
</div>
</div>
<div class="actions">
<button type="button" class="qty minus" onclick={ templ.JSFuncCall("changeCake", c.ID, c.Name, c.Price.String(), -1) }>
<span class="material-symbols-outlined">remove</span>
</button>
<span class="value" id={ "qty-" + strconv.Itoa(c.ID) }>0</span>
<button type="button" class="qty plus" onclick={ templ.JSFuncCall("changeCake", c.ID, c.Name, c.Price.String(), 1) }>
<span class="material-symbols-outlined">add</span>
</button>
</div>
</li>
}
</ul>
</div>
</section>
</div>
<aside class="order-aside">
<section class="card">
<header>
<h2>
<span class="material-symbols-outlined">receipt_long</span>
Podsumowanie
</h2>
</header>
<ul id="basket-items">
for _, c := range order.Cakes {
<li data-cake-id={ strconv.Itoa(c.ID) }>
<div class="basket-item-body">
<div class="name">{ c.Name }</div>
<div class="detail">{ c.Price.String() } PLN × <span class="qty">{ strconv.Itoa(c.Amount) }</span></div>
</div>
<div class="price">{ c.Total().String() } PLN</div>
<button type="button" class="remove" onclick="removeCake(this)">
<span class="material-symbols-outlined">close</span>
</button>
<input type="hidden" name={ "cake[" + strconv.Itoa(c.ID) + "]" } value={ strconv.Itoa(c.Amount) }/>
</li>
}
for _, s := range order.SpecialCakes {
<li data-special-id={ strconv.Itoa(s.ID) }>
<div class="basket-item-body">
<div class="name">{ s.Name }</div>
<div class="detail">{ specialCakeDetail(s) }</div>
if len(s.Tags) > 0 {
<div class="basket-item-tags">
for _, t := range s.Tags {
<span class="tag-chip sm">{ t.Name }</span>
}
</div>
}
</div>
<div class="price">{ s.Price.String() } PLN</div>
<div class="basket-item-actions">
<button type="button" class="btn-icon" onclick="editSpecialCake(this)" title="Edytuj">
<span class="material-symbols-outlined">edit</span>
</button>
<button type="button" class="remove" onclick="removeSpecialCake(this)" title="Usuń">
<span class="material-symbols-outlined">close</span>
</button>
</div>
<input type="hidden" name="special_name[]" value={ s.Name }/>
<input type="hidden" name="special_price[]" value={ s.Price.String() }/>
<input type="hidden" name="special_size[]" value={ s.Size }/>
<input type="hidden" name="special_shape[]" value={ s.Shape }/>
<input type="hidden" name="special_flavour[]" value={ s.Flavour }/>
<input type="hidden" name="special_notes[]" value={ s.Notes }/>
<input type="hidden" name="special_tags[]" value={ tagIDsComma(s.Tags) }/>
</li>
}
</ul>
<div class="summary-totals">
<div class="total-row">
<span>Subtotal</span>
<span id="subtotal-price">{ order.Subtotal().String() } PLN</span>
</div>
<div class="total-row">
<span>Zaliczka</span>
<span id="paid-amount">{ order.Paid.String() } PLN</span>
</div>
<div class="total-row grand">
<span>Do zapłaty</span>
<span id="total-price">{ order.Total().String() } PLN</span>
</div>
<button type="submit" class="btn-finalize">
<span class="material-symbols-outlined">check_circle</span>
Finalizuj zamówienie
</button>
</div>
</section>
</aside>
</form>
@SpecialCakeOverlay(allTags)
}
func orderStateJSON(order models.Order) string {
state := make(map[int]int)
for _, c := range order.Cakes {
state[c.ID] = c.Amount
}
b, _ := json.Marshal(state)
return string(b)
}