Clear all notifications

This commit is contained in:
Adrian Woźniak 2022-05-15 11:38:35 +02:00
parent 0f88287929
commit c047ce19b4
No known key found for this signature in database
GPG Key ID: 0012845A89C7352B
6 changed files with 79 additions and 32 deletions

7
Cargo.lock generated
View File

@ -2795,12 +2795,6 @@ dependencies = [
"unicode-xid", "unicode-xid",
] ]
[[package]]
name = "pure-rust-locales"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b45c49fc4f91f35bae654f85ebb3a44d60ac64f11b3166ffa609def390c732d8"
[[package]] [[package]]
name = "quick-error" name = "quick-error"
version = "1.2.3" version = "1.2.3"
@ -4362,7 +4356,6 @@ dependencies = [
"indexmap", "indexmap",
"js-sys", "js-sys",
"model", "model",
"pure-rust-locales",
"rusty-money", "rusty-money",
"seed 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "seed 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"seed_heroicons", "seed_heroicons",

View File

@ -29,8 +29,6 @@ indexmap = { version = "1", features = ["serde-1"] }
rusty-money = { version = "0.4.1", features = ["iso"] } rusty-money = { version = "0.4.1", features = ["iso"] }
pure-rust-locales = { version = "0.5.6" }
thiserror = { version = "1.0.31" } thiserror = { version = "1.0.31" }
[profile.release] [profile.release]

View File

@ -31,8 +31,8 @@ async fn perform<S: serde::de::DeserializeOwned + 'static>(req: Request<'_>) ->
Ok(json) => json, Ok(json) => json,
Err(_err) => match res.text().await { Err(_err) => match res.text().await {
Ok(text) => model::api::Failure { errors: vec![text] }, Ok(text) => model::api::Failure { errors: vec![text] },
Err(err) => model::api::Failure { Err(_err) => model::api::Failure {
errors: vec![format!("{:?}", err)], errors: vec!["There was internal server error. Please try later".into()],
}, },
}, },
}) })

View File

@ -30,5 +30,10 @@ pub fn define(i18n: &mut I18n) {
.define("Decagram", "Decagram") .define("Decagram", "Decagram")
.define("Kilogram", "Kilogram") .define("Kilogram", "Kilogram")
.define("Piece", "Sztukę") .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");
} }

View File

@ -122,7 +122,7 @@ pub fn update(msg: SessionMsg, model: &mut Model, orders: &mut impl Orders<Msg>)
seed::error!("net", net); seed::error!("net", net);
} }
FetchError::RequestError(e) => { FetchError::RequestError(e) => {
seed::log!(e); seed::error!(e);
} }
FetchError::StatusError(status) => match status.code { FetchError::StatusError(status) => match status.code {
401 | 403 => { 401 | 403 => {

View File

@ -13,6 +13,18 @@ pub enum NotificationMsg {
Clear, Clear,
} }
impl From<NotificationMsg> for shared::Msg {
fn from(msg: NotificationMsg) -> Self {
Self::Notification(msg)
}
}
impl From<NotificationMsg> for Msg {
fn from(msg: NotificationMsg) -> Self {
Self::Shared(msg.into())
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct Notification { pub struct Notification {
id: uuid::Uuid, id: uuid::Uuid,
@ -43,8 +55,8 @@ impl IntoNodes<Msg> for Type {
fn into_nodes(self) -> Vec<Node<Msg>> { fn into_nodes(self) -> Vec<Node<Msg>> {
match self { match self {
Type::Success => vec![success_icon()], Type::Success => vec![success_icon()],
Type::Info => vec![], Type::Info => vec![info_icon()],
Type::Warning => vec![], Type::Warning => vec![warning_icon()],
Type::Error => vec![error_icon()], Type::Error => vec![error_icon()],
} }
} }
@ -100,13 +112,30 @@ pub fn view(model: &crate::Model) -> Node<Msg> {
let notifications = model.shared.notifications.iter().map(|notification| { let notifications = model.shared.notifications.iter().map(|notification| {
message( message(
notification.id, notification.id,
notification.message.as_str(), &model.i18n.l(&notification.message),
notification.ty, notification.ty,
) )
}); });
div![ div![
C!["absolute inline-block top-0 right-0 bottom-auto left-auto p-2.5 text-xs z-10"], 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<Msg> {
] ]
} }
fn success_icon() -> Node<Msg> { fn icon(color: &str, d: &str) -> Node<Msg> {
svg![ svg![
attrs![ attrs![
"xmlns"=>"http://www.w3.org/2000/svg", "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", "viewBox" => "0 0 20 20",
"fill" => "currentColor" "fill" => "currentColor"
], ],
C![color],
path![attrs![ path![attrs![
"fill-rule" => "evenodd", "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" "clip-rule" => "evenodd"
]] ]]
] ]
} }
fn error_icon() -> Node<Msg> { fn trash(classes: &str) -> Node<Msg> {
svg![ svg![
attrs![ C![classes],
"xmlns" => "http://www.w3.org/2000/svg", attrs!(
"class" => "w-8 h-8 text-red-600", At::from("fill") => "none",
"viewBox" => "0 0 20 20", At::from("stroke") => "currentColor",
"fill" => "currentColor" At::from("viewBox") => "0 0 24 24",
], ),
path![attrs![ path![attrs!(
"fill-rule" => "evenodd", 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",
"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", At::from("stroke-linecap") => "round",
"clip-rule" => "evenodd" At::from("stroke-linejoin") => "round",
]] At::from("stroke-width") => "2",
)],
] ]
} }
#[inline(always)]
fn success_icon() -> Node<Msg> {
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<Msg> {
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<Msg> {
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<Msg> {
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<Msg> { fn close_icon() -> Node<Msg> {
span![ span![
C!["inline-flex items-center cursor-pointer"], C!["inline-flex items-center cursor-pointer"],