Compare commits

...

23 Commits

Author SHA1 Message Date
Alex Tavarez
d6256dfa18 Added some further clarification, added an unfinished section 2025-09-07 14:23:52 -04:00
Alex Tavarez
acc2106e67 Added tasks related to project structure changes and new pages, reordered tasks 2025-09-07 14:19:57 -04:00
Alex Tavarez
08850f4d82 Added another task set, this time planning for an extra page 2025-09-07 13:52:21 -04:00
Alex Tavarez
d17e421618 Updated to reflect current tasks 2025-09-07 00:20:41 -04:00
Alex Tavarez
56ce939843 Improved clarity by removing or refactoring disruptive paragraph or sidenote 2025-09-06 23:35:00 -04:00
Alex Tavarez
30a9f4cc82 Fixed typo 2025-09-06 23:31:57 -04:00
Alex Tavarez
3764fdcf99 Added note about idiomatic Elixir 2025-09-06 23:30:26 -04:00
Alex Tavarez
916584dfe9 Fixed typo 2025-09-06 23:23:00 -04:00
Alex Tavarez
681854dc58 Added more imperative language to instructional headers 2025-09-06 23:22:19 -04:00
Alex Tavarez
f02c0777c1 Fixed typo 2025-09-06 23:20:14 -04:00
Alex Tavarez
9189ba54cc Improved clarity 2025-09-06 23:17:49 -04:00
Alex Tavarez
b5a96c7940 Changed hypothetical shell variable to futureproof documentation, removed link to gitignored image 2025-09-06 23:14:59 -04:00
Alex Tavarez
e8232ee713 Changed and expanded upon default README supplied by 'mix phx.new' command 2025-09-06 23:10:00 -04:00
Alex Tavarez
776646ef12 Added reference to declared variable for users table's email field 2025-09-03 14:35:47 -04:00
Alex Tavarez
ab5711c584 Added a variable declaration in SQL script 2025-09-03 14:35:03 -04:00
Alex Tavarez
7a8555dc85 Created separate SQL file specifically for inserting initial default admin account 2025-09-03 14:28:35 -04:00
Alex Tavarez
77c87921f6 Added more field columns to schema creation for users table 2025-09-03 14:25:21 -04:00
Alex Tavarez
ab49a6d04f Changed tasks in tasklist 2025-09-03 13:15:00 -04:00
Alex Tavarez
9ac6866860 Attempting to add some HEEx error pages 2025-09-03 13:14:39 -04:00
Alex Tavarez
a2ce551e7c Added some temporary exclusions for git version control 2025-09-03 13:14:11 -04:00
Alex Tavarez
12220c730e HEEx pages for the website 2025-09-03 13:12:13 -04:00
Alex Tavarez
d7aa194327 Ignore static content 2025-09-03 13:00:29 -04:00
Alex Tavarez
1997fa2aab Removing symbolic link from repo 2025-09-03 12:57:41 -04:00
16 changed files with 811 additions and 13 deletions

10
.gitignore vendored
View File

@@ -42,11 +42,21 @@ npm-debug.log
# Backup files and directories # Backup files and directories
*.bak *.bak
# TOTP test file
otp-test.enc
# SSL certificates # SSL certificates
/priv/cert/* /priv/cert/*
# Ignore static content; must be manually shipped # Ignore static content; must be manually shipped
/priv/static/*/** /priv/static/*/**
/assets/css/*.tailwind
/assets/css/*.tailwind.map
/assets/sass/app.sass
# Ignore markdown; must be manually shipped # Ignore markdown; must be manually shipped
/lib/sukaato_web/controllers/page_md/**/* /lib/sukaato_web/controllers/page_md/**/*
# Temporary
/lib/sukaato_web/controllers/page_html/users/anon/*
/lib/sukaato_web/controllers/page_json/users/anon/*

View File

@@ -1,18 +1,63 @@
# Sukaato # Sukaato
To start your Phoenix server: This repository is to define a backend for, and to serve, my website. The code here is building upon the basis of a project structure and associated source code supplied by the [Elxir](https://elixir-lang.org/) [Phoenix](https://hexdocs.pm/phoenix/installation.html) web framework package(s)/module(s) and the associated CLI utilities.
* Run `mix setup` to install and setup dependencies > [!NOTE]
* Start Phoenix endpoint with `mix phx.server` or inside IEx with `iex -S mix phx.server` > Not only is this a WIP, but this project is the first time I've ever used the Elixir programming language. As of yet, the source code is not written idiomatically.
Now you can visit [`localhost:4000`](http://localhost:4000) from your browser. ## Execution and installation
Ready to run in production? Please [check our deployment guides](https://hexdocs.pm/phoenix/deployment.html). There are a collection of procedures to follow for proper execution and installation of this server and its website. This is a highly abstract, simplified summary of the execution and installation processes. The plan is to provide more detailed exposition and more precise articulation of the execution and installation processes as the project itself is developed, as some other packages, software tools, or scripts that may be introduced may change the needed detail or precision herein. Some design approaches, structure specifications, and so on, may also have yet to be finalized.
### Prerequisitess for Execution or Installation
#### Configure `site.toml`
Make sure to configure things like the website's name, author, etc., via the `${SUKAATO_SITE_SOURCE_ROOT}/site.toml` file.
#### Supply Resources to Themes
Make sure that subdirectories under path `${SUKAATO_SITE_SOURCE_ROOT}/priv/static/` are appropriately populated. Either follow the active/enabled theme's CSS/SASS path references, or change such path references to match custom `${SUKAATO_SITE_SOURCE_ROOT}/priv/static` prefixed filepaths.
References to paths in CSS/SASS file should be absolute paths, insofar as their root is known and is `${SUKAATO_SITE_SOURCE_ROOT}/priv/static`. That is, they are relative to the aforementioned path, but not relative to the CSS/SASS file being currently edited.
> [!WARNING]
> The paths referenced in CSS/SASS files recursively under `${SUKAATO_SITE_SOURCE_ROOT}/assets/sass/` or `${SUKAATO_SITE_SOURCE_ROOT}/assets/css/` are relative to `${SUKAATO_SITE_SOURCE_ROOT}/priv/static` and not each such CSS/SASS file currently being edited. This is UNLESS subdirectories of `${SUKAATO_SITE_SOURCE_ROOT}/priv/static/` [have not been marked as external for/to `:esbuild` in `${SUKAATO_SITE_SOURCE_ROOT}/config/config.exs`](https://hexdocs.pm/phoenix/asset_management.html#images-fonts-and-external-files); in that case, the given filepaths will never be found anyway.
SASS files can be found under path `${SUKAATO_SITE_SOURCE_ROOT}/assets/sass/themes/**/`, while CSS files can be found under path `${SUKAATO_SITE_SOURCE_ROOT}/assets/css/`.
> [!TIP]
> Avoid editing file `app.css` under `${SUKAATO_SITE_SOURCE_ROOT}/assets/css/` path directly. Edit SASS files under `${SUKAATO_SITE_SOURCE_ROOT}/assets/sass/themes/${theme_name}/` wherein `$theme_name` corresponds to name of enabled/active website theme. The aforementioned `app.css` file should be the final output starting from the preprocessing of SASS files recursively found under any subdirectory at `${SUKAATO_SITE_SOURCE_ROOT}/assets/sass/themes/`. Which subdirectory's SASS files are to be preprocessed as CSS is based on the relative imports in a symbolic link, `app.sass`, directly under `${SUKAATO_SITE_SOURCE_ROOT}/assets/sass/themes/`. This symbolic link should be to an `export.sass` file found directly under `${SUKAATO_SITE_SOURCE_ROOT}/assets/sass/themes/${theme_name}/` corresponding to the active/enabled website theme.
The website has a default theme supplied, but you are welcome to make your own. Website theme can be changed by assigning a value to `theme` in `${SUKAATO_SITE_SOURCE_ROOT}/site.toml`, so set it there once made.
> [!TIP]
> Make sure that all renderable stylesheet paths for files under `${SUKAATO_SITE_SOURCE_ROOT}/lib/sukaato_web/controllers/page_*/` are set to `/assets/app.css`, or a path relative to `${SUKAATO_SITE_SOURCE_ROOT}/priv/static` that has been made external (whether the directory exists yet or not) for/to `:esbuild`. Again, see about [asset management in Phoenix web framework](https://hexdocs.pm/phoenix/asset_management.html#images-fonts-and-external-files).
#### Supply Resources for Pages
> **TBC**
> This section is unfinished. Check back later.
### Run the project's server
This project was built using the Phoenix web framework. To start the Phoenix server:
* Place SSL/TLS certificates in/under path `/priv/cert`
* Make sure `config.exs`, `dev.exs`, or `prod.exs` [reflect the paths to these certificates](https://hexdocs.pm/phoenix/using_ssl.html)
* Run `mix setup` while at project root to install and setup dependencies
* Start Phoenix endpoint while at project root with `mix phx.server` or inside IEx with `iex -S mix phx.server`
Now you can visit [`localhost:4001`](https://localhost:4001) from your browser.
### Run this project in production
Ready to run in production? Please [check Phoenix web framework's deployment guides](https://hexdocs.pm/phoenix/deployment.html).
## Learn more ## Learn more
* Official website: https://www.phoenixframework.org/ * [More on the Phoenix web framework](https://www.phoenixframework.org/)
* Guides: https://hexdocs.pm/phoenix/overview.html * [Phoenix web framework guide](https://hexdocs.pm/phoenix/overview.html)
* Docs: https://hexdocs.pm/phoenix * [Phoenix web framework documentation](https://hexdocs.pm/phoenix)
* Forum: https://elixirforum.com/c/phoenix-forum * [Phoenix web framework forum](https://elixirforum.com/c/phoenix-forum)
* Source: https://github.com/phoenixframework/phoenix * [Phoenix web framework source repository](https://github.com/phoenixframework/phoenix)

View File

@@ -1 +0,0 @@
/home/rika/Portfolio/Documents/Source_Code/sukaato/assets/sass/themes/default/export.sass

View File

@@ -1,4 +1,5 @@
PRAGMA foreign_keys = ON; PRAGMA foreign_keys = ON;
DECLARE @email_address varchar = 'admin@sukaato.moe';
CREATE TABLE [IF NOT EXISTS] [User].users ( CREATE TABLE [IF NOT EXISTS] [User].users (
id INTEGER PRIMARY KEY, id INTEGER PRIMARY KEY,
@@ -34,7 +35,7 @@ INSERT INTO users (
VALUES ( VALUES (
'root', 'root',
'$argon2id$v=19$m=256,t=1,p=4$JRuXmK5RvRJvvpvpWIF2UA$0uf3V1FHaIVmCgp2JfF+Mfrm66ihKXhKkf0RN820y/k', '$argon2id$v=19$m=256,t=1,p=4$JRuXmK5RvRJvvpvpWIF2UA$0uf3V1FHaIVmCgp2JfF+Mfrm66ihKXhKkf0RN820y/k',
'admin@sukaato.moe', @email_address,
'[15, 15, 15, 15, 15, 15]' '[15, 15, 15, 15, 15, 15]'
); );

16
bin/make_admin.sql Normal file
View File

@@ -0,0 +1,16 @@
PRAGMA foreign_keys = ON;
DECLARE @email_address varchar = 'admin@sukaato.moe';
INSERT INTO users (
username,
password,
email,
perms
)
VALUES (
'root',
'$argon2id$v=19$m=256,t=1,p=4$JRuXmK5RvRJvvpvpWIF2UA$0uf3V1FHaIVmCgp2JfF+Mfrm66ihKXhKkf0RN820y/k',
@email_address,
'[15, 15, 15, 15, 15, 15]'
);

View File

@@ -1,7 +1,7 @@
#! /bin/bash #! /bin/bash
set -euo pipefail set -euo pipefail
mix phx.gen.schema User users name:string username:string password:string email:string dob:date gender_type:enum:trans:cis:nb gender_id:enum:fem:masc:combined:fluid:none bio:text affil:array:map perms:array:integer user_token:string pub_keys:map mix phx.gen.schema User users name:string username:string password:string email:string dob:date gender_type:enum:trans:cis:nb gender_id:enum:fem:masc:combined:fluid:none bio:text affil:array:map perms:array:integer user_token:string pub_keys:map totp_secret:string ltotp:utc_datetime fido_priority:integer fido_creds:array:string fido_keys:array:map fido_enabled:boolean fido_active:boolean totp_enabled:boolean totp_active:boolean
mix ecto.migrate mix ecto.migrate
mix phx.gen.schema Post posts title:string:unique abst:text auth_id:references:users rev_id:references:users slug:string content:text tags:array:string cat:string ledit:utc_datetime mix phx.gen.schema Post posts title:string:unique abst:text auth_id:references:users rev_id:references:users slug:string content:text tags:array:string cat:string ledit:utc_datetime
mix ecto.migrate mix ecto.migrate

View File

@@ -0,0 +1,30 @@
<!DOCTYPE html>
<% _rel_proj_root = "../../../.." %>
<html lang={@config["site"]["lang"]}>
<.html_head site_name={@config["site"]["name"]} site_author={@config["site"]["author"]} site_desc={@config["site"]["desc"]} />
<audio id="loaded" class="notifier" src={~p"/audio/page_load.mp3"}></audio>
<body id="err_body">
<template id="panel">
<button id="monoregistration" type="button" class="registbutt">Register</button>
<button id="monologin" type="button" class="loginbutt">Log in</button>
</template>
<div id="doc">
<main id="content" class="page_content">
<!-- @TODO: Replace some parts with Caddy HTTP error code placeholders -->
<article id="server_report">
<section><span>
<h1 id="status_code" class="error_code"><span>error_code error_label</span></h1>
<img src="" alt="">
<p id="status_message" class="error_message message">
<span>
error_message <br><br>trace
</span>
</p>
</span></section>
</article>
</main>
</div>
<div id="extra"></div>
<.html_foot />
</body>
</html>

View File

@@ -0,0 +1,30 @@
<!DOCTYPE html>
<% _rel_proj_root = "../../../.." %>
<html lang={@config["site"]["lang"]}>
<.html_head site_name={@config["site"]["name"]} site_author={@config["site"]["author"]} site_desc={@config["site"]["desc"]} />
<audio id="loaded" class="notifier" src={~p"/audio/page_load.mp3"}></audio>
<body id="err_body">
<template id="panel">
<button id="monoregistration" type="button" class="registbutt">Register</button>
<button id="monologin" type="button" class="loginbutt">Log in</button>
</template>
<div id="doc">
<main id="content" class="page_content">
<!-- @TODO: Replace some parts with Caddy HTTP error code placeholders -->
<article id="server_report">
<section><span>
<h1 id="status_code" class="error_code"><span>error_code error_label</span></h1>
<img src="" alt="">
<p id="status_message" class="error_message message">
<span>
error_message <br><br>trace
</span>
</p>
</span></section>
</article>
</main>
</div>
<div id="extra"></div>
<.html_foot />
</body>
</html>

View File

@@ -0,0 +1,122 @@
<!DOCTYPE html>
<% rel_proj_root = "../../../.." %>
<html lang={@config["site"]["lang"]}>
<.html_head site_name={@config["site"]["name"]} site_author={@config["site"]["author"]} site_desc={@config["site"]["desc"]} />
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
<audio id="loaded" class="notifier" src={~p"/audio/page_load.mp3"}></audio>
<body id="default_body">
<noscript>
<div id="noscript_panel" class="panel">
<!-- @TODO change below button button to anchor elements for ALL HEEx pages -->
<a id="monologin_noscript" class="loginbutt" href={~p"/login"}>Log in</a>
<a id="monoregistration_noscript" class="registbutt">Register</a>
</div>
</noscript>
<template id="panel" class="panel">
<!-- @TODO change below button button to anchor elements for ALL HEEx pages -->
<a id="monologin" class="loginbutt" href={~p"/login"}>Log in</a>
<a id="monoregistration" class="registbutt">Register</a>
</template>
<div id="banner">
<% # @TODO verify the below works %>
<%= raw File.read!(Path.expand("#{rel_proj_root}/priv/static/images/main.svg", __DIR__)) %>
<span class="frontmatter"><a id="home" href={~p"/"}><h1 id="site_title" class="title"><%= @config["site"]["name"] %></h1></a></span>
<nav id="site_nav">
<.navify page_links={@pages} />
</nav>
</div>
<div id="doc">
<main id="content" class="page_content">
<div id="affil_wrap">
<div>
<%= for i <- @affil do %>
<%= for item <- i do %>
<a href={item["protocol"] <> item["scheme_postfix"] <> item["address"]}>
<%= if Map.has_key?(item, "icon_uri") and item["icon_uri"] != "" do %>
<img src={item["icon_uri"]} />
<% else %>
<%= if Map.has_key?(item, "icon_name") and item["icon_name"] != "" do %>
<!-- @TODO either troubleshoot heroicons or draw from map of (social media logo?) images (SVG?) -->
<.affiliate icon={item["icon_name"]} />
<% else %>
<%= item["name"] %>
<% end %>
<% end %>
</a>
<% end %>
<% end %>
</div>
<div id="card_table">
<div id="affil_info">
<!-- <img src="https://static.vecteezy.com/system/resources/previews/022/185/914/original/metal-hand-sign-png.png" /> -->
<div>
<%= for i <- @affil do %>
<%= for item <- i do %>
<a href={item["protocol"] <> item["scheme_postfix"] <> item["address"]}>
<article>
<span><h1 id={item["name"] <> "_label"} class="contact_label"><%= item["name"] %></h1>
<p id={item["name"]} class="contact_datum">
<%= item["protocol"] <> " -> " <> item["address"] %>
</p></span>
</article>
</a>
<% end %>
<% end %>
</div>
</div>
</div>
</div>
<!-- <form id="contact_form" method="POST">
<label for="protocol" class="form_label">séance technique</label>
<select name="protocol" id="protocol">
<option value="email">email</option>
</select><br>
<div id="selected_protocol" class="form_group">
<label for="address_from" class="form_label">magician</label>
<input type="text" id="address_from" name="address_from" value="" /><br>
<label for="message" class="form_label">spell</label>
<textarea id="message" name="message" rows="20" cols="75" /><br>
<input type="submit" value="Submit" />
</div>
</form> -->
</main>
</div>
<div id="extra">
</div>
<.html_foot />
</body>
<script type="module">
// import { NotificationSounds } from "<%= ~p"/js/notifiers.js" %>";
import { Point, Line } from "<%= ~p"/js/space.js" %>";
import { Hitbox, Tracker, spatialTriggerY } from "<%= ~p"/js/triggers.js" %>";
import { reportPriority } from "<%= ~p"/js/err.js" %>";
reportPriority();
let sandbox = new Hitbox(document.body)
let sandbox_rect = sandbox.matter.getBoundingClientRect()
sandbox.y = sandbox_rect.y
let ceiling = new Point(0, Math.round(sandbox.y), 0)
let floor = new Point(0, Math.round(ceiling.y * (60 / sandbox.y)), 0)
let constraint = new Line(ceiling, floor)
window.addEventListener("resize", (e) => {
let sandbox_prev_y = sandbox.y
let sandbox_rect = sandbox.matter.getBoundingClientRect()
sandbox.y = sandbox_rect.y
ceiling.y = Math.round(sandbox.y)
floor.y = Math.round((ceiling.y * (60 / sandbox_prev_y)) + ((ceiling.y * (60 / sandbox_prev_y)) * (sandbox.y / sandbox_prev_y)))
constraint.point1 = ceiling
constraint.point2 = floor
constraint.reset()
console.log("Floor has changed to value %d", floor.y)
console.log(Math.round(ceiling.y * (sandbox.y / sandbox_prev_y)))
console.info("Logging \"top\" of %o on window resize as: %d", sandbox.matter, sandbox.y)
})
sandbox.matter.addEventListener("mousemove", (e) => {
let panel = document.getElementById("panel")
let tracker = new Tracker(e, panel)
tracker.y = tracker.event.clientY
// let yFloor = Math.round(panel.getBoundingClientRect().height)
spatialTriggerY(tracker, constraint, sandbox)
})
</script>
</html>

View File

@@ -0,0 +1,87 @@
<!DOCTYPE html>
<% rel_proj_root = "../../../.." %>
<html lang={@config["site"]["lang"]}>
<.html_head site_name={@config["site"]["name"]} site_author={@config["site"]["author"]} site_desc={@config["site"]["desc"]} />
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
<audio id="loaded" class="notifier" src={~p"/audio/page_load.mp3"}></audio>
<body id="default_body">
<% # database queries may go here %>
<noscript>
<div id="noscript_panel" class="panel">
<!-- @TODO change below button button to anchor elements for ALL HEEx pages -->
<a id="monologin_noscript" class="loginbutt" href={~p"/login"}>Log in</a>
<a id="monoregistration_noscript" class="registbutt">Register</a>
</div>
</noscript>
<template id="panel">
<a id="monologin" class="loginbutt" href={~p"/login"}>Log in</a>
<a id="monoregistration" class="registbutt">Register</a>
</template>
<div id="banner">
<% # @TODO verify the below works %>
<%= raw File.read!(Path.expand("#{rel_proj_root}/priv/static/images/main.svg", __DIR__)) %>
<span class="frontmatter"><a id="home" href={~p"/"}><h1 id="site_title" class="title"><%= @config["site"]["name"] %></h1></a></span>
<nav id="site_nav">
<.navify page_links={@pages} />
<!--
<% # @TODO create the following routes or redirects %>
<a href="moodboard">Moodboard</a>
<a href="portfolio">Portfolio</a>
<a href="watch"><%= @config["site"]["name"] %>TV</a>
<a href="listen"><%= @config["site"]["name"] %>Wave</a>
<a href="read"><%= @config["site"]["name"] %>Scrolls</a>
<a href="hack">./<%= @config["site"]["name"] %>.src</a>
-->
</nav>
</div>
<div id="doc">
<main id="content" class="page_content">
<!-- @TODO write a small explanation of site--take inspiration from neocities -->
<article id="intro" class="exposition">
<span><% # <.greet /> %>
<.markdown_content page_query={@page_name} /></span>
</article>
</main>
</div>
<div id="extra">
</div>
<.html_foot />
</body>
<script type="module">
import { NotificationSounds } from "<%= ~p"/js/notifiers.js" %>";
import { Point, Line } from "<%= ~p"/js/space.js" %>";
import { Hitbox, Tracker, spatialTriggerY } from "<%= ~p"/js/triggers.js" %>";
import { reportPriority } from "<%= ~p"/js/err.js" %>";
reportPriority();
var notifs = new NotificationSounds();
notifs.playSFX("loaded", 0.05, 5, [0.0, 0.01]);
let sandbox = new Hitbox(document.body)
let sandbox_rect = sandbox.matter.getBoundingClientRect()
sandbox.y = sandbox_rect.y
let ceiling = new Point(0, Math.round(sandbox.y), 0)
let floor = new Point(0, Math.round(ceiling.y * (60 / sandbox.y)), 0)
let constraint = new Line(ceiling, floor)
window.addEventListener("resize", (e) => {
let sandbox_prev_y = sandbox.y
let sandbox_rect = sandbox.matter.getBoundingClientRect()
sandbox.y = sandbox_rect.y
ceiling.y = Math.round(sandbox.y)
floor.y = Math.round((ceiling.y * (60 / sandbox_prev_y)) + ((ceiling.y * (60 / sandbox_prev_y)) * (sandbox.y / sandbox_prev_y)))
constraint.point1 = ceiling
constraint.point2 = floor
constraint.reset()
console.log("Floor has changed to value %d", floor.y)
console.log(Math.round(ceiling.y * (sandbox.y / sandbox_prev_y)))
console.info("Logging \"top\" of %o on window resize as: %d", sandbox.matter, sandbox.y)
})
sandbox.matter.addEventListener("mousemove", (e) => {
let panel = document.getElementById("panel")
let tracker = new Tracker(e, panel)
tracker.y = tracker.event.clientY
// let yFloor = Math.round(panel.getBoundingClientRect().height)
spatialTriggerY(tracker, constraint, sandbox)
})
</script>
</html>

View File

@@ -0,0 +1,82 @@
<!DOCTYPE html>
<% rel_proj_root = "../../../.." %>
<html lang={@config["site"]["lang"]}>
<.html_head site_name={@config["site"]["name"]} site_author={@config["site"]["author"]} site_desc={@config["site"]["desc"]} />
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
<!-- <audio id="loaded" class="notifier" src={~p"/audio/page_load.mp3"}></audio> -->
<body id="default_body">
<noscript>
<div id="noscript_panel" class="panel">
<!-- @TODO change below button button to anchor elements for ALL HEEx pages -->
<a id="monologin_noscript" class="loginbutt" href={~p"/login"}>Log in</a>
<a id="monoregistration_noscript" class="registbutt">Register</a>
</div>
</noscript>
<template id="panel" class="panel">
<!-- @TODO change below button button to anchor elements for ALL HEEx pages -->
<a id="monologin" class="loginbutt" href={~p"/login"}>Log in</a>
<a id="monoregistration" class="registbutt">Register</a>
</template>
<div id="banner">
<% # @TODO verify the below works %>
<%= raw File.read!(Path.expand("#{rel_proj_root}/priv/static/images/main.svg", __DIR__)) %>
<span class="frontmatter"><a id="home" href={~p"/"}><h1 id="site_title" class="title"><%= @config["site"]["name"] %></h1></a></span>
<nav id="site_nav">
<.navify page_links={@pages} />
</nav>
</div>
<div id="doc">
<main id="content" class="page_content">
<!-- @TODO write a small explanation of site--take inspiration from neocities -->
<%= if @attempted do %>
<span><p>Either you forgot your clerical title, or the incantation was wrong.</p></span>
<% end %>
<form method="post" autocomplete="on">
<label id="username_label" for="username"><%= @form_fields.username %></label><br>
<input type="text" id="username" name="username"><br>
<label id="password_label" for="password"><%= @form_fields.password %></label><br>
<input type="password" id="password" name="password"><br>
<input type="hidden" name="_csrf_token" value={Phoenix.Controller.get_csrf_token()} />
<.submission btn_name={@button_choice} />
</form>
</main>
</div>
<div id="extra">
</div>
<.html_foot />
</body>
<script type="module">
// import { NotificationSounds } from "<%= ~p"/js/notifiers.js" %>";
import { Point, Line } from "<%= ~p"/js/space.js" %>";
import { Hitbox, Tracker, spatialTriggerY } from "<%= ~p"/js/triggers.js" %>";
import { reportPriority } from "<%= ~p"/js/err.js" %>";
reportPriority();
let sandbox = new Hitbox(document.body)
let sandbox_rect = sandbox.matter.getBoundingClientRect()
sandbox.y = sandbox_rect.y
let ceiling = new Point(0, Math.round(sandbox.y), 0)
let floor = new Point(0, Math.round(ceiling.y * (60 / sandbox.y)), 0)
let constraint = new Line(ceiling, floor)
window.addEventListener("resize", (e) => {
let sandbox_prev_y = sandbox.y
let sandbox_rect = sandbox.matter.getBoundingClientRect()
sandbox.y = sandbox_rect.y
ceiling.y = Math.round(sandbox.y)
floor.y = Math.round((ceiling.y * (60 / sandbox_prev_y)) + ((ceiling.y * (60 / sandbox_prev_y)) * (sandbox.y / sandbox_prev_y)))
constraint.point1 = ceiling
constraint.point2 = floor
constraint.reset()
console.log("Floor has changed to value %d", floor.y)
console.log(Math.round(ceiling.y * (sandbox.y / sandbox_prev_y)))
console.info("Logging \"top\" of %o on window resize as: %d", sandbox.matter, sandbox.y)
})
sandbox.matter.addEventListener("mousemove", (e) => {
let panel = document.getElementById("panel")
let tracker = new Tracker(e, panel)
tracker.y = tracker.event.clientY
// let yFloor = Math.round(panel.getBoundingClientRect().height)
spatialTriggerY(tracker, constraint, sandbox)
})
</script>
</html>

View File

@@ -0,0 +1,81 @@
<!DOCTYPE html>
<% rel_proj_root = "../../../.." %>
<html lang={@config["site"]["lang"]}>
<.html_head site_name={@config["site"]["name"]} site_author={@config["site"]["author"]} site_desc={@config["site"]["desc"]} />
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
<!-- <audio id="loaded" class="notifier" src={~p"/audio/page_load.mp3"}></audio> -->
<body id="default_body">
<noscript>
<div id="noscript_panel" class="panel">
<!-- @TODO change below button button to anchor elements for ALL HEEx pages -->
<a id="monologin_noscript" class="loginbutt" href={~p"/login"}>Log in</a>
<a id="monoregistration_noscript" class="registbutt">Register</a>
</div>
</noscript>
<template id="panel">
<!-- @TODO change below button button to anchor elements for ALL HEEx pages -->
<a id="monologin" class="loginbutt" href={~p"/login"}>Log in</a>
<a id="monoregistration" class="registbutt">Register</a>
<!-- <button id="monoregistration" type="button" class="registbutt">Register</button>
<button id="monologin" type="button" class="loginbutt">Log in</button> -->
</template>
<div id="banner">
<% # @TODO verify the below works %>
<%= raw File.read!(Path.expand("#{rel_proj_root}/priv/static/images/main.svg", __DIR__)) %>
<span class="frontmatter"><a id="home" href={~p"/"}><h1 id="site_title" class="title"><%= @config["site"]["name"] %></h1></a></span>
<nav id="site_nav">
<.navify page_links={@pages} />
<noscript>
<a href={~p"/login"}>Passage</a>
</noscript>
</nav>
</div>
<div id="doc">
<main id="content" class="page_content">
<span><p>You are already acting in your capacity as clergy. <br>Do you wish to return to laity?</p></span>
<form method="post" autocomplete="on">
<input type="hidden" name="logout" value="true">
<input type="hidden" name="_csrf_token" value={Phoenix.Controller.get_csrf_token()} />
<.submission btn_name={@button_choice} />
</form>
</main>
</div>
<div id="extra">
</div>
<.html_foot />
</body>
<script type="module">
// import { NotificationSounds } from "<%= ~p"/js/notifiers.js" %>";
import { Point, Line } from "<%= ~p"/js/space.js" %>";
import { Hitbox, Tracker, spatialTriggerY } from "<%= ~p"/js/triggers.js" %>";
import { reportPriority } from "<%= ~p"/js/err.js" %>";
reportPriority();
let sandbox = new Hitbox(document.body)
let sandbox_rect = sandbox.matter.getBoundingClientRect()
sandbox.y = sandbox_rect.y
let ceiling = new Point(0, Math.round(sandbox.y), 0)
let floor = new Point(0, Math.round(ceiling.y * (60 / sandbox.y)), 0)
let constraint = new Line(ceiling, floor)
window.addEventListener("resize", (e) => {
let sandbox_prev_y = sandbox.y
let sandbox_rect = sandbox.matter.getBoundingClientRect()
sandbox.y = sandbox_rect.y
ceiling.y = Math.round(sandbox.y)
floor.y = Math.round((ceiling.y * (60 / sandbox_prev_y)) + ((ceiling.y * (60 / sandbox_prev_y)) * (sandbox.y / sandbox_prev_y)))
constraint.point1 = ceiling
constraint.point2 = floor
constraint.reset()
console.log("Floor has changed to value %d", floor.y)
console.log(Math.round(ceiling.y * (sandbox.y / sandbox_prev_y)))
console.info("Logging \"top\" of %o on window resize as: %d", sandbox.matter, sandbox.y)
})
sandbox.matter.addEventListener("mousemove", (e) => {
let panel = document.getElementById("panel")
let tracker = new Tracker(e, panel)
tracker.y = tracker.event.clientY
// let yFloor = Math.round(panel.getBoundingClientRect().height)
spatialTriggerY(tracker, constraint, sandbox)
})
</script>
</html>

View File

@@ -0,0 +1,91 @@
<!DOCTYPE html>
<% rel_proj_root = "../../../.." %>
<html lang={@config["site"]["lang"]}>
<.html_head site_name={@config["site"]["name"]} site_author={@config["site"]["author"]} site_desc={@config["site"]["desc"]} />
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
<audio id="loaded" class="notifier" src={~p"/audio/page_load.mp3"}></audio>
<body id="default_body">
<% # database queries may go here %>
<noscript>
<div id="noscript_panel" class="panel">
<!-- @TODO change below button button to anchor elements for ALL HEEx pages -->
<a id="monologin_noscript" class="loginbutt" href={~p"/login"}>Log in</a>
<a id="monoregistration_noscript" class="registbutt">Register</a>
</div>
</noscript>
<template id="panel">
<a id="monologin" class="loginbutt" href={~p"/login"}>Log in</a>
<a id="monoregistration" class="registbutt">Register</a>
</template>
<div id="banner">
<% # @TODO verify the below works %>
<%= raw File.read!(Path.expand("#{rel_proj_root}/priv/static/images/main.svg", __DIR__)) %>
<span class="frontmatter"><a id="home" href={~p"/"}><h1 id="site_title" class="title"><%= @config["site"]["name"] %></h1></a></span>
<nav id="site_nav">
<.navify page_links={@pages} />
</nav>
</div>
<div id="doc">
<main id="content" class="page_content">
<!-- @TODO write a small explanation of site--take inspiration from neocities -->
<div id="gpg_link">
<%= for q <- @qr do %>
<%= if elem(q, 0) != "" do %>
<a id="pubkey_link" class="cryptic" href={~p"/files/users/" <> @user <> "/gpg/" <> elem(q, 0) <> ".asc"}><h1><%= elem(q, 0) %></h1></a>
<% else %>
<h1>?</h1>
<% end %>
<%= if is_tuple(elem(q, 1)) do %>
<%= if elem(elem(q, 1), 0) == :ok do %>
<%= raw elem(elem(q, 1), 1) %>
<% end %>
<% end %>
<span><p id="pubkey_content" class="cryptic">
<% gpg_key = elem(q, 2) %>
-----BEGIN PGP PUBLIC KEY BLOCK-----<br>
<%= String.replace(gpg_key, "-----BEGIN PGP PUBLIC KEY BLOCK-----", "") |> String.replace("-----END PGP PUBLIC KEY BLOCK-----", "") %><br>
-----END PGP PUBLIC KEY BLOCK-----
</p></span>
<% end %>
</div>
</main>
</div>
<div id="extra">
</div>
<.html_foot />
</body>
<script type="module">
// import { NotificationSounds } from "<%= ~p"/js/notifiers.js" %>";
import { Hitbox, Tracker, spatialTriggerY } from "<%= ~p"/js/triggers.js" %>";
import { Point, Line } from "<%= ~p"/js/space.js" %>";
import { reportPriority } from "<%= ~p"/js/err.js" %>";
reportPriority();
let sandbox = new Hitbox(document.body)
let sandbox_rect = sandbox.matter.getBoundingClientRect()
sandbox.y = sandbox_rect.y
let ceiling = new Point(0, Math.round(sandbox.y), 0)
let floor = new Point(0, Math.round(ceiling.y * (60 / sandbox.y)), 0)
let constraint = new Line(ceiling, floor)
window.addEventListener("resize", (e) => {
let sandbox_prev_y = sandbox.y
let sandbox_rect = sandbox.matter.getBoundingClientRect()
sandbox.y = sandbox_rect.y
ceiling.y = Math.round(sandbox.y)
floor.y = Math.round((ceiling.y * (60 / sandbox_prev_y)) + ((ceiling.y * (60 / sandbox_prev_y)) * (sandbox.y / sandbox_prev_y)))
constraint.point1 = ceiling
constraint.point2 = floor
constraint.reset()
console.log("Floor has changed to value %d", floor.y)
console.log(Math.round(ceiling.y * (sandbox.y / sandbox_prev_y)))
console.info("Logging \"top\" of %o on window resize as: %d", sandbox.matter, sandbox.y)
})
sandbox.matter.addEventListener("mousemove", (e) => {
let panel = document.getElementById("panel")
let tracker = new Tracker(e, panel)
tracker.y = tracker.event.clientY
// let yFloor = Math.round(panel.getBoundingClientRect().height)
spatialTriggerY(tracker, constraint, sandbox)
})
</script>
</html>

View File

@@ -0,0 +1,86 @@
<!DOCTYPE html>
<% rel_proj_root = "../../../.." %>
<html lang={@config["site"]["lang"]}>
<.html_head site_name={@config["site"]["name"]} site_author={@config["site"]["author"]} site_desc={@config["site"]["desc"]} />
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
<audio id="loaded" class="notifier" src={~p"/audio/page_load.mp3"}></audio>
<body id="default_body">
<% # database queries may go here %>
<noscript>
<div id="noscript_panel" class="panel">
<!-- @TODO change below button button to anchor elements for ALL HEEx pages -->
<a id="monologin_noscript" class="loginbutt" href={~p"/login"}>Log in</a>
<a id="monoregistration_noscript" class="registbutt">Register</a>
</div>
</noscript>
<template id="panel">
<a id="monologin" class="loginbutt" href={~p"/login"}>Log in</a>
<a id="monoregistration" class="registbutt">Register</a>
</template>
<div id="banner">
<% # @TODO verify the below works %>
<%= raw File.read!(Path.expand("#{rel_proj_root}/priv/static/images/main.svg", __DIR__)) %>
<span class="frontmatter"><a id="home" href={~p"/"}><h1 id="site_title" class="title"><%= @config["site"]["name"] %></h1></a></span>
<nav id="site_nav">
<.navify page_links={@pages} />
<!--
<% # @TODO create the following routes or redirects %>
<a href="moodboard">Moodboard</a>
<a href="portfolio">Portfolio</a>
<a href="watch"><%= @config["site"]["name"] %>TV</a>
<a href="listen"><%= @config["site"]["name"] %>Wave</a>
<a href="read"><%= @config["site"]["name"] %>Scrolls</a>
<a href="hack">./<%= @config["site"]["name"] %>.src</a>
-->
</nav>
</div>
<div id="doc">
<main id="content" class="page_content">
<!-- @TODO write a small explanation of site--take inspiration from neocities -->
<article id="influences" class="exposition">
<span><.markdown_content page_query={@page_name} /></span>
</article>
<div id="thinker_gallery" class="tlist">
<.thinkify thinkers={@thinkers}/>
</div>
</main>
</div>
<div id="extra">
</div>
<.html_foot />
</body>
<script type="module">
/* import { NotificationSounds } from "<%= ~p"/js/notifiers.js" %>"; */
import { Hitbox, Tracker, spatialTriggerY } from "<%= ~p"/js/triggers.js" %>";
import { Point, Line } from "<%= ~p"/js/space.js" %>";
import { reportPriority } from "<%= ~p"/js/err.js" %>";
reportPriority();
let sandbox = new Hitbox(document.body)
let sandbox_rect = sandbox.matter.getBoundingClientRect()
sandbox.y = sandbox_rect.y
let ceiling = new Point(0, Math.round(sandbox.y), 0)
let floor = new Point(0, Math.round(ceiling.y * (60 / sandbox.y)), 0)
let constraint = new Line(ceiling, floor)
window.addEventListener("resize", (e) => {
let sandbox_prev_y = sandbox.y
let sandbox_rect = sandbox.matter.getBoundingClientRect()
sandbox.y = sandbox_rect.y
ceiling.y = Math.round(sandbox.y)
floor.y = Math.round((ceiling.y * (60 / sandbox_prev_y)) + ((ceiling.y * (60 / sandbox_prev_y)) * (sandbox.y / sandbox_prev_y)))
constraint.point1 = ceiling
constraint.point2 = floor
constraint.reset()
console.log("Floor has changed to value %d", floor.y)
console.log(Math.round(ceiling.y * (sandbox.y / sandbox_prev_y)))
console.info("Logging \"top\" of %o on window resize as: %d", sandbox.matter, sandbox.y)
})
sandbox.matter.addEventListener("mousemove", (e) => {
let panel = document.getElementById("panel")
let tracker = new Tracker(e, panel)
tracker.y = tracker.event.clientY
// let yFloor = Math.round(panel.getBoundingClientRect().height)
spatialTriggerY(tracker, constraint, sandbox)
})
</script>
</html>

View File

@@ -0,0 +1,90 @@
<!DOCTYPE html>
<% rel_proj_root = "../../../.." %>
<html lang={@config["site"]["lang"]}>
<.html_head site_name={@config["site"]["name"]} site_author={@config["site"]["author"]} site_desc={@config["site"]["desc"]} />
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
<!-- <audio id="loaded" class="notifier" src={~p"/audio/page_load.mp3"}></audio> -->
<body id="default_body">
<noscript>
<div id="noscript_panel" class="panel">
<!-- @TODO change below button button to anchor elements for ALL HEEx pages -->
<a id="monologin_noscript" class="loginbutt">Log in</a>
<a id="monoregistration_noscript" class="registbutt">Register</a>
</div>
</noscript>
<template id="panel">
<!-- @TODO change below button button to anchor elements for ALL HEEx pages -->
<a id="monologin" class="loginbutt">Log in</a>
<a id="monoregistration" class="registbutt">Register</a>
</template>
<div id="banner">
<% # @TODO verify the below works %>
<%= raw File.read!(Path.expand("#{rel_proj_root}/priv/static/images/main.svg", __DIR__)) %>
<span class="frontmatter"><a id="home" href={~p"/"}><h1 id="site_title" class="title"><%= @config["site"]["name"] %></h1></a></span>
<nav id="site_nav">
<.navify page_links={@pages} />
</nav>
</div>
<div id="doc">
<main id="content" class="page_content">
<!-- @TODO write a small explanation of site--take inspiration from neocities -->
<%= if @attempted do %>
<span><p>No traces of daimonic possession detected via clairvoyance. Try again?</p></span>
<% else %>
<span><p>By clairvoyance the cult shall detect if you've been properly daimonically possessed!</p></span>
<% end %>
<img />
<form method="post" autocomplete="on">
<input type="hidden" name="_csrf_token" value={Phoenix.Controller.get_csrf_token()} />
<%= if @totp do %>
<label for="totp">Enter TOTP Code</label><br>
<input type="text" id="totp" name="code" maxlength="6"><br>
<% end %>
<%= if @fido do %>
<label for="fido"></label><br>
<input type="text" id="fido" name="chall_resp"><br>
<!-- <input type="hidden" name="chall" value=""> -->
<% end %>
<input type="submit" class="acct_manager" value="Verify">
</form>
</main>
</div>
<div id="extra">
</div>
<.html_foot />
</body>
<script type="module">
// import { NotificationSounds } from "<%= ~p"/js/notifiers.js" %>";
import { Point, Line } from "<%= ~p"/js/space.js" %>";
import { Hitbox, Tracker, spatialTriggerY } from "<%= ~p"/js/triggers.js" %>";
import { reportPriority } from "<%= ~p"/js/err.js" %>";
reportPriority();
let sandbox = new Hitbox(document.body)
let sandbox_rect = sandbox.matter.getBoundingClientRect()
sandbox.y = sandbox_rect.y
let ceiling = new Point(0, Math.round(sandbox.y), 0)
let floor = new Point(0, Math.round(ceiling.y * (60 / sandbox.y)), 0)
let constraint = new Line(ceiling, floor)
window.addEventListener("resize", (e) => {
let sandbox_prev_y = sandbox.y
let sandbox_rect = sandbox.matter.getBoundingClientRect()
sandbox.y = sandbox_rect.y
ceiling.y = Math.round(sandbox.y)
floor.y = Math.round((ceiling.y * (60 / sandbox_prev_y)) + ((ceiling.y * (60 / sandbox_prev_y)) * (sandbox.y / sandbox_prev_y)))
constraint.point1 = ceiling
constraint.point2 = floor
constraint.reset()
console.log("Floor has changed to value %d", floor.y)
console.log(Math.round(ceiling.y * (sandbox.y / sandbox_prev_y)))
console.info("Logging \"top\" of %o on window resize as: %d", sandbox.matter, sandbox.y)
})
sandbox.matter.addEventListener("mousemove", (e) => {
let panel = document.getElementById("panel")
let tracker = new Tracker(e, panel)
tracker.y = tracker.event.clientY
// let yFloor = Math.round(panel.getBoundingClientRect().height)
spatialTriggerY(tracker, constraint, sandbox)
})
</script>
</html>

28
tasks.org Normal file
View File

@@ -0,0 +1,28 @@
#+author: Alex Tavarez
#+email: ajt95@prole.biz
#+language: en
* PLANNED
** TODO [#A] Move Markdown and JSON files used by HEEx pages to new directories ~${SUKAATO_SITE_SOURCE_ROOT}/priv/static/{md,json}~
- May require editing some paths in file ~${SUKAATO_SITE_SOURCE_ROOT}/lib/sukaato_web/marker.ex~
- May require marking the new paths relative to ~${SUKAATO_SITE_SOURCE_ROOT}/priv/static~ as external to/for ~:esbuild~ in ~${SUKAATO_SITE_SOURCE_ROOT}/config/config.exs~ (see [[https://hexdocs.pm/phoenix/asset_management.html#images-fonts-and-external-files][asset management in Phoenix web framework]])
** TODO [#A] Add JSON file containing object list for favorite albums, named "albums.json"
*** TODO [#A] Add equivalently structured Elixir default object list in file ~${SUKAATO_SITE_SOURCE_ROOT}/lib/sukaato_web/controllers/page_controller.ex~, using an Elixir struct data type declared in ~${SUKAATO_SITE_SOURCE_ROOT}/lib/sukaato_web/controllers/web_types.ex~
*** TODO [#A] Add a HEEx file (with existing route and controller / view function) in ~${SUKAATO_SITE_SOURCE_ROOT}/lib/sukaato_web/controllers/page_html/~ with the same base filename (i.e., "albums.html.heex")
** TODO [#A] Add profile and account management page, visible after login to website
** TODO [#A] Add page/iframe or page element for drafting, publishing and editing blogposts, visible after login to website
- May require use of Phoenix LiveView
** TODO [#A] Implement ability for ~SukaatoWeb.Marker~ module in ~${SUKAATO_SITE_SOURCE_ROOT}/lib/sukaato_web/marker.ex~ to parse/render markdown posts or posts in database
*** TODO [#A] Add page for feed of blogposts and for individual posts
**** TODO [#B] Implement RSS feed for blogpost feed
** TODO [#C] Add a page for favorite music albums
** TODO [#C] Create or implement APIs for broader administrative capabilities
- May require use of Phoenix LiveView
** TODO [#A] Implement passkey login authentication flow "thread" to website
** TODO [#B] Add basic admin dashboard containing essentials, visible after admin login to website
- Should contain announcement publishing
- Should contain user managing
* IN PROGRESS
* FINISHED