use axum::{extract::State, routing::get, Router}; use maud::Markup; use sqlx::sqlite::SqlitePool; use crate::{channel::repo::Provider as _, error::InternalError, login::repo::logins::Login}; async fn index( State(db): State, login: Option, ) -> Result { match login { None => Ok(templates::unauthenticated()), Some(login) => index_authenticated(db, login).await, } } async fn index_authenticated(db: SqlitePool, login: Login) -> Result { let mut tx = db.begin().await?; let joined_channels = tx.channels().joined(&login.id).await?; let unjoined_channels = tx.channels().unjoined(&login.id).await?; tx.commit().await?; Ok(templates::authenticated( login, &joined_channels, &unjoined_channels, )) } pub fn router() -> Router { Router::new().route("/", get(index)) } mod templates { use maud::{html, Markup, DOCTYPE}; use crate::{channel::repo::Channel, login::repo::logins::Login}; pub fn authenticated<'c>( login: Login, joined_channels: impl IntoIterator, unjoined_channels: impl IntoIterator, ) -> Markup { html! { (DOCTYPE) head { title { "hi" } } body { section { (channel_list(joined_channels)) (join_channel(unjoined_channels)) (create_channel()) } section { (logout_form(&login.name)) } } } } fn channel_list<'c>(joined_channels: impl IntoIterator) -> Markup { html! { ul { @for channel in joined_channels { (joined_channel_entry(&channel)) } } } } fn joined_channel_entry(channel: &Channel) -> Markup { let leave_url = format!("/{}/leave", channel.id); html! { li { (channel.name) " (" (channel.id) ")" form action=(leave_url) method="post" { button { "leave" } } } } } fn join_channel<'c>(unjoined_channels: impl IntoIterator) -> Markup { html! { form action="join" method="post" { select name="channel" required { option value="" { "channel" } @for channel in unjoined_channels { option value=(channel.id) { (channel.name) " (" (channel.id) ")" } } } button { "join" } } } } fn create_channel() -> Markup { html! { form action="/create" method="post" { label { "name" input name="name" type="text" {} } button { "start channel" } } } } fn logout_form(name: &str) -> Markup { html! { form action="/logout" method="post" { button { "bye, " (name) } } } } pub fn unauthenticated() -> Markup { html! { (DOCTYPE) head { title { "hi" } } body { (login_form()) } } } fn login_form() -> Markup { html! { form action="/login" method="post" { label { "login" input name="name" type="text" {} } label { "password" input name="password" type="password" {} } button { "hi" } } } } }