This commit is contained in:
2025-03-05 01:25:02 +01:00
parent 0da5cc573e
commit 976a416081
6 changed files with 147 additions and 46 deletions

View File

@@ -23,7 +23,7 @@ derive_more = { version = "2", features = [
] }
http = "1"
image = { version = "0.25", optional = true }
leptos = { version = "0.7.4", features = ["tracing"] }
leptos = { version = "0.7.7", features = ["tracing"] }
leptos_axum = { version = "0.7", optional = true }
leptos_meta = { version = "0.7" }
leptos_router = { version = "0.7.0" }

View File

@@ -12,11 +12,13 @@ pub fn Button(
#[prop(optional)] color: Gradient,
#[prop(into, optional)] highlight: MaybeProp<bool>,
onclick: impl FnMut(MouseEvent) + 'static,
) -> impl IntoView {
let icon_view = icon.get().map(|i| {
let icon_view = i.into_view();
let mut classes = "self-center mx-5 my-2.5 text-pink-500 rounded-sm".to_string();
let mut classes = "self-center mx-5 my-2.5 rounded-sm".to_string();
classes.push(' ');
classes.push_str(color.class_text());
@@ -41,7 +43,7 @@ pub fn Button(
type="button"
class="mb-2 me-2 hover:brightness-125 active:brightness-90"
>
<OutlinedBox color>
<OutlinedBox color highlight>
<div class="flex items-stretch">{icon_view} {separator} {text_view}</div>
</OutlinedBox>
</button>

View File

@@ -11,6 +11,8 @@ pub enum Icon {
ArrowPath,
PaperAirplaneSolid,
NoSymbol,
Trophy,
ArrowTrendingUp,
}
impl Icon {
// TODO: Actually impl IntoView for Icon instead
@@ -25,6 +27,8 @@ impl Icon {
Icon::ArrowPath => view! { <ArrowPath /> }.into_any(),
Icon::PaperAirplaneSolid => view! { <PaperAirplaneSolid /> }.into_any(),
Icon::NoSymbol => view! { <NoSymbol /> }.into_any(),
Icon::Trophy => view! { <Trophy /> }.into_any(),
Icon::ArrowTrendingUp => view! { <ArrowTrendingUp /> }.into_any(),
}
}
}
@@ -182,3 +186,43 @@ pub fn NoSymbol() -> impl IntoView {
</svg>
}
}
#[component]
pub fn Trophy() -> impl IntoView {
view! {
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="size-6"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M16.5 18.75h-9m9 0a3 3 0 0 1 3 3h-15a3 3 0 0 1 3-3m9 0v-3.375c0-.621-.503-1.125-1.125-1.125h-.871M7.5 18.75v-3.375c0-.621.504-1.125 1.125-1.125h.872m5.007 0H9.497m5.007 0a7.454 7.454 0 0 1-.982-3.172M9.497 14.25a7.454 7.454 0 0 0 .981-3.172M5.25 4.236c-.982.143-1.954.317-2.916.52A6.003 6.003 0 0 0 7.73 9.728M5.25 4.236V4.5c0 2.108.966 3.99 2.48 5.228M5.25 4.236V2.721C7.456 2.41 9.71 2.25 12 2.25c2.291 0 4.545.16 6.75.47v1.516M7.73 9.728a6.726 6.726 0 0 0 2.748 1.35m8.272-6.842V4.5c0 2.108-.966 3.99-2.48 5.228m2.48-5.492a46.32 46.32 0 0 1 2.916.52 6.003 6.003 0 0 1-5.395 4.972m0 0a6.726 6.726 0 0 1-2.749 1.35m0 0a6.772 6.772 0 0 1-3.044 0"
/>
</svg>
}
}
#[component]
pub fn ArrowTrendingUp() -> impl IntoView {
view! {
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="size-6"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M2.25 18 9 11.25l4.306 4.306a11.95 11.95 0 0 1 5.814-5.518l2.74-1.22m0 0-5.94-2.281m5.94 2.28-2.28 5.941"
/>
</svg>
}
}

View File

@@ -2,16 +2,43 @@ use crate::gradient::Gradient;
use leptos::prelude::*;
#[component]
pub fn OutlinedBox(children: Children, color: Gradient) -> impl IntoView {
let mut classes = "p-0.5 bg-gradient-to-br rounded-lg".to_string();
classes.push(' ');
classes.push_str(color.class_from());
classes.push(' ');
classes.push_str(color.class_to());
pub fn OutlinedBox(children: Children, color: Gradient, #[prop(optional)] highlight: MaybeProp<bool>) -> impl IntoView {
let highlight = move || highlight.get().unwrap_or(false);
let outer_classes = move || {
let mut c = "p-0.5 bg-gradient-to-br rounded-lg".to_string();
c.push(' ');
c.push_str(color.class_from());
c.push(' ');
c.push_str(color.class_to());
if highlight() {
c.push(' ');
c.push_str("brightness-110");
}
c
};
let inner_classes = move || {
let mut c = "py-1.5 rounded-md".to_string();
if highlight() {
let bg = match color {
Gradient::PinkOrange => "bg-pink-900",
Gradient::CyanBlue => "bg-cyan-900",
Gradient::TealLime => "bg-teal-900",
};
c.push(' ');
c.push_str(bg);
} else {
c.push(' ');
c.push_str("bg-gray-900");
}
c
};
view! {
<div class=classes>
<div class="py-1.5 bg-gray-900 rounded-md">{children()}</div>
<div class=outer_classes>
<div class=inner_classes>{children()}</div>
</div>
}
}

View File

@@ -21,9 +21,9 @@
// | |
// +--------------------------------------+
// + ------- + + ------ -+ +---------+
// | Flash | | Top | | Attempt |
// + ------- + + ------ -+ +---------+
// +---------+ +---------+ +---------+
// | Flash | | Send | | Attempt |
// +---------+ +---------+ +---------+
// +---------- <Latest attempt> ----------+
// | Today: <Attempt> |
@@ -94,6 +94,7 @@ pub fn Wall() -> impl IntoView {
let ui_is_flash = RwSignal::new(false);
let ui_is_climbed = RwSignal::new(false);
let ui_is_attempt = RwSignal::new(false);
let ui_is_favorite = RwSignal::new(false);
// On reception of user interaction state, set UI signals
@@ -163,17 +164,44 @@ pub fn Wall() -> impl IntoView {
<div>
<div class="flex">
<Checkbox
checked=ui_is_flash
<Button
onclick=move |_| {
ui_is_flash
.update(|x| {
*x = !*x;
});
}
text="Flash"
icon=Icon::BoltSolid
color=Gradient::CyanBlue
highlight=Signal::derive(move || { ui_is_flash.get() })
/>
<Checkbox
checked=ui_is_climbed
text="Top"
<Button
onclick=move |_| {
ui_is_climbed
.update(|x| {
*x = !*x;
});
}
text="Send"
icon=Icon::Trophy
color=Gradient::TealLime
highlight=Signal::derive(move || { ui_is_climbed.get() })
/>
<Button
onclick=move |_| {
ui_is_attempt
.update(|x| {
*x = !*x;
});
}
text="Attempt"
icon=Icon::ArrowTrendingUp
color=Gradient::PinkOrange
highlight=Signal::derive(move || { ui_is_attempt.get() })
/>
<Checkbox checked=ui_is_favorite text="Attempt" />
</div>
<Button