Skip to main content

web/pages/tag/
autocomplete.rs

1use axum::{Extension, Json, extract::Query, http::StatusCode};
2use serde::{Deserialize, Serialize};
3
4use crate::jwt_auth::JWTAuthMiddleware;
5
6#[derive(Serialize)]
7pub struct TagSuggestion {
8    name: String,
9    value: Option<String>,
10}
11
12pub async fn transaction_tag_names(
13    Extension(jwt_auth): Extension<JWTAuthMiddleware>,
14) -> Result<Json<Vec<TagSuggestion>>, (StatusCode, Json<serde_json::Value>)> {
15    let user = &jwt_auth.user;
16    let server_user = server::user::User { id: user.id };
17
18    match server_user.list_transaction_tag_names().await {
19        Ok(names) => {
20            let suggestions = names
21                .into_iter()
22                .map(|name| TagSuggestion { name, value: None })
23                .collect();
24            Ok(Json(suggestions))
25        }
26        Err(e) => {
27            let error_response = serde_json::json!({
28                "status": "fail",
29                "message": "Failed to fetch transaction tag names",
30            });
31            log::error!("Failed to fetch transaction tag names: {e:?}");
32            Err((StatusCode::INTERNAL_SERVER_ERROR, Json(error_response)))
33        }
34    }
35}
36
37#[derive(Deserialize)]
38pub struct TagValuesQuery {
39    name: String,
40}
41
42pub async fn transaction_tag_values(
43    Query(query): Query<TagValuesQuery>,
44    Extension(jwt_auth): Extension<JWTAuthMiddleware>,
45) -> Result<Json<Vec<TagSuggestion>>, (StatusCode, Json<serde_json::Value>)> {
46    let user = &jwt_auth.user;
47    let server_user = server::user::User { id: user.id };
48
49    match server_user.list_transaction_tag_values(&query.name).await {
50        Ok(values) => {
51            let suggestions = values
52                .into_iter()
53                .map(|value| TagSuggestion {
54                    name: value.clone(),
55                    value: Some(value),
56                })
57                .collect();
58            Ok(Json(suggestions))
59        }
60        Err(e) => {
61            let error_response = serde_json::json!({
62                "status": "fail",
63                "message": "Failed to fetch transaction tag values",
64            });
65            log::error!(
66                "Failed to fetch transaction tag values for '{}': {e:?}",
67                query.name
68            );
69            Err((StatusCode::INTERNAL_SERVER_ERROR, Json(error_response)))
70        }
71    }
72}
73
74pub async fn account_tag_names(
75    Extension(jwt_auth): Extension<JWTAuthMiddleware>,
76) -> Result<Json<Vec<TagSuggestion>>, (StatusCode, Json<serde_json::Value>)> {
77    let user = &jwt_auth.user;
78    let server_user = server::user::User { id: user.id };
79
80    match server_user.list_account_tag_names().await {
81        Ok(names) => {
82            let suggestions = names
83                .into_iter()
84                .map(|name| TagSuggestion { name, value: None })
85                .collect();
86            Ok(Json(suggestions))
87        }
88        Err(e) => {
89            let error_response = serde_json::json!({
90                "status": "fail",
91                "message": "Failed to fetch account tag names",
92            });
93            log::error!("Failed to fetch account tag names: {e:?}");
94            Err((StatusCode::INTERNAL_SERVER_ERROR, Json(error_response)))
95        }
96    }
97}
98
99pub async fn account_tag_values(
100    Query(query): Query<TagValuesQuery>,
101    Extension(jwt_auth): Extension<JWTAuthMiddleware>,
102) -> Result<Json<Vec<TagSuggestion>>, (StatusCode, Json<serde_json::Value>)> {
103    let user = &jwt_auth.user;
104    let server_user = server::user::User { id: user.id };
105
106    match server_user.list_account_tag_values(&query.name).await {
107        Ok(values) => {
108            let suggestions = values
109                .into_iter()
110                .map(|value| TagSuggestion {
111                    name: value.clone(),
112                    value: Some(value),
113                })
114                .collect();
115            Ok(Json(suggestions))
116        }
117        Err(e) => {
118            let error_response = serde_json::json!({
119                "status": "fail",
120                "message": "Failed to fetch account tag values",
121            });
122            log::error!(
123                "Failed to fetch account tag values for '{}': {e:?}",
124                query.name
125            );
126            Err((StatusCode::INTERNAL_SERVER_ERROR, Json(error_response)))
127        }
128    }
129}
130
131pub async fn split_tag_names(
132    Extension(jwt_auth): Extension<JWTAuthMiddleware>,
133) -> Result<Json<Vec<TagSuggestion>>, (StatusCode, Json<serde_json::Value>)> {
134    let user = &jwt_auth.user;
135    let server_user = server::user::User { id: user.id };
136
137    match server_user.list_split_tag_names().await {
138        Ok(names) => {
139            let suggestions = names
140                .into_iter()
141                .map(|name| TagSuggestion { name, value: None })
142                .collect();
143            Ok(Json(suggestions))
144        }
145        Err(e) => {
146            let error_response = serde_json::json!({
147                "status": "fail",
148                "message": "Failed to fetch split tag names",
149            });
150            log::error!("Failed to fetch split tag names: {e:?}");
151            Err((StatusCode::INTERNAL_SERVER_ERROR, Json(error_response)))
152        }
153    }
154}
155
156pub async fn split_tag_values(
157    Query(query): Query<TagValuesQuery>,
158    Extension(jwt_auth): Extension<JWTAuthMiddleware>,
159) -> Result<Json<Vec<TagSuggestion>>, (StatusCode, Json<serde_json::Value>)> {
160    let user = &jwt_auth.user;
161    let server_user = server::user::User { id: user.id };
162
163    match server_user.list_split_tag_values(&query.name).await {
164        Ok(values) => {
165            let suggestions = values
166                .into_iter()
167                .map(|value| TagSuggestion {
168                    name: value.clone(),
169                    value: Some(value),
170                })
171                .collect();
172            Ok(Json(suggestions))
173        }
174        Err(e) => {
175            let error_response = serde_json::json!({
176                "status": "fail",
177                "message": "Failed to fetch split tag values",
178            });
179            log::error!(
180                "Failed to fetch split tag values for '{}': {e:?}",
181                query.name
182            );
183            Err((StatusCode::INTERNAL_SERVER_ERROR, Json(error_response)))
184        }
185    }
186}