151 lines
7 KiB
Common Lisp
151 lines
7 KiB
Common Lisp
(text "{%- import \"components.html\" as components -%} {%- import \"macros.html\" as macros -%}")
|
|
(text "<!doctype html>")
|
|
|
|
(html
|
|
("lang" "en")
|
|
(head
|
|
(meta ("charset" "UTF-8"))
|
|
(meta ("name" "viewport") ("content" "width=device-width, initial-scale=1.0"))
|
|
(meta ("http-equiv" "X-UA-Compatible") ("content" "ie=edge"))
|
|
|
|
(link ("rel" "icon") ("href" "/public/favicon.svg"))
|
|
(link ("rel" "stylesheet") ("href" "/css/style.css?v=tetratto-{{ random_cache_breaker }}"))
|
|
|
|
(text "{% if user -%}
|
|
<script>
|
|
window.localStorage.setItem(
|
|
\"tetratto:theme\",
|
|
\"{{ user.settings.theme_preference }}\",
|
|
);
|
|
</script>
|
|
{%- endif %}")
|
|
|
|
(text "<script>
|
|
globalThis.ns_config = {
|
|
root: \"/js/\",
|
|
verbose: false,
|
|
version: \"tetratto-{{ random_cache_breaker }}\",
|
|
};
|
|
|
|
globalThis._app_base = {
|
|
name: \"tetratto\",
|
|
ns_store: {},
|
|
classes: {},
|
|
};
|
|
|
|
globalThis.no_policy = false;
|
|
globalThis.BUILD_CODE = \"{{ random_cache_breaker }}\";
|
|
globalThis.TETRATTO_LINK_HANDLER_CTX = \"net\";
|
|
</script>")
|
|
|
|
(script ("src" "/js/loader.js?v=tetratto-{{ random_cache_breaker }}" ))
|
|
(script ("src" "/js/atto.js?v=tetratto-{{ random_cache_breaker }}" ))
|
|
(script ("defer" "true") ("src" "/js/proto_links.js?v=tetratto-{{ random_cache_breaker }}" ))
|
|
|
|
(meta ("name" "theme-color") ("content" "{{ config.color }}"))
|
|
(meta ("name" "description") ("content" "{{ config.description }}"))
|
|
(meta ("property" "og:type") ("content" "website"))
|
|
(meta ("property" "og:site_name") ("content" "{{ config.name }}"))
|
|
|
|
(meta ("name" "turbo-prefetch") ("content" "false"))
|
|
(meta ("name" "turbo-refresh-method") ("content" "morph"))
|
|
(meta ("name" "turbo-refresh-scroll") ("content" "preserve"))
|
|
|
|
(script ("src" "https://unpkg.com/@hotwired/turbo@8.0.5/dist/turbo.es2017-esm.js") ("type" "module") ("async" "") ("defer" ""))
|
|
|
|
(text "{% block head %}{% endblock %}"))
|
|
|
|
(body
|
|
(div
|
|
("id" "page")
|
|
(text "{% if user and user.id == 0 -%}")
|
|
; account banned message
|
|
(article
|
|
(main
|
|
(div
|
|
("class" "card-nest")
|
|
(div
|
|
("class" "card small flex items-center gap-2 red")
|
|
(icon (text "frown"))
|
|
(str (text "general:label.account_banned")))
|
|
|
|
(div
|
|
("class" "card flex flex-col gap-2 no_p_margin")
|
|
(str (text "general:label.account_banned_body"))
|
|
(hr)
|
|
(span ("class" "fade") (text "The following reason was provided by a moderator:"))
|
|
(div
|
|
("class" "card lowered w-full")
|
|
(text "{{ user.ban_reason|markdown|safe }}"))))))
|
|
|
|
; if we aren't banned, just show the page body
|
|
(text "{% elif user and user.awaiting_purchase %}")
|
|
; account waiting for payment message
|
|
(article
|
|
(main
|
|
(div
|
|
("class" "card-nest")
|
|
(div
|
|
("class" "card small flex items-center gap-2 red")
|
|
(icon (text "frown"))
|
|
(str (text "general:label.must_activate_account")))
|
|
|
|
(div
|
|
("class" "card no_p_margin flex flex-col gap-2")
|
|
(p (text "Since you didn't provide an invite code, you'll need to activate your account to use it."))
|
|
(p (text "Supporter is a recurring membership. If you cancel it, your account will be locked again unless you renew your subscription or provide an invite code."))
|
|
(div
|
|
("class" "card w-full lowered flex flex-col gap-2")
|
|
(text "{{ components::become_supporter_button() }}"))
|
|
(p (text "Alternatively, you can provide an invite code to activate your account."))
|
|
(form
|
|
("class" "card w-full lowered flex flex-col gap-2")
|
|
("onsubmit" "update_invite_code(event)")
|
|
(div
|
|
("class" "flex flex-col gap-1")
|
|
(label
|
|
("for" "invite_code")
|
|
(b
|
|
(text "Invite code")))
|
|
(input
|
|
("type" "text")
|
|
("placeholder" "invite code")
|
|
("name" "invite_code")
|
|
("required" "")
|
|
("id" "invite_code")))
|
|
|
|
(button
|
|
(text "Submit")))
|
|
|
|
(script
|
|
(text "async function update_invite_code(e) {
|
|
e.preventDefault();
|
|
await trigger(\"atto::debounce\", [\"invite_codes::try\"]);
|
|
fetch(\"/api/v1/auth/user/me/invite_code\", {
|
|
method: \"POST\",
|
|
headers: {
|
|
\"Content-Type\": \"application/json\",
|
|
},
|
|
body: JSON.stringify({
|
|
invite_code: e.target.invite_code.value,
|
|
}),
|
|
})
|
|
.then((res) => res.json())
|
|
.then((res) => {
|
|
trigger(\"atto::toast\", [
|
|
res.ok ? \"success\" : \"error\",
|
|
res.message,
|
|
]);
|
|
|
|
if (res.ok) {
|
|
window.location.reload();
|
|
}
|
|
});
|
|
}"))))))
|
|
(text "{% else %}")
|
|
; page body
|
|
(text "{% block body %}{% endblock %}")
|
|
(text "{%- endif %}")
|
|
(text "<!-- html_footer_goes_here -->"))
|
|
|
|
(text "{% include \"body.html\" %}")))
|