diff --git a/src/db/mod.rs b/src/db/mod.rs index bbb5fa5..f18a856 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -43,6 +43,22 @@ impl Database { Ok(users) } + pub fn get_guild(&self, guild_id: u64) -> Result { + let mut query = self.conn.prepare( + " + SELECT + Guild.name + FROM Guild + WHERE Guild.id = :guild_id + ", + )?; + + let guild_name = + query.query_row(&[(":guild_id", &guild_id.to_string())], |row| row.get(0))?; + + Ok(guild_name) + } + pub(crate) fn get_guilds(&self) -> Result> { let mut query = self.conn.prepare( " diff --git a/src/page.rs b/src/page.rs index ab8081b..3854a92 100644 --- a/src/page.rs +++ b/src/page.rs @@ -176,9 +176,15 @@ pub(crate) async fn guild_dashboard( user: User, Path(guild_id): Path, ) -> Result, Redirect> { - let (guild_intros, guild_channels, all_user_intros, user_permissions) = { + let (guild_name, guild_intros, guild_channels, all_user_intros, user_permissions) = { let db = state.db.lock().await; + let guild_name = db.get_guild(guild_id).map_err(|err| { + error!(?err, %guild_id, "couldn't get guild"); + // TODO: change to actual error + Redirect::to(&format!("{}/login", state.origin)) + })?; + let guild_intros = db.get_guild_intros(guild_id).map_err(|err| { error!(?err, %guild_id, "couldn't get guild intros"); // TODO: change to actual error @@ -199,6 +205,7 @@ pub(crate) async fn guild_dashboard( .unwrap_or_default(); ( + guild_name, guild_intros, guild_channels, all_user_intros, @@ -207,8 +214,10 @@ pub(crate) async fn guild_dashboard( }; let can_upload = user_permissions.can(auth::Permission::UploadSounds); + let can_add_channel = user_permissions.can(auth::Permission::AddChannel); let is_moderator = user_permissions.can(auth::Permission::Moderator); - let mod_dashboard = moderator_dashboard(&state, &state.secrets.bot_token, guild_id).await; + let mod_dashboard = + moderator_dashboard(&state, &state.secrets.bot_token, guild_id, user_permissions).await; let user_intros = all_user_intros .iter() @@ -222,17 +231,16 @@ pub(crate) async fn guild_dashboard( b.builder(Tag::HeaderGroup, |b| { b.attribute("class", "container") .builder(Tag::Header1, |b| b.text("MemeJoin - A bot for user intros")) - .builder_text(Tag::Header6, &user.name) + .builder_text(Tag::Header6, &format!("{} - {}", user.name, guild_name)) }) }) .builder(Tag::Empty, |b| { - let mut b = if is_moderator { + let mut b = if is_moderator || can_add_channel { b.builder(Tag::Div, |b| { b.attribute("class", "container") .builder(Tag::Article, |b| { - b.builder_text(Tag::Header, "Wow, you're a moderator") + b.builder_text(Tag::Header, "Server Settings") .push_builder(mod_dashboard) - .builder_text(Tag::Footer, "End of super cool mod section") }) }) } else { @@ -338,16 +346,14 @@ fn upload_form(origin: &str, guild_id: u64) -> HtmxBuilder { .attribute("hx-encoding", "multipart/form-data") .builder(Tag::FieldSet, |b| { b.attribute("class", "container") + .attribute("role", "group") + .input(|b| b.attribute("type", "file").attribute("name", "file")) .input(|b| { b.attribute("name", "name") .attribute("placeholder", "enter intro title") }) - .label(|b| { - b.text("Choose File") - .input(|b| b.attribute("type", "file").attribute("name", "file")) - }) + .button(|b| b.attribute("type", "submit").text("Upload")) }) - .button(|b| b.attribute("type", "submit").text("Upload")) }) } @@ -357,29 +363,39 @@ fn ytdl_form(origin: &str, guild_id: u64) -> HtmxBuilder { .hx_get(&format!("{}/v2/intros/{}/add", origin, guild_id)) .builder(Tag::FieldSet, |b| { b.attribute("class", "container") - .label(|b| { - b.text("Video Url").input(|b| { - b.attribute("placeholder", "enter video url") - .attribute("name", "url") - }) + .attribute("role", "group") + .input(|b| { + b.attribute("placeholder", "enter video url") + .attribute("name", "url") }) - .label(|b| { - b.text("Intro Title").input(|b| { - b.attribute("placeholder", "enter intro title") - .attribute("name", "name") - }) + .input(|b| { + b.attribute("placeholder", "enter intro title") + .attribute("name", "name") }) + .button(|b| b.attribute("type", "submit").text("Upload")) }) - .button(|b| b.attribute("type", "submit").text("Upload")) }) } -async fn moderator_dashboard(state: &ApiState, bot_token: &str, guild_id: u64) -> HtmxBuilder { +async fn moderator_dashboard( + state: &ApiState, + bot_token: &str, + guild_id: u64, + user_permissions: auth::Permissions, +) -> HtmxBuilder { let permissions_editor = permissions_editor(state, guild_id).await; let channel_editor = channel_editor(state, bot_token, guild_id).await; - HtmxBuilder::new(Tag::Empty) - .push_builder(permissions_editor) - .push_builder(channel_editor) + + let mut b = HtmxBuilder::new(Tag::Empty); + + if user_permissions.can(auth::Permission::Moderator) { + b = b.push_builder(permissions_editor); + } + if user_permissions.can(auth::Permission::AddChannel) { + b = b.push_builder(channel_editor); + } + + b } async fn channel_editor(state: &ApiState, bot_token: &str, guild_id: u64) -> HtmxBuilder { @@ -422,28 +438,30 @@ async fn channel_editor(state: &ApiState, bot_token: &str, guild_id: u64) -> Htm }; if got_channels && !channels.is_empty() { - HtmxBuilder::new(Tag::Empty).form(|b| { - b.attribute("class", "container") - .hx_post(&format!("{}/guild/{}/add_channel", state.origin, guild_id)) - .attribute("hx-encoding", "multipart/form-data") - .builder(Tag::FieldSet, |b| { - let mut b = b - .attribute("class", "container") - .attribute("style", "max-height: 50%; overflow-y: scroll"); - for channel_name in channels { - b = b.builder(Tag::Label, |b| { - b.builder(Tag::Input, |b| { - b.attribute("type", "checkbox") - .attribute("name", &channel_name.to_string()) - }) - .builder_text(Tag::Paragraph, &channel_name) - }); - } + HtmxBuilder::new(Tag::Details) + .builder_text(Tag::Summary, "Add Channels") + .form(|b| { + b.attribute("class", "container") + .hx_post(&format!("{}/guild/{}/add_channel", state.origin, guild_id)) + .attribute("hx-encoding", "multipart/form-data") + .builder(Tag::FieldSet, |b| { + let mut b = b + .attribute("class", "container") + .attribute("style", "max-height: 50%; overflow-y: scroll"); + for channel_name in channels { + b = b.builder(Tag::Label, |b| { + b.builder(Tag::Input, |b| { + b.attribute("type", "checkbox") + .attribute("name", &channel_name.to_string()) + }) + .builder_text(Tag::Paragraph, &channel_name) + }); + } - b - }) - .button(|b| b.attribute("type", "submit").text("Add Channel")) - }) + b + }) + .button(|b| b.attribute("type", "submit").text("Add Channel")) + }) } else if channels.is_empty() { HtmxBuilder::new(Tag::Empty) } else { @@ -455,63 +473,66 @@ async fn permissions_editor(state: &ApiState, guild_id: u64) -> HtmxBuilder { let db = state.db.lock().await; let user_permissions = db.get_all_user_permissions(guild_id).unwrap_or_default(); - HtmxBuilder::new(Tag::Empty).form(|b| { - b.hx_post(&format!( - "{}/guild/{}/permissions/update", - state.origin, guild_id - )) - .attribute("hx-encoding", "multipart/form-data") - .builder(Tag::Table, |b| { - let mut b = b.attribute("role", "grid").builder(Tag::TableHead, |b| { - let mut b = b.builder_text(Tag::TableHeader, "User"); - - for perm in enum_iterator::all::() { - if perm == auth::Permission::Moderator || perm == auth::Permission::None { - continue; - } - - b = b.builder_text(Tag::TableHeader, &perm.to_string()); - } - - b - }); - - for permission in user_permissions { - b = b.builder(Tag::TableRow, |b| { - let mut b = b.builder_text(Tag::TableData, permission.0.as_str()); + HtmxBuilder::new(Tag::Details) + .builder_text(Tag::Summary, "Permissions") + .form(|b| { + b.hx_post(&format!( + "{}/guild/{}/permissions/update", + state.origin, guild_id + )) + .attribute("hx-encoding", "multipart/form-data") + .builder(Tag::Table, |b| { + let mut b = b.attribute("role", "grid").builder(Tag::TableHead, |b| { + let mut b = b.builder_text(Tag::TableHeader, "User"); for perm in enum_iterator::all::() { if perm == auth::Permission::Moderator || perm == auth::Permission::None { continue; } - b = b.builder(Tag::TableData, |b| { - b.builder(Tag::Input, |b| { - let mut b = b - .attribute("type", "checkbox") - .attribute("name", &format!("{}#{}", permission.0, perm)); - - if permission.1.can(auth::Permission::Moderator) { - b = b.flag("disabled"); - } - - if permission.1.can(perm) { - return b.flag("checked"); - } - - b - }) - }); + b = b.builder_text(Tag::TableHeader, &perm.to_string()); } b }); - } - b + for permission in user_permissions { + b = b.builder(Tag::TableRow, |b| { + let mut b = b.builder_text(Tag::TableData, permission.0.as_str()); + + for perm in enum_iterator::all::() { + if perm == auth::Permission::Moderator || perm == auth::Permission::None + { + continue; + } + + b = b.builder(Tag::TableData, |b| { + b.builder(Tag::Input, |b| { + let mut b = b + .attribute("type", "checkbox") + .attribute("name", &format!("{}#{}", permission.0, perm)); + + if permission.1.can(auth::Permission::Moderator) { + b = b.flag("disabled"); + } + + if permission.1.can(perm) { + return b.flag("checked"); + } + + b + }) + }); + } + + b + }); + } + + b + }) + .button(|b| b.attribute("type", "submit").text("Update Permissions")) }) - .button(|b| b.attribute("type", "submit").text("Update Permissions")) - }) } pub(crate) async fn login(