(text "{% extends \"root.html\" %} {% block head %}") (title (text "Wallet - {{ config.name }}")) (text "{% endblock %} {% block body %} {{ macros::nav(selected=\"wallet\") }}") (main ("class" "flex flex_col gap_2") (div ("class" "card_nest") (div ("class" "card small flex items_center justify_between gap_2") (span ("class" "flex items_center gap_2") (icon (text "piggy-bank")) (span (str (text "general:link.wallet")))) (button ("class" "lowered small square tiny big_icon") ("onclick" "document.getElementById('buy_dialog').showModal()") ("title" "Buy coins") (icon (text "plus")))) (div ("class" "card lowered flex flex_col gap_4") (button ("class" "card button raised") ("onclick" "document.getElementById('buy_dialog').showModal()") (b (text "Coin balance")) (h3 ("class" "flex gap_2 items_center") ("style" "height: 24px") (icon (text "badge-cent")) (text "{{ user.coins }}"))))) (div ("class" "card_nest") (div ("class" "card small flex items_center justify_between gap_2") (span ("class" "flex items_center gap_2") (icon (text "clock")) (span (str (text "economy:label.recent_transfers"))))) (div ("class" "card lowered flex flex_col gap_4") (div ("class" "w_full") ("style" "overflow: auto") (table ("class" "w_full") (thead (th (text "Created")) (th (text "Sender")) (th (text "Receiver")) (th (text "Amount")) (th (text "Product")) (th (text "Source")) (th (text "Actions"))) (tbody (text "{% for transfer in list -%}") (tr (td (span ("class" "date short") (text "{{ transfer[3].created }}"))) (td ("class" "w_content") (text "{{ components::full_username(user=transfer[0], wrap=false) }}")) (td ("class" "w_content") (text "{{ components::full_username(user=transfer[1], wrap=false) }}")) (td ("class" "flex items_center gap_1") (text "{{ transfer[3].amount }}") (text "{% if transfer[3].is_pending -%}") (span ("class" "flex items_center gap_1") ("title" "Pending") (icon (text "clock"))) (text "{%- endif %}")) (td (text "{% if transfer[2] -%}") (a ("href" "/product/{{ transfer[2].id }}") (icon (text "external-link"))) (text "{%- endif %}")) (td (text "{{ transfer[3].source }}")) (td (text "{% if user.id == transfer[1].id and transfer[3].source == '\"Sale\"' -%}") ; we're the receiver (button ("class" "small tiny square raised camo big_icon") ("onclick" "issue_refund('{{ transfer[3].id }}')") ("title" "Issue refund") (icon (text "undo"))) (text "{%- endif %}"))) (text "{%- endfor %}"))))))) (dialog ("id" "buy_dialog") (div ("class" "inner flex flex_col gap_2") (p (text "All coin purchases are one-time and will not recur.")) (p (text "If you do not receive your coins within a minute of purchase, please contact support.")) (button ("class" "lowered w_full justify_start") ("onclick" "checkout('Coins100')") (text "100 coins ({{ config.stripe.price_texts.coins_100 }})")) (button ("class" "w_full justify_start") ("onclick" "checkout('Coins400')") (text "400 coins ({{ config.stripe.price_texts.coins_400 }})")) (hr ("class" "margin")) (div ("class" "flex gap_2 justify_between") (div null?) (button ("class" "lowered red") ("type" "button") ("onclick", "document.getElementById('buy_dialog').close()") (icon (text "x")) (str (text "dialog:action.cancel")))))) (script (text "globalThis.checkout = (product) => { document.getElementById('buy_dialog').close(); fetch(\"/api/v1/service_hooks/stripe/checkout\", { method: \"POST\", headers: { \"Content-Type\": \"application/json\", }, body: JSON.stringify({ product, }), }) .then((res) => res.json()) .then((res) => { trigger(\"atto::toast\", [res.ok ? \"success\" : \"error\", res.message]); if (res.ok) { window.location.href = res.payload; } }); } globalThis.issue_refund = async (transfer) => { if ( !(await trigger(\"atto::confirm\", [ \"Are you sure you would like to do this?\", ])) ) { return; } fetch(`/api/v1/transfers/${transfer}/refund`, { method: \"POST\", }) .then((res) => res.json()) .then((res) => { trigger(\"atto::toast\", [res.ok ? \"success\" : \"error\", res.message]); }); }")) (text "{% endblock %}")