Cancel approved booking is now possible.

main
Josef Rokos 12 months ago
parent cb1071c243
commit 084911c992

@ -1,18 +1,25 @@
use chrono::{Datelike, Local}; use chrono::{Datelike, Local};
use leptos::*; use leptos::*;
use crate::backend::data::{ApiResponse, ResSumWithItems}; use crate::backend::data::{ApiResponse, ReservationState, ResSumWithItems};
use crate::backend::reservation::{month_chart, reservations_in_month, year_chart, years}; use crate::backend::reservation::{month_chart, reservations_in_month, year_chart, years};
use crate::components::modal_box::{DialogOpener, ModalBody, ModalDialog}; use crate::components::modal_box::{DialogOpener, ModalBody, ModalDialog};
use crate::components::user_menu::MenuOpener;
use crate::locales::{loc_date, show_day, trl}; use crate::locales::{loc_date, show_day, trl};
use crate::pages::new_reservations::CancelDialog;
#[component] #[component]
fn booking_detail(reservation: ReadSignal<ResSumWithItems>, opener: DialogOpener) -> impl IntoView { fn booking_detail(reservation: ReadSignal<ResSumWithItems>, opener: DialogOpener) -> impl IntoView {
let menu = MenuOpener::new();
let cancel_opener = DialogOpener::new();
let menu_visible = create_rw_signal(false);
view! { view! {
<CancelDialog opener=cancel_opener reservation=reservation/>
<ModalDialog title="Booking detail" opener=opener> <ModalDialog title="Booking detail" opener=opener>
<ModalBody> <ModalBody>
<p> <p>
{move || { {move || {
let detail = reservation.get(); let detail = reservation.get();
menu_visible.set(detail.summary.state != ReservationState::Canceled);
view! { view! {
<b>{show_day(&detail.summary.date.weekday())}" - "{loc_date(detail.summary.date)}</b><br/> <b>{show_day(&detail.summary.date.weekday())}" - "{loc_date(detail.summary.date)}</b><br/>
<For each=move || detail.reservations.clone() <For each=move || detail.reservations.clone()
@ -30,10 +37,33 @@ fn booking_detail(reservation: ReadSignal<ResSumWithItems>, opener: DialogOpener
</Show> </Show>
} }
} }
{trl("Price: ")}{detail.summary.price.to_string()}<br/> {trl("Price: ")}{detail.summary.price.to_string()}
} }
}} }}
</p> </p>
<Show when=move || menu_visible.get()>
<table width="100%">
<tr>
<td width="100%"></td>
<td>
<div class="dropdown">
<button type="button" class="btn p-0 dropdown-toggle hide-arrow"
on:click=move |_| menu.toggle()>
<i class="bx bx-dots-vertical-rounded"></i>
</button>
<div class={move || if menu.visible() {"dropdown-menu show"} else {"dropdown-menu"} }
style="position: absolute; insert: 0px 0px auto; margin: 0px; transform: translate3d(-160px, 0px, 0px);"
on:mouseleave=move |_| menu.toggle()>
<a class="dropdown-item text-danger" href="javascript:void(0);" on:click=move |_| {
cancel_opener.show();
}>
<i class="bx bx-trash me-1"></i> {trl("Cancel")}</a>
</div>
</div>
</td>
</tr>
</table>
</Show>
</ModalBody> </ModalBody>
</ModalDialog> </ModalDialog>
} }
@ -46,10 +76,10 @@ pub fn bookings() -> impl IntoView {
let year = create_rw_signal(Local::now().year()); let year = create_rw_signal(Local::now().year());
let month = create_rw_signal(Local::now().month()); let month = create_rw_signal(Local::now().month());
let chart = create_blocking_resource(move || year.get(),move |y| month_chart(y)); let chart = create_blocking_resource(move || year.get(),move |y| month_chart(y));
let reservations = create_blocking_resource(move || (year.get(), month.get()), move |p| reservations_in_month(p.0, p.1)); let detail_dlg = DialogOpener::new();
let reservations = create_blocking_resource(move || (year.get(), month.get(), detail_dlg.visible()), move |p| reservations_in_month(p.0, p.1));
let all_months: Vec<u32> = vec![1,2,3,4,5,6,7,8,9,10,11,12]; let all_months: Vec<u32> = vec![1,2,3,4,5,6,7,8,9,10,11,12];
let res_detail = create_rw_signal(ResSumWithItems::default()); let res_detail = create_rw_signal(ResSumWithItems::default());
let detail_dlg = DialogOpener::new();
view! { view! {
<h1>{trl("Booking overview")}</h1> <h1>{trl("Booking overview")}</h1>

@ -26,7 +26,7 @@ fn approve_dialog(reservation: ReadSignal<ResSumWithItems>, opener: DialogOpener
} }
#[component] #[component]
fn cancel_dialog(reservation: ReadSignal<ResSumWithItems>, opener: DialogOpener) -> impl IntoView { pub fn cancel_dialog(reservation: ReadSignal<ResSumWithItems>, opener: DialogOpener) -> impl IntoView {
let cancel = create_server_action::<Cancel>(); let cancel = create_server_action::<Cancel>();
view! { view! {

@ -1,15 +1,20 @@
use leptos::*; use leptos::*;
use crate::backend::data::ApiResponse; use crate::backend::data::{ApiResponse, ResSumWithItems};
use crate::backend::reservation::get_next_reservations; use crate::backend::reservation::get_next_reservations;
use crate::components::modal_box::DialogOpener; use crate::components::modal_box::DialogOpener;
use crate::locales::{loc_date, show_day, trl}; use crate::locales::{loc_date, show_day, trl};
use chrono::Datelike; use chrono::Datelike;
use crate::components::user_menu::MenuOpener;
use crate::pages::new_reservations::CancelDialog;
#[component] #[component]
pub fn next_reservations(app_opener: DialogOpener, cancel_opener: DialogOpener) -> impl IntoView { pub fn next_reservations(app_opener: DialogOpener, cancel_opener: DialogOpener) -> impl IntoView {
let res = create_blocking_resource( move || app_opener.visible() || cancel_opener.visible(), move |_| get_next_reservations()); let res = create_blocking_resource( move || app_opener.visible() || cancel_opener.visible(), move |_| get_next_reservations());
let menu = MenuOpener::new();
let reservation = create_rw_signal(ResSumWithItems::default());
view! { view! {
<CancelDialog opener=cancel_opener reservation=reservation.read_only()/>
<div class="card mb-3"> <div class="card mb-3">
<div class="card-body"> <div class="card-body">
<h5 class="card-title"><i class="bx bx-basket"></i>" "{trl("Next approved bookings")}</h5> <h5 class="card-title"><i class="bx bx-basket"></i>" "{trl("Next approved bookings")}</h5>
@ -27,6 +32,7 @@ pub fn next_reservations(app_opener: DialogOpener, cancel_opener: DialogOpener)
let:data> let:data>
{move || { {move || {
let data = data.clone(); let data = data.clone();
let cancel_data = data.clone();
view! { view! {
<b>{show_day(&data.summary.date.weekday())}" - "{loc_date(data.summary.date)}</b><br/> <b>{show_day(&data.summary.date.weekday())}" - "{loc_date(data.summary.date)}</b><br/>
<For each=move || data.reservations.clone() <For each=move || data.reservations.clone()
@ -45,6 +51,28 @@ pub fn next_reservations(app_opener: DialogOpener, cancel_opener: DialogOpener)
} }
}} }}
{trl("Price: ")}{data.summary.price.to_string()}<br/> {trl("Price: ")}{data.summary.price.to_string()}<br/>
<table width="100%">
<tr>
<td width="100%"></td>
<td>
<div class="dropdown">
<button type="button" class="btn p-0 dropdown-toggle hide-arrow"
on:click=move |_| menu.toggle()>
<i class="bx bx-dots-vertical-rounded"></i>
</button>
<div class={move || if menu.visible() {"dropdown-menu show"} else {"dropdown-menu"} }
style="position: absolute; insert: 0px 0px auto; margin: 0px; transform: translate3d(-160px, 0px, 0px);"
on:mouseleave=move |_| menu.toggle()>
<a class="dropdown-item text-danger" href="javascript:void(0);" on:click=move |_| {
reservation.set(cancel_data.clone());
cancel_opener.show();
}>
<i class="bx bx-trash me-1"></i> {trl("Cancel")}</a>
</div>
</div>
</td>
</tr>
</table>
<hr/> <hr/>
} }
}} }}

Loading…
Cancel
Save