profile of a new registered users
This commit is contained in:
112
src/controllers/account.rs
Normal file
112
src/controllers/account.rs
Normal file
@@ -0,0 +1,112 @@
|
||||
//! Customer account area. Currently just the shipping/contact profile, whose
|
||||
//! fields prefill the checkout form. Gated to authenticated non-admin users:
|
||||
//! anonymous visitors are bounced to `/login`. Admins have their own area and
|
||||
//! are sent to the dashboard.
|
||||
|
||||
use axum_extra::extract::cookie::CookieJar;
|
||||
use loco_rs::prelude::*;
|
||||
use serde::Deserialize;
|
||||
use serde_json::json;
|
||||
|
||||
use crate::{
|
||||
controllers::i18n::current_lang,
|
||||
models::customer_profiles::{self, ProfileFields},
|
||||
shared::guard,
|
||||
};
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct ProfileForm {
|
||||
phone_prefix: Option<String>,
|
||||
phone: Option<String>,
|
||||
address: Option<String>,
|
||||
city: Option<String>,
|
||||
zip: Option<String>,
|
||||
country: Option<String>,
|
||||
}
|
||||
|
||||
fn trimmed(value: Option<&str>) -> Option<String> {
|
||||
value.map(str::trim).filter(|v| !v.is_empty()).map(String::from)
|
||||
}
|
||||
|
||||
impl From<ProfileForm> for ProfileFields {
|
||||
fn from(form: ProfileForm) -> Self {
|
||||
Self {
|
||||
phone_prefix: trimmed(form.phone_prefix.as_deref()),
|
||||
phone: trimmed(form.phone.as_deref()),
|
||||
address: trimmed(form.address.as_deref()),
|
||||
city: trimmed(form.city.as_deref()),
|
||||
zip: trimmed(form.zip.as_deref()),
|
||||
country: trimmed(form.country.as_deref()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Render the profile form for `profile` (which may be `None` for a customer
|
||||
/// who hasn't saved anything yet). `saved` shows the success banner after a
|
||||
/// POST.
|
||||
fn profile_view(
|
||||
v: &TeraView,
|
||||
jar: &CookieJar,
|
||||
name: &str,
|
||||
email: &str,
|
||||
profile: Option<&customer_profiles::Model>,
|
||||
saved: bool,
|
||||
) -> Result<Response> {
|
||||
format::view(
|
||||
v,
|
||||
"account/profile.html",
|
||||
json!({
|
||||
"logged_in_admin": false,
|
||||
"logged_in_customer": true,
|
||||
"saved": saved,
|
||||
"name": name,
|
||||
"email": email,
|
||||
"phone_prefix": profile.and_then(|p| p.phone_prefix.clone()),
|
||||
"phone": profile.and_then(|p| p.phone.clone()),
|
||||
"address": profile.and_then(|p| p.address.clone()),
|
||||
"city": profile.and_then(|p| p.city.clone()),
|
||||
"zip": profile.and_then(|p| p.zip.clone()),
|
||||
"country": profile.and_then(|p| p.country.clone()),
|
||||
"lang": current_lang(jar),
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn profile_page(
|
||||
jar: CookieJar,
|
||||
ViewEngine(v): ViewEngine<TeraView>,
|
||||
State(ctx): State<AppContext>,
|
||||
) -> Result<Response> {
|
||||
let Some(user) = guard::current_user(&ctx, &jar).await else {
|
||||
return format::redirect("/login");
|
||||
};
|
||||
if guard::is_admin(&ctx, &user) {
|
||||
return format::redirect("/admin/dashboard");
|
||||
}
|
||||
let profile = customer_profiles::Model::find_for_user(&ctx.db, user.id).await?;
|
||||
profile_view(&v, &jar, &user.name, &user.email, profile.as_ref(), false)
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn save_profile(
|
||||
jar: CookieJar,
|
||||
ViewEngine(v): ViewEngine<TeraView>,
|
||||
State(ctx): State<AppContext>,
|
||||
Form(form): Form<ProfileForm>,
|
||||
) -> Result<Response> {
|
||||
let Some(user) = guard::current_user(&ctx, &jar).await else {
|
||||
return format::redirect("/login");
|
||||
};
|
||||
if guard::is_admin(&ctx, &user) {
|
||||
return format::redirect("/admin/dashboard");
|
||||
}
|
||||
let profile = customer_profiles::Model::upsert(&ctx.db, user.id, form.into()).await?;
|
||||
profile_view(&v, &jar, &user.name, &user.email, Some(&profile), true)
|
||||
}
|
||||
|
||||
pub fn routes() -> Routes {
|
||||
Routes::new()
|
||||
.add("/account/profile", get(profile_page))
|
||||
.add("/account/profile", post(save_profile))
|
||||
}
|
||||
Reference in New Issue
Block a user