1
use std::sync::Arc;
2

            
3
use axum::{
4
    Router, middleware,
5
    routing::{get, post},
6
};
7

            
8
#[cfg(feature = "scripting")]
9
use crate::pages::script;
10
use crate::{
11
    AppState,
12
    files::download_file,
13
    handler::{
14
        get_home_link, get_logout_link, get_me_handler, get_version, login_user_handler,
15
        logout_handler, refresh_access_token_handler, register_user_handler,
16
    },
17
    jwt_auth::{admin, auth},
18
    pages::{account, commodity, file_table, report, tag},
19
    redirect_middleware::redirect_on_auth_error,
20
};
21

            
22
1
pub fn create_pages_router(app_state: Arc<AppState>) -> Router<Arc<AppState>> {
23
1
    Router::new()
24
1
        .route(
25
1
            "/commodity/create",
26
1
            get(crate::pages::commodity::create::submit::commodity_create_page),
27
        )
28
1
        .route(
29
1
            "/commodity/list",
30
1
            get(crate::pages::commodity::list::commodity_list_page),
31
        )
32
1
        .route_layer(middleware::from_fn_with_state(app_state.clone(), auth))
33
1
        .route_layer(middleware::from_fn(redirect_on_auth_error))
34
1
        .with_state(app_state.clone())
35
1
}
36

            
37
1
pub fn create_accounts_router(app_state: Arc<AppState>) -> Router<Arc<AppState>> {
38
1
    Router::new()
39
1
        .route(
40
1
            "/account/create",
41
1
            get(crate::pages::account::create::submit::account_create_page),
42
        )
43
1
        .route(
44
1
            "/account/list",
45
1
            get(crate::pages::account::list::account_list_page),
46
        )
47
1
        .route(
48
1
            "/account/manage",
49
1
            get(crate::pages::account::manage::account_manage_page),
50
        )
51
1
        .route_layer(middleware::from_fn_with_state(app_state.clone(), auth))
52
1
        .route_layer(middleware::from_fn(redirect_on_auth_error))
53
1
        .with_state(app_state.clone())
54
1
}
55

            
56
1
pub fn create_transactions_router(app_state: Arc<AppState>) -> Router<Arc<AppState>> {
57
1
    Router::new()
58
1
        .route(
59
1
            "/transaction/create",
60
1
            get(crate::pages::transaction::create::submit::transaction_create_page),
61
        )
62
1
        .route(
63
1
            "/transaction/list",
64
1
            get(crate::pages::transaction::list::transaction_list_page),
65
        )
66
1
        .route(
67
1
            "/transaction/edit/{id}",
68
1
            get(crate::pages::transaction::edit::submit::transaction_edit_page),
69
        )
70
1
        .route_layer(middleware::from_fn_with_state(app_state.clone(), auth))
71
1
        .route_layer(middleware::from_fn(redirect_on_auth_error))
72
1
        .with_state(app_state.clone())
73
1
}
74

            
75
pub fn create_tags_router(app_state: Arc<AppState>) -> Router<Arc<AppState>> {
76
    Router::new()
77
        .route(
78
            "/tag/create",
79
            get(crate::pages::tag::create::tag_create_page),
80
        )
81
        .route("/tag/list", get(crate::pages::tag::list::tag_list_page))
82
        .route(
83
            "/tag/edit/{id}",
84
            get(crate::pages::tag::edit::tag_edit_page),
85
        )
86
        .route_layer(middleware::from_fn_with_state(app_state.clone(), auth))
87
        .route_layer(middleware::from_fn(redirect_on_auth_error))
88
        .with_state(app_state.clone())
89
}
90

            
91
#[cfg(feature = "scripting")]
92
pub fn create_scripts_router(app_state: Arc<AppState>) -> Router<Arc<AppState>> {
93
    Router::new()
94
        .route("/script/create", get(script::edit::script_create_page))
95
        .route("/script/list", get(script::list::script_list_page))
96
        .route("/script/edit/{id}", get(script::edit::script_edit_page))
97
        .route_layer(middleware::from_fn_with_state(app_state.clone(), auth))
98
        .route_layer(middleware::from_fn(redirect_on_auth_error))
99
        .with_state(app_state.clone())
100
}
101

            
102
pub fn create_reports_router(app_state: Arc<AppState>) -> Router<Arc<AppState>> {
103
    Router::new()
104
        .route("/report/balance", get(report::balance::balance_report_page))
105
        .route(
106
            "/report/income-expense",
107
            get(report::income_expense::income_expense_report_page),
108
        )
109
        .route(
110
            "/report/trial-balance",
111
            get(report::trial_balance::trial_balance_report_page),
112
        )
113
        .route_layer(middleware::from_fn_with_state(app_state.clone(), auth))
114
        .route_layer(middleware::from_fn(redirect_on_auth_error))
115
        .with_state(app_state.clone())
116
}
117

            
118
3
pub fn create_api_router(app_state: Arc<AppState>) -> Router<Arc<AppState>> {
119
3
    let public_router = Router::new()
120
3
        .route("/auth/login", post(login_user_handler))
121
3
        .route("/version", get(get_version));
122

            
123
3
    let auth_router = Router::new()
124
3
        .route("/auth/refresh", get(refresh_access_token_handler))
125
3
        .route("/files/list", get(file_table))
126
3
        .route("/files/download/{file_name}", get(download_file))
127
3
        .route("/auth/logout", get(logout_handler))
128
3
        .route("/users/me", get(get_me_handler))
129
3
        .route("/htmx/logoutlink", get(get_logout_link))
130
3
        .route_layer(middleware::from_fn_with_state(app_state.clone(), auth))
131
3
        .with_state(app_state.clone());
132

            
133
3
    let account_router = Router::new()
134
3
        .route("/account/list", get(account::list::account_table))
135
3
        .route("/account/info", get(account::list::account_info))
136
3
        .route("/account/tree", get(account::manage::account_tree))
137
3
        .route(
138
3
            "/account/manage/view",
139
3
            get(account::manage::account_manage_view),
140
        )
141
3
        .route(
142
3
            "/account/manage/details",
143
3
            get(account::manage::account_manage_details),
144
        )
145
3
        .route(
146
3
            "/account/manage/tag",
147
3
            post(account::manage::account_manage_set_tag),
148
        )
149
3
        .route(
150
3
            "/account/manage/tag/submit",
151
3
            post(account::manage::account_manage_set_tag_submit),
152
        )
153
3
        .route(
154
3
            "/account/manage/tag/delete/{tag_id}",
155
3
            post(account::manage::account_manage_delete_tag_submit),
156
        )
157
3
        .route("/account/search", post(account::search::search_accounts))
158
3
        .route(
159
3
            "/account/create/submit",
160
3
            post(account::create::submit::create_account),
161
        )
162
3
        .route(
163
3
            "/account/create/validate/name",
164
3
            post(account::create::validate::validate_name),
165
        )
166
3
        .route("/account/rename", post(account::edit::rename_account))
167
3
        .route(
168
3
            "/account/{id}/tags/submit",
169
3
            post(account::edit::account_tags_submit),
170
        )
171
3
        .route_layer(middleware::from_fn_with_state(app_state.clone(), auth))
172
3
        .with_state(app_state.clone());
173

            
174
3
    let nav_router = Router::new()
175
3
        .route("/nav/home", get(get_home_link))
176
3
        .route_layer(middleware::from_fn_with_state(app_state.clone(), auth))
177
3
        .with_state(app_state.clone());
178

            
179
3
    let commodity_router = Router::new()
180
3
        .route("/commodity/list", get(commodity::list::commodity_table))
181
3
        .route(
182
3
            "/commodity/search",
183
3
            post(commodity::search::search_commodities),
184
        )
185
3
        .route(
186
3
            "/commodity/create/submit",
187
3
            post(commodity::create::submit::commodity_submit),
188
        )
189
3
        .route(
190
3
            "/commodity/create/validate/symbol",
191
3
            post(commodity::create::validate::validate_symbol),
192
        )
193
3
        .route(
194
3
            "/commodity/create/validate/name",
195
3
            post(commodity::create::validate::validate_name),
196
        )
197
3
        .route_layer(middleware::from_fn_with_state(app_state.clone(), auth))
198
3
        .with_state(app_state.clone());
199

            
200
3
    let transaction_router = Router::new()
201
3
        .route(
202
3
            "/transaction/list",
203
3
            get(crate::pages::transaction::list::transaction_table),
204
        )
205
3
        .route(
206
3
            "/transaction/split/create",
207
3
            get(crate::pages::transaction::create::split::split_create_handler),
208
        )
209
3
        .route(
210
3
            "/transaction/create/submit",
211
3
            post(crate::pages::transaction::create::submit::transaction_submit),
212
        )
213
3
        .route(
214
3
            "/transaction/create/validate/amount",
215
3
            post(crate::pages::transaction::validate::validate_amount_html),
216
        )
217
3
        .route(
218
3
            "/transaction/create/validate/from_account",
219
3
            post(crate::pages::transaction::validate::validate_from_account_html),
220
        )
221
3
        .route(
222
3
            "/transaction/create/validate/to_account",
223
3
            post(crate::pages::transaction::validate::validate_to_account_html),
224
        )
225
3
        .route(
226
3
            "/transaction/create/validate/note",
227
3
            post(crate::pages::transaction::validate::validate_note_html),
228
        )
229
3
        .route(
230
3
            "/transaction/edit/submit",
231
3
            post(crate::pages::transaction::edit::submit::transaction_edit_submit),
232
        )
233
3
        .route(
234
3
            "/transaction/edit/validate/amount",
235
3
            post(crate::pages::transaction::validate::validate_amount_json),
236
        )
237
3
        .route(
238
3
            "/transaction/edit/validate/from_account",
239
3
            post(crate::pages::transaction::validate::validate_from_account_json),
240
        )
241
3
        .route(
242
3
            "/transaction/edit/validate/to_account",
243
3
            post(crate::pages::transaction::validate::validate_to_account_json),
244
        )
245
3
        .route(
246
3
            "/transaction/edit/validate/note",
247
3
            post(crate::pages::transaction::validate::validate_note_json),
248
        )
249
3
        .route(
250
3
            "/transaction/delete/{id}",
251
3
            post(crate::pages::transaction::delete::submit::transaction_delete_submit),
252
        )
253
3
        .route_layer(middleware::from_fn_with_state(app_state.clone(), auth))
254
3
        .with_state(app_state.clone());
255

            
256
3
    let tag_router = Router::new()
257
3
        .route("/tag/list", get(tag::list::tag_table))
258
3
        .route("/tag/create/submit", post(tag::create::create_tag))
259
3
        .route(
260
3
            "/transaction/{id}/tag/create/submit",
261
3
            post(tag::create::create_transaction_tag),
262
        )
263
3
        .route(
264
3
            "/split/{id}/tag/create/submit",
265
3
            post(tag::create::create_split_tag),
266
        )
267
3
        .route(
268
3
            "/account/{id}/tag/create/submit",
269
3
            post(tag::create::create_account_tag),
270
        )
271
3
        .route("/tag/edit/submit", post(tag::edit::edit_tag))
272
3
        .route("/tag/delete/{id}", post(tag::edit::delete_tag))
273
3
        .route(
274
3
            "/tags/transaction/names",
275
3
            get(tag::autocomplete::transaction_tag_names),
276
        )
277
3
        .route(
278
3
            "/tags/transaction/values",
279
3
            get(tag::autocomplete::transaction_tag_values),
280
        )
281
3
        .route("/tags/split/names", get(tag::autocomplete::split_tag_names))
282
3
        .route(
283
3
            "/tags/split/values",
284
3
            get(tag::autocomplete::split_tag_values),
285
        )
286
3
        .route(
287
3
            "/tags/account/names",
288
3
            get(tag::autocomplete::account_tag_names),
289
        )
290
3
        .route(
291
3
            "/tags/account/values",
292
3
            get(tag::autocomplete::account_tag_values),
293
        )
294
3
        .route_layer(middleware::from_fn_with_state(app_state.clone(), auth))
295
3
        .with_state(app_state.clone());
296

            
297
    #[cfg(feature = "scripting")]
298
3
    let script_router = Router::new()
299
3
        .route("/script/list", get(script::list::script_table))
300
3
        .route("/script/create/submit", post(script::edit::create_script))
301
3
        .route("/script/edit/submit", post(script::edit::edit_script))
302
3
        .route(
303
3
            "/script/bytecode/{id}",
304
3
            post(script::edit::upload_script_bytecode),
305
        )
306
3
        .route("/script/delete/{id}", post(script::edit::delete_script))
307
3
        .route(
308
3
            "/account/{account_id}/script/run/{script_id}",
309
3
            post(account::edit::run_account_script),
310
        )
311
3
        .route_layer(middleware::from_fn_with_state(app_state.clone(), auth))
312
3
        .with_state(app_state.clone());
313

            
314
3
    let report_router = Router::new()
315
3
        .route(
316
3
            "/report/balance",
317
3
            get(report::balance::balance_report_table),
318
        )
319
3
        .route(
320
3
            "/report/income-expense",
321
3
            get(report::income_expense::income_expense_report_table),
322
        )
323
3
        .route(
324
3
            "/report/trial-balance",
325
3
            get(report::trial_balance::trial_balance_report_table),
326
        )
327
3
        .route_layer(middleware::from_fn_with_state(app_state.clone(), auth))
328
3
        .with_state(app_state.clone());
329

            
330
3
    let admin_router = Router::new()
331
3
        .route("/auth/register", post(register_user_handler))
332
3
        .route_layer(middleware::from_fn_with_state(app_state.clone(), admin))
333
3
        .route_layer(middleware::from_fn_with_state(app_state, auth));
334

            
335
3
    let router = Router::new()
336
3
        .merge(public_router)
337
3
        .merge(nav_router)
338
3
        .merge(auth_router)
339
3
        .merge(account_router)
340
3
        .merge(commodity_router)
341
3
        .merge(transaction_router)
342
3
        .merge(tag_router)
343
3
        .merge(report_router)
344
3
        .merge(admin_router);
345

            
346
    #[cfg(feature = "scripting")]
347
3
    let router = router.merge(script_router);
348

            
349
3
    router
350
3
}