1
use askama::Template;
2
use axum::{Extension, Json, extract::State, http::StatusCode, response::IntoResponse};
3
use serde::Deserialize;
4
use server::command::account::CreateAccount;
5
use std::sync::Arc;
6
use uuid::Uuid;
7

            
8
use crate::{AppState, jwt_auth::JWTAuthMiddleware, pages::HtmlTemplate};
9

            
10
#[derive(Template)]
11
#[template(path = "pages/account/create.html")]
12
struct AccountCreatePage;
13

            
14
pub async fn account_create_page() -> impl IntoResponse {
15
    HtmlTemplate(AccountCreatePage)
16
}
17

            
18
#[derive(Template)]
19
#[template(path = "components/account/create.html")]
20
struct AccountFormTemplate;
21

            
22
pub async fn account_form() -> impl IntoResponse {
23
    HtmlTemplate(AccountFormTemplate)
24
}
25

            
26
#[derive(Deserialize)]
27
pub struct AccountForm {
28
    name: String,
29
    parent_id: Option<String>,
30
}
31

            
32
4
pub async fn create_account(
33
4
    State(_data): State<Arc<AppState>>,
34
4
    Extension(jwt_auth): Extension<JWTAuthMiddleware>,
35
4
    Json(form): Json<AccountForm>,
36
4
) -> Result<impl IntoResponse, (StatusCode, Json<serde_json::Value>)> {
37
4
    let user = &jwt_auth.user;
38

            
39
    // Parse parent UUID with proper error handling
40

            
41
4
    let parent_id = if let Some(parent) = form.parent_id {
42
3
        if parent.is_empty() {
43
            None
44
3
        } else if let Ok(id) = Uuid::parse_str(&parent) {
45
1
            Some(id)
46
        } else {
47
2
            let error_response = serde_json::json!({
48
2
                "status": "fail",
49
2
                "message": t!("Invalid parent account ID format"),
50
            });
51
2
            return Err((StatusCode::BAD_REQUEST, Json(error_response)));
52
        }
53
    } else {
54
1
        None
55
    };
56

            
57
    // Create the account using the new macro API
58
2
    let mut builder = CreateAccount::new().name(form.name).user_id(user.id);
59

            
60
    // Add parent if provided
61
2
    if let Some(parent) = parent_id {
62
1
        builder = builder.parent(parent);
63
1
    }
64

            
65
2
    match builder.run().await {
66
        Ok(result) => match result {
67
            Some(id) => Ok(format!("{}: {}", t!("New account id"), id)),
68
            None => Ok("New account created".to_string()),
69
        },
70
2
        Err(e) => {
71
2
            let error_response = serde_json::json!({
72
2
                "status": "fail",
73
2
                "message": t!("Failed to create account"),
74
            });
75

            
76
2
            log::error!("Failed to create account: {e:?}");
77
2
            Err((StatusCode::INTERNAL_SERVER_ERROR, Json(error_response)))
78
        }
79
    }
80
4
}