Implemented booking overview.
parent
ab3e85573d
commit
aa45cb48ba
@ -0,0 +1,154 @@
|
||||
use chrono::{Datelike, Local};
|
||||
use leptos::*;
|
||||
use crate::backend::data::ApiResponse;
|
||||
use crate::backend::reservation::{month_chart, reservations_in_month, year_chart, years};
|
||||
use crate::locales::{loc_date, trl};
|
||||
|
||||
#[component]
|
||||
pub fn bookings() -> impl IntoView {
|
||||
let year_chart = create_blocking_resource(||(), |_| year_chart());
|
||||
let years = create_blocking_resource(||(), |_| years());
|
||||
let year = create_rw_signal(Local::now().year());
|
||||
let month = create_rw_signal(Local::now().month());
|
||||
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];
|
||||
|
||||
view! {
|
||||
<h1>{trl("Booking overview")}</h1>
|
||||
<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: "
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<Transition fallback=move || view! {<div>"Loading"</div>} >
|
||||
{
|
||||
years.get().map(|y| match y {
|
||||
Ok(y) => {
|
||||
view! {
|
||||
<select class="form-select" on:change=move |ev| {
|
||||
let new_value = event_target_value(&ev).parse::<i32>().unwrap_or_default();
|
||||
year.set(new_value);
|
||||
}>
|
||||
<For each=move || y.clone() key=|i| *i let:y>
|
||||
<option prop:value=move || y prop:selected=move || year.get() == y>{y}</option>
|
||||
</For>
|
||||
</select>
|
||||
}
|
||||
}
|
||||
Err(_) => {view! {<select><option></option></select>}}
|
||||
})
|
||||
}
|
||||
</Transition>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<div class="nav-link">
|
||||
"Měsíc: "
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<select class="form-select" on:change=move |ev| {
|
||||
let new_value = event_target_value(&ev).parse::<u32>().unwrap_or_default();
|
||||
month.set(new_value);
|
||||
}>
|
||||
<For each=move || all_months.clone() key=|i| *i let:m>
|
||||
<option prop:value=move || m prop:selected=move || month.get() == m>{m}</option>
|
||||
</For>
|
||||
</select>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="row mb-3">
|
||||
<div class="col-md">
|
||||
<div class="card md-3">
|
||||
<Transition fallback=move || view! {<div>"Loading"</div>}>
|
||||
{
|
||||
chart.get().map(move |c| match c {
|
||||
Ok(c) => { match c {
|
||||
ApiResponse::Data(c) => {view! {<img style="margin: 1em" src={c.clone()} /> }}
|
||||
ApiResponse::Error(_) => {view! {<img src=""/> }} }
|
||||
}
|
||||
Err(_) => { view! {<img src=""/> } }
|
||||
})
|
||||
}
|
||||
</Transition>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<div class="card md-3">
|
||||
<Transition fallback=move || view! {<div>"Loading"</div>}>
|
||||
{
|
||||
year_chart.get().map(move |c| match c {
|
||||
Ok(c) => { match c {
|
||||
ApiResponse::Data(c) => {view! {<img style="margin: 1em" src={c.clone()} /> }}
|
||||
ApiResponse::Error(_) => {view! {<img src=""/> }} }
|
||||
}
|
||||
Err(_) => { view! {<img src=""/> } }
|
||||
})
|
||||
}
|
||||
</Transition>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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("Date")}</th>
|
||||
<th>{trl("Customer")}</th>
|
||||
<th>{trl("Price")}</th>
|
||||
<th>{trl("State")}</th>
|
||||
<th>{trl("Actions")}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
{
|
||||
reservations.get().map(|r| match r {
|
||||
Ok(r) => { match r {
|
||||
ApiResponse::Data(r) => {
|
||||
view! {
|
||||
<tbody class="table-border-bottom-0">
|
||||
<For each=move || r.clone()
|
||||
key=|i| i.summary.id()
|
||||
let:data>
|
||||
<tr>
|
||||
<td>{loc_date(data.summary.date)}</td>
|
||||
<td>{data.customer.full_name}</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>
|
||||
</button></td>
|
||||
</tr>
|
||||
</For>
|
||||
</tbody>
|
||||
}
|
||||
}
|
||||
ApiResponse::Error(e) => {
|
||||
view! {<tbody class="table-border-bottom-0">
|
||||
<tr><td colspan=5>{trl("Something went wrong")}<br/>{e.to_string()}</td></tr></tbody>}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
view! {<tbody class="table-border-bottom-0">
|
||||
<tr><td colspan=5>{trl("Something went wrong")}<br/>{e.to_string()}</td></tr></tbody>}
|
||||
}
|
||||
})
|
||||
}
|
||||
</table>
|
||||
</Transition>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue