diff --git a/crates/ezidam/src/icons.rs b/crates/ezidam/src/icons.rs index 761766c..a0a42d0 100644 --- a/crates/ezidam/src/icons.rs +++ b/crates/ezidam/src/icons.rs @@ -36,7 +36,10 @@ impl Icon { "moon", Moon, r#""#, "sun", Sun, r#""#, "arrow-left", ArrowLeft, r#""#, - "alert-triangle-large", AlertTriangleLarge, r#""# + "alert-triangle-large", AlertTriangleLarge, r#""#, + "id-badge-2", IdBadge2, r#""#, + "user", User, r#""#, + "at", At, r#""# } } @@ -54,6 +57,9 @@ pub fn icons_to_templates(tera: &mut Tera) { Icon::Sun, Icon::ArrowLeft, Icon::AlertTriangleLarge, + Icon::IdBadge2, + Icon::User, + Icon::At, ]; // For each icon, it will output: ("icons/name", "...") diff --git a/crates/ezidam/src/menu/items/user.rs b/crates/ezidam/src/menu/items/user.rs index 804e9e9..c722103 100644 --- a/crates/ezidam/src/menu/items/user.rs +++ b/crates/ezidam/src/menu/items/user.rs @@ -1,25 +1,39 @@ use crate::icons::Icon; -use crate::menu::MainItem; +use crate::menu::{MainItem, SubItem}; use crate::routes; use rocket::uri; pub enum UserMenu { Home, + Settings, } impl UserMenu { pub fn id(&self) -> &'static str { match self { UserMenu::Home => "home", + UserMenu::Settings => "settings", } } pub fn list() -> Vec { - vec![MainItem { - id: UserMenu::Home.id(), - label: "Home", - link: uri!(routes::root::home::homepage).to_string(), - icon: Icon::Home.svg, - sub: None, - }] + vec![ + MainItem { + id: UserMenu::Home.id(), + label: "Home", + link: uri!(routes::root::home::homepage).to_string(), + icon: Icon::Home.svg, + sub: None, + }, + MainItem { + id: UserMenu::Settings.id(), + label: "Settings", + link: uri!(routes::settings::user_settings).to_string(), + icon: Icon::Settings.svg, + sub: Some(vec![SubItem { + label: "Personal", + link: uri!(routes::settings::user_settings_personal).to_string(), + }]), + }, + ] } } diff --git a/crates/ezidam/src/page.rs b/crates/ezidam/src/page.rs index f41d41e..bcc1666 100644 --- a/crates/ezidam/src/page.rs +++ b/crates/ezidam/src/page.rs @@ -21,6 +21,7 @@ pub enum Page { AdminAppsList(AdminAppsList), AdminAppsNew(AdminAppsNew), AdminAppsView(AdminAppsView), + UserPersonalSettings(UserPersonalSettings), } impl Page { @@ -38,6 +39,7 @@ impl Page { Page::AdminAppsList(_) => "pages/admin/apps/list", Page::AdminAppsNew(_) => "pages/admin/apps/new", Page::AdminAppsView(_) => "pages/admin/apps/view", + Page::UserPersonalSettings(_) => "pages/settings/personal", } } @@ -55,6 +57,7 @@ impl Page { Page::AdminAppsList(_) => "Applications", Page::AdminAppsNew(_) => "New application", Page::AdminAppsView(_) => "Application info", + Page::UserPersonalSettings(_) => "Personal settings", } } @@ -74,6 +77,7 @@ impl Page { Page::AdminAppsList(_) => Some(AdminMenu::Apps.into()), Page::AdminAppsNew(_) => Some(AdminMenu::Apps.into()), Page::AdminAppsView(_) => Some(AdminMenu::Apps.into()), + Page::UserPersonalSettings(_) => Some(UserMenu::Settings.into()), } } @@ -91,6 +95,7 @@ impl Page { Page::AdminAppsList(list) => Box::new(list), Page::AdminAppsNew(new) => Box::new(new), Page::AdminAppsView(view) => Box::new(view), + Page::UserPersonalSettings(personal) => Box::new(personal), } } } diff --git a/crates/ezidam/src/page/content.rs b/crates/ezidam/src/page/content.rs index 5bf425d..de3553a 100644 --- a/crates/ezidam/src/page/content.rs +++ b/crates/ezidam/src/page/content.rs @@ -2,3 +2,4 @@ pub use crate::error::content::*; pub use crate::routes::admin::content::*; pub use crate::routes::oauth::content::*; pub use crate::routes::root::content::*; +pub use crate::routes::settings::content::*; diff --git a/crates/ezidam/src/routes.rs b/crates/ezidam/src/routes.rs index 57bc79b..03c6050 100644 --- a/crates/ezidam/src/routes.rs +++ b/crates/ezidam/src/routes.rs @@ -3,6 +3,7 @@ use rocket::{Build, Rocket}; pub mod admin; pub mod oauth; pub mod root; +pub mod settings; pub mod setup; pub mod well_known; @@ -42,4 +43,6 @@ pub fn routes(rocket_builder: Rocket) -> Rocket { .mount("/", well_known::routes()) // Admin .mount("/", admin::routes()) + // Settings + .mount("/", settings::routes()) } diff --git a/crates/ezidam/src/routes/settings.rs b/crates/ezidam/src/routes/settings.rs new file mode 100644 index 0000000..031c2a8 --- /dev/null +++ b/crates/ezidam/src/routes/settings.rs @@ -0,0 +1,29 @@ +use super::prelude::*; +pub use personal::*; +use rocket::get; + +pub mod personal; + +pub fn routes() -> Vec { + routes![user_settings, user_settings_personal] +} + +#[get("/settings")] +pub async fn user_settings(_user: JwtUser) -> Redirect { + Redirect::to(uri!(user_settings_personal)) +} + +pub mod content { + use jwt::JwtClaims; + use rocket::serde::Serialize; + + #[derive(Serialize)] + #[serde(crate = "rocket::serde")] + #[derive(Clone)] + pub struct UserPersonalSettings { + pub user: JwtClaims, + pub username: String, + pub name: Option, + pub email: Option, + } +} diff --git a/crates/ezidam/src/routes/settings/personal.rs b/crates/ezidam/src/routes/settings/personal.rs new file mode 100644 index 0000000..958b881 --- /dev/null +++ b/crates/ezidam/src/routes/settings/personal.rs @@ -0,0 +1,25 @@ +use crate::routes::prelude::*; +use rocket::get; +use users::User; + +#[get("/settings/personal")] +pub async fn user_settings_personal( + mut db: Connection, + jwt_user: JwtUser, + flash: Option>, +) -> Result { + let user = User::get_by_login(&mut *db, &jwt_user.0.subject) + .await? + .ok_or_else(|| Error::not_found(jwt_user.0.subject.to_string()))?; + + let page = Page::UserPersonalSettings(super::content::UserPersonalSettings { + user: jwt_user.0, + username: user.username().into(), + name: user.name().map(String::from), + email: user.email().map(String::from), + }); + + Ok(flash + .map(|flash| Page::with_flash(page.clone(), flash)) + .unwrap_or_else(|| page.into())) +} diff --git a/crates/ezidam/templates/pages/settings/personal.html.tera b/crates/ezidam/templates/pages/settings/personal.html.tera new file mode 100644 index 0000000..a5b42d0 --- /dev/null +++ b/crates/ezidam/templates/pages/settings/personal.html.tera @@ -0,0 +1,89 @@ +{% extends "shell" %} + +{% block content %} + + + + + + + Settings + + + + + + + + + + {% if flash %} + + {{ flash.1 | safe }} + + {% endif %} + + + + + + + Personal + + + + + + + My Profile + + + + + Username + + + {% include "icons/id-badge-2" %} + + + + + + Full Name + + + {% include "icons/user" %} + + + + + + Email address + + + {% include "icons/at" %} + + + + + + + + + + + + + + +{% endblock content %}