diff --git a/server/server.go b/server/server.go
index 16452c3..c23e330 100644
--- a/server/server.go
+++ b/server/server.go
@@ -31,13 +31,13 @@ func New(store *store.Store) *Server {
mux := http.NewServeMux()
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 /cake/", server.render(server.cake))
+ mux.HandleFunc("GET /cake", server.render(server.cake))
mux.HandleFunc("GET /cakes", server.render(server.cakes))
- mux.HandleFunc("POST /order/", server.render(server.postOrder))
+ mux.HandleFunc("POST /order", server.render(server.postOrder))
mux.HandleFunc("POST /order/{id}/status", server.render(server.updateStatus))
- mux.HandleFunc("POST /cake/", server.render(server.postCake))
+ mux.HandleFunc("POST /cake", server.render(server.postCake))
mux.HandleFunc("GET /blocked", server.render(server.blocked))
mux.HandleFunc("POST /blocked", server.render(server.postBlocked))
mux.HandleFunc("POST /blocked/{id}/delete", server.render(server.deleteBlocked))
diff --git a/server/static/order.js b/server/static/order.js
index b3fb3c5..828c3ce 100644
--- a/server/static/order.js
+++ b/server/static/order.js
@@ -5,47 +5,48 @@ var activeCakeTags = [];
function openSpecialCakeOverlay() {
editingSpecialId = null;
- document.getElementById('sc-overlay-title').textContent = 'Dodaj tort specjalny';
- document.getElementById('sc-name').value = '';
- document.getElementById('sc-price').value = '';
- document.getElementById('sc-size').value = '';
- document.getElementById('sc-shape').value = '';
- document.getElementById('sc-flavour').value = '';
- document.getElementById('sc-notes').value = '';
- document.getElementById('sc-new-tag').value = '';
- var cbs = document.querySelectorAll('.sc-tag-cb');
+ document.getElementById("sc-overlay-title").textContent =
+ "Dodaj tort specjalny";
+ document.getElementById("sc-name").value = "";
+ document.getElementById("sc-price").value = "";
+ document.getElementById("sc-size").value = "";
+ document.getElementById("sc-shape").value = "";
+ document.getElementById("sc-flavour").value = "";
+ document.getElementById("sc-notes").value = "";
+ document.getElementById("sc-new-tag").value = "";
+ var cbs = document.querySelectorAll(".sc-tag-cb");
for (var i = 0; i < cbs.length; i++) cbs[i].checked = false;
- document.getElementById('sc-overlay').classList.add('open');
- document.getElementById('sc-name').focus();
+ document.getElementById("sc-overlay").classList.add("open");
+ document.getElementById("sc-name").focus();
}
function closeSpecialCakeOverlay() {
- document.getElementById('sc-overlay').classList.remove('open');
+ document.getElementById("sc-overlay").classList.remove("open");
editingSpecialId = null;
}
function getOverlayFormData() {
return {
- name: document.getElementById('sc-name').value.trim(),
- price: document.getElementById('sc-price').value,
- size: document.getElementById('sc-size').value.trim(),
- shape: document.getElementById('sc-shape').value,
- flavour: document.getElementById('sc-flavour').value.trim(),
- notes: document.getElementById('sc-notes').value.trim(),
- tagIds: (function() {
+ name: document.getElementById("sc-name").value.trim(),
+ price: document.getElementById("sc-price").value,
+ size: document.getElementById("sc-size").value.trim(),
+ shape: document.getElementById("sc-shape").value,
+ flavour: document.getElementById("sc-flavour").value.trim(),
+ notes: document.getElementById("sc-notes").value.trim(),
+ tagIds: (function () {
var ids = [];
- var cbs = document.querySelectorAll('.sc-tag-cb:checked');
+ var cbs = document.querySelectorAll(".sc-tag-cb:checked");
for (var i = 0; i < cbs.length; i++) ids.push(cbs[i].value);
return ids;
})(),
- tagNames: (function() {
+ tagNames: (function () {
var names = [];
- var cbs = document.querySelectorAll('.sc-tag-cb:checked');
+ var cbs = document.querySelectorAll(".sc-tag-cb:checked");
for (var i = 0; i < cbs.length; i++)
- names.push(cbs[i].closest('.tag-chip').textContent.trim());
+ names.push(cbs[i].closest(".tag-chip").textContent.trim());
return names;
})(),
- newTag: document.getElementById('sc-new-tag').value.trim()
+ newTag: document.getElementById("sc-new-tag").value.trim(),
};
}
@@ -53,40 +54,61 @@ function buildSpecialCakeHTML(d) {
var parts = [];
if (d.size) parts.push(d.size);
if (d.flavour) parts.push(d.flavour);
- if (d.shape === 'round') parts.push('okragly');
- else if (d.shape === 'square') parts.push('kwadrat');
- if (d.notes) parts.push('notatka: ' + d.notes);
- var detail = parts.length ? parts.join(', ') : '';
- var tagHtml = d.tagNames.length > 0 || d.newTag ? '
";
var priceVal = Number(d.price).toFixed(2);
- var tagIdsStr = d.tagIds.join(',');
+ var tagIdsStr = d.tagIds.join(",");
var html =
'' +
- '
' + d.name + '
' +
- '
' + detail + '
' +
+ '
' +
+ d.name +
+ "
" +
+ '
' +
+ detail +
+ "
" +
tagHtml +
- '
' +
- '' + priceVal + ' PLN
' +
+ "" +
+ '' +
+ priceVal +
+ " PLN
" +
'' +
'' +
'' +
- '
' +
- '' +
- '' +
- '' +
- '' +
- '' +
- '' +
- '';
+ "" +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '';
if (d.newTag)
- html += '';
+ html +=
+ '';
return html;
}
@@ -94,50 +116,57 @@ function saveSpecialCake() {
var d = getOverlayFormData();
if (!d.name) return;
if (editingSpecialId) {
- var item = document.querySelector('#basket-items li[data-special-id="' + editingSpecialId + '"]');
+ var item = document.querySelector(
+ '#basket-items li[data-special-id="' + editingSpecialId + '"]',
+ );
if (item) {
item.innerHTML = buildSpecialCakeHTML(d);
}
} else {
d.id = Date.now();
- var item = document.createElement('li');
- item.setAttribute('data-special-id', d.id);
+ var item = document.createElement("li");
+ item.setAttribute("data-special-id", d.id);
item.innerHTML = buildSpecialCakeHTML(d);
- document.getElementById('basket-items').appendChild(item);
+ document.getElementById("basket-items").appendChild(item);
}
closeSpecialCakeOverlay();
updateTotals();
}
function editSpecialCake(btn) {
- var item = btn.closest('li');
- var id = item.getAttribute('data-special-id');
+ var item = btn.closest("li");
+ var id = item.getAttribute("data-special-id");
editingSpecialId = id;
- document.getElementById('sc-overlay-title').textContent = 'Edytuj tort specjalny';
+ document.getElementById("sc-overlay-title").textContent =
+ "Edytuj tort specjalny";
var hidden = item.querySelectorAll('input[type="hidden"]');
var vals = {};
for (var i = 0; i < hidden.length; i++) {
- var name = hidden[i].getAttribute('name');
+ var name = hidden[i].getAttribute("name");
vals[name] = hidden[i].value;
}
- document.getElementById('sc-name').value = vals['special_name[]'] || '';
- document.getElementById('sc-price').value = vals['special_price[]'] || '';
- document.getElementById('sc-size').value = vals['special_size[]'] || '';
- document.getElementById('sc-shape').value = vals['special_shape[]'] || '';
- document.getElementById('sc-flavour').value = vals['special_flavour[]'] || '';
- document.getElementById('sc-notes').value = vals['special_notes[]'] || '';
- var currentTagIds = (vals['special_tags[]'] || '').split(',').filter(function(x) { return x; });
- document.getElementById('sc-new-tag').value = '';
- var cbs = document.querySelectorAll('.sc-tag-cb');
+ document.getElementById("sc-name").value = vals["special_name[]"] || "";
+ document.getElementById("sc-price").value = vals["special_price[]"] || "";
+ document.getElementById("sc-size").value = vals["special_size[]"] || "";
+ document.getElementById("sc-shape").value = vals["special_shape[]"] || "";
+ document.getElementById("sc-flavour").value = vals["special_flavour[]"] || "";
+ document.getElementById("sc-notes").value = vals["special_notes[]"] || "";
+ var currentTagIds = (vals["special_tags[]"] || "")
+ .split(",")
+ .filter(function (x) {
+ return x;
+ });
+ document.getElementById("sc-new-tag").value = "";
+ var cbs = document.querySelectorAll(".sc-tag-cb");
for (var i = 0; i < cbs.length; i++) {
cbs[i].checked = currentTagIds.indexOf(cbs[i].value) >= 0;
}
- document.getElementById('sc-overlay').classList.add('open');
- document.getElementById('sc-name').focus();
+ document.getElementById("sc-overlay").classList.add("open");
+ document.getElementById("sc-name").focus();
}
function removeSpecialCake(btn) {
- btn.closest('li').remove();
+ btn.closest("li").remove();
updateTotals();
}
@@ -146,40 +175,48 @@ function changeCake(id, name, price, delta) {
if (input != null) {
var qty = Number(input.value) + delta;
if (qty <= 0) {
- input.closest('li').remove();
+ input.closest("li").remove();
updateTotals();
updateCatalogueQty(id, 0);
return;
}
input.value = qty;
- var item = input.closest('li');
- item.querySelector('.qty').innerText = qty;
- item.querySelector('.price').innerText = price * qty + ' PLN';
+ var item = input.closest("li");
+ item.querySelector(".qty").innerText = qty;
+ item.querySelector(".price").innerText = price * qty + " PLN";
updateTotals();
updateCatalogueQty(id, qty);
return;
}
if (delta <= 0) return;
- var item = document.createElement('li');
- item.setAttribute('data-cake-id', id);
+ var item = document.createElement("li");
+ item.setAttribute("data-cake-id", id);
item.innerHTML =
'' +
- '
' + name + '
' +
- '
' + price + ' PLN × 1
' +
- '
' +
- '' + price + ' PLN
' +
+ '' +
+ name +
+ "
" +
+ '' +
+ price +
+ ' PLN × 1
' +
+ "" +
+ '' +
+ price +
+ " PLN
" +
'' +
- '';
- document.getElementById('basket-items').appendChild(item);
+ "" +
+ '';
+ document.getElementById("basket-items").appendChild(item);
updateTotals();
updateCatalogueQty(id, 1);
}
function removeCake(btn) {
- var item = btn.closest('li');
- var id = item.getAttribute('data-cake-id');
+ var item = btn.closest("li");
+ var id = item.getAttribute("data-cake-id");
item.remove();
updateTotals();
updateCatalogueQty(id, 0);
@@ -187,59 +224,64 @@ function removeCake(btn) {
function updatePrepaid() {
var paid = Number(document.querySelector('[name="paid"]')?.value || 0);
- document.getElementById('paid-amount').innerText = paid.toFixed(2) + ' PLN';
- document.getElementById('total-price').innerText = (subtotal - paid).toFixed(2) + ' PLN';
+ document.getElementById("paid-amount").innerText = paid.toFixed(2) + " PLN";
+ document.getElementById("total-price").innerText =
+ (subtotal - paid).toFixed(2) + " PLN";
}
function updateTotals() {
subtotal = 0;
- var items = document.querySelectorAll('#basket-items li');
+ var items = document.querySelectorAll("#basket-items li");
items.forEach(function (item) {
- var priceText = item.querySelector('.price').innerText;
- var price = Number(priceText.split(' ')[0]);
- if (item.hasAttribute('data-special-id')) {
+ var priceText = item.querySelector(".price").innerText;
+ var price = Number(priceText.split(" ")[0]);
+ if (item.hasAttribute("data-special-id")) {
subtotal += price;
} else {
- var qty = Number(item.querySelector('.qty').innerText);
+ var qty = Number(item.querySelector(".qty").innerText);
subtotal += price * qty;
}
});
- document.getElementById('subtotal-price').innerText = subtotal.toFixed(2) + ' PLN';
+ document.getElementById("subtotal-price").innerText =
+ subtotal.toFixed(2) + " PLN";
updatePrepaid();
}
function updateCatalogueQty(id, qty) {
- var el = document.getElementById('qty-' + id);
+ var el = document.getElementById("qty-" + id);
if (el) el.innerText = qty;
}
function toggleCatalogueTagFilter(btn) {
- var tag = btn.getAttribute('data-tag');
+ var tag = btn.getAttribute("data-tag");
var idx = activeCatalogueTags.indexOf(tag);
if (idx >= 0) {
activeCatalogueTags.splice(idx, 1);
- btn.classList.remove('active');
+ btn.classList.remove("active");
} else {
activeCatalogueTags.push(tag);
- btn.classList.add('active');
+ btn.classList.add("active");
}
applyCatalogueFilters();
}
function getCatalogueTextQuery() {
- var input = document.querySelector('#catalogue-grid').closest('.card').querySelector('input[type="text"]');
- return input ? input.value.toLowerCase() : '';
+ var input = document
+ .querySelector("#catalogue-grid")
+ .closest(".card")
+ .querySelector('input[type="text"]');
+ return input ? input.value.toLowerCase() : "";
}
function applyCatalogueFilters() {
var query = getCatalogueTextQuery();
- var items = document.querySelectorAll('#catalogue-grid > li');
+ var items = document.querySelectorAll("#catalogue-grid > li");
items.forEach(function (item) {
- var name = item.getAttribute('data-name').toLowerCase();
+ var name = item.getAttribute("data-name").toLowerCase();
var matchesText = name.includes(query);
var matchesTags = true;
if (activeCatalogueTags.length > 0) {
- var itemTags = (item.getAttribute('data-tags') || '').split(',');
+ var itemTags = (item.getAttribute("data-tags") || "").split(",");
for (var i = 0; i < activeCatalogueTags.length; i++) {
if (itemTags.indexOf(activeCatalogueTags[i]) < 0) {
matchesTags = false;
@@ -247,7 +289,7 @@ function applyCatalogueFilters() {
}
}
}
- item.classList.toggle('hide', !(matchesText && matchesTags));
+ item.classList.toggle("hide", !(matchesText && matchesTags));
});
}
@@ -256,126 +298,151 @@ function filterCatalogue(input) {
}
function toggleCakeTagFilter(btn) {
- var tag = btn.getAttribute('data-tag');
+ var tag = btn.getAttribute("data-tag");
var idx = activeCakeTags.indexOf(tag);
if (idx >= 0) {
activeCakeTags.splice(idx, 1);
- btn.classList.remove('active');
+ btn.classList.remove("active");
} else {
activeCakeTags.push(tag);
- btn.classList.add('active');
+ btn.classList.add("active");
}
- var rows = document.querySelectorAll('#cakes-card tbody tr');
+ var rows = document.querySelectorAll("#cakes-card tbody tr");
for (var i = 0; i < rows.length; i++) {
- if (activeCakeTags.length === 0) { rows[i].classList.remove('hide'); continue; }
- var rowTags = (rows[i].getAttribute('data-tags') || '').split(',');
+ if (activeCakeTags.length === 0) {
+ rows[i].classList.remove("hide");
+ continue;
+ }
+ var rowTags = (rows[i].getAttribute("data-tags") || "").split(",");
var match = false;
for (var j = 0; j < activeCakeTags.length; j++) {
- if (rowTags.indexOf(activeCakeTags[j]) >= 0) { match = true; break; }
+ if (rowTags.indexOf(activeCakeTags[j]) >= 0) {
+ match = true;
+ break;
+ }
}
- rows[i].classList.toggle('hide', !match);
+ rows[i].classList.toggle("hide", !match);
}
}
function filterOrders(input) {
var q = input.value.toLowerCase();
- var table = input.closest('.card').querySelector('.data-table');
+ var table = input.closest(".card").querySelector(".data-table");
if (!table) return;
- var rows = table.querySelectorAll('tbody tr');
+ var rows = table.querySelectorAll("tbody tr");
for (var i = 0; i < rows.length; i++) {
var id = rows[i].children[0].textContent.toLowerCase();
var customer = rows[i].children[1].textContent.toLowerCase();
- rows[i].classList.toggle('hide', !(id.includes(q) || customer.includes(q)));
+ rows[i].classList.toggle("hide", !(id.includes(q) || customer.includes(q)));
}
}
function setLocation(btn, value) {
- var group = btn.closest('.toggle-group');
- group.querySelectorAll('.toggle-btn').forEach(function(b) { b.classList.remove('active'); });
- btn.classList.add('active');
+ var group = btn.closest(".toggle-group");
+ group.querySelectorAll(".toggle-btn").forEach(function (b) {
+ b.classList.remove("active");
+ });
+ btn.classList.add("active");
group.querySelector('input[type="hidden"]').value = value;
}
function confirmBlockedDate(form) {
var date = form.querySelector('[name="date"]').value;
- var blocked = JSON.parse(form.getAttribute('data-blocked-dates') || '[]');
+ var blocked = JSON.parse(form.getAttribute("data-blocked-dates") || "[]");
var hasSpecial = form.querySelector('[name="special_name[]"]');
if (hasSpecial && blocked.indexOf(date) >= 0) {
- return confirm('Data ' + date + ' jest zablokowana dla zamówień z tortami specjalnymi. Czy na pewno chcesz kontynuować?');
+ return confirm(
+ "Data " +
+ date +
+ " jest zablokowana dla zamówień z tortami specjalnymi. Czy na pewno chcesz kontynuować?",
+ );
}
return true;
}
function initOrderPage() {
- var form = document.querySelector('.order-form');
+ var form = document.querySelector(".order-form");
if (!form) return;
- var state = form.getAttribute('data-state');
+ var state = form.getAttribute("data-state");
if (state) {
try {
var data = JSON.parse(state);
for (var id in data) {
updateCatalogueQty(Number(id), data[id]);
}
- } catch(e) {}
+ } catch (e) {}
}
updateTotals();
}
function setActiveLink() {
var path = window.location.pathname;
- var links = document.querySelectorAll('nav > a');
+ if (path === "/cake") {
+ path = "/cakes";
+ }
+ console.log(path);
+ var links = document.querySelectorAll("nav > a");
for (var i = 0; i < links.length; i++) {
- links[i].classList.toggle('active', links[i].getAttribute('href') === path);
+ links[i].classList.toggle("active", links[i].getAttribute("href") === path);
}
}
function viewSpecialCake(btn) {
- var tr = btn.closest('tr');
- document.getElementById('sc-view-title').textContent = tr.getAttribute('data-sc-name');
- document.getElementById('sc-view-name').textContent = tr.getAttribute('data-sc-name');
- document.getElementById('sc-view-price').textContent = tr.getAttribute('data-sc-price') + ' PLN';
- document.getElementById('sc-view-size').textContent = tr.getAttribute('data-sc-size') || '—';
- var shapeVal = tr.getAttribute('data-sc-shape');
- var shapeText = '';
- if (shapeVal === 'round') shapeText = 'Okrągły';
- else if (shapeVal === 'square') shapeText = 'Kwadrat';
- else shapeText = shapeVal || '—';
- document.getElementById('sc-view-shape').textContent = shapeText;
- document.getElementById('sc-view-flavour').textContent = tr.getAttribute('data-sc-flavour') || '—';
- document.getElementById('sc-view-notes').textContent = tr.getAttribute('data-sc-notes') || '—';
- document.getElementById('sc-view-client').textContent = tr.getAttribute('data-sc-client');
- document.getElementById('sc-view-date').textContent = tr.getAttribute('data-sc-date');
- var tagsStr = tr.getAttribute('data-sc-tags');
- var tagsContainer = document.getElementById('sc-view-tags');
- tagsContainer.innerHTML = '';
+ var tr = btn.closest("tr");
+ document.getElementById("sc-view-title").textContent =
+ tr.getAttribute("data-sc-name");
+ document.getElementById("sc-view-name").textContent =
+ tr.getAttribute("data-sc-name");
+ document.getElementById("sc-view-price").textContent =
+ tr.getAttribute("data-sc-price") + " PLN";
+ document.getElementById("sc-view-size").textContent =
+ tr.getAttribute("data-sc-size") || "—";
+ var shapeVal = tr.getAttribute("data-sc-shape");
+ var shapeText = "";
+ if (shapeVal === "round") shapeText = "Okrągły";
+ else if (shapeVal === "square") shapeText = "Kwadrat";
+ else shapeText = shapeVal || "—";
+ document.getElementById("sc-view-shape").textContent = shapeText;
+ document.getElementById("sc-view-flavour").textContent =
+ tr.getAttribute("data-sc-flavour") || "—";
+ document.getElementById("sc-view-notes").textContent =
+ tr.getAttribute("data-sc-notes") || "—";
+ document.getElementById("sc-view-client").textContent =
+ tr.getAttribute("data-sc-client");
+ document.getElementById("sc-view-date").textContent =
+ tr.getAttribute("data-sc-date");
+ var tagsStr = tr.getAttribute("data-sc-tags");
+ var tagsContainer = document.getElementById("sc-view-tags");
+ tagsContainer.innerHTML = "";
if (tagsStr) {
- var tagNames = tagsStr.split(',');
+ var tagNames = tagsStr.split(",");
for (var i = 0; i < tagNames.length; i++) {
if (tagNames[i].trim()) {
- var tag = document.createElement('span');
- tag.className = 'tag-chip sm';
+ var tag = document.createElement("span");
+ tag.className = "tag-chip sm";
tag.textContent = tagNames[i].trim();
tagsContainer.appendChild(tag);
}
}
- document.getElementById('sc-view-tags-field').classList.remove('hide');
+ document.getElementById("sc-view-tags-field").classList.remove("hide");
} else {
- document.getElementById('sc-view-tags-field').classList.add('hide');
+ document.getElementById("sc-view-tags-field").classList.add("hide");
}
- document.getElementById('sc-view-order-link').href = '/order/' + tr.getAttribute('data-sc-order-id');
- document.getElementById('sc-view-overlay').classList.add('open');
+ document.getElementById("sc-view-order-link").href =
+ "/order/" + tr.getAttribute("data-sc-order-id");
+ document.getElementById("sc-view-overlay").classList.add("open");
}
function closeViewSpecialCake() {
- document.getElementById('sc-view-overlay').classList.remove('open');
+ document.getElementById("sc-view-overlay").classList.remove("open");
}
-document.addEventListener('DOMContentLoaded', function() {
+document.addEventListener("DOMContentLoaded", function () {
setActiveLink();
initOrderPage();
});
-document.addEventListener('htmx:afterSettle', function() {
+document.addEventListener("htmx:afterSettle", function () {
setActiveLink();
initOrderPage();
});
diff --git a/server/templates/layout.templ b/server/templates/layout.templ
index d336d2b..db3388a 100644
--- a/server/templates/layout.templ
+++ b/server/templates/layout.templ
@@ -1,5 +1,12 @@
package templates
+templ link(href string, icon string, name string) {
+
+ { icon }
+ { name }
+
+}
+
templ Layout(title string, main templ.Component) {
@@ -16,23 +23,11 @@ templ Layout(title string, main templ.Component) {
@main