2025-05-31 10:17:49 -04:00
( 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" ) )
2025-06-19 15:48:04 -04:00
( link ( "rel" "stylesheet" ) ( "href" "/css/style.css?v=tetratto-{{ random_cache_breaker }}" ) )
2025-05-31 10:17:49 -04:00
( text " {% if user -%}
<script>
window.localStorage.setItem (
\"tetratto:theme\",
\"{{ user.settings.theme_preference }}\",
) ;
</script>
{%- endif %} " )
( text " <script>
globalThis.ns_config = {
root: \"/js/\",
2025-06-25 23:15:24 -04:00
verbose: false,
2025-06-18 19:21:01 -04:00
version: \"tetratto-{{ random_cache_breaker }}\",
2025-05-31 10:17:49 -04:00
} ;
globalThis._app_base = {
name: \"tetratto\",
ns_store: {},
classes: {},
} ;
globalThis.no_policy = false ;
2025-06-17 01:52:17 -04:00
globalThis.BUILD_CODE = \"{{ random_cache_breaker }}\" ;
2025-05-31 10:17:49 -04:00
</script> " )
2025-06-18 19:21:01 -04:00
( script ( "src" "/js/loader.js?v=tetratto-{{ random_cache_breaker }}" ) )
( script ( "src" "/js/atto.js?v=tetratto-{{ random_cache_breaker }}" ) )
2025-05-31 10:17:49 -04:00
( meta ( "name" "theme-color" ) ( "content" "{{ config.color }}" ) )
( meta ( "name" "description" ) ( "content" "{{ config.description }}" ) )
( meta ( "property" "og:type" ) ( "content" "website" ) )
2025-06-01 12:25:33 -04:00
( meta ( "property" "og:site_name" ) ( "content" "{{ config.name }}" ) )
2025-05-31 10:17:49 -04:00
( 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" )
2025-05-31 13:07:34 -04:00
( icon ( text "frown" ) )
( str ( text "general:label.account_banned" ) ) )
2025-05-31 10:17:49 -04:00
( div
( "class" "card" )
2025-05-31 13:07:34 -04:00
( str ( text "general:label.account_banned_body" ) ) ) ) ) )
2025-05-31 10:17:49 -04:00
; if we aren't banned, just show the page body
2025-07-03 21:56:21 -04:00
( 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 %}" )
2025-05-31 10:17:49 -04:00
( text "<!-- html_footer_goes_here -->" ) )
2025-06-09 16:45:36 -04:00
( text "{% include \"body.html\" %}" ) ) )