1
use std::sync::Arc;
2

            
3
use crate::AppState;
4

            
5
use crate::files::{S3File, list_s3};
6
use askama::Template;
7
use axum::{
8
    extract::State,
9
    http::StatusCode,
10
    response::{Html, IntoResponse, Response},
11
};
12
use axum_extra::extract::CookieJar;
13
pub mod account;
14
pub mod commodity;
15
pub mod report;
16
pub mod script;
17
pub mod tag;
18
pub mod template;
19
pub mod transaction;
20
pub mod validation;
21

            
22
3
pub async fn index(cookie_jar: CookieJar) -> impl IntoResponse {
23
3
    let is_logged_in = match cookie_jar.get("access_token") {
24
        Some(cookie) => crate::auth_keys::verify(cookie.value(), crate::token::TokenType::Access)
25
            .await
26
            .is_some(),
27
3
        None => false,
28
    };
29

            
30
3
    let template = IndexTemplate {
31
3
        is_logged_in,
32
3
        scripting_enabled: true,
33
3
    };
34

            
35
3
    HtmlTemplate(template)
36
3
}
37

            
38
#[derive(Template)]
39
#[template(path = "pages/index.html")]
40
struct IndexTemplate {
41
    is_logged_in: bool,
42
    scripting_enabled: bool,
43
}
44

            
45
1
pub async fn file_table(
46
1
    State(data): State<Arc<AppState>>,
47
1
) -> Result<impl IntoResponse, StatusCode> {
48
1
    let frac = State(&data).frac;
49
1
    let template = FileTableTemplate {
50
1
        files: list_s3(State(data)).await?,
51
1
        frac,
52
    };
53
1
    Ok(HtmlTemplate(template))
54
1
}
55

            
56
#[derive(Template)]
57
#[template(path = "components/file-table.html")]
58
struct FileTableTemplate {
59
    files: Vec<S3File>,
60
    frac: i64,
61
}
62

            
63
1
pub async fn register() -> impl IntoResponse {
64
1
    let template = RegisterTemplate {};
65
1
    HtmlTemplate(template)
66
1
}
67

            
68
#[derive(Template)]
69
#[template(path = "pages/register.html")]
70
struct RegisterTemplate;
71

            
72
1
pub async fn login() -> impl IntoResponse {
73
1
    let template = LoginTemplate {};
74
1
    HtmlTemplate(template)
75
1
}
76

            
77
#[derive(Template)]
78
#[template(path = "pages/login.html")]
79
struct LoginTemplate;
80

            
81
/// A wrapper type that we'll use to encapsulate HTML parsed by askama into valid HTML for axum to serve.
82
struct HtmlTemplate<T>(T);
83

            
84
/// Allows us to convert Askama HTML templates into valid HTML for axum to serve in the response.
85
impl<T> IntoResponse for HtmlTemplate<T>
86
where
87
    T: Template,
88
{
89
12
    fn into_response(self) -> Response {
90
        // Attempt to render the template with askama
91
12
        match self.0.render() {
92
            // If we're able to successfully parse and aggregate the template, serve it
93
12
            Ok(html) => Html(html).into_response(),
94
            // If we're not, return an error or some bit of fallback HTML
95
            Err(err) => (
96
                StatusCode::INTERNAL_SERVER_ERROR,
97
                format!("Failed to render template. Error: {err}"),
98
            )
99
                .into_response(),
100
        }
101
12
    }
102
}