1
use askama::Template;
2
use axum::{Extension, Json, extract::State, response::IntoResponse};
3
use serde::Deserialize;
4
use server::command::{CmdResult, FinanceEntity, account::ListAccounts};
5
use sqlx::types::Uuid;
6
use std::sync::Arc;
7

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

            
10
#[derive(Deserialize)]
11
pub struct AccountSearch {
12
    #[serde(rename = "parent-search")]
13
    query: Option<String>,
14
}
15

            
16
#[derive(Template)]
17
#[template(path = "components/account/search_results.html")]
18
struct AccountSearchResults {
19
    accounts: Vec<AccountView>,
20
}
21

            
22
struct AccountView {
23
    id: Uuid,
24
    name: String,
25
}
26

            
27
2
pub async fn search_accounts(
28
2
    State(_data): State<Arc<AppState>>,
29
2
    Extension(jwt_auth): Extension<JWTAuthMiddleware>,
30
2
    Json(form): Json<AccountSearch>,
31
3
) -> impl IntoResponse {
32
2
    let result = match ListAccounts::new().user_id(jwt_auth.user.id).run().await {
33
        Ok(Some(CmdResult::TaggedEntities(entities))) => entities,
34
2
        _ => return HtmlTemplate(AccountSearchResults { accounts: vec![] }),
35
    };
36

            
37
    let mut accounts = Vec::new();
38
    for (entity, tags) in result {
39
        if let FinanceEntity::Account(account) = entity {
40
            // Find name tag
41
            let name = if let FinanceEntity::Tag(n) = &tags["name"] {
42
                n.tag_value.clone()
43
            } else {
44
                continue;
45
            };
46

            
47
            // Filter by search query if provided
48
            if let Some(query) = &form.query {
49
                if query.is_empty() || name.to_lowercase().contains(&query.to_lowercase()) {
50
                    accounts.push(AccountView {
51
                        id: account.id,
52
                        name,
53
                    });
54
                }
55
            } else {
56
                accounts.push(AccountView {
57
                    id: account.id,
58
                    name,
59
                });
60
            }
61
        }
62
    }
63

            
64
    HtmlTemplate(AccountSearchResults { accounts })
65
2
}