Datum auswählbar machen
This commit is contained in:
parent
6ea404845a
commit
165d68ca50
@ -40,3 +40,11 @@ pub async fn get_unavailable_json(pool: web::Data<Pool>) -> Result<HttpResponse,
|
|||||||
|
|
||||||
Ok(HttpResponse::Ok().json(tasks))
|
Ok(HttpResponse::Ok().json(tasks))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_dates_json(pool: web::Data<Pool>) -> Result<HttpResponse, Error> {
|
||||||
|
let dates = db::read::get_dates(&pool)
|
||||||
|
.await
|
||||||
|
.map_err(error::ErrorInternalServerError)?;
|
||||||
|
|
||||||
|
Ok(HttpResponse::Ok().json(dates))
|
||||||
|
}
|
||||||
|
@ -5,7 +5,8 @@ use serde::{Deserialize, Serialize};
|
|||||||
use sqlx::query_as;
|
use sqlx::query_as;
|
||||||
|
|
||||||
use terminwahl_typen::{
|
use terminwahl_typen::{
|
||||||
AppointmentSlot, AppointmentSlots, IdType, Nutzer, SlotId, Subject, Subjects, Teacher, Teachers,
|
AppointmentSlot, AppointmentSlots, Date, Dates, IdType, Nutzer, SlotId, Subject, Subjects,
|
||||||
|
Teacher, Teachers,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::Pool;
|
use super::Pool;
|
||||||
@ -93,7 +94,20 @@ pub async fn get_unavailable(db: &Pool) -> Result<HashSet<SlotId>, sqlx::Error>
|
|||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub async fn get_dates(db: &Pool) -> Result<Dates, sqlx::Error> {
|
||||||
|
match query_as!(
|
||||||
|
Date,
|
||||||
|
r#"
|
||||||
|
SELECT *
|
||||||
|
FROM `date`;"#,
|
||||||
|
)
|
||||||
|
.fetch_all(db)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(elems) => Ok(elems.into_iter().collect()),
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
pub struct TeacherWithAppointments {
|
pub struct TeacherWithAppointments {
|
||||||
teacher: Teacher,
|
teacher: Teacher,
|
||||||
|
@ -69,6 +69,7 @@ async fn main() -> std::io::Result<()> {
|
|||||||
.wrap(Logger::default())
|
.wrap(Logger::default())
|
||||||
.wrap(session_store)
|
.wrap(session_store)
|
||||||
.wrap(error_handlers)
|
.wrap(error_handlers)
|
||||||
|
.service(web::resource("/get/dates").route(web::get().to(api::read::get_dates_json)))
|
||||||
.service(
|
.service(
|
||||||
web::resource("/get/teachers/{date_key}")
|
web::resource("/get/teachers/{date_key}")
|
||||||
.route(web::get().to(api::read::get_teachers_json)),
|
.route(web::get().to(api::read::get_teachers_json)),
|
||||||
|
@ -4,8 +4,8 @@ use std::collections::{HashMap, HashSet};
|
|||||||
use gloo::console::log;
|
use gloo::console::log;
|
||||||
use requests::{fetch_dates, fetch_slots, fetch_teachers, fetch_unavailable, send_appointments};
|
use requests::{fetch_dates, fetch_slots, fetch_teachers, fetch_unavailable, send_appointments};
|
||||||
use terminwahl_typen::{
|
use terminwahl_typen::{
|
||||||
AppointmentSlot, AppointmentSlots, Dates, IdType, Nutzer, PlannedAppointment, RequestState,
|
AppointmentSlot, AppointmentSlots, Date, Dates, IdType, Nutzer, PlannedAppointment,
|
||||||
SlotId, Teacher, Teachers,
|
RequestState, SlotId, Teacher, Teachers,
|
||||||
};
|
};
|
||||||
use web_sys::HtmlInputElement;
|
use web_sys::HtmlInputElement;
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
@ -16,11 +16,12 @@ pub enum Msg {
|
|||||||
UpdateSchüler(String),
|
UpdateSchüler(String),
|
||||||
UpdateEmail(String),
|
UpdateEmail(String),
|
||||||
DataEntered(Nutzer),
|
DataEntered(Nutzer),
|
||||||
GetTeachers,
|
GetTeachers(IdType),
|
||||||
ReceivedTeachers(Teachers),
|
ReceivedTeachers(Teachers),
|
||||||
GetDates,
|
GetDates,
|
||||||
ReceivedDates(Dates),
|
ReceivedDates(Dates),
|
||||||
GetSlots,
|
SelectDate(IdType),
|
||||||
|
GetSlots(IdType),
|
||||||
ReceivedSlots(AppointmentSlots),
|
ReceivedSlots(AppointmentSlots),
|
||||||
Selected(PlannedAppointment),
|
Selected(PlannedAppointment),
|
||||||
TooMany,
|
TooMany,
|
||||||
@ -33,6 +34,7 @@ pub struct App {
|
|||||||
nutzer: Option<Nutzer>,
|
nutzer: Option<Nutzer>,
|
||||||
tmp_nutzer: Nutzer,
|
tmp_nutzer: Nutzer,
|
||||||
dates: Option<Dates>,
|
dates: Option<Dates>,
|
||||||
|
selected_date: Option<Date>,
|
||||||
teachers: Option<Teachers>,
|
teachers: Option<Teachers>,
|
||||||
slots: Option<AppointmentSlots>,
|
slots: Option<AppointmentSlots>,
|
||||||
appointments: HashMap<SlotId, PlannedAppointment>,
|
appointments: HashMap<SlotId, PlannedAppointment>,
|
||||||
@ -58,6 +60,7 @@ impl Component for App {
|
|||||||
appointments: HashMap::new(),
|
appointments: HashMap::new(),
|
||||||
slots: None,
|
slots: None,
|
||||||
dates: None,
|
dates: None,
|
||||||
|
selected_date: None,
|
||||||
unavailable: None,
|
unavailable: None,
|
||||||
teachers: None,
|
teachers: None,
|
||||||
nutzer: None,
|
nutzer: None,
|
||||||
@ -89,8 +92,8 @@ impl Component for App {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
Msg::TooMany => todo!(),
|
Msg::TooMany => todo!(),
|
||||||
Msg::GetTeachers => {
|
Msg::GetTeachers(id) => {
|
||||||
ctx.link().send_future(fetch_teachers());
|
ctx.link().send_future(fetch_teachers(id));
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
Msg::ReceivedTeachers(teachers) => {
|
Msg::ReceivedTeachers(teachers) => {
|
||||||
@ -102,13 +105,25 @@ impl Component for App {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
Msg::ReceivedDates(dates) => {
|
Msg::ReceivedDates(dates) => {
|
||||||
|
if dates.len() == 1 {
|
||||||
|
ctx.link()
|
||||||
|
.send_message(Msg::SelectDate(dates.first().unwrap().id))
|
||||||
|
}
|
||||||
self.dates = Some(dates);
|
self.dates = Some(dates);
|
||||||
ctx.link().send_message(Msg::GetTeachers);
|
|
||||||
ctx.link().send_message(Msg::GetSlots);
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
Msg::GetSlots => {
|
Msg::SelectDate(date_id) => {
|
||||||
ctx.link().send_future(fetch_slots());
|
ctx.link().send_message(Msg::GetTeachers(date_id));
|
||||||
|
ctx.link().send_message(Msg::GetSlots(date_id));
|
||||||
|
let date = self
|
||||||
|
.dates
|
||||||
|
.as_ref()
|
||||||
|
.map(|dts| dts.iter().find(|d| d.id == date_id).unwrap());
|
||||||
|
self.selected_date = Some(date.expect("A date should be found").clone());
|
||||||
|
true
|
||||||
|
}
|
||||||
|
Msg::GetSlots(id) => {
|
||||||
|
ctx.link().send_future(fetch_slots(id));
|
||||||
ctx.link().send_future(fetch_unavailable());
|
ctx.link().send_future(fetch_unavailable());
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
@ -164,24 +179,35 @@ impl Component for App {
|
|||||||
html! {<>
|
html! {<>
|
||||||
<section class="hero is-warning">
|
<section class="hero is-warning">
|
||||||
<div class="hero-body">
|
<div class="hero-body">
|
||||||
<p class="title has-text-link">
|
|
||||||
{"Elternsprechtag"}
|
{if let Some(d) = self.selected_date.as_ref(){ html!{
|
||||||
</p>
|
<><p class="title has-text-link">
|
||||||
<p class="subtitle">
|
{&d.name}
|
||||||
{"Am 28.02.23"}
|
</p><p class="subtitle">
|
||||||
</p>
|
{&d.subtitle}
|
||||||
|
</p><p class="subtitle">
|
||||||
|
{"Am "}{d.start_time.format("%d.%m.%Y")}
|
||||||
|
</p></>}}else{html!(<p class="title has-text-link">{"Elternsprechtag"}</p>)}}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="section">
|
<div class="section">
|
||||||
{
|
{
|
||||||
if let Some(_saved) = self.successfully_saved.as_ref(){self.view_dank_dialog(ctx)} else if self.nutzer.is_none(){
|
if let Some(dates) = self.dates.as_ref(){
|
||||||
self.view_eingabe_daten(ctx)
|
if let Some(date) = self.selected_date.as_ref(){
|
||||||
}
|
if let Some(_saved) = self.successfully_saved.as_ref(){
|
||||||
else
|
self.view_dank_dialog(ctx)
|
||||||
{
|
} else if self.nutzer.is_none(){
|
||||||
self.view_auswahl_termine(ctx)
|
self.view_eingabe_daten(ctx)
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self.view_auswahl_termine(ctx)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.view_auswahl_date(dates, ctx)
|
||||||
|
}
|
||||||
|
}else{html!(<h1>{"Loading"}</h1>)}
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -192,6 +218,35 @@ impl Component for App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
|
fn view_auswahl_date(&self, dates: &Dates, ctx: &Context<Self>) -> Html {
|
||||||
|
let onchange = ctx.link().callback(|e: Event| {
|
||||||
|
let input: HtmlInputElement = e.target_unchecked_into();
|
||||||
|
Msg::SelectDate(input.value().parse().unwrap())
|
||||||
|
});
|
||||||
|
html! {
|
||||||
|
<div class="columns is-centered">
|
||||||
|
<div class="column is-half">
|
||||||
|
<div class="notification is-light">
|
||||||
|
<figure class="image container is-128x128" id="headerlogo">
|
||||||
|
<img src="/logoheader.png" />
|
||||||
|
</figure>
|
||||||
|
<div class="box mt-3 is-light">
|
||||||
|
<p>{"Anmeldung zum Elternsprechtag!"}</p><p>{"Bitte wählen Sie den Sprechtag zu welchem Sie sich anmelden möchten:"}</p>
|
||||||
|
</div>
|
||||||
|
<div class="select is-rounded is-fullwidth">
|
||||||
|
<select onchange={onchange}>
|
||||||
|
<option selected=true value="--">{"Bitte wählen Sie einen Termin"}</option>
|
||||||
|
{dates.iter().map(|dt|html!{
|
||||||
|
<option value={dt.id.to_string()}>{&dt.name}{" – "}{&dt.start_time.format("%d.%m.%Y")}</option>
|
||||||
|
}).collect::<Html>()}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn view_eingabe_daten(&self, ctx: &Context<Self>) -> Html {
|
fn view_eingabe_daten(&self, ctx: &Context<Self>) -> Html {
|
||||||
html! { <div class="columns is-centered">
|
html! { <div class="columns is-centered">
|
||||||
<div class="column is-half">
|
<div class="column is-half">
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use gloo::net::http::Request;
|
use gloo::net::http::Request;
|
||||||
use terminwahl_typen::{Nutzer, PlannedAppointment, RequestState};
|
use terminwahl_typen::{IdType, Nutzer, PlannedAppointment, RequestState};
|
||||||
|
|
||||||
use crate::Msg;
|
use crate::Msg;
|
||||||
|
|
||||||
@ -15,9 +15,9 @@ pub async fn fetch_dates() -> Result<Msg, Msg> {
|
|||||||
Ok(Msg::ReceivedDates(response))
|
Ok(Msg::ReceivedDates(response))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn fetch_teachers() -> Result<Msg, Msg> {
|
pub async fn fetch_teachers(id: IdType) -> Result<Msg, Msg> {
|
||||||
// Send the request to the specified URL.
|
// Send the request to the specified URL.
|
||||||
let response = Request::get("/get/teachers/1").send().await;
|
let response = Request::get(&format!("/get/teachers/{}", id)).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))?
|
||||||
@ -27,9 +27,9 @@ pub async fn fetch_teachers() -> Result<Msg, Msg> {
|
|||||||
Ok(Msg::ReceivedTeachers(response))
|
Ok(Msg::ReceivedTeachers(response))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn fetch_slots() -> Result<Msg, Msg> {
|
pub async fn fetch_slots(id: IdType) -> Result<Msg, Msg> {
|
||||||
// Send the request to the specified URL.
|
// Send the request to the specified URL.
|
||||||
let response = Request::get("/get/slots/1").send().await;
|
let response = Request::get(&format!("/get/slots/{}", id)).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))?
|
||||||
|
@ -88,11 +88,11 @@ impl Nutzer {
|
|||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
pub struct Date {
|
pub struct Date {
|
||||||
id: IdType,
|
pub id: IdType,
|
||||||
name: String,
|
pub name: String,
|
||||||
subtitle: String,
|
pub subtitle: String,
|
||||||
start_time: NaiveDateTime,
|
pub start_time: NaiveDateTime,
|
||||||
end_time: NaiveDateTime,
|
pub end_time: NaiveDateTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Dates = Vec<Date>;
|
pub type Dates = Vec<Date>;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user