tetratto/crates/app/src/public/html/economy/edit.lisp
2025-08-08 14:17:40 -04:00

355 lines
12 KiB
Common Lisp

(text "{% extends \"root.html\" %} {% block head %}")
(title
(text "Manage product - {{ config.name }}"))
(text "{% endblock %} {% block body %} {{ macros::nav(selected=\"\") }}")
(main
("class" "flex flex_col gap_2")
(div
("class" "card_nest")
(div
("class" "card small flex gap_2 items_center")
(icon (text "pencil-line"))
(b
(str (text "economy:label.title"))))
(form
("class" "card flex flex_col gap_2")
("onsubmit" "update_title_from_form(event)")
(div
("class" "flex flex_col gap_1")
(label
("for" "title")
(str (text "economy:label.title")))
(input
("type" "text")
("name" "title")
("id" "title")
("placeholder" "title")
("required" "")
("minlength" "2")
("maxlength" "128")
("value" "{{ product.title }}")))
(button (str (text "general:action.save")))))
(div
("class" "card_nest")
(div
("class" "card small flex gap_2 items_center")
(icon (text "pencil-line"))
(b
(str (text "economy:label.description"))))
(form
("class" "card flex flex_col gap_2")
("onsubmit" "update_description_from_form(event)")
(div
("class" "flex flex_col gap_1")
(label
("for" "description")
(str (text "economy:label.description")))
(textarea
("name" "description")
("id" "description")
("placeholder" "description")
("required" "")
("minlength" "2")
("maxlength" "1024")
(text "{{ product.description }}")))
(button (str (text "general:action.save")))))
(div
("class" "card_nest")
(div
("class" "card small flex gap_2 items_center")
(icon (text "badge-cent"))
(b
(str (text "economy:label.price"))))
(form
("class" "card flex flex_col gap_2")
("onsubmit" "update_price_from_form(event)")
(label
("for" "on_sale")
("class" "flex items_center gap_2")
(input
("type" "checkbox")
("id" "on_sale")
("name" "on_sale")
("class" "w_content")
("checked" "{{ product.on_sale }}")
("oninput" "event.preventDefault(); update_on_sale_from_form(event.target.checked)"))
(span
(str (text "economy:label.on_sale"))))
(label
("for" "single_use")
("class" "flex items_center gap_2")
(input
("type" "checkbox")
("id" "single_use")
("name" "single_use")
("class" "w_content")
("checked" "{{ product.single_use }}")
("oninput" "event.preventDefault(); update_single_use_from_form(event.target.checked)"))
(span
(str (text "economy:label.single_use"))))
(div
("class" "flex flex_col gap_1")
(label
("for" "title")
(str (text "economy:label.price")))
(input
("type" "number")
("name" "price")
("id" "price")
("placeholder" "price")
("required" "")
("min" "0")
("max" "1000000")
("value" "{{ product.price }}")))
(button (str (text "general:action.save")))))
(div
("class" "card_nest")
(div
("class" "card small flex gap_2 items_center")
(icon (text "weight"))
(b
(str (text "economy:label.stock"))))
(form
("class" "card flex flex_col gap_2")
("onsubmit" "update_stock_from_form(event)")
(label
("for" "unlimited")
("class" "flex items_center gap_2")
(input
("type" "checkbox")
("id" "unlimited")
("name" "unlimited")
("class" "w_content")
("checked" "{{ product.stock == -1 }}")
("oninput" "event.preventDefault(); event.target.checked ? document.getElementById('stock').value = -1 : document.getElementById('stock').value = 0"))
(span
(str (text "economy:label.unlimited"))))
(div
("class" "flex flex_col gap_1")
(label
("for" "title")
(str (text "economy:label.stock")))
(input
("type" "number")
("name" "stock")
("id" "stock")
("placeholder" "stock")
("required" "")
("min" "-1")
("max" "1000000")
("value" "{{ product.stock }}")))
(button (str (text "general:action.save")))))
(div
("class" "card_nest")
(div
("class" "card small flex gap_2 items_center")
(icon (text "package-check"))
(b
(str (text "economy:label.fulfillment_style"))))
(form
("class" "card flex flex_col gap_2")
("onsubmit" "update_method_from_form(event)")
(p (text "If you choose to send an automated mail letter upon purchase, users will automatically receive the message you supply below."))
(p (text "If you disable automail, you'll be required to manually mail users who have purchased your product before the transfer is finalized."))
(label
("for" "use_automail")
("class" "flex items_center gap_2")
(input
("type" "checkbox")
("id" "use_automail")
("name" "use_automail")
("class" "w_content")
("oninput" "mirror_use_automail()")
("checked" "{% if product.method != \"ManualMail\" -%} true {%- else -%} false {%- endif %}"))
(span
(str (text "economy:label.use_automail"))))
(div
("class" "flex flex_col gap_1")
(label
("for" "automail_message")
(str (text "economy:label.automail_message")))
(textarea
("name" "automail_message")
("id" "automail_message")
("placeholder" "automail_message")
(text "{% if product.method != \"ManualMail\" -%} {{ product.method.AutoMail }} {%- endif %}")))
(button (str (text "general:action.save")))))
(a
("class" "button secondary")
("href" "/product/{{ product.id }}")
(icon (text "arrow-left"))
(str (text "general:action.back"))))
(script
(text "async function update_title_from_form(e) {
e.preventDefault();
await trigger(\"atto::debounce\", [\"products::update\"]);
fetch(\"/api/v1/products/{{ product.id }}/title\", {
method: \"POST\",
headers: {
\"Content-Type\": \"application/json\",
},
body: JSON.stringify({
title: e.target.title.value,
}),
})
.then((res) => res.json())
.then((res) => {
trigger(\"atto::toast\", [
res.ok ? \"success\" : \"error\",
res.message,
]);
});
}
async function update_description_from_form(e) {
e.preventDefault();
await trigger(\"atto::debounce\", [\"products::update\"]);
fetch(\"/api/v1/products/{{ product.id }}/description\", {
method: \"POST\",
headers: {
\"Content-Type\": \"application/json\",
},
body: JSON.stringify({
description: e.target.description.value,
}),
})
.then((res) => res.json())
.then((res) => {
trigger(\"atto::toast\", [
res.ok ? \"success\" : \"error\",
res.message,
]);
});
}
async function update_on_sale_from_form(on_sale) {
await trigger(\"atto::debounce\", [\"products::update\"]);
fetch(\"/api/v1/products/{{ product.id }}/on_sale\", {
method: \"POST\",
headers: {
\"Content-Type\": \"application/json\",
},
body: JSON.stringify({
on_sale,
}),
})
.then((res) => res.json())
.then((res) => {
trigger(\"atto::toast\", [
res.ok ? \"success\" : \"error\",
res.message,
]);
});
}
async function update_single_use_from_form(single_use) {
await trigger(\"atto::debounce\", [\"products::update\"]);
fetch(\"/api/v1/products/{{ product.id }}/single_use\", {
method: \"POST\",
headers: {
\"Content-Type\": \"application/json\",
},
body: JSON.stringify({
single_use,
}),
})
.then((res) => res.json())
.then((res) => {
trigger(\"atto::toast\", [
res.ok ? \"success\" : \"error\",
res.message,
]);
});
}
async function update_price_from_form(e) {
e.preventDefault();
await trigger(\"atto::debounce\", [\"products::update\"]);
fetch(\"/api/v1/products/{{ product.id }}/price\", {
method: \"POST\",
headers: {
\"Content-Type\": \"application/json\",
},
body: JSON.stringify({
price: e.target.price.valueAsNumber,
}),
})
.then((res) => res.json())
.then((res) => {
trigger(\"atto::toast\", [
res.ok ? \"success\" : \"error\",
res.message,
]);
});
}
async function update_stock_from_form(e) {
e.preventDefault();
await trigger(\"atto::debounce\", [\"products::update\"]);
fetch(\"/api/v1/products/{{ product.id }}/stock\", {
method: \"POST\",
headers: {
\"Content-Type\": \"application/json\",
},
body: JSON.stringify({
stock: e.target.stock.valueAsNumber,
}),
})
.then((res) => res.json())
.then((res) => {
trigger(\"atto::toast\", [
res.ok ? \"success\" : \"error\",
res.message,
]);
});
}
async function update_method_from_form(e) {
e.preventDefault();
await trigger(\"atto::debounce\", [\"products::update\"]);
fetch(\"/api/v1/products/{{ product.id }}/method\", {
method: \"POST\",
headers: {
\"Content-Type\": \"application/json\",
},
body: JSON.stringify({
method: e.target.use_automail.checked ? { AutoMail: e.target.automail_message.value } : \"ManualMail\",
}),
})
.then((res) => res.json())
.then((res) => {
trigger(\"atto::toast\", [
res.ok ? \"success\" : \"error\",
res.message,
]);
});
}
globalThis.mirror_use_automail = () => {
const use_automail = document.getElementById(\"use_automail\").checked;
if (use_automail) {
document.getElementById(\"automail_message\").removeAttribute(\"disabled\");
} else {
document.getElementById(\"automail_message\").setAttribute(\"disabled\", \"true\");
}
}
setTimeout(() => {
mirror_use_automail();
}, 150);"))
(text "{% endblock %}")