146 lines
4.8 KiB
Common Lisp
146 lines
4.8 KiB
Common Lisp
(text "{% extends \"root.html\" %} {% block head %}")
|
|
(title
|
|
(text "{{ product.title }} - {{ config.name }}"))
|
|
(text "{% endblock %} {% block body %} {{ macros::nav(selected=\"\") }}")
|
|
(main
|
|
("class" "flex flex_col gap_2")
|
|
(text "{{ components::post_media(upload_ids=product.uploads.thumbnails) }}")
|
|
(div
|
|
("class" "card flex flex_col gap_2")
|
|
(h3
|
|
("style" "height: 32px")
|
|
(text "{{ product.title }}"))
|
|
(text "{{ components::full_username(user=owner) }}")
|
|
|
|
(text "{% if product.stock >= 0 -%}")
|
|
(span ("class" "red") (text "{{ product.stock }} remaining"))
|
|
(text "{%- endif %}")
|
|
|
|
(div
|
|
("class" "card lowered w_full no_p_margin")
|
|
(text "{{ product.description|markdown|safe }}"))
|
|
|
|
(text "{% if already_purchased -%}")
|
|
(span
|
|
("class" "green flex items_center gap_2")
|
|
(icon (text "circle-check"))
|
|
(str (text "economy:label.already_purchased")))
|
|
(text "{%- endif %}")
|
|
|
|
(div
|
|
("class" "flex gap_2 items_center")
|
|
(text "{% if user.id != product.owner -%}")
|
|
(text "{% if not already_purchased -%}")
|
|
; price
|
|
(a
|
|
("class" "button camo lowered")
|
|
("href" "/wallet")
|
|
("target" "_blank")
|
|
(icon (text "badge-cent"))
|
|
(text "{{ product.price }}"))
|
|
; buy button
|
|
(button
|
|
("onclick" "purchase()")
|
|
("disabled" "{{ product.stock == 0 }}")
|
|
(icon (text "piggy-bank"))
|
|
(str (text "economy:action.buy")))
|
|
(text "{% else %}")
|
|
; profile style snippets
|
|
(text "{% if product.method == \"ProfileStyle\" -%} {% if not product.id in applied_configurations_mapped -%}")
|
|
(button
|
|
("onclick" "apply()")
|
|
(icon (text "check"))
|
|
(str (text "economy:action.apply")))
|
|
(text "{% else %}")
|
|
(button
|
|
("onclick" "remove()")
|
|
(icon (text "x"))
|
|
(str (text "economy:action.unapply")))
|
|
(text "{%- endif %} {%- endif %}")
|
|
; ...
|
|
(text "{%- endif %}")
|
|
(text "{% else %}")
|
|
(a
|
|
("class" "button")
|
|
("href" "/product/{{ product.id }}/edit")
|
|
(icon (text "settings"))
|
|
(str (text "general:label.edit")))
|
|
(text "{%- endif %}"))))
|
|
|
|
(script
|
|
(text "async function purchase() {
|
|
await trigger(\"atto::debounce\", [\"products::buy\"]);
|
|
|
|
if (
|
|
!(await trigger(\"atto::confirm\", [
|
|
\"Are you sure you would like to do this? Your new balance will be {{ user.coins - product.price }} coins.\",
|
|
]))
|
|
) {
|
|
return;
|
|
}
|
|
|
|
fetch(\"/api/v1/products/{{ product.id }}/buy\", {
|
|
method: \"POST\",
|
|
})
|
|
.then((res) => res.json())
|
|
.then((res) => {
|
|
trigger(\"atto::toast\", [
|
|
res.ok ? \"success\" : \"error\",
|
|
res.message,
|
|
]);
|
|
|
|
if (res.ok) {
|
|
window.location.reload();
|
|
}
|
|
});
|
|
}
|
|
|
|
async function apply() {
|
|
await trigger(\"atto::debounce\", [\"user::update\"]);
|
|
fetch(\"/api/v1/auth/user/{{ user.id }}/applied_configuration\", {
|
|
method: \"POST\",
|
|
headers: {
|
|
\"Content-Type\": \"application/json\",
|
|
},
|
|
body: JSON.stringify({
|
|
\"type\": \"StyleSnippet\",
|
|
\"id\": \"{{ product.id }}\",
|
|
}),
|
|
})
|
|
.then((res) => res.json())
|
|
.then((res) => {
|
|
trigger(\"atto::toast\", [
|
|
res.ok ? \"success\" : \"error\",
|
|
res.message,
|
|
]);
|
|
|
|
if (res.ok) {
|
|
window.location.reload();
|
|
}
|
|
});
|
|
}
|
|
|
|
async function remove() {
|
|
await trigger(\"atto::debounce\", [\"user::update\"]);
|
|
fetch(\"/api/v1/auth/user/{{ user.id }}/applied_configuration\", {
|
|
method: \"DELETE\",
|
|
headers: {
|
|
\"Content-Type\": \"application/json\",
|
|
},
|
|
body: JSON.stringify({
|
|
\"id\": \"{{ product.id }}\",
|
|
}),
|
|
})
|
|
.then((res) => res.json())
|
|
.then((res) => {
|
|
trigger(\"atto::toast\", [
|
|
res.ok ? \"success\" : \"error\",
|
|
res.message,
|
|
]);
|
|
|
|
if (res.ok) {
|
|
window.location.reload();
|
|
}
|
|
});
|
|
}"))
|
|
(text "{% endblock %}")
|