diff --git a/admin_frontend/src/templates.rs b/admin_frontend/src/templates.rs index 776a5ba1..8ceb36e9 100644 --- a/admin_frontend/src/templates.rs +++ b/admin_frontend/src/templates.rs @@ -17,3 +17,24 @@ pub struct Admin; pub struct Users<'a> { pub users: &'a [gotrue_entity::User], } + +#[derive(Template)] +#[template(path = "user_details.html")] +pub struct UserDetails<'a> { + pub user: &'a gotrue_entity::User, +} + +// Any filter defined in the module `filters` is accessible in your template. +mod filters { + pub fn default( + input: &Option, + default_val: &str, + ) -> ::askama::Result { + Ok( + input + .as_ref() + .map(|i| i.to_string()) + .unwrap_or_else(|| default_val.to_string()), + ) + } +} diff --git a/admin_frontend/src/web_app.rs b/admin_frontend/src/web_app.rs index 21589207..4189d79d 100644 --- a/admin_frontend/src/web_app.rs +++ b/admin_frontend/src/web_app.rs @@ -1,7 +1,7 @@ use crate::access_token::WebAccessToken; use crate::error::RenderError; use askama::Template; -use axum::extract::State; +use axum::extract::{Path, State}; use axum::response::Result; use axum::{response::Html, routing::get, Router}; @@ -14,14 +14,15 @@ pub fn router() -> Router { .route("/login", get(login_handler)) .route("/admin", get(admin_handler)) .route("/admin/users", get(admin_users_handler)) + .route("/admin/users/:user_id", get(admin_user_details_handler)) } -pub async fn home_handler(access_token: WebAccessToken) -> Result, RenderError> { +pub async fn home_handler(_access_token: WebAccessToken) -> Result, RenderError> { let s = templates::Home {}.render()?; Ok(Html(s)) } -pub async fn admin_handler(access_token: WebAccessToken) -> Result, RenderError> { +pub async fn admin_handler(_access_token: WebAccessToken) -> Result, RenderError> { let s = templates::Admin {}.render()?; Ok(Html(s)) } @@ -46,6 +47,22 @@ pub async fn admin_users_handler( Ok(Html(s)) } +pub async fn admin_user_details_handler( + State(state): State, + access_token: WebAccessToken, + Path(user_id): Path, +) -> Result, RenderError> { + println!("---------- user_id: {}", user_id); + // http://localhost:3000/admin/users/3c093675-c4e0-4329-bd92-c1e8345afdd2 + let users = state + .gotrue_client + .admin_user_details(&access_token.0, &user_id) + .await + .unwrap(); // TODO: handle error + let s = templates::UserDetails { user: &users }.render()?; + Ok(Html(s)) +} + pub async fn login_handler() -> Result, RenderError> { let s = templates::Login {}.render()?; Ok(Html(s)) diff --git a/admin_frontend/templates/user_details.html b/admin_frontend/templates/user_details.html new file mode 100644 index 00000000..29841f1d --- /dev/null +++ b/admin_frontend/templates/user_details.html @@ -0,0 +1,25 @@ + + + + + + + User Detail + + + + +

User Detail

+

{{ user.email|escape }}

+

Phone: {{ user.phone|escape }}

+

Email Confirmed At: {{ user.email_confirmed_at|default("-") }}

+

Phone Confirmed At: {{ user.phone_confirmed_at|default("-")|escape }}

+

Last Sign In At: {{ user.last_sign_in_at|default("-")|escape }}

+

Created At: {{ user.created_at|escape }}

+

Updated At: {{ user.updated_at|escape }}

+ + + Back to User List + + + diff --git a/admin_frontend/templates/users.html b/admin_frontend/templates/users.html index e1d665bb..d08a40e2 100644 --- a/admin_frontend/templates/users.html +++ b/admin_frontend/templates/users.html @@ -9,6 +9,7 @@ Id Email Created At + Action {% for user in users %} @@ -16,6 +17,7 @@ {{ user.id|escape }} {{ user.email|escape }} {{ user.created_at|escape }} + Go {% endfor %} diff --git a/libs/gotrue/src/api.rs b/libs/gotrue/src/api.rs index f5816ffe..f0d29a67 100644 --- a/libs/gotrue/src/api.rs +++ b/libs/gotrue/src/api.rs @@ -131,6 +131,20 @@ impl Client { to_gotrue_result(resp).await } + pub async fn admin_user_details( + &self, + access_token: &str, + user_id: &str, // uuid + ) -> Result { + let resp = self + .client + .get(format!("{}/admin/users/{}", self.base_url, user_id)) + .header("Authorization", format!("Bearer {}", access_token)) + .send() + .await?; + to_gotrue_result(resp).await + } + pub async fn admin_add_user( &self, access_token: &str,