board-scheckbook #686

Merged
philipp merged 5 commits from board-scheckbook into staging 2024-08-19 12:13:02 +02:00
3 changed files with 90 additions and 0 deletions
Showing only changes of commit ed9d93410e - Show all commits

View File

@ -648,6 +648,14 @@ ORDER BY last_access DESC
.is_ok() .is_ok()
} }
pub async fn create_with_mail(db: &SqlitePool, name: &str, mail: &str) -> bool {
let name = name.trim();
sqlx::query!("INSERT INTO USER(name, mail) VALUES (?, ?)", name, mail)
.execute(db)
.await
.is_ok()
}
pub async fn update(&self, db: &SqlitePool, data: UserEditForm<'_>) { pub async fn update(&self, db: &SqlitePool, data: UserEditForm<'_>) {
let mut family_id = data.family_id; let mut family_id = data.family_id;

View File

@ -14,6 +14,7 @@ use crate::{
tera::Config, tera::Config,
}; };
use futures::future::join_all; use futures::future::join_all;
use lettre::Address;
use rocket::{ use rocket::{
form::Form, form::Form,
fs::TempFile, fs::TempFile,
@ -349,6 +350,58 @@ async fn create(
} }
} }
#[derive(FromForm, Debug)]
struct UserAddScheckbuchForm<'r> {
name: &'r str,
mail: &'r str,
}
#[post("/user/new/scheckbuch", data = "<data>")]
async fn create_scheckbuch(
db: &State<SqlitePool>,
data: Form<UserAddScheckbuchForm<'_>>,
admin: VorstandUser,
config: &State<Config>,
) -> Flash<Redirect> {
// 1. Check mail adress
let mail = data.mail.trim();
if mail.parse::<Address>().is_err() {
return Flash::error(
Redirect::to("/admin/user/scheckbuch"),
format!("Keine gültige Mailadresse"),
);
}
// 2. Check name
let name = data.name.trim();
if User::find_by_name(db, name).await.is_some() {
return Flash::error(
Redirect::to("/admin/user/scheckbuch"),
format!(
"Kann kein Scheckbuch erstellen, der Name wird bereits von einem User verwendet"
),
);
}
// 3. Create user
User::create_with_mail(db, name, mail).await;
let user = User::find_by_name(db, name).await.unwrap();
// 4. Add 'scheckbuch' role
let scheckbuch = Role::find_by_name(db, "scheckbuch").await.unwrap();
user.add_role(db, &scheckbuch).await;
// 4. Send welcome mail (+ notification)
user.send_welcome_email(db, &config.smtp_pw).await.unwrap();
Log::create(
db,
format!("{} created new scheckbuch: {data:?}", admin.name),
)
.await;
Flash::success(Redirect::to("/admin/user/scheckbuch"), &format!("Scheckbuch erfolgreich erstellt. Eine E-Mail in der alles erklärt wird, wurde an {mail} verschickt."))
}
pub fn routes() -> Vec<Route> { pub fn routes() -> Vec<Route> {
routes![ routes![
index, index,
@ -356,6 +409,7 @@ pub fn routes() -> Vec<Route> {
resetpw, resetpw,
update, update,
create, create,
create_scheckbuch,
delete, delete,
fees, fees,
fees_paid, fees_paid,

View File

@ -4,6 +4,34 @@
{% block content %} {% block content %}
<div class="max-w-screen-lg w-full bg-white dark:bg-primary-900 text-black dark:text-white rounded-md block shadow mt-5"> <div class="max-w-screen-lg w-full bg-white dark:bg-primary-900 text-black dark:text-white rounded-md block shadow mt-5">
<h1 class="h1">Scheckbücher</h1> <h1 class="h1">Scheckbücher</h1>
<form action="/admin/user/new/scheckbuch"
method="post"
class="mt-4 bg-primary-900 rounded-md text-white px-3 pb-3 pt-2 sm:flex items-end justify-between">
<div class="w-full">
<h2 class="text-md font-bold mb-2 uppercase tracking-wide">Neues Scheckbuch hinzufügen</h2>
<div class="grid md:grid-cols-3">
<div>
<label for="name" class="sr-only">Name</label>
<input type="text"
name="name"
class="relative block rounded-md border-0 py-1.5 px-2 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-primary-600 sm:text-sm sm:leading-6 mb-2 md:mb-0"
placeholder="Name" />
</div>
<div>
<label for="name" class="sr-only">Mail</label>
<input type="mail"
name="mail"
class="relative block rounded-md border-0 py-1.5 px-2 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-primary-600 sm:text-sm sm:leading-6 mb-2 md:mb-0"
placeholder="Mail" />
</div>
</div>
</div>
<div class="text-right">
<input value="Hinzufügen"
type="submit"
class="w-28 mt-2 sm:mt-0 rounded-md bg-primary-500 px-3 py-2 text-sm font-semibold text-white hover:bg-primary-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-600 cursor-pointer" />
</div>
</form>
<!-- START filterBar --> <!-- START filterBar -->
<div class="search-wrapper"> <div class="search-wrapper">
<label for="name" class="sr-only">Suche</label> <label for="name" class="sr-only">Suche</label>