diff --git a/Cargo.lock b/Cargo.lock index fb25260..8c32ac1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2795,12 +2795,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "pure-rust-locales" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45c49fc4f91f35bae654f85ebb3a44d60ac64f11b3166ffa609def390c732d8" - [[package]] name = "quick-error" version = "1.2.3" @@ -4362,7 +4356,6 @@ dependencies = [ "indexmap", "js-sys", "model", - "pure-rust-locales", "rusty-money", "seed 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "seed_heroicons", diff --git a/web/Cargo.toml b/web/Cargo.toml index 84dc14a..5484df2 100644 --- a/web/Cargo.toml +++ b/web/Cargo.toml @@ -29,8 +29,6 @@ indexmap = { version = "1", features = ["serde-1"] } rusty-money = { version = "0.4.1", features = ["iso"] } -pure-rust-locales = { version = "0.5.6" } - thiserror = { version = "1.0.31" } [profile.release] diff --git a/web/src/api.rs b/web/src/api.rs index ff601f7..8d387a5 100644 --- a/web/src/api.rs +++ b/web/src/api.rs @@ -31,8 +31,8 @@ async fn perform(req: Request<'_>) -> Ok(json) => json, Err(_err) => match res.text().await { Ok(text) => model::api::Failure { errors: vec![text] }, - Err(err) => model::api::Failure { - errors: vec![format!("{:?}", err)], + Err(_err) => model::api::Failure { + errors: vec!["There was internal server error. Please try later".into()], }, }, }) diff --git a/web/src/i18n/pl.rs b/web/src/i18n/pl.rs index b2a9725..3d7c34f 100644 --- a/web/src/i18n/pl.rs +++ b/web/src/i18n/pl.rs @@ -30,5 +30,10 @@ pub fn define(i18n: &mut I18n) { .define("Decagram", "Decagram") .define("Kilogram", "Kilogram") .define("Piece", "Sztukę") - .define("Out of stock", "Brak na stanie"); + .define("Out of stock", "Brak na stanie") + .define( + "There was internal server error. Please try later", + "Wystąpił błąd, proszę spróbować później", + ) + .define("Can't create account", "Adres e-mail i/lub login są zajęte"); } diff --git a/web/src/session.rs b/web/src/session.rs index 2e6294f..37b49e1 100644 --- a/web/src/session.rs +++ b/web/src/session.rs @@ -122,7 +122,7 @@ pub fn update(msg: SessionMsg, model: &mut Model, orders: &mut impl Orders) seed::error!("net", net); } FetchError::RequestError(e) => { - seed::log!(e); + seed::error!(e); } FetchError::StatusError(status) => match status.code { 401 | 403 => { diff --git a/web/src/shared/notification.rs b/web/src/shared/notification.rs index 6b7f0b5..5191e94 100644 --- a/web/src/shared/notification.rs +++ b/web/src/shared/notification.rs @@ -13,6 +13,18 @@ pub enum NotificationMsg { Clear, } +impl From for shared::Msg { + fn from(msg: NotificationMsg) -> Self { + Self::Notification(msg) + } +} + +impl From for Msg { + fn from(msg: NotificationMsg) -> Self { + Self::Shared(msg.into()) + } +} + #[derive(Debug)] pub struct Notification { id: uuid::Uuid, @@ -43,8 +55,8 @@ impl IntoNodes for Type { fn into_nodes(self) -> Vec> { match self { Type::Success => vec![success_icon()], - Type::Info => vec![], - Type::Warning => vec![], + Type::Info => vec![info_icon()], + Type::Warning => vec![warning_icon()], Type::Error => vec![error_icon()], } } @@ -100,13 +112,30 @@ pub fn view(model: &crate::Model) -> Node { let notifications = model.shared.notifications.iter().map(|notification| { message( notification.id, - notification.message.as_str(), + &model.i18n.l(¬ification.message), notification.ty, ) }); + div![ C!["absolute inline-block top-0 right-0 bottom-auto left-auto p-2.5 text-xs z-10"], - notifications + notifications, + div![ + C!["flex items-center justify-between max-w-xs p-4 bg-white border shadow-sm"], + div![ + C!["inline-block w-full"], + a![ + C!["flex items-center inline-block cursor-pointer w-full justify-between"], + ev(Ev::Click, move |ev| { + ev.prevent_default(); + ev.stop_propagation(); + Msg::Shared(NotificationMsg::Clear.into()) + }), + p![C!["ml-3 text-sm font-bold"], "Remove all"], + trash("w-8 h-8") + ] + ] + ] ] } @@ -130,38 +159,60 @@ pub fn message(id: uuid::Uuid, message: &str, icon: Type) -> Node { ] } -fn success_icon() -> Node { +fn icon(color: &str, d: &str) -> Node { svg![ attrs![ "xmlns"=>"http://www.w3.org/2000/svg", - "class" => "w-8 h-8 text-green-500", + "class" => "w-8 h-8", "viewBox" => "0 0 20 20", "fill" => "currentColor" ], + C![color], path![attrs![ "fill-rule" => "evenodd", - "d" => "M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z", + "d" => d, "clip-rule" => "evenodd" ]] ] } -fn error_icon() -> Node { +fn trash(classes: &str) -> Node { svg![ - attrs![ - "xmlns" => "http://www.w3.org/2000/svg", - "class" => "w-8 h-8 text-red-600", - "viewBox" => "0 0 20 20", - "fill" => "currentColor" - ], - path![attrs![ - "fill-rule" => "evenodd", - "d" => "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z", - "clip-rule" => "evenodd" - ]] + C![classes], + attrs!( + At::from("fill") => "none", + At::from("stroke") => "currentColor", + At::from("viewBox") => "0 0 24 24", + ), + path![attrs!( + At::from("d") => "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16", + At::from("stroke-linecap") => "round", + At::from("stroke-linejoin") => "round", + At::from("stroke-width") => "2", + )], ] } +#[inline(always)] +fn success_icon() -> Node { + icon("text-green-500", "M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z") +} + +#[inline(always)] +fn info_icon() -> Node { + icon("text-blue-600", "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z") +} + +#[inline(always)] +fn warning_icon() -> Node { + icon("text-yellow-600", "M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z") +} + +#[inline(always)] +fn error_icon() -> Node { + icon("text-red-600", "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z") +} + fn close_icon() -> Node { span![ C!["inline-flex items-center cursor-pointer"],