384 lines
13 KiB
Common Lisp
384 lines
13 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")))))
|
|
|
|
(div
|
|
("class" "flex gap_2")
|
|
(a
|
|
("class" "button secondary")
|
|
("href" "/product/{{ product.id }}")
|
|
(icon (text "arrow-left"))
|
|
(str (text "general:action.back")))
|
|
|
|
(button
|
|
("class" "lowered red")
|
|
("onclick" "delete_product()")
|
|
(icon (text "trash"))
|
|
(str (text "general:action.delete")))))
|
|
|
|
(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,
|
|
]);
|
|
});
|
|
}
|
|
|
|
async function delete_product() {
|
|
if (
|
|
!(await trigger(\"atto::confirm\", [
|
|
\"Are you sure you would like to do this?\",
|
|
]))
|
|
) {
|
|
return;
|
|
}
|
|
|
|
fetch(\"/api/v1/products/{{ product.id }}\", {
|
|
method: \"DELETE\",
|
|
})
|
|
.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 %}")
|