diff --git a/assets/Leptos_logo.png b/assets/Leptos_logo.png new file mode 100644 index 0000000..97b20e5 Binary files /dev/null and b/assets/Leptos_logo.png differ diff --git a/assets/rust.png b/assets/rust.png new file mode 100644 index 0000000..7829bae Binary files /dev/null and b/assets/rust.png differ diff --git a/assets/tables-basic.html b/assets/tables-basic.html deleted file mode 100644 index 9324494..0000000 --- a/assets/tables-basic.html +++ /dev/null @@ -1,4023 +0,0 @@ - - - - - - - - Tables - Basic Tables | Sneat - Bootstrap 5 HTML Admin Template - Pro - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - - - - - -
- - -
-

Tables / Basic Tables

- - -
-
Table Basic
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ProjectClientUsersStatusActions
Angular ProjectAlbert Cook -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Active - -
React ProjectBarry Hunter -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Completed - -
VueJs ProjectTrevor Baker -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Scheduled - -
- Bootstrap Project - Jerry Milton -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Pending - -
-
-
- - -
- - -
-
Table Dark
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ProjectClientUsersStatusActions
Angular ProjectAlbert Cook -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Active - -
React ProjectBarry Hunter -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Completed - -
VueJs ProjectTrevor Baker -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Scheduled - -
- Bootstrap Project - Jerry Milton -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Pending - -
-
-
- - -
- - -
-
Dark Table head
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ProjectClientUsersStatusActions
Angular ProjectAlbert Cook -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Active - -
React ProjectBarry Hunter -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Completed - -
VueJs ProjectTrevor Baker -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Scheduled - -
- Bootstrap Project - Jerry Milton -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Pending - -
-
-
- - -
- - -
-
Light Table head
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ProjectClientUsersStatusActions
Angular ProjectAlbert Cook -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Active - -
React ProjectBarry Hunter -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Completed - -
VueJs ProjectTrevor Baker -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Scheduled - -
- Bootstrap Project - Jerry Milton -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Pending - -
-
-
- - -
- - -
-
Table Header & Footer
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ProjectClientUsersStatusActions
Angular ProjectAlbert Cook -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Active - -
React ProjectBarry Hunter -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Completed - -
VueJs ProjectTrevor Baker -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Scheduled - -
- Bootstrap Project - Jerry Milton -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Pending - -
ProjectClientUsersStatusActions
-
-
- - -
- - -
-
Table Caption
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- List of Projects -
ProjectClientUsersStatusActions
Angular ProjectAlbert Cook -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Active - -
React ProjectBarry Hunter -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Completed - -
VueJs ProjectTrevor Baker -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Scheduled - -
- Bootstrap Project - Jerry Milton -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Pending - -
-
-
- - -
- - -
-
Striped rows
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ProjectClientUsersStatusActions
Angular ProjectAlbert Cook -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Active - -
React ProjectBarry Hunter -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Completed - -
VueJs ProjectTrevor Baker -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Scheduled - -
- Bootstrap Project - Jerry Milton -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Pending - -
-
-
- - -
- - -
-
Bordered Table
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ProjectClientUsersStatusActions
- Angular Project - Albert Cook -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Active - -
React ProjectBarry Hunter -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Completed - -
VueJs ProjectTrevor Baker -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Scheduled - -
- Bootstrap Project - Jerry Milton -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Pending - -
-
-
-
- - -
- - -
-
Borderless Table
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ProjectClientUsersStatusActions
Angular ProjectAlbert Cook -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Active - -
React ProjectBarry Hunter -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Completed - -
VueJs ProjectTrevor Baker -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Scheduled - -
- Bootstrap Project - Jerry Milton -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Pending - -
-
-
- - -
- - -
-
Hoverable rows
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ProjectClientUsersStatusActions
Angular ProjectAlbert Cook -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Active - -
React ProjectBarry Hunter -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Completed - -
VueJs ProjectTrevor Baker -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Scheduled - -
- Bootstrap Project - Jerry Milton -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Pending - -
-
-
- - -
- - - -
-
Small Table
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ProjectClientUsersStatusActions
Angular ProjectAlbert Cook -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Active - -
React ProjectBarry Hunter -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Completed - -
VueJs ProjectTrevor Baker -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Scheduled - -
- Bootstrap Project - Jerry Milton -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Pending - -
-
-
- - -
- - - -
-
Contextual Classes
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ProjectClientUsersStatusActions
Sketch ProjectRonnie Shane -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Active - -
React ProjectBarry Hunter -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Completed - -
Angular ProjectAlbert Cook -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Active - -
VueJs ProjectTrevor Baker -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Scheduled - -
- Bootstrap Project - Jerry Milton -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Pending - -
Sketch ProjectSarah Banks -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Active - -
React CustomTed Richer -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Scheduled - -
- Latest Bootstrap - Perry Parker -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Pending - -
Angular UIAna Bell -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Completed - -
Bootstrap UIJerry Milton -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Completed - -
-
-
- - -
- - -
Table without Card
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ProjectClientUsersStatusActions
Angular ProjectAlbert Cook -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Active - -
React ProjectBarry Hunter -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Completed - -
VueJs ProjectTrevor Baker -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Scheduled - -
- Bootstrap Project - Jerry Milton -
    -
  • - Avatar -
  • -
  • - Avatar -
  • -
  • - Avatar -
  • -
-
Pending - -
-
- - -
- - -
-
Responsive Table
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#Table headingTable headingTable headingTable headingTable headingTable headingTable headingTable headingTable heading
1Table cellTable cellTable cellTable cellTable cellTable cellTable cellTable cellTable cell
2Table cellTable cellTable cellTable cellTable cellTable cellTable cellTable cellTable cell
3Table cellTable cellTable cellTable cellTable cellTable cellTable cellTable cellTable cell
-
-
- -
- - - - - - -
-
- -
- -
- - -
-
- - -
- Upgrade to Pro -
- - - - - - - - - - - - - - - - - - - - - - diff --git a/src/app.rs b/src/app.rs index d05676e..640a2c5 100644 --- a/src/app.rs +++ b/src/app.rs @@ -8,6 +8,7 @@ use crate::components::admin_portal::AdminPortal; use crate::components::header::Header; use crate::components::user_menu::MenuOpener; use crate::pages::all_reservations::Bookings; +use crate::pages::customers::Customers; use crate::pages::login::Login; use crate::pages::mail_settings::MailSettings; use crate::pages::public::Public; @@ -97,6 +98,11 @@ pub fn App() -> impl IntoView { }/> + + + + }/> diff --git a/src/backend/customer.rs b/src/backend/customer.rs index e1c8517..085a362 100644 --- a/src/backend/customer.rs +++ b/src/backend/customer.rs @@ -1,11 +1,14 @@ use cfg_if::cfg_if; +use leptos::{server, ServerFnError}; +use crate::backend::data::ApiResponse; +use crate::backend::data::Customer; cfg_if! { if #[cfg(feature = "ssr")] { use sqlx::{Postgres, Transaction}; use sqlx::{query_as, query}; use sqlx::Error; - use crate::backend::data::Customer; use std::ops::DerefMut; + use leptos::expect_context; pub async fn find_customer_by_email(email: &str, tx: &mut Transaction<'_, Postgres>) -> Option { let customer = query_as::<_, Customer>("SELECT * FROM customer WHERE email = $1") @@ -48,3 +51,19 @@ cfg_if! { if #[cfg(feature = "ssr")] { Ok(find_customer_by_email(email, tx).await.ok_or(Error::RowNotFound)?) } }} + +#[server] +pub async fn get_customers() -> Result>, ServerFnError> { + use crate::backend::get_pool; + use crate::perm_check; + + perm_check!(is_logged_in); + + let pool = get_pool().await?; + + let customers = query_as::<_, Customer>("SELECT * FROM customer") + .fetch_all(&pool) + .await?; + + Ok(ApiResponse::Data(customers)) +} \ No newline at end of file diff --git a/src/components/admin_portal.rs b/src/components/admin_portal.rs index f709194..dafec98 100644 --- a/src/components/admin_portal.rs +++ b/src/components/admin_portal.rs @@ -1,11 +1,30 @@ use leptos::*; use crate::backend::data::User; -use crate::components::modal_box::DialogOpener; +use crate::components::modal_box::{DialogOpener, ModalBody, ModalDialog}; use crate::components::user_menu::{MenuOpener, UserMenu}; use crate::locales::trl; use crate::pages::change_pwd::ChangePassword; use crate::pages::profile_edit::ProfileEdit; +#[component] +fn about(opener: DialogOpener) -> impl IntoView { + view! { + + +

+

+ {trl("Online booking application for sports facilities and service providers.")}

+

+ " " +

+ "(c) 2023 - 2024" +
+

+
+
+ } +} + #[component] fn settings_menu(opener: MenuOpener) -> impl IntoView { view! { @@ -44,6 +63,7 @@ pub fn AdminPortal(children: Children) -> impl IntoView { let editor = DialogOpener::new(); let pw_changer = DialogOpener::new(); let drawer = use_context::().expect("No drawer opener"); + let about_dlg = DialogOpener::new(); view! {
@@ -69,21 +89,21 @@ pub fn AdminPortal(children: Children) -> impl IntoView { @@ -141,6 +161,7 @@ pub fn AdminPortal(children: Children) -> impl IntoView {
+ {children()}
diff --git a/src/locales/catalogues.rs b/src/locales/catalogues.rs index e51d0b0..2ee2b4e 100644 --- a/src/locales/catalogues.rs +++ b/src/locales/catalogues.rs @@ -78,6 +78,28 @@ lazy_static! { ("Your reservation has been successfully saved.", "Vaše rezervace byla úspěšně uložena."), ("We look forward to seeing you on", "Těšíme se na vaši návštěvu"), ("Create booking", "Vytvořit rezervaci"), + ("Online booking application for sports facilities and service providers.", "Online rezervační aplikace pro sportovní zařízení a provozovatele služeb."), + ("About", "O aplikaci"), + ("Booking summary", "Všechny rezervace"), + ("Customers", "Zákazníci"), + ("Customer", "Zákazník"), + ("Booking overview", "Rezervace"), + ("Base settings", "Základní nastavení"), + ("Mail settings", "Nastavení e-mailů"), + ("New booking", "Nová rezervace"), + ("New booking - for customer", "Nová rezervace - zákazníkovi"), + ("Booking approved", "Schválení rezervace"), + ("Booking canceled", "Zrušení rezervace"), + ("Subject", "Předmět"), + ("Subject: ", "Předmět: "), + ("Edit mail", "Upravit e-mail"), + ("Year: ", "Rok: "), + ("Month: ", "Měsíc: "), + ("New", "Nová"), + ("Approved", "Potvrzená"), + ("Canceled", "Zrušená"), + ("Booking detail", "Detail rezervace"), + ("State", "Stav") ])), ("sk", HashMap::from( [ ("Dashboard", "Prehlad"), diff --git a/src/pages/all_reservations.rs b/src/pages/all_reservations.rs index f4511ce..ba685ad 100644 --- a/src/pages/all_reservations.rs +++ b/src/pages/all_reservations.rs @@ -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, opener: DialogOpener) -> impl IntoView { + view! { + + +

+ {move || { + let detail = reservation.get(); + view! { + {show_day(&detail.summary.date.weekday())}" - "{loc_date(detail.summary.date)}
+ + {item.property.name}": "{item.reservation.from.to_string()}" - "{item.reservation.to.to_string()}
+
+ {trl("Customer: ")}{detail.customer.full_name}", "{detail.customer.email}", "{detail.customer.phone}
+ { + let note = detail.summary.note.clone(); + let show = note.is_some() && !note.clone().unwrap().is_empty(); + view! { + + {trl("Note: ")}{note.clone()}
+
+ } + } + {trl("Price: ")}{detail.summary.price.to_string()}
+ } + }} +

+
+
+ } +} #[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 = 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! {

{trl("Booking overview")}

+