Merge branch 'master' into gractwo
All checks were successful
mnemo-build-and-publish / gractwo-mnemo-build (push) Successful in 1m13s
All checks were successful
mnemo-build-and-publish / gractwo-mnemo-build (push) Successful in 1m13s
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,6 +2,7 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
/database
|
/database
|
||||||
/mnemodata
|
/mnemodata
|
||||||
|
/scripts
|
||||||
*.db
|
*.db
|
||||||
*.db-shm
|
*.db-shm
|
||||||
*.db-wal
|
*.db-wal
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
use maud::{Markup, PreEscaped, html};
|
use maud::{Markup, PreEscaped, html};
|
||||||
|
use sqlx::PgConnection;
|
||||||
|
|
||||||
use crate::{users::User, web::icons};
|
use crate::{
|
||||||
|
users::{User, permissions::Permission},
|
||||||
|
web::icons,
|
||||||
|
};
|
||||||
|
|
||||||
// (SHOWTEXT, LINK, ICON, REQUIRES_LOG_IN)
|
// (SHOWTEXT, LINK, ICON, REQUIRES_LOG_IN)
|
||||||
const LINKS: &[(&str, &str, &str, bool)] = &[
|
const LINKS: &[(&str, &str, &str, bool)] = &[
|
||||||
@@ -13,7 +17,12 @@ const LINKS: &[(&str, &str, &str, bool)] = &[
|
|||||||
("Logs", "/logs", icons::CLIPBOARD_CLOCK, true),
|
("Logs", "/logs", icons::CLIPBOARD_CLOCK, true),
|
||||||
];
|
];
|
||||||
|
|
||||||
pub fn nav(user: Option<&User>, uri: &str) -> Markup {
|
pub async fn nav(conn: &mut PgConnection, user: Option<&User>, uri: &str) -> Markup {
|
||||||
|
#[rustfmt::skip]
|
||||||
|
let show_instance_conf = match user {
|
||||||
|
Some(u) if u.has_permission(conn, Permission::ConfigureInstance).await.is_ok_and(|r| r) => true,
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
html!(
|
html!(
|
||||||
div class="flex items-center text-sm gap-4 border-b border-neutral-200/25 bg-neutral-200/5 px-4 py-2" {
|
div class="flex items-center text-sm gap-4 border-b border-neutral-200/25 bg-neutral-200/5 px-4 py-2" {
|
||||||
a href="/dashboard" class="font-lora font-semibold hidden xs:block md:text-xl sm:mr-2" {"Mnemosyne"}
|
a href="/dashboard" class="font-lora font-semibold hidden xs:block md:text-xl sm:mr-2" {"Mnemosyne"}
|
||||||
@@ -56,11 +65,13 @@ pub fn nav(user: Option<&User>, uri: &str) -> Markup {
|
|||||||
div class="scale-[.7]" {(PreEscaped(icons::SETTINGS))}
|
div class="scale-[.7]" {(PreEscaped(icons::SETTINGS))}
|
||||||
p {"User Settings"}
|
p {"User Settings"}
|
||||||
}
|
}
|
||||||
|
@if show_instance_conf {
|
||||||
div class="h-px w-full bg-neutral-200/15" {}
|
div class="h-px w-full bg-neutral-200/15" {}
|
||||||
a href="/instance-config" class="px-4 py-2 flex items-center gap-2 hover:bg-neutral-200/10 font-lexend text-sm text-neutral-200 transition-colors" {
|
a href="/instance-config" class="px-4 py-2 flex items-center gap-2 hover:bg-neutral-200/10 font-lexend text-sm text-neutral-200 transition-colors" {
|
||||||
div class="scale-[.7]" {(PreEscaped(icons::SERVER))}
|
div class="scale-[.7]" {(PreEscaped(icons::SERVER))}
|
||||||
p {"Instance Config"}
|
p {"Instance Config"}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
div class="h-px w-full bg-neutral-200/15" {}
|
div class="h-px w-full bg-neutral-200/15" {}
|
||||||
form action="/api/auth/logout-form" method="post" {
|
form action="/api/auth/logout-form" method="post" {
|
||||||
button type="submit" class="w-full text-left flex items-center gap-2 px-4 py-2 hover:bg-neutral-200/10 cursor-pointer font-lexend text-sm text-red-300 transition-colors" {
|
button type="submit" class="w-full text-left flex items-center gap-2 px-4 py-2 hover:bg-neutral-200/10 cursor-pointer font-lexend text-sm text-red-300 transition-colors" {
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ pub async fn page(
|
|||||||
Ok(base(
|
Ok(base(
|
||||||
"Instance Config | Mnemosyne",
|
"Instance Config | Mnemosyne",
|
||||||
html!(
|
html!(
|
||||||
(nav(Some(&u), req.uri().path()))
|
(nav(&mut conn, Some(&u), req.uri().path()).await)
|
||||||
|
|
||||||
div class="max-w-4xl mx-auto px-2" {
|
div class="max-w-4xl mx-auto px-2" {
|
||||||
div class="mx-auto max-w-4xl my-4 mb-8" {
|
div class="mx-auto max-w-4xl my-4 mb-8" {
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ pub async fn page(
|
|||||||
Ok(base(
|
Ok(base(
|
||||||
"Dashboard | Mnemosyne",
|
"Dashboard | Mnemosyne",
|
||||||
html!(
|
html!(
|
||||||
(nav(u.as_ref(), req.uri().path()))
|
(nav(&mut conn, u.as_ref(), req.uri().path()).await)
|
||||||
|
|
||||||
div class="mx-auto max-w-4xl px-2 mt-4 grid grid-cols-1 --sm:grid-cols-2 gap-4" {
|
div class="mx-auto max-w-4xl px-2 mt-4 grid grid-cols-1 --sm:grid-cols-2 gap-4" {
|
||||||
div class="flex flex-col" {
|
div class="flex flex-col" {
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ pub async fn page(
|
|||||||
Ok(base(
|
Ok(base(
|
||||||
"Logs | Mnemosyne",
|
"Logs | Mnemosyne",
|
||||||
html!(
|
html!(
|
||||||
(nav(Some(&u), req.uri().path()))
|
(nav(&mut tx, Some(&u), req.uri().path()).await)
|
||||||
|
|
||||||
@if true {//let Ok(true) = u.has_permission(&mut *tx, Permission::BrowseServerLogs) {
|
@if true {//let Ok(true) = u.has_permission(&mut *tx, Permission::BrowseServerLogs) {
|
||||||
div class="max-w-4xl mx-auto px-2" {
|
div class="max-w-4xl mx-auto px-2" {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ pub async fn page(State(state): State<MnemoState>, req: Request) -> Result<Marku
|
|||||||
Ok(base(
|
Ok(base(
|
||||||
"Not Found | Mnemosyne",
|
"Not Found | Mnemosyne",
|
||||||
html!(
|
html!(
|
||||||
(nav(u.as_ref(), req.uri().path()))
|
(nav(&mut conn, u.as_ref(), req.uri().path()).await)
|
||||||
|
|
||||||
div class="mx-auto max-w-4xl px-2 mt-8 mb-2" {
|
div class="mx-auto max-w-4xl px-2 mt-8 mb-2" {
|
||||||
h1 class="text-4xl font-lora font-semibold mb-1" { "Not Found" }
|
h1 class="text-4xl font-lora font-semibold mb-1" { "Not Found" }
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ pub async fn page(
|
|||||||
Ok(base(
|
Ok(base(
|
||||||
"Persons | Mnemosyne",
|
"Persons | Mnemosyne",
|
||||||
html!(
|
html!(
|
||||||
(nav(Some(&u), req.uri().path()))
|
(nav(&mut conn, Some(&u), req.uri().path()).await)
|
||||||
|
|
||||||
div class="mx-auto max-w-4xl px-2 my-4" {
|
div class="mx-auto max-w-4xl px-2 my-4" {
|
||||||
p class="flex items-center gap-2" {
|
p class="flex items-center gap-2" {
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ pub async fn page(
|
|||||||
Ok(base(
|
Ok(base(
|
||||||
&title,
|
&title,
|
||||||
html!(
|
html!(
|
||||||
(nav(Some(&u), req.uri().path()))
|
(nav(&mut conn, Some(&u), req.uri().path()).await)
|
||||||
|
|
||||||
div class="mx-auto max-w-4xl px-2 my-4" {
|
div class="mx-auto max-w-4xl px-2 my-4" {
|
||||||
@if let Ok(p) = p {
|
@if let Ok(p) = p {
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ pub async fn page(
|
|||||||
Ok(base(
|
Ok(base(
|
||||||
"Quotes | Mnemosyne",
|
"Quotes | Mnemosyne",
|
||||||
html!(
|
html!(
|
||||||
(nav(Some(&u), req.uri().path()))
|
(nav(&mut conn, Some(&u), req.uri().path()).await)
|
||||||
|
|
||||||
div class="max-w-4xl mx-auto px-2" {
|
div class="max-w-4xl mx-auto px-2" {
|
||||||
div class="my-4 flex justify-between" {
|
div class="my-4 flex justify-between" {
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ pub async fn page(
|
|||||||
Ok(base(
|
Ok(base(
|
||||||
"Add Quote | Mnemosyne",
|
"Add Quote | Mnemosyne",
|
||||||
html!(
|
html!(
|
||||||
(nav(Some(&u), req.uri().path()))
|
(nav(&mut conn, Some(&u), req.uri().path()).await)
|
||||||
|
|
||||||
div class="max-w-4xl mx-auto px-2" {
|
div class="max-w-4xl mx-auto px-2" {
|
||||||
div class="my-4 flex justify-between" {
|
div class="my-4 flex justify-between" {
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ pub async fn page(
|
|||||||
Ok(base(
|
Ok(base(
|
||||||
"Tags | Mnemosyne",
|
"Tags | Mnemosyne",
|
||||||
html!(
|
html!(
|
||||||
(nav(Some(&u), req.uri().path()))
|
(nav(&mut conn, Some(&u), req.uri().path()).await)
|
||||||
|
|
||||||
div class="mx-auto max-w-4xl px-2 my-4" {
|
div class="mx-auto max-w-4xl px-2 my-4" {
|
||||||
p class="flex items-center gap-2" {
|
p class="flex items-center gap-2" {
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ pub async fn page(
|
|||||||
Ok(base(
|
Ok(base(
|
||||||
"Users | Mnemosyne",
|
"Users | Mnemosyne",
|
||||||
html!(
|
html!(
|
||||||
(nav(Some(&u), req.uri().path()))
|
(nav(&mut conn, Some(&u), req.uri().path()).await)
|
||||||
|
|
||||||
div class="mx-auto max-w-4xl px-2 my-4" {
|
div class="mx-auto max-w-4xl px-2 my-4" {
|
||||||
p class="flex items-center gap-2" {
|
p class="flex items-center gap-2" {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ pub async fn page(
|
|||||||
Ok(base(
|
Ok(base(
|
||||||
"Create User | Mnemosyne",
|
"Create User | Mnemosyne",
|
||||||
html!(
|
html!(
|
||||||
(nav(Some(&u), req.uri().path()))
|
(nav(&mut conn, Some(&u), req.uri().path()).await)
|
||||||
|
|
||||||
div class="mx-auto max-w-4xl px-2 my-4" {
|
div class="mx-auto max-w-4xl px-2 my-4" {
|
||||||
p class="flex items-center gap-2" {
|
p class="flex items-center gap-2" {
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ pub async fn page(
|
|||||||
return Ok(base(
|
return Ok(base(
|
||||||
"No such user | Mnemosyne",
|
"No such user | Mnemosyne",
|
||||||
html!(
|
html!(
|
||||||
(nav(Some(&u), req.uri().path()))
|
(nav(&mut tx, Some(&u), req.uri().path()).await)
|
||||||
div class="mx-auto max-w-4xl mt-16 text-center" {
|
div class="mx-auto max-w-4xl mt-16 text-center" {
|
||||||
div class="text-6xl mb-4" { "?" }
|
div class="text-6xl mb-4" { "?" }
|
||||||
p class="text-red-400 text-lg" { "No such user found." }
|
p class="text-red-400 text-lg" { "No such user found." }
|
||||||
@@ -48,7 +48,7 @@ pub async fn page(
|
|||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Ok(base("Error | Mnemosyne", html!(
|
return Ok(base("Error | Mnemosyne", html!(
|
||||||
(nav(Some(&u), req.uri().path()))
|
(nav(&mut tx, Some(&u), req.uri().path()).await)
|
||||||
p class="text-red-400 text-center my-4" { "An error occurred while loading this profile." }
|
p class="text-red-400 text-center my-4" { "An error occurred while loading this profile." }
|
||||||
)).into_response());
|
)).into_response());
|
||||||
}
|
}
|
||||||
@@ -70,7 +70,7 @@ pub async fn page(
|
|||||||
Ok(base(
|
Ok(base(
|
||||||
&format!("@{} | Mnemosyne", user.handle),
|
&format!("@{} | Mnemosyne", user.handle),
|
||||||
html!(
|
html!(
|
||||||
(nav(Some(&u), req.uri().path()))
|
(nav(&mut tx, Some(&u), req.uri().path()).await)
|
||||||
|
|
||||||
// banner
|
// banner
|
||||||
div class="relative w-full h-48 sm:h-56 md:h-64 bg-linear-to-b from-neutral-800 from-25% to-emerald-950 overflow-hidden" {
|
div class="relative w-full h-48 sm:h-56 md:h-64 bg-linear-to-b from-neutral-800 from-25% to-emerald-950 overflow-hidden" {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ pub async fn page(
|
|||||||
Ok(base(
|
Ok(base(
|
||||||
"User Settings | Mnemosyne",
|
"User Settings | Mnemosyne",
|
||||||
html!(
|
html!(
|
||||||
(nav(Some(&u), req.uri().path()))
|
(nav(&mut conn, Some(&u), req.uri().path()).await)
|
||||||
|
|
||||||
div class="max-w-4xl mx-auto px-2" {
|
div class="max-w-4xl mx-auto px-2" {
|
||||||
div class="mx-auto max-w-4xl my-4" {
|
div class="mx-auto max-w-4xl my-4" {
|
||||||
|
|||||||
Reference in New Issue
Block a user