summaryrefslogtreecommitdiff
path: root/src/index
diff options
context:
space:
mode:
Diffstat (limited to 'src/index')
-rw-r--r--src/index/app.rs24
-rw-r--r--src/index/mod.rs3
-rw-r--r--src/index/routes.rs22
-rw-r--r--src/index/templates.rs89
4 files changed, 138 insertions, 0 deletions
diff --git a/src/index/app.rs b/src/index/app.rs
new file mode 100644
index 0000000..79f5a9a
--- /dev/null
+++ b/src/index/app.rs
@@ -0,0 +1,24 @@
+use sqlx::sqlite::SqlitePool;
+
+use crate::{
+ channel::repo::{Channel, Provider as _},
+ error::BoxedError,
+};
+
+pub struct Index<'a> {
+ db: &'a SqlitePool,
+}
+
+impl<'a> Index<'a> {
+ pub fn new(db: &'a SqlitePool) -> Self {
+ Self { db }
+ }
+
+ pub async fn for_authenticated(&self) -> Result<Vec<Channel>, BoxedError> {
+ let mut tx = self.db.begin().await?;
+ let channels = tx.channels().all().await?;
+ tx.commit().await?;
+
+ Ok(channels)
+ }
+}
diff --git a/src/index/mod.rs b/src/index/mod.rs
new file mode 100644
index 0000000..0d89a50
--- /dev/null
+++ b/src/index/mod.rs
@@ -0,0 +1,3 @@
+pub mod app;
+pub mod routes;
+mod templates;
diff --git a/src/index/routes.rs b/src/index/routes.rs
new file mode 100644
index 0000000..c57278f
--- /dev/null
+++ b/src/index/routes.rs
@@ -0,0 +1,22 @@
+use axum::{extract::State, routing::get, Router};
+use maud::Markup;
+
+use super::templates;
+use crate::{app::App, error::InternalError, login::repo::logins::Login};
+
+async fn index(State(app): State<App>, login: Option<Login>) -> Result<Markup, InternalError> {
+ match login {
+ None => Ok(templates::unauthenticated()),
+ Some(login) => index_authenticated(app, login).await,
+ }
+}
+
+async fn index_authenticated(app: App, login: Login) -> Result<Markup, InternalError> {
+ let channels = app.index().for_authenticated().await?;
+
+ Ok(templates::authenticated(login, &channels))
+}
+
+pub fn router() -> Router<App> {
+ Router::new().route("/", get(index))
+}
diff --git a/src/index/templates.rs b/src/index/templates.rs
new file mode 100644
index 0000000..fdb750b
--- /dev/null
+++ b/src/index/templates.rs
@@ -0,0 +1,89 @@
+use maud::{html, Markup, DOCTYPE};
+
+use crate::{channel::repo::Channel, login::repo::logins::Login};
+
+pub fn authenticated<'c>(login: Login, channels: impl IntoIterator<Item = &'c Channel>) -> Markup {
+ html! {
+ (DOCTYPE)
+ head {
+ title { "hi" }
+ }
+ body {
+ section {
+ (channel_list(channels))
+ (create_channel())
+ }
+ section {
+ (logout_form(&login.name))
+ }
+ }
+ }
+}
+
+fn channel_list<'c>(channels: impl IntoIterator<Item = &'c Channel>) -> Markup {
+ html! {
+ ul {
+ @for channel in channels {
+ (channel_list_entry(&channel))
+ }
+ }
+ }
+}
+
+fn channel_list_entry(channel: &Channel) -> Markup {
+ html! {
+ li {
+ (channel.name) " (" (channel.id) ")"
+ }
+ }
+}
+
+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" }
+ }
+ }
+}