use chrono::{Duration, Local, NaiveDate, NaiveTime, Timelike}; use leptos::*; use leptos_captcha::{Captcha, pow_dispatch}; use leptos_router::*; use rust_decimal::Decimal; use crate::backend::appearance::get_appearance; use crate::backend::customer::get_remembered; use crate::backend::data::{ApiResponse, ClosingTime, Customer, DayHour, Reservation, ResProperty, SlotType, TmCheck}; use crate::backend::reservation::{CreateReservation, get_public_form_data, is_reserved}; use crate::backend::user::get_pow; use crate::components::data_form::ForValidation; use crate::components::modal_box::DialogOpener; use crate::locales::trl; use crate::pages::res_dialogs::{ResError, ResSaved}; use crate::validator::Validator; #[component] fn time_selector( hours: Vec, reservations: Vec, property: ResProperty, slots: RwSignal>, price: RwSignal, day: ReadSignal, closing_days: Option) -> impl IntoView { let closed = if let Some(c) = closing_days { day.get() >= c.from_date && day.get() <= c.to_date } else { false }; let checks = if !closed { hours.into_iter().map(|h| { match property.slot { SlotType::Quarter => { let mut ret: Vec = vec![]; logging::log!("quarter"); for n in 0..(h.to() - h.from()).num_minutes() * 4 / 60 { ret.push(TmCheck { from: h.from() + Duration::minutes(n * 15), to: h.from() + Duration::minutes((n + 1) * 15) }); } ret } SlotType::Half => { let mut ret: Vec = vec![]; logging::log!("half"); for n in 0..(h.to() - h.from()).num_minutes() * 2 / 60 { ret.push(TmCheck { from: h.from() + Duration::minutes(n * 30), to: h.from() + Duration::minutes((n + 1) * 30) }); } ret } SlotType::Hour => { let mut ret: Vec = vec![]; for n in 0..(h.to() - h.from()).num_minutes() / 60 { ret.push(TmCheck { from: h.from() + Duration::minutes(n * 60), to: h.from() + Duration::minutes((n + 1) * 60) }); } ret } SlotType::Day => { let mut ret: Vec = vec![]; ret.push(TmCheck { from: NaiveTime::from_hms_opt(0, 0, 0).unwrap(), to: NaiveTime::from_hms_opt(23, 59, 59).unwrap() }); ret } } }).collect::>().into_iter().flatten().collect::>() } else { vec![] }; let prop_id = property.id(); let closed = checks.is_empty(); view! {
{trl("Closed")}
} } #[component] pub fn Public() -> impl IntoView { let day = create_rw_signal(NaiveDate::default()); let form_data = create_blocking_resource(move || day.get(), move |d| get_public_form_data(d)); let slots = create_rw_signal::>(vec![]); let price = create_rw_signal(Decimal::from(0)); let cr_reservation = create_server_action::(); let validator = Validator::new(); let invalid_dlg = DialogOpener::new(); let result_dlg = DialogOpener::new(); let result = cr_reservation.value(); let is_pending = create_rw_signal(None); let active_str = create_rw_signal("true".to_string()); let get_customer = create_blocking_resource(||(), move |_| get_remembered()); let appearance = create_blocking_resource(||(), move |_| get_appearance()); let customer = create_rw_signal(Customer::default()); create_effect(move |_| { day.set(Local::now().date_naive()); }); view! { {trl("Loading...")}

}> { appearance.get().map(|a| match a { Ok(a) => { let app = a.clone(); view! {

{app.title.clone().unwrap_or_default()}

} }, Err(e) => {view! {

{trl("Error loading data")}

{e.to_string()}

}} }) }
" "{trl("Booking")}
{trl("Loading...")}

}> {move || { get_customer.get().map(|c| match c { Err(_) => {}, Ok(c) => { if let Some(c) = c { customer.set(c); } } }); form_data.get().map(|u| match u { Err(e) => { view! {
{e.to_string()}
}} Ok(u) => { match u { ApiResponse::Data(p) => { view! {
{data.property.name.clone()}
} }, ApiResponse::Error(s) => { view! {
{trl(&s)}
} } }} }) }}
{trl("Total price of booking")}
{move || format!("{} Kč", price.get())}
" "{trl("Who is booking")}
} }