Some work on the frontend

This commit is contained in:
Lennart K
2025-07-04 19:44:17 +02:00
parent a5663bf006
commit 40938cba02
16 changed files with 470 additions and 300 deletions

View File

@@ -0,0 +1,53 @@
use std::sync::Arc;
use askama::Template;
use askama_web::WebTemplate;
use axum::{Extension, extract::Path, response::IntoResponse};
use http::StatusCode;
use rustical_store::{Addressbook, AddressbookStore, auth::Principal};
use crate::pages::user::{Section, UserPage};
impl Section for AddressbooksSection {
fn name() -> &'static str {
"addressbooks"
}
}
#[derive(Template, WebTemplate)]
#[template(path = "components/sections/addressbooks_section.html")]
pub struct AddressbooksSection {
pub user: Principal,
pub addressbooks: Vec<Addressbook>,
pub deleted_addressbooks: Vec<Addressbook>,
}
pub async fn route_addressbooks<AS: AddressbookStore>(
Path(user_id): Path<String>,
Extension(addr_store): Extension<Arc<AS>>,
user: Principal,
) -> impl IntoResponse {
if user_id != user.id {
return StatusCode::UNAUTHORIZED.into_response();
}
let mut addressbooks = vec![];
for group in user.memberships() {
addressbooks.extend(addr_store.get_addressbooks(group).await.unwrap());
}
let mut deleted_addressbooks = vec![];
for group in user.memberships() {
deleted_addressbooks.extend(addr_store.get_deleted_addressbooks(group).await.unwrap());
}
UserPage {
section: AddressbooksSection {
user: user.clone(),
addressbooks,
deleted_addressbooks,
},
user,
}
.into_response()
}

View File

@@ -0,0 +1,52 @@
use std::sync::Arc;
use crate::pages::user::{Section, UserPage};
use askama::Template;
use askama_web::WebTemplate;
use axum::{Extension, extract::Path, response::IntoResponse};
use http::StatusCode;
use rustical_store::{Calendar, CalendarStore, auth::Principal};
impl Section for CalendarsSection {
fn name() -> &'static str {
"calendars"
}
}
#[derive(Template, WebTemplate)]
#[template(path = "components/sections/calendars_section.html")]
pub struct CalendarsSection {
pub user: Principal,
pub calendars: Vec<Calendar>,
pub deleted_calendars: Vec<Calendar>,
}
pub async fn route_calendars<CS: CalendarStore>(
Path(user_id): Path<String>,
Extension(cal_store): Extension<Arc<CS>>,
user: Principal,
) -> impl IntoResponse {
if user_id != user.id {
return StatusCode::UNAUTHORIZED.into_response();
}
let mut calendars = vec![];
for group in user.memberships() {
calendars.extend(cal_store.get_calendars(group).await.unwrap());
}
let mut deleted_calendars = vec![];
for group in user.memberships() {
deleted_calendars.extend(cal_store.get_deleted_calendars(group).await.unwrap());
}
UserPage {
section: CalendarsSection {
user: user.clone(),
calendars,
deleted_calendars,
},
user,
}
.into_response()
}

View File

@@ -1,5 +1,7 @@
pub mod addressbook;
pub mod addressbooks;
pub mod app_token;
pub mod calendar;
pub mod calendars;
pub mod login;
pub mod user;

View File

@@ -11,19 +11,23 @@ use axum_extra::{TypedHeader, extract::Host};
use headers::UserAgent;
use http::StatusCode;
use rustical_store::{
Addressbook, AddressbookStore, Calendar, CalendarStore,
AddressbookStore, CalendarStore,
auth::{AppToken, AuthenticationProvider, Principal},
};
use crate::pages::user::{Section, UserPage};
impl Section for ProfileSection {
fn name() -> &'static str {
"profile"
}
}
#[derive(Template, WebTemplate)]
#[template(path = "pages/user.html")]
pub struct UserPage {
#[template(path = "components/sections/profile_section.html")]
pub struct ProfileSection {
pub user: Principal,
pub app_tokens: Vec<AppToken>,
pub calendars: Vec<Calendar>,
pub deleted_calendars: Vec<Calendar>,
pub addressbooks: Vec<Addressbook>,
pub deleted_addressbooks: Vec<Addressbook>,
pub is_apple: bool,
pub davx5_hostname: Option<String>,
}
@@ -69,14 +73,13 @@ pub async fn route_user_named<
let davx5_hostname = user_agent.as_str().contains("Android").then_some(host);
UserPage {
app_tokens: auth_provider.get_app_tokens(&user.id).await.unwrap(),
calendars,
deleted_calendars,
addressbooks,
deleted_addressbooks,
section: ProfileSection {
user: user.clone(),
app_tokens: auth_provider.get_app_tokens(&user.id).await.unwrap(),
is_apple,
davx5_hostname,
},
user,
is_apple,
davx5_hostname,
}
.into_response()
}