1use topcoat::{
4 Result,
5 context::Cx,
6 router::{
7 content::{Css, Json},
8 query_params, route,
9 },
10};
11
12use crate::{data::load, params::UsageParams, style::CSS};
13
14#[route(GET "/api/report")]
16async fn report(cx: &Cx) -> Result<Json<Vec<tokenburn_core::ReportRow>>> {
17 let query = query_params::<UsageParams>(cx)?.to_query();
18 Ok(Json(
19 load(query, &Default::default(), tokenburn_core::Currency::USD)
20 .await
21 .report,
22 ))
23}
24
25#[route(GET "/api/health")]
27async fn health() -> Result<Json<&'static str>> {
28 Ok(Json("ok"))
29}
30
31#[route(GET "/api/themes")]
33async fn themes() -> Result<Json<serde_json::Value>> {
34 Ok(Json(crate::theme::catalogue()))
35}
36
37#[route(GET "/style.css")]
38async fn style() -> Result<Css<&'static str>> {
39 Ok(Css(CSS))
40}
41
42#[route(GET "/cyberpunk.css")]
44async fn cyberpunk_style() -> Result<Css<&'static str>> {
45 Ok(Css(crate::theme::CYBERPUNK_CSS))
46}