Added captcha to booking form. Deleted useless files.
This commit is contained in:
@@ -214,7 +214,7 @@ pub fn is_reserved(reservations: &Vec<Reservation>, time: &NaiveTime, property:
|
||||
}
|
||||
|
||||
#[server]
|
||||
pub async fn create_reservation(reservation: CrReservation) -> Result<ApiResponse<NaiveDate>, ServerFnError> {
|
||||
pub async fn create_reservation(reservation: CrReservation, pow: String) -> Result<ApiResponse<NaiveDate>, ServerFnError> {
|
||||
use crate::backend::get_pool;
|
||||
use crate::backend::customer::find_customer_by_email;
|
||||
use crate::backend::customer::sync_customer_data;
|
||||
@@ -226,6 +226,9 @@ pub async fn create_reservation(reservation: CrReservation) -> Result<ApiRespons
|
||||
use chrono::Local;
|
||||
use sqlx::query;
|
||||
use rust_decimal::Decimal;
|
||||
use leptos_captcha::spow::pow::Pow;
|
||||
|
||||
Pow::validate(&pow)?;
|
||||
|
||||
let slots = reservation.slots().iter().fold(HashMap::new(), |mut map, s| {
|
||||
let slot_str = s.split("|").collect::<Vec<_>>();
|
||||
|
||||
@@ -306,4 +306,11 @@ pub async fn delete_user(id: i32) -> Result<ApiResponse<()>, ServerFnError> {
|
||||
info!("User deleted");
|
||||
|
||||
Ok(ApiResponse::Data(()))
|
||||
}
|
||||
|
||||
#[server]
|
||||
pub async fn get_pow() -> Result<String, ServerFnError> {
|
||||
use leptos_captcha::spow::pow::Pow;
|
||||
|
||||
Ok(Pow::new(10)?.to_string())
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
use leptos_captcha::spow::pow::Pow;
|
||||
use log::error;
|
||||
use rezervator::backend::company::check_company;
|
||||
use rezervator::backend::mail::check_messages;
|
||||
@@ -37,6 +38,8 @@ async fn main() -> std::io::Result<()> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
Pow::init_random().expect("Cannot init captcha");
|
||||
|
||||
let cfg_path = matches.opt_str("c").unwrap_or("config.toml".to_string());
|
||||
|
||||
env_logger::Builder::from_env(Env::default().default_filter_or("debug")).init();
|
||||
|
||||
+24
-9
@@ -1,9 +1,11 @@
|
||||
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::data::{ApiResponse, 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;
|
||||
@@ -97,6 +99,7 @@ pub fn Public() -> impl IntoView {
|
||||
let invalid_dlg = DialogOpener::new();
|
||||
let result_dlg = DialogOpener::new();
|
||||
let result = cr_reservation.value();
|
||||
let is_pending = create_rw_signal(None);
|
||||
|
||||
create_effect(move |_| {
|
||||
day.set(Local::now().date_naive());
|
||||
@@ -104,18 +107,29 @@ pub fn Public() -> impl IntoView {
|
||||
|
||||
view! {
|
||||
<ResError opener=invalid_dlg validator=validator/>
|
||||
<ResSaved opener=result_dlg save_result=result day=day price=price.write_only() slots=slots.write_only()/>
|
||||
<ResSaved opener=result_dlg
|
||||
save_result=result
|
||||
day=day
|
||||
price=price.write_only()
|
||||
slots=slots.write_only()
|
||||
captcha_state=is_pending.read_only()/>
|
||||
<div class="card-body">
|
||||
<ActionForm
|
||||
on:submit=move |ev| {
|
||||
let act = CreateReservation::from_event(&ev);
|
||||
if !act.is_err() {
|
||||
validator.check(act.unwrap().entity(), &ev);
|
||||
}
|
||||
if !validator.is_valid() {
|
||||
invalid_dlg.show();
|
||||
} else {
|
||||
result_dlg.show();
|
||||
cr_reservation.set_pending(true);
|
||||
if let Ok(mut act) = CreateReservation::from_event(&ev) {
|
||||
validator.check(act.entity(), &ev);
|
||||
|
||||
if !validator.is_valid() {
|
||||
invalid_dlg.show();
|
||||
} else {
|
||||
ev.prevent_default();
|
||||
pow_dispatch(get_pow, is_pending, move |pow| {
|
||||
act.pow = pow.unwrap();
|
||||
cr_reservation.dispatch(act);
|
||||
});
|
||||
result_dlg.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
action=cr_reservation>
|
||||
@@ -246,6 +260,7 @@ pub fn Public() -> impl IntoView {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<Captcha is_pending />
|
||||
<div class="modal-footer">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{trl("Book")}
|
||||
|
||||
@@ -32,7 +32,8 @@ pub fn res_saved(
|
||||
save_result: RwSignal<Option<Result<ApiResponse<NaiveDate>, ServerFnError>>>,
|
||||
day: RwSignal<NaiveDate>,
|
||||
price: WriteSignal<Decimal>,
|
||||
slots: WriteSignal<Vec<String>>) -> impl IntoView {
|
||||
slots: WriteSignal<Vec<String>>,
|
||||
captcha_state: ReadSignal<Option<bool>>) -> impl IntoView {
|
||||
view! {{move ||{
|
||||
if let Some(r) = save_result.get() {
|
||||
match r {
|
||||
@@ -40,7 +41,9 @@ pub fn res_saved(
|
||||
match ar {
|
||||
ApiResponse::Data(d) => {
|
||||
view! {
|
||||
<div>
|
||||
<div style={ move || if let Some(c) = captcha_state.get() {
|
||||
if c {"display: none;"} else {"display: block;"}
|
||||
} else {"display: block;"}}>
|
||||
<ModalDialog opener=opener title="Reservation saved">
|
||||
<ModalBody>
|
||||
<p>
|
||||
|
||||
Reference in New Issue
Block a user