use acton_htmx::{observability, state::ActonHtmxState};
use acton_reactive::prelude::ActonApp;
use axum::{
response::Html,
routing::{get, post},
Router,
};
use axum_htmx::{HxEvent, HxRedirect, HxRefresh, HxRequest, HxResponseTrigger};
use serde_json::json;
use tracing::info;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
observability::init()?;
let mut runtime = ActonApp::launch();
let state = ActonHtmxState::new(&mut runtime).await?;
let app = Router::new()
.route("/", get(index))
.route("/partial", get(partial))
.route("/redirect", post(redirect))
.route("/trigger", post(trigger))
.route("/refresh", post(refresh))
.with_state(state);
info!("Starting simple HTMX server on http://127.0.0.1:3000");
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000").await?;
axum::serve(listener, app).await?;
runtime.shutdown_all().await?;
Ok(())
}
async fn index() -> Html<&'static str> {
Html(include_str!("simple_htmx.html"))
}
async fn partial(HxRequest(is_htmx): HxRequest) -> Html<String> {
if is_htmx {
Html("<p>This is a partial response (HTMX detected)</p>".to_string())
} else {
Html("<html><body><h1>Full Page</h1></body></html>".to_string())
}
}
async fn redirect() -> (HxRedirect, Html<&'static str>) {
info!("Redirecting...");
(HxRedirect::from("/"), Html("<p>Redirecting...</p>"))
}
async fn trigger() -> (HxResponseTrigger, Html<&'static str>) {
info!("Triggering event");
let event =
HxEvent::new_with_data("myEvent", json!({"message": "Hello!"})).expect("valid JSON");
(
HxResponseTrigger::normal([event]),
Html("<p>Event triggered!</p>"),
)
}
async fn refresh() -> (HxRefresh, Html<&'static str>) {
info!("Triggering refresh");
(HxRefresh::from(true), Html("<p>Refreshing...</p>"))
}