diff --git a/crates/frontend/public/templates/layouts/default.html b/crates/frontend/public/templates/layouts/default.html
index 46a1388..329b116 100644
--- a/crates/frontend/public/templates/layouts/default.html
+++ b/crates/frontend/public/templates/layouts/default.html
@@ -14,9 +14,11 @@
RustiCal
{% block header_center %}{% endblock %}
-
+ {% if self.get_user().is_some() %}
+
+ {% endif %}
{% endblock %}
diff --git a/crates/frontend/src/nextcloud_login/routes.rs b/crates/frontend/src/nextcloud_login/routes.rs
index 773d328..b0056ad 100644
--- a/crates/frontend/src/nextcloud_login/routes.rs
+++ b/crates/frontend/src/nextcloud_login/routes.rs
@@ -2,7 +2,7 @@ use super::{
NextcloudFlow, NextcloudFlows, NextcloudLoginPoll, NextcloudLoginResponse,
NextcloudSuccessResponse,
};
-use crate::routes::app_token::generate_app_token;
+use crate::{pages::DefaultLayoutData, routes::app_token::generate_app_token};
use askama::Template;
use axum::{
Extension, Form, Json,
@@ -100,6 +100,12 @@ struct NextcloudLoginPage {
app_name: String,
}
+impl DefaultLayoutData for NextcloudLoginPage {
+ fn get_user(&self) -> Option<&Principal> {
+ None
+ }
+}
+
#[instrument(skip(state))]
pub async fn get_nextcloud_flow(
Extension(state): Extension
>,
@@ -130,6 +136,13 @@ pub struct NextcloudAuthorizeForm {
#[template(path = "pages/nextcloud_login/success.html")]
struct NextcloudLoginSuccessPage {
app_name: String,
+ user: Principal,
+}
+
+impl DefaultLayoutData for NextcloudLoginSuccessPage {
+ fn get_user(&self) -> Option<&Principal> {
+ Some(&self.user)
+ }
}
#[instrument(skip(state))]
@@ -150,6 +163,7 @@ pub async fn post_nextcloud_flow(
Ok(Html(
NextcloudLoginSuccessPage {
app_name: flow.app_name.clone(),
+ user,
}
.render()
.unwrap(),
diff --git a/crates/frontend/src/pages/mod.rs b/crates/frontend/src/pages/mod.rs
index 22d12a3..b4bad06 100644
--- a/crates/frontend/src/pages/mod.rs
+++ b/crates/frontend/src/pages/mod.rs
@@ -1 +1,8 @@
+use rustical_store::auth::Principal;
+
pub mod user;
+
+/// Required by the base layout
+pub trait DefaultLayoutData {
+ fn get_user(&self) -> Option<&Principal>;
+}
diff --git a/crates/frontend/src/pages/user.rs b/crates/frontend/src/pages/user.rs
index e395ea0..32f71c7 100644
--- a/crates/frontend/src/pages/user.rs
+++ b/crates/frontend/src/pages/user.rs
@@ -2,6 +2,8 @@ use askama::Template;
use askama_web::WebTemplate;
use rustical_store::auth::Principal;
+use crate::pages::DefaultLayoutData;
+
pub trait Section: Template {
fn name() -> &'static str;
}
@@ -12,3 +14,9 @@ pub struct UserPage {
pub user: Principal,
pub section: S,
}
+
+impl DefaultLayoutData for UserPage {
+ fn get_user(&self) -> Option<&Principal> {
+ Some(&self.user)
+ }
+}
diff --git a/crates/frontend/src/routes/addressbook.rs b/crates/frontend/src/routes/addressbook.rs
index 66e80d0..4e7ee38 100644
--- a/crates/frontend/src/routes/addressbook.rs
+++ b/crates/frontend/src/routes/addressbook.rs
@@ -12,10 +12,19 @@ use headers::Referer;
use http::StatusCode;
use rustical_store::{Addressbook, AddressbookStore, auth::Principal};
+use crate::pages::DefaultLayoutData;
+
#[derive(Template, WebTemplate)]
#[template(path = "pages/addressbook.html")]
struct AddressbookPage {
addressbook: Addressbook,
+ user: Principal,
+}
+
+impl DefaultLayoutData for AddressbookPage {
+ fn get_user(&self) -> Option<&Principal> {
+ Some(&self.user)
+ }
}
pub async fn route_addressbook(
@@ -28,6 +37,7 @@ pub async fn route_addressbook(
}
Ok(AddressbookPage {
addressbook: store.get_addressbook(&owner, &addrbook_id, true).await?,
+ user,
}
.into_response())
}
diff --git a/crates/frontend/src/routes/calendar.rs b/crates/frontend/src/routes/calendar.rs
index 37c5428..7ed9f07 100644
--- a/crates/frontend/src/routes/calendar.rs
+++ b/crates/frontend/src/routes/calendar.rs
@@ -1,5 +1,4 @@
-use std::sync::Arc;
-
+use crate::pages::DefaultLayoutData;
use askama::Template;
use askama_web::WebTemplate;
use axum::{
@@ -11,11 +10,19 @@ use axum_extra::TypedHeader;
use headers::Referer;
use http::StatusCode;
use rustical_store::{Calendar, CalendarStore, auth::Principal};
+use std::sync::Arc;
#[derive(Template, WebTemplate)]
#[template(path = "pages/calendar.html")]
struct CalendarPage {
calendar: Calendar,
+ user: Principal,
+}
+
+impl DefaultLayoutData for CalendarPage {
+ fn get_user(&self) -> Option<&Principal> {
+ Some(&self.user)
+ }
}
pub async fn route_calendar(
@@ -28,6 +35,7 @@ pub async fn route_calendar(
}
Ok(CalendarPage {
calendar: store.get_calendar(&owner, &cal_id, true).await?,
+ user,
}
.into_response())
}
diff --git a/crates/frontend/src/routes/login.rs b/crates/frontend/src/routes/login.rs
index 66eab34..39682c5 100644
--- a/crates/frontend/src/routes/login.rs
+++ b/crates/frontend/src/routes/login.rs
@@ -1,6 +1,6 @@
use std::sync::Arc;
-use crate::{FrontendConfig, OidcConfig};
+use crate::{FrontendConfig, OidcConfig, pages::DefaultLayoutData};
use askama::Template;
use askama_web::WebTemplate;
use axum::{
@@ -24,6 +24,12 @@ struct LoginPage<'a> {
allow_password_login: bool,
}
+impl DefaultLayoutData for LoginPage<'_> {
+ fn get_user(&self) -> Option<&rustical_store::auth::Principal> {
+ None
+ }
+}
+
struct OidcProviderData<'a> {
pub name: &'a str,
pub redirect_url: String,