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))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 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;
 | 
			
		||||
@ -93,7 +94,20 @@ pub async fn get_unavailable(db: &Pool) -> Result<HashSet<SlotId>, sqlx::Error>
 | 
			
		||||
        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)]
 | 
			
		||||
pub struct TeacherWithAppointments {
 | 
			
		||||
    teacher: Teacher,
 | 
			
		||||
 | 
			
		||||
@ -69,6 +69,7 @@ async fn main() -> std::io::Result<()> {
 | 
			
		||||
            .wrap(Logger::default())
 | 
			
		||||
            .wrap(session_store)
 | 
			
		||||
            .wrap(error_handlers)
 | 
			
		||||
            .service(web::resource("/get/dates").route(web::get().to(api::read::get_dates_json)))
 | 
			
		||||
            .service(
 | 
			
		||||
                web::resource("/get/teachers/{date_key}")
 | 
			
		||||
                    .route(web::get().to(api::read::get_teachers_json)),
 | 
			
		||||
 | 
			
		||||
@ -4,8 +4,8 @@ use std::collections::{HashMap, HashSet};
 | 
			
		||||
use gloo::console::log;
 | 
			
		||||
use requests::{fetch_dates, fetch_slots, fetch_teachers, fetch_unavailable, send_appointments};
 | 
			
		||||
use terminwahl_typen::{
 | 
			
		||||
    AppointmentSlot, AppointmentSlots, Dates, IdType, Nutzer, PlannedAppointment, RequestState,
 | 
			
		||||
    SlotId, Teacher, Teachers,
 | 
			
		||||
    AppointmentSlot, AppointmentSlots, Date, Dates, IdType, Nutzer, PlannedAppointment,
 | 
			
		||||
    RequestState, SlotId, Teacher, Teachers,
 | 
			
		||||
};
 | 
			
		||||
use web_sys::HtmlInputElement;
 | 
			
		||||
use yew::prelude::*;
 | 
			
		||||
@ -16,11 +16,12 @@ pub enum Msg {
 | 
			
		||||
    UpdateSchüler(String),
 | 
			
		||||
    UpdateEmail(String),
 | 
			
		||||
    DataEntered(Nutzer),
 | 
			
		||||
    GetTeachers,
 | 
			
		||||
    GetTeachers(IdType),
 | 
			
		||||
    ReceivedTeachers(Teachers),
 | 
			
		||||
    GetDates,
 | 
			
		||||
    ReceivedDates(Dates),
 | 
			
		||||
    GetSlots,
 | 
			
		||||
    SelectDate(IdType),
 | 
			
		||||
    GetSlots(IdType),
 | 
			
		||||
    ReceivedSlots(AppointmentSlots),
 | 
			
		||||
    Selected(PlannedAppointment),
 | 
			
		||||
    TooMany,
 | 
			
		||||
@ -33,6 +34,7 @@ pub struct App {
 | 
			
		||||
    nutzer: Option<Nutzer>,
 | 
			
		||||
    tmp_nutzer: Nutzer,
 | 
			
		||||
    dates: Option<Dates>,
 | 
			
		||||
    selected_date: Option<Date>,
 | 
			
		||||
    teachers: Option<Teachers>,
 | 
			
		||||
    slots: Option<AppointmentSlots>,
 | 
			
		||||
    appointments: HashMap<SlotId, PlannedAppointment>,
 | 
			
		||||
@ -58,6 +60,7 @@ impl Component for App {
 | 
			
		||||
            appointments: HashMap::new(),
 | 
			
		||||
            slots: None,
 | 
			
		||||
            dates: None,
 | 
			
		||||
            selected_date: None,
 | 
			
		||||
            unavailable: None,
 | 
			
		||||
            teachers: None,
 | 
			
		||||
            nutzer: None,
 | 
			
		||||
@ -89,8 +92,8 @@ impl Component for App {
 | 
			
		||||
                true
 | 
			
		||||
            }
 | 
			
		||||
            Msg::TooMany => todo!(),
 | 
			
		||||
            Msg::GetTeachers => {
 | 
			
		||||
                ctx.link().send_future(fetch_teachers());
 | 
			
		||||
            Msg::GetTeachers(id) => {
 | 
			
		||||
                ctx.link().send_future(fetch_teachers(id));
 | 
			
		||||
                false
 | 
			
		||||
            }
 | 
			
		||||
            Msg::ReceivedTeachers(teachers) => {
 | 
			
		||||
@ -102,13 +105,25 @@ impl Component for App {
 | 
			
		||||
                false
 | 
			
		||||
            }
 | 
			
		||||
            Msg::ReceivedDates(dates) => {
 | 
			
		||||
                if dates.len() == 1 {
 | 
			
		||||
                    ctx.link()
 | 
			
		||||
                        .send_message(Msg::SelectDate(dates.first().unwrap().id))
 | 
			
		||||
                }
 | 
			
		||||
                self.dates = Some(dates);
 | 
			
		||||
                ctx.link().send_message(Msg::GetTeachers);
 | 
			
		||||
                ctx.link().send_message(Msg::GetSlots);
 | 
			
		||||
                true
 | 
			
		||||
            }
 | 
			
		||||
            Msg::GetSlots => {
 | 
			
		||||
                ctx.link().send_future(fetch_slots());
 | 
			
		||||
            Msg::SelectDate(date_id) => {
 | 
			
		||||
                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());
 | 
			
		||||
                false
 | 
			
		||||
            }
 | 
			
		||||
@ -164,24 +179,35 @@ impl Component for App {
 | 
			
		||||
        html! {<>
 | 
			
		||||
            <section class="hero is-warning">
 | 
			
		||||
            <div class="hero-body">
 | 
			
		||||
              <p class="title has-text-link">
 | 
			
		||||
                {"Elternsprechtag"}
 | 
			
		||||
              </p>
 | 
			
		||||
              <p class="subtitle">
 | 
			
		||||
                {"Am 28.02.23"}
 | 
			
		||||
              </p>
 | 
			
		||||
 | 
			
		||||
              {if let Some(d) = self.selected_date.as_ref(){ html!{
 | 
			
		||||
            <><p class="title has-text-link">
 | 
			
		||||
                {&d.name}
 | 
			
		||||
              </p><p class="subtitle">
 | 
			
		||||
                {&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>
 | 
			
		||||
          </section>
 | 
			
		||||
          <div class="container">
 | 
			
		||||
            <div class="section">
 | 
			
		||||
                {
 | 
			
		||||
                    if let Some(_saved) = self.successfully_saved.as_ref(){self.view_dank_dialog(ctx)} else if self.nutzer.is_none(){
 | 
			
		||||
                        self.view_eingabe_daten(ctx)
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        self.view_auswahl_termine(ctx)
 | 
			
		||||
                    }
 | 
			
		||||
                    if let Some(dates) = self.dates.as_ref(){
 | 
			
		||||
                        if let Some(date) = self.selected_date.as_ref(){
 | 
			
		||||
                            if let Some(_saved) = self.successfully_saved.as_ref(){
 | 
			
		||||
                                self.view_dank_dialog(ctx)
 | 
			
		||||
                            } else if self.nutzer.is_none(){
 | 
			
		||||
                                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>
 | 
			
		||||
@ -192,6 +218,35 @@ impl Component for 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 {
 | 
			
		||||
        html! {        <div class="columns is-centered">
 | 
			
		||||
          <div class="column is-half">
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
use gloo::net::http::Request;
 | 
			
		||||
use terminwahl_typen::{Nutzer, PlannedAppointment, RequestState};
 | 
			
		||||
use terminwahl_typen::{IdType, Nutzer, PlannedAppointment, RequestState};
 | 
			
		||||
 | 
			
		||||
use crate::Msg;
 | 
			
		||||
 | 
			
		||||
@ -15,9 +15,9 @@ pub async fn fetch_dates() -> Result<Msg, Msg> {
 | 
			
		||||
    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.
 | 
			
		||||
    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.
 | 
			
		||||
    let response = response
 | 
			
		||||
        .map_err(|_| Msg::AppointmentsSent(RequestState::Error))?
 | 
			
		||||
@ -27,9 +27,9 @@ pub async fn fetch_teachers() -> Result<Msg, Msg> {
 | 
			
		||||
    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.
 | 
			
		||||
    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.
 | 
			
		||||
    let response = response
 | 
			
		||||
        .map_err(|_| Msg::AppointmentsSent(RequestState::Error))?
 | 
			
		||||
 | 
			
		||||
@ -88,11 +88,11 @@ impl Nutzer {
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Deserialize, Serialize, Clone)]
 | 
			
		||||
pub struct Date {
 | 
			
		||||
    id: IdType,
 | 
			
		||||
    name: String,
 | 
			
		||||
    subtitle: String,
 | 
			
		||||
    start_time: NaiveDateTime,
 | 
			
		||||
    end_time: NaiveDateTime,
 | 
			
		||||
    pub id: IdType,
 | 
			
		||||
    pub name: String,
 | 
			
		||||
    pub subtitle: String,
 | 
			
		||||
    pub start_time: NaiveDateTime,
 | 
			
		||||
    pub end_time: NaiveDateTime,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub type Dates = Vec<Date>;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user