Merge branch 'master' into gractwo
All checks were successful
mnemo-build-and-publish / gractwo-mnemo-build (push) Successful in 1m14s
All checks were successful
mnemo-build-and-publish / gractwo-mnemo-build (push) Successful in 1m14s
This commit is contained in:
@@ -4,7 +4,7 @@ use crate::{quotes::Quote, web::icons};
|
||||
|
||||
pub fn quote(quote: &Quote) -> Markup {
|
||||
html!(
|
||||
div class="border border-neutral-200/25 bg-neutral-200/5 p-3 pb-1 overflow-clip rounded-md relative flex flex-col" {
|
||||
div class="border border-neutral-200/25 bg-neutral-200/5 p-3 pb-1 overflow-clip rounded-md relative flex flex-col transition-colors group-hover/a:border-neutral-200/35 group-hover/a:bg-neutral-200/10" {
|
||||
div class="absolute top-4 right-6 -rotate-12 opacity-[.025] scale-x-[4.5] scale-y-[4]" {
|
||||
(PreEscaped(icons::QUOTE))
|
||||
}
|
||||
|
||||
@@ -61,7 +61,9 @@ pub async fn page(
|
||||
"This just in! This quote was added "
|
||||
(format_time_ago(q.get_creation_timestamp())) " ago."
|
||||
}
|
||||
div class="flex-1 [&>div]:h-full" {(quote(q))}
|
||||
div class="flex-1 [&>div]:h-full" {
|
||||
a href=(format!("/quotes/{}", q.id)) class="group/a" {(quote(q))}
|
||||
}
|
||||
} @else {
|
||||
p class="text-neutral-500 font-light mb-4" {"No quotes yet."}
|
||||
}
|
||||
@@ -76,7 +78,9 @@ pub async fn page(
|
||||
"This quote was added "
|
||||
(format_time_ago(q.get_creation_timestamp())) " ago."
|
||||
}
|
||||
div class="flex-1 [&>div]:h-full" {(quote(&q))}
|
||||
div class="flex-1 [&>div]:h-full" {
|
||||
a href=(format!("/quotes/{}", q.id)) class="group/a" {(quote(&q))}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ pub async fn page(
|
||||
}
|
||||
div class="flex flex-col gap-4 mb-8" {
|
||||
@for q in "es {
|
||||
a href=(format!("/quotes/{}", q.id)) {(quote(q))}
|
||||
a href=(format!("/quotes/{}", q.id)) class="group/a" {(quote(q))}
|
||||
}
|
||||
|
||||
div class="flex justify-between items-center mt-4 text-neutral-400" {
|
||||
|
||||
@@ -3,6 +3,7 @@ use axum::{
|
||||
http::HeaderMap,
|
||||
response::{IntoResponse, Redirect, Response},
|
||||
};
|
||||
use http::StatusCode;
|
||||
use maud::{PreEscaped, html};
|
||||
use uuid::Uuid;
|
||||
|
||||
@@ -14,6 +15,7 @@ use crate::{
|
||||
users::{
|
||||
User,
|
||||
auth::{UserAuthRequired, UserAuthenticate},
|
||||
permissions::Permission,
|
||||
},
|
||||
web::{
|
||||
components::{nav::nav, quote::quote},
|
||||
@@ -33,6 +35,9 @@ pub async fn page(
|
||||
None => return Ok(Redirect::to(&format!("/login?r={}", req.uri().path())).into_response()),
|
||||
};
|
||||
let q = Quote::get_by_id(&mut conn, id).await;
|
||||
let can_delete = u
|
||||
.has_permission(&mut conn, Permission::DeleteQuotes)
|
||||
.await?;
|
||||
|
||||
Ok(base(
|
||||
"Add Quote | Mnemosyne",
|
||||
@@ -53,9 +58,11 @@ pub async fn page(
|
||||
span class="scale-[.75]" {(PreEscaped(icons::PEN))}
|
||||
"Edit"
|
||||
}
|
||||
a href=(format!("/quotes/{id}/delete")) class="px-2 py-1 cursor-pointer border rounded flex flex-row gap-1 bg-pink-400/10 border-pink-400/25 hover:bg-pink-400/20 hover:border-pink-400/45" {
|
||||
span class="scale-[.75]" {(PreEscaped(icons::TRASH))}
|
||||
"Delete"
|
||||
@if can_delete {
|
||||
a href=(format!("/quotes/{id}/delete")) class="px-2 py-1 cursor-pointer border rounded flex flex-row gap-1 bg-pink-400/10 border-pink-400/25 hover:bg-pink-400/20 hover:border-pink-400/45" {
|
||||
span class="scale-[.75]" {(PreEscaped(icons::TRASH))}
|
||||
"Delete"
|
||||
}
|
||||
}
|
||||
}
|
||||
} @else {
|
||||
@@ -126,6 +133,9 @@ pub async fn delete(
|
||||
) -> Result<Response, CompositeError> {
|
||||
let mut tx = state.pool.begin().await?;
|
||||
let u = User::authenticate(&mut *tx, &headers).await?.required()?;
|
||||
if !u.has_permission(&mut tx, Permission::DeleteQuotes).await? {
|
||||
return Ok((StatusCode::FORBIDDEN, "No permission.").into_response());
|
||||
}
|
||||
|
||||
let q = Quote::get_by_id(&mut *tx, id).await?;
|
||||
LogEntry::new(&mut *tx, u, LogAction::DeleteQuote { quote: q.clone() }).await?;
|
||||
|
||||
@@ -3,6 +3,7 @@ use axum::{
|
||||
response::{IntoResponse, Redirect, Response},
|
||||
};
|
||||
use maud::{PreEscaped, html};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
MnemoState,
|
||||
@@ -27,7 +28,14 @@ pub async fn page(
|
||||
Some(u) => u,
|
||||
None => return Ok(Redirect::to(&format!("/login?r={}", req.uri().path())).into_response()),
|
||||
};
|
||||
let us = User::get_all(&mut *conn).await;
|
||||
let us = User::get_all(&mut *conn).await.map(|mut v| {
|
||||
v.sort_by_key(|p| match p.id {
|
||||
id if id == Uuid::nil() => (0, p.id),
|
||||
id if id == Uuid::max() => (1, p.id),
|
||||
_ => (2, p.id),
|
||||
});
|
||||
v
|
||||
});
|
||||
let can_create_users = u
|
||||
.has_permission(&mut *conn, Permission::ManuallyCreateUsers)
|
||||
.await;
|
||||
|
||||
Reference in New Issue
Block a user