1
use askama::Template;
2
use axum::{
3
    Extension, Json,
4
    extract::{Path, State},
5
    http::StatusCode,
6
    response::IntoResponse,
7
};
8
use serde::Deserialize;
9
use sqlx::types::Uuid;
10
use std::sync::Arc;
11

            
12
use crate::{AppState, jwt_auth::JWTAuthMiddleware, pages::HtmlTemplate};
13

            
14
#[derive(Template)]
15
#[template(path = "pages/tag/create.html")]
16
struct TagCreatePage;
17

            
18
pub async fn tag_create_page() -> impl IntoResponse {
19
    HtmlTemplate(TagCreatePage {})
20
}
21

            
22
#[derive(Deserialize)]
23
pub struct TagForm {
24
    tag_name: String,
25
    tag_value: String,
26
    description: Option<String>,
27
}
28

            
29
4
pub async fn create_tag(
30
4
    State(_data): State<Arc<AppState>>,
31
4
    Extension(jwt_auth): Extension<JWTAuthMiddleware>,
32
4
    Json(form): Json<TagForm>,
33
6
) -> Result<impl IntoResponse, (StatusCode, Json<serde_json::Value>)> {
34
4
    let user = &jwt_auth.user;
35
4
    let server_user = server::user::User { id: user.id };
36

            
37
4
    let description = form.description.filter(|desc| !desc.is_empty());
38

            
39
4
    match server_user
40
4
        .create_tag(form.tag_name, form.tag_value, description)
41
4
        .await
42
    {
43
        Ok(id) => Ok(format!("{}: {}", t!("New tag id"), id)),
44
4
        Err(e) => {
45
4
            let error_response = serde_json::json!({
46
4
                "status": "fail",
47
4
                "message": t!("Failed to create tag"),
48
            });
49

            
50
4
            log::error!("Failed to create tag: {e:?}");
51
4
            Err((StatusCode::INTERNAL_SERVER_ERROR, Json(error_response)))
52
        }
53
    }
54
4
}
55

            
56
4
pub async fn create_transaction_tag(
57
4
    Path(transaction_id): Path<String>,
58
4
    State(_data): State<Arc<AppState>>,
59
4
    Extension(jwt_auth): Extension<JWTAuthMiddleware>,
60
4
    Json(form): Json<TagForm>,
61
6
) -> Result<impl IntoResponse, (StatusCode, Json<serde_json::Value>)> {
62
4
    let user = &jwt_auth.user;
63

            
64
4
    let tx_uuid = Uuid::parse_str(&transaction_id).map_err(|_| {
65
2
        let error_response = serde_json::json!({
66
2
            "status": "fail",
67
2
            "message": "Invalid transaction ID format",
68
        });
69
2
        (StatusCode::BAD_REQUEST, Json(error_response))
70
2
    })?;
71

            
72
2
    let server_user = server::user::User { id: user.id };
73
2
    let description = form.description.filter(|desc| !desc.is_empty());
74

            
75
2
    match server_user
76
2
        .create_transaction_tag(tx_uuid, form.tag_name, form.tag_value, description)
77
2
        .await
78
    {
79
        Ok(id) => Ok(format!("{}: {}", t!("New transaction tag id"), id)),
80
2
        Err(e) => {
81
2
            let error_response = serde_json::json!({
82
2
                "status": "fail",
83
2
                "message": t!("Failed to create transaction tag"),
84
            });
85

            
86
2
            log::error!("Failed to create transaction tag: {e:?}");
87
2
            Err((StatusCode::INTERNAL_SERVER_ERROR, Json(error_response)))
88
        }
89
    }
90
4
}
91

            
92
pub async fn create_split_tag(
93
    Path(split_id): Path<String>,
94
    State(_data): State<Arc<AppState>>,
95
    Extension(jwt_auth): Extension<JWTAuthMiddleware>,
96
    Json(form): Json<TagForm>,
97
) -> Result<impl IntoResponse, (StatusCode, Json<serde_json::Value>)> {
98
    let user = &jwt_auth.user;
99

            
100
    let split_uuid = Uuid::parse_str(&split_id).map_err(|_| {
101
        let error_response = serde_json::json!({
102
            "status": "fail",
103
            "message": "Invalid split ID format",
104
        });
105
        (StatusCode::BAD_REQUEST, Json(error_response))
106
    })?;
107

            
108
    let server_user = server::user::User { id: user.id };
109
    let description = form.description.filter(|desc| !desc.is_empty());
110

            
111
    match server_user
112
        .create_split_tag(split_uuid, form.tag_name, form.tag_value, description)
113
        .await
114
    {
115
        Ok(id) => Ok(format!("{}: {}", t!("New split tag id"), id)),
116
        Err(e) => {
117
            let error_response = serde_json::json!({
118
                "status": "fail",
119
                "message": t!("Failed to create split tag"),
120
            });
121

            
122
            log::error!("Failed to create split tag: {e:?}");
123
            Err((StatusCode::INTERNAL_SERVER_ERROR, Json(error_response)))
124
        }
125
    }
126
}