Added customers overview, booking detail dialog and about dialog.

This commit is contained in:
2024-02-15 16:46:57 +01:00
parent 952f8fbe94
commit 549ec86684
11 changed files with 186 additions and 4041 deletions
+50 -9
View File
@@ -1,8 +1,43 @@
use chrono::{Datelike, Local};
use leptos::*;
use crate::backend::data::ApiResponse;
use crate::backend::data::{ApiResponse, ResSumWithItems};
use crate::backend::reservation::{month_chart, reservations_in_month, year_chart, years};
use crate::locales::{loc_date, trl};
use crate::components::modal_box::{DialogOpener, ModalBody, ModalDialog};
use crate::locales::{loc_date, show_day, trl};
#[component]
fn booking_detail(reservation: ReadSignal<ResSumWithItems>, opener: DialogOpener) -> impl IntoView {
view! {
<ModalDialog title="Booking detail" opener=opener>
<ModalBody>
<p>
{move || {
let detail = reservation.get();
view! {
<b>{show_day(&detail.summary.date.weekday())}" - "{loc_date(detail.summary.date)}</b><br/>
<For each=move || detail.reservations.clone()
key=|item| item.reservation.id()
let:item>
{item.property.name}": "{item.reservation.from.to_string()}" - "{item.reservation.to.to_string()}<br/>
</For>
{trl("Customer: ")}{detail.customer.full_name}", "<a href={format!("mailto:{}", detail.customer.email)}>{detail.customer.email}</a>", "{detail.customer.phone}<br/>
{
let note = detail.summary.note.clone();
let show = note.is_some() && !note.clone().unwrap().is_empty();
view! {
<Show when=move || show>
{trl("Note: ")}{note.clone()}<br/>
</Show>
}
}
{trl("Price: ")}{detail.summary.price.to_string()}<br/>
}
}}
</p>
</ModalBody>
</ModalDialog>
}
}
#[component]
pub fn bookings() -> impl IntoView {
@@ -13,15 +48,18 @@ pub fn bookings() -> impl IntoView {
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 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 detail_dlg = DialogOpener::new();
view! {
<h1>{trl("Booking overview")}</h1>
<BookingDetail reservation=res_detail.read_only() opener=detail_dlg />
<nav class="navbar navbar-expand-lg navbar-light bg-light mb-5">
<div class="container-fluid">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<div class="nav-link">
"Rok: "
{trl("Year: ")}
</div>
</li>
<li class="nav-item">
@@ -47,7 +85,7 @@ pub fn bookings() -> impl IntoView {
</li>
<li class="nav-item">
<div class="nav-link">
"Měsíc: "
{trl("Month: ")}
</div>
</li>
<li class="nav-item">
@@ -121,12 +159,15 @@ pub fn bookings() -> impl IntoView {
let:data>
<tr>
<td>{loc_date(data.summary.date)}</td>
<td>{data.customer.full_name}</td>
<td>{data.customer.full_name.clone()}</td>
<td>{data.summary.price.to_string()}</td>
<td>{data.summary.state.to_string()}</td>
<td><button type="button" class="btn p-0 dropdown-toggle hide-arrow">
//on:click=move |_| menu.toggle()>
<i class="bx bx-dots-vertical-rounded"></i>
<td>{trl(&data.summary.state.to_string())}</td>
<td><button type="button" class="btn"
on:click=move |_| {
res_detail.set(data.clone());
detail_dlg.show();
}>
<i class="bx bx-show"></i>
</button></td>
</tr>
</For>
+58
View File
@@ -0,0 +1,58 @@
use leptos::*;
use crate::backend::customer::get_customers;
use crate::backend::data::ApiResponse;
use crate::locales::trl;
#[component]
pub fn customers() -> impl IntoView {
let customers = create_blocking_resource(||(), |_| get_customers());
view! {
<h1>{trl("Customers")}</h1>
<div class="row mb-3">
<div class="card">
<div class="card-body">
<Transition fallback=move || view! {<div>"Loading"</div>}>
<table class="table card-table">
<thead>
<tr>
<th>{trl("Full name")}</th>
<th>{trl("E-mail")}</th>
<th>{trl("Phone")}</th>
</tr>
</thead>
{
customers.get().map(|c| match c {
Ok(c) => {match c {
ApiResponse::Data(c) => {
view! {
<tbody>
<For each=move || c.clone() key=|i| i.id() let:data>
<tr>
<td>{data.full_name}</td>
<td>{data.email}</td>
<td>{data.phone}</td>
</tr>
</For>
</tbody>
}
}
ApiResponse::Error(e) => {
view! {<tbody class="table-border-bottom-0">
<tr><td colspan=3>{trl("Something went wrong")}<br/>{e.to_string()}</td></tr></tbody>}
}
}
}
Err(e) => {
view! {<tbody class="table-border-bottom-0">
<tr><td colspan=3>{trl("Something went wrong")}<br/>{e.to_string()}</td></tr></tbody>}
}
})
}
</table>
</Transition>
</div>
</div>
</div>
}
}
+1 -1
View File
@@ -15,7 +15,7 @@ fn mail_edit(opener: DialogOpener, mail: ReadSignal<Message>) -> impl IntoView {
<input type="hidden" prop:value={move || mail.get().msg_type.to_string()} name="message[msg_type]"/>
<div class="row">
<div class="col mb-3">
<label for="subject" class="form-label">"Subject"</label>
<label for="subject" class="form-label">{trl("Subject")}</label>
<input
type="text"
id="nameWithTitle"
+1
View File
@@ -20,4 +20,5 @@ mod new_reservations;
pub mod mail_settings;
mod mail_view;
pub mod all_reservations;
pub mod customers;