datum hinzu fügen

This commit is contained in:
Franz Dietrich 2024-01-31 12:01:04 +01:00
parent 1cb3090f64
commit f79cbc36c4
12 changed files with 1138 additions and 657 deletions

3
.gitignore vendored
View File

@ -1,5 +1,4 @@
/*/target /*/target
/target /target
terminwahl_front/dist terminwahl_front/dist
db.sqlite*
db.sqlite*

1660
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
if [ ! -f terminwahl_front/static/bulma.sass ]; then if [ ! -f terminwahl_front/static/bulma.sass ]; then
pushd terminwahl_front/static/ pushd terminwahl_front/static/ || exit
wget https://github.com/jgthms/bulma/releases/download/0.9.4/bulma-0.9.4.zip wget https://github.com/jgthms/bulma/releases/download/0.9.4/bulma-0.9.4.zip
unzip bulma-0.9.4.zip unzip bulma-0.9.4.zip
ln -s bulma/sass/ sass ln -s bulma/sass/ sass
@ -9,7 +9,7 @@ if [ ! -f terminwahl_front/static/bulma.sass ]; then
unzip fontawesome-free-6.3.0-web.zip unzip fontawesome-free-6.3.0-web.zip
ln -s fontawesome-free-6.3.0-web/scss/ scss ln -s fontawesome-free-6.3.0-web/scss/ scss
ln -s fontawesome-free-6.3.0-web/webfonts webfonts ln -s fontawesome-free-6.3.0-web/webfonts webfonts
popd popd || exit
fi fi
systemctl stop Terminwahl systemctl stop Terminwahl

View File

@ -0,0 +1,49 @@
-- Add migration script here
CREATE TABLE date (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
subtitle TEXT NOT NULL,
start_time DATETIME NOT NULL,
end_time DATETIME NOT NULL
);
INSERT INTO date (id, name, subtitle, start_time, end_time)
VALUES (
1,
'OS 2023',
'2023',
'2023-02-28 12:00:00',
'2023-02-28 18:00:00'
);
-- Create a temporary table
CREATE TEMPORARY TABLE temp_appointment_slots AS
SELECT *
FROM appointment_slots;
DROP TABLE appointment_slots;
-- Recreate the appointments table with the new column and foreign key constraint
CREATE TABLE appointment_slots (
id INTEGER PRIMARY KEY,
start_time DATETIME NOT NULL,
end_time DATETIME NOT NULL,
date_id INTEGER DEFAULT 1 Not NULL,
-- Add the new column
FOREIGN KEY (date_id) REFERENCES date(id) -- Add the foreign key constraint
);
-- Insert data back into the new appointments table from the temporary table
INSERT INTO appointment_slots
SELECT *,
1
FROM temp_appointment_slots;
-- Drop the temporary table
DROP TABLE temp_appointment_slots;
CREATE TABLE teacher_dates (
teacher_id INTEGER NOT NULL,
date_id INTEGER NOT NULL,
PRIMARY KEY (teacher_id, date_id),
FOREIGN KEY (teacher_id) REFERENCES teachers(id),
FOREIGN KEY (date_id) REFERENCES date(id)
);
INSERT INTO teacher_dates (teacher_id, date_id)
SELECT teachers.id AS teacher_id,
date.id AS date_id
FROM teachers,
date;

View File

@ -1,9 +1,14 @@
use actix_web::{error, web, Error, HttpResponse}; use actix_web::{error, web, Error, HttpResponse};
use terminwahl_typen::IdType;
use crate::db::{self, Pool}; use crate::db::{self, Pool};
pub async fn get_teachers_json(pool: web::Data<Pool>) -> Result<HttpResponse, Error> { pub async fn get_teachers_json(
let tasks = db::read::get_teachers(&pool) pool: web::Data<Pool>,
path: web::Path<IdType>,
) -> Result<HttpResponse, Error> {
let date_id = path.into_inner();
let tasks = db::read::get_teachers(&pool, date_id)
.await .await
.map_err(error::ErrorInternalServerError)?; .map_err(error::ErrorInternalServerError)?;
@ -17,8 +22,12 @@ pub async fn get_subjects_json(pool: web::Data<Pool>) -> Result<HttpResponse, Er
Ok(HttpResponse::Ok().json(tasks)) Ok(HttpResponse::Ok().json(tasks))
} }
pub async fn get_slots_json(pool: web::Data<Pool>) -> Result<HttpResponse, Error> { pub async fn get_slots_json(
let tasks = db::read::get_slots(&pool) pool: web::Data<Pool>,
path: web::Path<IdType>,
) -> Result<HttpResponse, Error> {
let date_id = path.into_inner();
let tasks = db::read::get_slots(&pool, date_id)
.await .await
.map_err(error::ErrorInternalServerError)?; .map_err(error::ErrorInternalServerError)?;

View File

@ -10,12 +10,17 @@ use terminwahl_typen::{
use super::Pool; use super::Pool;
pub async fn get_teachers(db: &Pool) -> Result<Teachers, sqlx::Error> { pub async fn get_teachers(db: &Pool, date_id: IdType) -> Result<Teachers, sqlx::Error> {
query_as!( query_as!(
Teacher, Teacher,
r#" r#"
SELECT * SELECT
FROM `teachers`"#, id,
ansprache,
last_name,
subject_id
FROM `teachers` JOIN teacher_dates ON teachers.id = teacher_dates.teacher_id where date_id = ?"#,
date_id
) )
.fetch_all(db) .fetch_all(db)
.await .await
@ -44,12 +49,13 @@ pub async fn get_subjects(db: &Pool) -> Result<Subjects, sqlx::Error> {
.await .await
} }
pub async fn get_slots(db: &Pool) -> Result<AppointmentSlots, sqlx::Error> { pub async fn get_slots(db: &Pool, date_id: IdType) -> Result<AppointmentSlots, sqlx::Error> {
match query_as!( match query_as!(
AppointmentSlot, AppointmentSlot,
r#" r#"
SELECT * SELECT id, start_time, end_time, date_id
FROM `appointment_slots`"#, FROM `appointment_slots` where date_id = ?"#,
date_id
) )
.fetch_all(db) .fetch_all(db)
.await .await
@ -109,8 +115,11 @@ pub struct AssignedAppointment {
nutzer: Nutzer, nutzer: Nutzer,
} }
pub async fn get_all_teachers(db: &Pool) -> Result<Vec<TeacherWithAppointments>, sqlx::Error> { pub async fn get_all_teachers(
let teachers = get_teachers(db).await?; db: &Pool,
date_id: IdType,
) -> Result<Vec<TeacherWithAppointments>, sqlx::Error> {
let teachers = get_teachers(db, date_id).await?;
let mut response = Vec::new(); let mut response = Vec::new();
for teacher in teachers.into_iter() { for teacher in teachers.into_iter() {

View File

@ -70,12 +70,16 @@ async fn main() -> std::io::Result<()> {
.wrap(session_store) .wrap(session_store)
.wrap(error_handlers) .wrap(error_handlers)
.service( .service(
web::resource("/get/teachers").route(web::get().to(api::read::get_teachers_json)), web::resource("/get/teachers/{date_key}")
.route(web::get().to(api::read::get_teachers_json)),
) )
.service( .service(
web::resource("/get/subjects").route(web::get().to(api::read::get_subjects_json)), web::resource("/get/subjects").route(web::get().to(api::read::get_subjects_json)),
) )
.service(web::resource("/get/slots").route(web::get().to(api::read::get_slots_json))) .service(
web::resource("/get/slots/{date_key}")
.route(web::get().to(api::read::get_slots_json)),
)
.service( .service(
web::resource("/get/unavailable") web::resource("/get/unavailable")
.route(web::get().to(api::read::get_unavailable_json)), .route(web::get().to(api::read::get_unavailable_json)),

View File

@ -60,12 +60,12 @@ pub async fn export_appointments(
_mailer: web::Data<AsyncSmtpTransport<Tokio1Executor>>, _mailer: web::Data<AsyncSmtpTransport<Tokio1Executor>>,
handlebars: web::Data<Handlebars<'_>>, handlebars: web::Data<Handlebars<'_>>,
css: web::Data<CssPath>, css: web::Data<CssPath>,
path: web::Path<String>, path: web::Path<(String, IdType)>,
) -> Result<HttpResponse, error::Error> { ) -> Result<HttpResponse, error::Error> {
let password = path.into_inner(); let (password, date_id) = path.into_inner();
dbg!(&password); dbg!(&password);
if password == "AllExport1517" { if password == "AllExport1517" {
match get_all_teachers(&pool).await { match get_all_teachers(&pool, date_id).await {
Ok(teachers) => { Ok(teachers) => {
dbg!(&teachers); dbg!(&teachers);
let data = json!({ let data = json!({

View File

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<title>Yew App</title> <title>Elternsprechtag</title>
<link data-trunk rel="scss" href="static/my_bulma_colors.scss" /> <link data-trunk rel="scss" href="static/my_bulma_colors.scss" />
<link data-trunk rel="copy-file" href="static/logoheader.png" /> <link data-trunk rel="copy-file" href="static/logoheader.png" />
<link data-trunk rel="copy-dir" href="static/webfonts" /> <link data-trunk rel="copy-dir" href="static/webfonts" />

View File

@ -1,11 +1,11 @@
use gloo::net::http::{Method, Request}; use gloo::net::http::Request;
use terminwahl_typen::{Nutzer, PlannedAppointment, RequestState}; use terminwahl_typen::{Nutzer, PlannedAppointment, RequestState};
use crate::Msg; use crate::Msg;
pub async fn fetch_teachers() -> Result<Msg, Msg> { pub async fn fetch_teachers() -> Result<Msg, Msg> {
// Send the request to the specified URL. // Send the request to the specified URL.
let response = Request::new("/get/teachers").send().await; let response = Request::get("/get/teachers/1").send().await;
// Return the ZuordnungMessage with the given network object and the response. // Return the ZuordnungMessage with the given network object and the response.
let response = response let response = response
.map_err(|_| Msg::AppointmentsSent(RequestState::Error))? .map_err(|_| Msg::AppointmentsSent(RequestState::Error))?
@ -17,7 +17,7 @@ pub async fn fetch_teachers() -> Result<Msg, Msg> {
pub async fn fetch_slots() -> Result<Msg, Msg> { pub async fn fetch_slots() -> Result<Msg, Msg> {
// Send the request to the specified URL. // Send the request to the specified URL.
let response = Request::new("/get/slots").send().await; let response = Request::get("/get/slots/1").send().await;
// Return the ZuordnungMessage with the given network object and the response. // Return the ZuordnungMessage with the given network object and the response.
let response = response let response = response
.map_err(|_| Msg::AppointmentsSent(RequestState::Error))? .map_err(|_| Msg::AppointmentsSent(RequestState::Error))?
@ -29,7 +29,7 @@ pub async fn fetch_slots() -> Result<Msg, Msg> {
pub async fn fetch_unavailable() -> Result<Msg, Msg> { pub async fn fetch_unavailable() -> Result<Msg, Msg> {
// Send the request to the specified URL. // Send the request to the specified URL.
let response = Request::new("/get/unavailable").send().await; let response = Request::get("/get/unavailable").send().await;
// Return the ZuordnungMessage with the given network object and the response. // Return the ZuordnungMessage with the given network object and the response.
let response = response let response = response
.map_err(|_| Msg::AppointmentsSent(RequestState::Error))? .map_err(|_| Msg::AppointmentsSent(RequestState::Error))?
@ -43,8 +43,7 @@ pub async fn send_appointments(
appointments: Vec<PlannedAppointment>, appointments: Vec<PlannedAppointment>,
nutzer: Nutzer, nutzer: Nutzer,
) -> Result<Msg, Msg> { ) -> Result<Msg, Msg> {
let response = Request::new("/send/appointments") let response = Request::post("/send/appointments")
.method(Method::POST)
.json(&(&appointments, &nutzer)) .json(&(&appointments, &nutzer))
.map_err(|_| Msg::AppointmentsSent(RequestState::Error))? .map_err(|_| Msg::AppointmentsSent(RequestState::Error))?
.send() .send()

View File

@ -1,4 +1,7 @@
bulma.sass bulma.sass
sass/ sass
webfonts/ webfonts
scss/ scss
*.zip
bulma
fontawesome*

View File

@ -41,6 +41,7 @@ pub struct AppointmentSlot {
pub id: IdType, pub id: IdType,
pub start_time: NaiveDateTime, pub start_time: NaiveDateTime,
pub end_time: NaiveDateTime, pub end_time: NaiveDateTime,
pub date_id: IdType,
} }
#[derive(Debug, Deserialize, Serialize, Clone)] #[derive(Debug, Deserialize, Serialize, Clone)]