use crate::model::{ log::Log, notification::Notification, role::Role, user::{User, UserWithDetails, VorstandUser}, }; use itertools::Itertools; use rocket::{ form::Form, get, post, request::FlashMessage, response::{Flash, Redirect}, routes, FromForm, Route, State, }; use rocket_dyn_templates::{tera::Context, Template}; use sqlx::SqlitePool; #[get("/notification")] async fn index( db: &State, user: VorstandUser, flash: Option>, ) -> Template { let mut context = Context::new(); if let Some(msg) = flash { context.insert("flash", &msg.into_inner()); } context.insert( "loggedin_user", &UserWithDetails::from_user(user.user, db).await, ); let users: Vec = User::all(db) .await .into_iter() .filter(|u| u.last_access.is_some()) // Not useful to send notifications to people who are // not logging in .sorted_by_key(|u| u.name.clone()) .collect(); context.insert("roles", &Role::all(db).await); context.insert("users", &users); Template::render("admin/notification", context.into_json()) } #[derive(FromForm, Debug)] pub struct NotificationToSendGroup { pub(crate) role_id: i32, pub(crate) category: String, pub(crate) message: String, } #[derive(FromForm, Debug)] pub struct NotificationToSendUser { pub(crate) user_id: i32, pub(crate) category: String, pub(crate) message: String, } #[post("/notification/group", data = "")] async fn send_group( db: &State, data: Form, admin: VorstandUser, ) -> Flash { let d = data.into_inner(); Log::create( db, format!("{admin:?} trying to send this notification: {d:?}"), ) .await; let Some(role) = Role::find_by_id(db, d.role_id).await else { return Flash::error(Redirect::to("/admin/notification"), "Rolle gibt's ned"); }; for user in User::all_with_role(db, &role).await { Notification::create(db, &user, &d.message, &d.category, None, None).await; } Log::create(db, "Notification successfully sent".into()).await; Flash::success( Redirect::to("/admin/notification"), "Nachricht ausgeschickt", ) } #[post("/notification/user", data = "")] async fn send_user( db: &State, data: Form, admin: VorstandUser, ) -> Flash { let d = data.into_inner(); Log::create( db, format!("{admin:?} trying to send this notification: {d:?}"), ) .await; let Some(user) = User::find_by_id(db, d.user_id).await else { return Flash::error(Redirect::to("/admin/notification"), "User gibt's ned"); }; Notification::create(db, &user, &d.message, &d.category, None, None).await; Log::create(db, "Notification successfully sent".into()).await; Flash::success( Redirect::to("/admin/notification"), "Nachricht ausgeschickt", ) } pub fn routes() -> Vec { routes![index, send_user, send_group] }