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! {