major features update
This commit is contained in:
parent
519fb49901
commit
4e2fab67c5
48 changed files with 3925 additions and 208 deletions
105
src/web/mod.rs
Normal file
105
src/web/mod.rs
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
use axum::RequestPartsExt;
|
||||
use axum::extract::FromRequestParts;
|
||||
// use axum::response::{IntoResponse, Redirect};
|
||||
use http::request::Parts;
|
||||
use maud::{DOCTYPE, Markup, html};
|
||||
use sqlx::FromRow;
|
||||
|
||||
use super::models::user::{AuthSession, User};
|
||||
use super::{AppError, AppState};
|
||||
|
||||
pub mod auth;
|
||||
pub mod contact;
|
||||
pub mod home;
|
||||
pub mod ics;
|
||||
pub mod journal;
|
||||
pub mod settings;
|
||||
|
||||
#[derive(Debug, FromRow)]
|
||||
struct ContactLink {
|
||||
name: String,
|
||||
contact_id: u32,
|
||||
}
|
||||
pub struct Layout {
|
||||
contact_links: Vec<ContactLink>,
|
||||
user: User,
|
||||
}
|
||||
|
||||
impl FromRequestParts<AppState> for Layout {
|
||||
type Rejection = AppError;
|
||||
|
||||
async fn from_request_parts(
|
||||
parts: &mut Parts,
|
||||
state: &AppState,
|
||||
) -> Result<Self, Self::Rejection> {
|
||||
let auth_session = parts
|
||||
.extract::<AuthSession>()
|
||||
.await
|
||||
.map_err(|_| anyhow::Error::msg("could not get session"))?;
|
||||
let user = auth_session.user.unwrap();
|
||||
|
||||
let contact_links: Vec<ContactLink> = sqlx::query_as(
|
||||
"select c.id as contact_id,
|
||||
coalesce(n.name, '(unnamed)') as name
|
||||
from contacts c
|
||||
left join names n on c.id = n.contact_id
|
||||
where n.sort is null or n.sort = 0
|
||||
order by name asc",
|
||||
)
|
||||
.fetch_all(&state.db(&user).pool)
|
||||
.await?;
|
||||
|
||||
Ok(Layout {
|
||||
contact_links,
|
||||
user,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Layout {
|
||||
pub fn render(&self, css: Option<Vec<&str>>, content: Markup) -> Markup {
|
||||
html! {
|
||||
(DOCTYPE)
|
||||
html {
|
||||
head {
|
||||
link rel="stylesheet" type="text/css" href="/static/index.css";
|
||||
meta name="viewport" content="width=device-width";
|
||||
script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.7/dist/htmx.min.js" {}
|
||||
script src="https://cdn.jsdelivr.net/npm/htmx-ext-response-targets@2.0.4" integrity="sha384-T41oglUPvXLGBVyRdZsVRxNWnOOqCynaPubjUVjxhsjFTKrFJGEMm3/0KGmNQ+Pg" crossorigin="anonymous" {}
|
||||
script src="https://cdn.jsdelivr.net/npm/alpinejs@3.15.0/dist/cdn.min.js" defer {}
|
||||
@if let Some(hrefs) = css {
|
||||
@for href in hrefs {
|
||||
link rel="stylesheet" type="text/css" href=(href);
|
||||
}
|
||||
}
|
||||
}
|
||||
body x-data="{ sidebar: false }" {
|
||||
header {
|
||||
input #sidebar-show-hide type="button" x-on:click="sidebar = !sidebar" value="☰";
|
||||
h1 { a href="/" { "Mascarpone" } }
|
||||
span { (self.user.username) }
|
||||
a href="/settings" { "Settings" }
|
||||
a href="/logout" { "Logout" }
|
||||
}
|
||||
section #content {
|
||||
nav #contacts-sidebar x-bind:class="sidebar ? 'show' : 'hide'" {
|
||||
ul {
|
||||
li { button hx-post="/contact/new" { "+ Add Contact" } }
|
||||
@for link in &self.contact_links {
|
||||
li {
|
||||
a href=(format!("/contact/{}", link.contact_id)) {
|
||||
(link.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
main {
|
||||
(content)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue