Added customers overview, booking detail dialog and about dialog.
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
@@ -20,4 +20,5 @@ mod new_reservations;
|
||||
pub mod mail_settings;
|
||||
mod mail_view;
|
||||
pub mod all_reservations;
|
||||
pub mod customers;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user