feat: add and display events

This commit is contained in:
Max Hohlfeld 2024-04-01 19:24:20 +02:00
parent fedfc87259
commit 3216a091f8
6 changed files with 128 additions and 16 deletions

View File

@ -54,7 +54,7 @@ async fn get_index(
let area = Area::read_by_id(pool.get_ref(), current_user.area_id)
.await
.unwrap();
let events = Event::read_by_date(pool.get_ref(), date).await.unwrap();
let events = Event::read_by_date_including_location(pool.get_ref(), date).await.unwrap();
let availabillities = Availabillity::read_by_date_including_user(pool.get_ref(), date)
.await
.unwrap();

View File

@ -1,11 +1,52 @@
use actix_identity::Identity;
use actix_web::{web, HttpResponse, Responder};
use actix_web::{http::header::LOCATION, web, HttpResponse, Responder};
use chrono::{NaiveDate, NaiveTime};
use serde::Deserialize;
use sqlx::PgPool;
use crate::models::{Event, Role, User};
#[derive(Deserialize)]
pub struct NewEventForm {
name: String,
date: NaiveDate,
from: NaiveTime,
till: NaiveTime,
location: i32,
voluntarywachhabender: Option<bool>,
amount: i16,
clothing: String,
}
#[actix_web::post("/events/new")]
pub async fn post(user: Identity, pool: web::Data<PgPool>) -> impl Responder {
pub async fn post(
user: Identity,
pool: web::Data<PgPool>,
form: web::Form<NewEventForm>,
) -> impl Responder {
let current_user = User::read_by_id(pool.get_ref(), user.id().unwrap().parse().unwrap())
.await
.unwrap();
return HttpResponse::BadRequest().finish();
if current_user.role != Role::Admin && current_user.role != Role::AreaManager {
return HttpResponse::Unauthorized().finish();
}
let return_location = format!("/?data={}", form.date);
match Event::create(
pool.get_ref(),
&form.date,
&form.from,
&form.till,
&form.name,
form.location,
form.voluntarywachhabender.is_some() && form.voluntarywachhabender.unwrap(),
form.amount,
&form.clothing,
)
.await {
Ok(_) => HttpResponse::Found().insert_header((LOCATION, return_location)).finish(),
Err(_) => HttpResponse::BadRequest().body("Fehler beim Erstellen")
}
}

View File

@ -2,18 +2,18 @@ use actix_web::web::ServiceConfig;
use chrono::NaiveDate;
use serde::Deserialize;
mod events;
mod location;
mod user;
mod events;
#[derive(Deserialize)]
pub struct IdPath {
pub id: i32
pub id: i32,
}
#[derive(Deserialize)]
pub struct NaiveDateQuery {
pub date: NaiveDate
pub date: NaiveDate,
}
pub fn init(cfg: &mut ServiceConfig) {
@ -30,5 +30,5 @@ pub fn init(cfg: &mut ServiceConfig) {
cfg.service(user::delete::delete);
cfg.service(events::get_new::get);
// cfg.service(events::post_new::);
cfg.service(events::post_new::post);
}

View File

@ -1,6 +1,8 @@
use chrono::{NaiveDate, NaiveTime};
use sqlx::{query, PgPool};
use super::Location;
pub struct Event {
pub id: i32,
pub date: NaiveDate,
@ -8,6 +10,7 @@ pub struct Event {
pub end_time: NaiveTime,
pub name: String,
pub location_id: i32,
pub location: Option<Location>,
pub voluntary_wachhabender: bool,
pub amount_of_posten: i16,
pub clothing: String,
@ -17,14 +20,14 @@ pub struct Event {
impl Event {
pub async fn create(
pool: &PgPool,
date: NaiveDate,
start_time: NaiveTime,
end_time: NaiveTime,
name: String,
date: &NaiveDate,
start_time: &NaiveTime,
end_time: &NaiveTime,
name: &String,
location_id: i32,
voluntary_wachhabender: bool,
amount_of_posten: i16,
clothing: String,
clothing: &String,
) -> anyhow::Result<i32> {
let result = query!("INSERT INTO event (date, startTime, endTime, name, locationId, voluntaryWachhabender, amountOfPosten, clothing) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING id;", date, start_time, end_time, name, location_id, voluntary_wachhabender, amount_of_posten, clothing).fetch_one(pool).await?;
@ -45,6 +48,61 @@ impl Event {
end_time: record.endtime,
name: record.name.to_string(),
location_id: record.locationid,
location: None,
voluntary_wachhabender: record.voluntarywachhabender,
amount_of_posten: record.amountofposten,
clothing: record.clothing.to_string(),
canceled: record.canceled,
})
.collect();
Ok(events)
}
pub async fn read_by_date_including_location(
pool: &PgPool,
date: NaiveDate,
) -> anyhow::Result<Vec<Event>> {
let records = query!(
r#"
SELECT
event.id AS eventId,
event.date,
event.startTime,
event.endTime,
event.name,
event.locationId,
event.voluntaryWachhabender,
event.amountOfPosten,
event.clothing,
event.canceled,
location.id,
location.name AS locationName,
location.areaId AS locationAreaId
FROM event
JOIN location ON event.locationId = location.id
WHERE date = $1;
"#,
date
)
.fetch_all(pool)
.await?;
let events = records
.iter()
.map(|record| Event {
id: record.eventid,
date: record.date,
start_time: record.starttime,
end_time: record.endtime,
name: record.name.to_string(),
location_id: record.locationid,
location: Some(Location {
id: record.locationid,
name: record.locationname.to_string(),
area_id: record.locationareaid,
area: None
}),
voluntary_wachhabender: record.voluntarywachhabender,
amount_of_posten: record.amountofposten,
clothing: record.clothing.to_string(),

View File

@ -62,7 +62,7 @@
<div class="field is-narrow">
<div class="control">
<label class="checkbox">
<input class="checkbox" type="checkbox" name="voluntaryWachhabender">
<input class="checkbox" type="checkbox" name="voluntarywachhabender" value="true">
</label>
</div>
</div>
@ -76,7 +76,7 @@
<div class="field-body">
<div class="field">
<div class="control">
<input class="input" type="number" name="name" min="1" max="100"/>
<input class="input" type="number" name="amount" min="1" max="100"/>
</div>
</div>
</div>

View File

@ -37,7 +37,20 @@
{% else %}
{% for event in events %}
<div class="box">
<h5 class="title is-5">{{ event.name }}</h5>
{% if event.canceled %}<b>Veranstaltung abgesagt!</b>{% endif %}
<div class="level">
<h5 class="title is-5 level-left">{{ event.name }}</h5>
<span class ="level-right">
<a href="" class="button is-primary level-item">planen</a>
<a href="" class="button is-primary-light level-item">bearbeiten</a>
<a href="" class="button is-warning level-item">als abgesagt markieren</a>
</span>
</div>
<p>Ort: {{ event.location.as_ref().unwrap().name }}</p>
<p>Zeitraum: {{ event.start_time }} bis {{ event.end_time }}</p>
<p>Anzahl der Posten: {{ event.amount_of_posten }}</p>
<p>Wachhabender durch FF gestellt: {{ event.voluntary_wachhabender }}</p>
<p>Kleidungsordnung: {{ event.clothing }}</p>
</div>
{% endfor %}
{% endif %}