Add overlay when data fetching
This commit is contained in:
parent
a8ef3d03f9
commit
79e6498245
3
.gitignore
vendored
3
.gitignore
vendored
@ -2,7 +2,7 @@ target
|
|||||||
.env
|
.env
|
||||||
/venv
|
/venv
|
||||||
.cargo
|
.cargo
|
||||||
/.idea
|
.idea
|
||||||
web/static/index.html
|
web/static/index.html
|
||||||
web/static/assets
|
web/static/assets
|
||||||
# Logs
|
# Logs
|
||||||
@ -22,7 +22,6 @@ dist-ssr
|
|||||||
# Editor directories and files
|
# Editor directories and files
|
||||||
.vscode/*
|
.vscode/*
|
||||||
!.vscode/extensions.json
|
!.vscode/extensions.json
|
||||||
.idea
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*.suo
|
*.suo
|
||||||
*.ntvs*
|
*.ntvs*
|
||||||
|
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -2358,7 +2358,7 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "reminder-rs"
|
name = "reminder-rs"
|
||||||
version = "1.7.0-rc1"
|
version = "1.7.0-rc2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.21.7",
|
"base64 0.21.7",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "reminder-rs"
|
name = "reminder-rs"
|
||||||
version = "1.7.0-rc1"
|
version = "1.7.0-rc2"
|
||||||
authors = ["Jude Southworth <judesouthworth@pm.me>"]
|
authors = ["Jude Southworth <judesouthworth@pm.me>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "AGPL-3.0 only"
|
license = "AGPL-3.0 only"
|
||||||
|
@ -4,16 +4,16 @@ The re-re-rewrite of the dashboard.
|
|||||||
|
|
||||||
## Why
|
## Why
|
||||||
|
|
||||||
The existing beta variant of the dashboard is written using vanilla JavaScript. This is fine,
|
The existing beta variant of the dashboard is written using vanilla JavaScript. This is fine,
|
||||||
but annoying to update. This would've been okay if I was more dedicated to updating the vanilla
|
but annoying to update. This would've been okay if I was more dedicated to updating the vanilla
|
||||||
JavaScript too, but I want to experiment with "new" things.
|
JavaScript too, but I want to experiment with "new" things.
|
||||||
|
|
||||||
This also allows me to expand my frontend skills, which is relevant to part of my job.
|
This also allows me to expand my frontend skills, which is relevant to part of my job.
|
||||||
|
|
||||||
## Developing
|
## Developing
|
||||||
|
|
||||||
1. Download the parent repo: https://gitea.jellypro.xyz/jude/reminder-bot
|
1. Run both `npm run dev` and `cargo run`
|
||||||
2. Initialise the submodules: `git pull --recurse-submodules`
|
2. Symlink assets: assuming cloned
|
||||||
3. Run both `npm run dev` and `cargo run`
|
into `$HOME`, `ln -s $HOME/reminder-bot/reminder-dashboard/dist/index.html $HOME/reminder-bot/web/static/index.html`
|
||||||
4. Symlink assets: assuming cloned into `$HOME`, `ln -s $HOME/reminder-bot/reminder-dashboard/dist/index.html $HOME/reminder-bot/web/static/index.html` and
|
and
|
||||||
`ln -s $HOME/reminder-bot/reminder-dashboard/dist/static/assets $HOME/reminder-bot/web/static/assets`
|
`ln -s $HOME/reminder-bot/reminder-dashboard/dist/static/assets $HOME/reminder-bot/web/static/assets`
|
||||||
|
@ -14,7 +14,7 @@ enum Sort {
|
|||||||
export const GuildReminders = () => {
|
export const GuildReminders = () => {
|
||||||
const { guild } = useParams();
|
const { guild } = useParams();
|
||||||
|
|
||||||
const { isSuccess, data: guildReminders } = useQuery(fetchGuildReminders(guild));
|
const { isSuccess, isFetching, data: guildReminders } = useQuery(fetchGuildReminders(guild));
|
||||||
const { data: channels } = useQuery(fetchGuildChannels(guild));
|
const { data: channels } = useQuery(fetchGuildChannels(guild));
|
||||||
|
|
||||||
const [collapsed, setCollapsed] = useState(false);
|
const [collapsed, setCollapsed] = useState(false);
|
||||||
@ -85,7 +85,7 @@ export const GuildReminders = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id={"guildReminders"}>
|
<div id={"guildReminders"} className={isFetching ? "loading" : ""}>
|
||||||
{isSuccess &&
|
{isSuccess &&
|
||||||
guildReminders
|
guildReminders
|
||||||
.sort((r1, r2) => {
|
.sort((r1, r2) => {
|
||||||
|
@ -97,3 +97,15 @@ macro_rules! json_err {
|
|||||||
Err(json!({ "error": $message }))
|
Err(json!({ "error": $message }))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! path {
|
||||||
|
($path:expr) => {{
|
||||||
|
use rocket::fs::relative;
|
||||||
|
|
||||||
|
if Path::new(concat!("/lib/reminder-rs/", $path)).exists() {
|
||||||
|
concat!("/lib/reminder-rs/", $path)
|
||||||
|
} else {
|
||||||
|
relative!($path)
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
@ -2,12 +2,8 @@ use std::path::Path;
|
|||||||
|
|
||||||
use chrono::{naive::NaiveDateTime, Utc};
|
use chrono::{naive::NaiveDateTime, Utc};
|
||||||
use rand::{rngs::OsRng, seq::IteratorRandom};
|
use rand::{rngs::OsRng, seq::IteratorRandom};
|
||||||
use rocket::{
|
use rocket::{fs::NamedFile, http::CookieJar, response::Redirect, serde::json::json};
|
||||||
fs::{relative, NamedFile},
|
use rocket_dyn_templates::Template;
|
||||||
http::CookieJar,
|
|
||||||
response::Redirect,
|
|
||||||
serde::json::json,
|
|
||||||
};
|
|
||||||
use secrecy::ExposeSecret;
|
use secrecy::ExposeSecret;
|
||||||
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
||||||
use serenity::{
|
use serenity::{
|
||||||
@ -19,6 +15,7 @@ use serenity::{
|
|||||||
use sqlx::types::Json;
|
use sqlx::types::Json;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
catchers::internal_server_error,
|
||||||
check_guild_subscription, check_subscription,
|
check_guild_subscription, check_subscription,
|
||||||
consts::{
|
consts::{
|
||||||
CHARACTERS, DAY, DEFAULT_AVATAR, MAX_CONTENT_LENGTH, MAX_EMBED_AUTHOR_LENGTH,
|
CHARACTERS, DAY, DEFAULT_AVATAR, MAX_CONTENT_LENGTH, MAX_EMBED_AUTHOR_LENGTH,
|
||||||
@ -672,28 +669,44 @@ async fn create_database_channel(
|
|||||||
Ok(row.id)
|
Ok(row.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/")]
|
#[derive(Responder)]
|
||||||
pub async fn dashboard_home(cookies: &CookieJar<'_>) -> Result<NamedFile, Redirect> {
|
pub enum DashboardPage {
|
||||||
if cookies.get_private("userid").is_some() {
|
#[response(status = 200)]
|
||||||
NamedFile::open(Path::new(relative!("static/index.html"))).await.map_err(|e| {
|
Ok(NamedFile),
|
||||||
warn!("Couldn't render dashboard: {:?}", e);
|
#[response(status = 200)]
|
||||||
|
Unauthorised(Redirect),
|
||||||
|
#[response(status = 500)]
|
||||||
|
NotConfigured(Template),
|
||||||
|
}
|
||||||
|
|
||||||
Redirect::to("/login/discord")
|
#[get("/")]
|
||||||
})
|
pub async fn dashboard_home(cookies: &CookieJar<'_>) -> DashboardPage {
|
||||||
|
if cookies.get_private("userid").is_some() {
|
||||||
|
match NamedFile::open(Path::new(path!("static/index.html"))).await {
|
||||||
|
Ok(f) => DashboardPage::Ok(f),
|
||||||
|
Err(e) => {
|
||||||
|
warn!("Couldn't render dashboard: {:?}", e);
|
||||||
|
|
||||||
|
DashboardPage::NotConfigured(internal_server_error().await)
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(Redirect::to("/login/discord"))
|
DashboardPage::Unauthorised(Redirect::to("/login/discord"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/<_..>")]
|
#[get("/<_..>")]
|
||||||
pub async fn dashboard(cookies: &CookieJar<'_>) -> Result<NamedFile, Redirect> {
|
pub async fn dashboard(cookies: &CookieJar<'_>) -> DashboardPage {
|
||||||
if cookies.get_private("userid").is_some() {
|
if cookies.get_private("userid").is_some() {
|
||||||
NamedFile::open(Path::new(relative!("static/index.html"))).await.map_err(|e| {
|
match NamedFile::open(Path::new(path!("static/index.html"))).await {
|
||||||
warn!("Couldn't render dashboard: {:?}", e);
|
Ok(f) => DashboardPage::Ok(f),
|
||||||
|
Err(e) => {
|
||||||
|
warn!("Couldn't render dashboard: {:?}", e);
|
||||||
|
|
||||||
Redirect::to("/login/discord")
|
DashboardPage::NotConfigured(internal_server_error().await)
|
||||||
})
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(Redirect::to("/login/discord"))
|
DashboardPage::Unauthorised(Redirect::to("/login/discord"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
/home/jude/reminder-dashboard/dist/static/assets
|
/home/jude/reminder-bot/reminder-dashboard/dist/static/assets
|
@ -55,6 +55,7 @@ div.reminderContent.is-collapsed .hide-box {
|
|||||||
div.reminderContent.is-collapsed .hide-box i {
|
div.reminderContent.is-collapsed .hide-box i {
|
||||||
transform: rotate(90deg);
|
transform: rotate(90deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* END */
|
/* END */
|
||||||
|
|
||||||
/* dashboard styles */
|
/* dashboard styles */
|
||||||
@ -202,6 +203,7 @@ div.interval-group {
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* !Interval inputs */
|
/* !Interval inputs */
|
||||||
|
|
||||||
.left-pad {
|
.left-pad {
|
||||||
@ -239,7 +241,7 @@ span.spacer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nav .dashboard-button {
|
nav .dashboard-button {
|
||||||
background: white ;
|
background: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
span.patreon-color {
|
span.patreon-color {
|
||||||
@ -694,7 +696,7 @@ li.highlight {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* loader */
|
/* loaders */
|
||||||
#loader {
|
#loader {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
@ -707,6 +709,11 @@ li.highlight {
|
|||||||
font-size: 6rem;
|
font-size: 6rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loading {
|
||||||
|
opacity: 0.2;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
/* END */
|
/* END */
|
||||||
|
|
||||||
div.reminderError {
|
div.reminderError {
|
||||||
|
@ -1 +0,0 @@
|
|||||||
/home/jude/reminder-dashboard/dist/index.html
|
|
@ -32,27 +32,54 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<nav class="navbar is-dark is-spaced is-size-4" role="navigation" aria-label="main navigation">
|
<div style="min-height: 100vh;">
|
||||||
<div class="navbar-brand">
|
<nav class="navbar is-dark is-spaced is-size-4" role="navigation" aria-label="main navigation">
|
||||||
<a class="navbar-item" href="/">
|
<div class="navbar-brand">
|
||||||
<figure class="image">
|
<a class="navbar-item" href="/">
|
||||||
<img src="/static/img/logo_flat.webp" alt="Reminder Bot Logo" class="is-rounded" style="width: auto;">
|
<figure class="image">
|
||||||
</figure>
|
<img src="/static/img/logo_flat.webp" alt="Reminder Bot Logo" class="is-rounded" style="width: auto;">
|
||||||
</a>
|
</figure>
|
||||||
|
</a>
|
||||||
|
|
||||||
<a role="button" class="navbar-burger is-right" aria-label="menu" aria-expanded="false" data-target="pageNavbar">
|
<a role="button" class="navbar-burger is-right" aria-label="menu" aria-expanded="false" data-target="pageNavbar">
|
||||||
<span aria-hidden="true"></span>
|
<span aria-hidden="true"></span>
|
||||||
<span aria-hidden="true"></span>
|
<span aria-hidden="true"></span>
|
||||||
<span aria-hidden="true"></span>
|
<span aria-hidden="true"></span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="navbar-menu">
|
<div class="navbar-menu">
|
||||||
<div class="navbar-start">
|
<div class="navbar-start">
|
||||||
|
<a class="navbar-item" href="https://invite.reminder-bot.com">
|
||||||
|
<i class="fas fa-plus"></i>
|
||||||
|
</a>
|
||||||
|
<a class="navbar-item" href="https://gitea.jellypro.xyz/jude">
|
||||||
|
<i class="fab fa-git-square"></i>
|
||||||
|
</a>
|
||||||
|
<a class="navbar-item" href="https://discord.jellywx.com">
|
||||||
|
<i class="fab fa-discord"></i>
|
||||||
|
</a>
|
||||||
|
<a class="navbar-item" href="/help">
|
||||||
|
<i class="fas fa-book"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="navbar-end">
|
||||||
|
<div class="navbar-item">
|
||||||
|
<a class="button is-rounded is-light" href="/dashboard">
|
||||||
|
<p>
|
||||||
|
<span>Dashboard</span> <span class="icon"><i class="fas fa-chevron-right"></i></span>
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="navbar-menu is-hidden-desktop" id="pageNavbar">
|
||||||
<a class="navbar-item" href="https://invite.reminder-bot.com">
|
<a class="navbar-item" href="https://invite.reminder-bot.com">
|
||||||
<i class="fas fa-plus"></i>
|
<i class="fas fa-plus"></i>
|
||||||
</a>
|
</a>
|
||||||
<a class="navbar-item" href="https://gitea.jellypro.xyz/jude">
|
<a class="navbar-item" href="https://github.com/jellywx">
|
||||||
<i class="fab fa-git-square"></i>
|
<i class="fab fa-github"></i>
|
||||||
</a>
|
</a>
|
||||||
<a class="navbar-item" href="https://discord.jellywx.com">
|
<a class="navbar-item" href="https://discord.jellywx.com">
|
||||||
<i class="fab fa-discord"></i>
|
<i class="fab fa-discord"></i>
|
||||||
@ -60,92 +87,67 @@
|
|||||||
<a class="navbar-item" href="/help">
|
<a class="navbar-item" href="/help">
|
||||||
<i class="fas fa-book"></i>
|
<i class="fas fa-book"></i>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="navbar-end">
|
|
||||||
<div class="navbar-item">
|
<div class="navbar-item">
|
||||||
<a class="button is-rounded is-light" href="/dashboard">
|
<a href="/dashboard">
|
||||||
<p>
|
<p>
|
||||||
<span>Dashboard</span> <span class="icon"><i class="fas fa-chevron-right"></i></span>
|
Dashboard <span class="icon"><i class="fas fa-chevron-right"></i></span>
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</nav>
|
||||||
|
|
||||||
<div class="navbar-menu is-hidden-desktop" id="pageNavbar">
|
{% if not hide_title_block %}
|
||||||
<a class="navbar-item" href="https://invite.reminder-bot.com">
|
<section class="hero is-small is-dark">
|
||||||
<i class="fas fa-plus"></i>
|
<div class="hero-body">
|
||||||
</a>
|
<div class="">
|
||||||
<a class="navbar-item" href="https://github.com/jellywx">
|
<h1 class="title is-1">{{ page_title }}</h1>
|
||||||
<i class="fab fa-github"></i>
|
<h2 class="subtitle is-3">{{ page_subtitle }}
|
||||||
</a>
|
{% if page_emoji %}
|
||||||
<a class="navbar-item" href="https://discord.jellywx.com">
|
<span class="icon"><i class="fas {{ page_emoji }}"></i></span>
|
||||||
<i class="fab fa-discord"></i>
|
{% endif %}
|
||||||
</a>
|
</h2>
|
||||||
<a class="navbar-item" href="/help">
|
</div>
|
||||||
<i class="fas fa-book"></i>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<div class="navbar-item">
|
|
||||||
<a href="/dashboard">
|
|
||||||
<p>
|
|
||||||
Dashboard <span class="icon"><i class="fas fa-chevron-right"></i></span>
|
|
||||||
</p>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
{% if not hide_title_block %}
|
|
||||||
<section class="hero is-small is-dark">
|
|
||||||
<div class="hero-body">
|
|
||||||
<div class="">
|
|
||||||
<h1 class="title is-1">{{ page_title }}</h1>
|
|
||||||
<h2 class="subtitle is-3">{{ page_subtitle }}
|
|
||||||
{% if page_emoji %}
|
|
||||||
<span class="icon"><i class="fas {{ page_emoji }}"></i></span>
|
|
||||||
{% endif %}
|
|
||||||
</h2>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
{% if show_invite %}
|
{% if show_invite %}
|
||||||
<div class="hero-foot has-text-centered">
|
<div class="hero-foot has-text-centered">
|
||||||
<a class="button is-size-4 is-rounded is-success" href="https://invite.reminder-bot.com">
|
<a class="button is-size-4 is-rounded is-success" href="https://invite.reminder-bot.com">
|
||||||
<p class="is-size-4">
|
<p class="is-size-4">
|
||||||
<span>Add to your Server</span> <span class="icon"><i class="fas fa-chevron-right"></i></span>
|
<span>Add to your Server</span> <span class="icon"><i class="fas fa-chevron-right"></i></span>
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{% elif show_contact %}
|
{% elif show_contact %}
|
||||||
<div class="hero-foot has-text-centered">
|
<div class="hero-foot has-text-centered">
|
||||||
<a class="button is-size-4 is-rounded is-primary" href="https://discord.jellywx.com">
|
<a class="button is-size-4 is-rounded is-primary" href="https://discord.jellywx.com">
|
||||||
<p class="is-size-4">
|
<p class="is-size-4">
|
||||||
<span>Join Discord</span> <span class="icon"><i class="fas fa-chevron-right"></i></span>
|
<span>Join Discord</span> <span class="icon"><i class="fas fa-chevron-right"></i></span>
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{% elif show_login %}
|
{% elif show_login %}
|
||||||
<div class="hero-foot has-text-centered">
|
<div class="hero-foot has-text-centered">
|
||||||
<a class="button is-size-4 is-rounded is-light" href="/login/discord">
|
<a class="button is-size-4 is-rounded is-light" href="/login/discord">
|
||||||
<p class="is-size-4">
|
<p class="is-size-4">
|
||||||
<span>Login with Discord</span> <span class="icon"><i class="fas fa-chevron-right"></i></span>
|
<span>Login with Discord</span> <span class="icon"><i class="fas fa-chevron-right"></i></span>
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 160">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 160">
|
||||||
<path transform="scale(1, 0.5)" fill="#98dc9a" fill-opacity="1" d="M0,288L80,266.7C160,245,320,203,480,202.7C640,203,800,245,960,218.7C1120,192,1280,96,1360,48L1440,0L1440,0L1360,0C1280,0,1120,0,960,0C800,0,640,0,480,0C320,0,160,0,80,0L0,0Z"></path>
|
<path transform="scale(1, 0.5)" fill="#98dc9a" fill-opacity="1" d="M0,288L80,266.7C160,245,320,203,480,202.7C640,203,800,245,960,218.7C1120,192,1280,96,1360,48L1440,0L1440,0L1360,0C1280,0,1120,0,960,0C800,0,640,0,480,0C320,0,160,0,80,0L0,0Z"></path>
|
||||||
<path transform="scale(1, 0.5)" fill="#363636" fill-opacity="1" d="M0,224L60,202.7C120,181,240,139,360,138.7C480,139,600,181,720,197.3C840,213,960,203,1080,176C1200,149,1320,107,1380,85.3L1440,64L1440,0L1380,0C1320,0,1200,0,1080,0C960,0,840,0,720,0C600,0,480,0,360,0C240,0,120,0,60,0L0,0Z">
|
<path transform="scale(1, 0.5)" fill="#363636" fill-opacity="1" d="M0,224L60,202.7C120,181,240,139,360,138.7C480,139,600,181,720,197.3C840,213,960,203,1080,176C1200,149,1320,107,1380,85.3L1440,64L1440,0L1380,0C1320,0,1200,0,1080,0C960,0,840,0,720,0C600,0,480,0,360,0C240,0,120,0,60,0L0,0Z">
|
||||||
</path>
|
</path>
|
||||||
</svg>
|
</svg>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
</div>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
<footer class="footer">
|
<footer class="footer">
|
||||||
@ -165,25 +167,15 @@
|
|||||||
<script>
|
<script>
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
|
||||||
// Get all "navbar-burger" elements
|
|
||||||
const $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0);
|
const $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0);
|
||||||
|
|
||||||
// Check if there are any navbar burgers
|
|
||||||
if ($navbarBurgers.length > 0) {
|
if ($navbarBurgers.length > 0) {
|
||||||
|
$navbarBurgers.forEach( el => {
|
||||||
|
el.addEventListener('click', () => {
|
||||||
|
const target = el.dataset.target;
|
||||||
|
const $target = document.getElementById(target);
|
||||||
|
|
||||||
// Add a click event on each of them
|
el.classList.toggle('is-active');
|
||||||
$navbarBurgers.forEach( el => {
|
$target.classList.toggle('is-active');
|
||||||
el.addEventListener('click', () => {
|
|
||||||
|
|
||||||
// Get the target from the "data-target" attribute
|
|
||||||
const target = el.dataset.target;
|
|
||||||
const $target = document.getElementById(target);
|
|
||||||
|
|
||||||
// Toggle the "is-active" class on both the "navbar-burger" and the "navbar-menu"
|
|
||||||
el.classList.toggle('is-active');
|
|
||||||
$target.classList.toggle('is-active');
|
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -6,5 +6,5 @@
|
|||||||
{% set show_contact = True %}
|
{% set show_contact = True %}
|
||||||
|
|
||||||
{% set page_title = "Forbidden" %}
|
{% set page_title = "Forbidden" %}
|
||||||
{% set page_subtitle = "You currently cannot access this page, if it exists. Sorry." %}
|
{% set page_subtitle = "You currently cannot access this page, if it exists." %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -6,5 +6,5 @@
|
|||||||
{% set show_contact = True %}
|
{% set show_contact = True %}
|
||||||
|
|
||||||
{% set page_title = "File Not Found" %}
|
{% set page_title = "File Not Found" %}
|
||||||
{% set page_subtitle = "This page does not exist. Sorry." %}
|
{% set page_subtitle = "This page does not exist." %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
Loading…
Reference in New Issue
Block a user