header
This commit is contained in:
parent
5fd2b1206a
commit
8beaa5b0d4
@ -40,11 +40,6 @@ pub fn App() -> impl leptos::IntoView {
|
||||
<Title text="Ascend" />
|
||||
|
||||
<Router>
|
||||
// <nav class="shadow-md mb-2 bg-white border-gray-200 px-4 lg:px-6 py-2.5">
|
||||
// <div class="flex flex-wrap justify-start items-center gap-4 max-w-screen-xl">
|
||||
// <HeaderItem text="Home" link="/"/>
|
||||
// </div>
|
||||
// </nav>
|
||||
<main>
|
||||
<Routes fallback=|| "Not found">
|
||||
<Route path=path!("/wall") view=Wall />
|
||||
|
@ -1,6 +1,54 @@
|
||||
use leptos::prelude::*;
|
||||
|
||||
#[component]
|
||||
pub fn Header() -> impl leptos::IntoView {
|
||||
leptos::view! { <div class="border-b py-2 mb-4">"Ascend"</div> }
|
||||
pub struct HeaderItems {
|
||||
pub left: Vec<HeaderItem>,
|
||||
pub middle: Vec<HeaderItem>,
|
||||
pub right: Vec<HeaderItem>,
|
||||
}
|
||||
|
||||
pub struct HeaderItem {
|
||||
pub text: String,
|
||||
pub link: Option<String>,
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn Header(items: HeaderItems) -> impl IntoView {
|
||||
let HeaderItems { left, middle, right } = items;
|
||||
|
||||
view! {
|
||||
<div class="text-xl font-semibold p-4 flex gap-4">
|
||||
// Left side of header
|
||||
<Items items=left />
|
||||
|
||||
// Expanding space in the middle
|
||||
<div class="flex-auto mx-auto">
|
||||
<Items items=middle />
|
||||
</div>
|
||||
|
||||
// Right side of header
|
||||
<Items items=right />
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn Items(items: Vec<HeaderItem>) -> impl IntoView {
|
||||
items.into_iter().map(|item| view! { <Item item /> }).collect_view()
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn Item(item: HeaderItem) -> impl IntoView {
|
||||
let text = item.text;
|
||||
let link = item.link;
|
||||
|
||||
if let Some(link) = link {
|
||||
view! {
|
||||
<a href=link>
|
||||
<span class="whitespace-nowrap">{text}</span>
|
||||
</a>
|
||||
}
|
||||
.into_any()
|
||||
} else {
|
||||
view! { <span class="whitespace-nowrap">{text}</span> }.into_any()
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
use crate::codec::ron::RonCodec;
|
||||
use crate::components::header::Header;
|
||||
use crate::components::header::HeaderItem;
|
||||
use crate::components::header::HeaderItems;
|
||||
use crate::models;
|
||||
use crate::models::HoldPosition;
|
||||
use crate::models::Wall;
|
||||
@ -21,10 +23,54 @@ pub fn EditWall() -> impl leptos::IntoView {
|
||||
load_initial_data().await.unwrap()
|
||||
};
|
||||
|
||||
let header_items = HeaderItems {
|
||||
left: vec![HeaderItem {
|
||||
text: "← ".to_string(),
|
||||
link: Some("/wall".to_string()),
|
||||
}],
|
||||
middle: vec![HeaderItem {
|
||||
text: "Edit wall".to_string(),
|
||||
link: None,
|
||||
}],
|
||||
right: vec![],
|
||||
};
|
||||
|
||||
leptos::view! {
|
||||
<div class="min-w-screen min-h-screen bg-slate-900">
|
||||
<div class="container mx-auto">
|
||||
<Header />
|
||||
<div class="flex">
|
||||
// Left gradient chunk
|
||||
<div class="flex-grow">
|
||||
<div class="h-2/5" style="background: #eaac53" />
|
||||
<div class="h-3/5" style="background: linear-gradient(to bottom left, #eaac53 49.5%, rgb(15 23 42) 50.5%)" />
|
||||
</div>
|
||||
|
||||
<div class="flex-none container mx-auto text-black" style="background: #eaac53">
|
||||
<Header items=header_items />
|
||||
</div>
|
||||
|
||||
// Right gradient chunk
|
||||
<div class="flex-grow" style="background: #eaac53" />
|
||||
</div>
|
||||
<div class="flex">
|
||||
// Left gradient chunk
|
||||
<div class="flex-grow" />
|
||||
|
||||
<div class="flex-none container mx-auto">
|
||||
// Background color gradient
|
||||
<div
|
||||
class="h-6"
|
||||
style="background: linear-gradient(to bottom left, #eaac53 49.5%, rgb(15 23 42) 50.5%)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
// Right gradient chunk
|
||||
<div class="flex-grow">
|
||||
<div class="h-4/5" style="background: #eaac53" />
|
||||
<div class="h-1/5" style="background: linear-gradient(to bottom right, #eaac53 49.5%, rgb(15 23 42) 50.5%)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container mx-auto mt-2">
|
||||
<Await future=load let:data>
|
||||
<Ready data=data.deref().to_owned() />
|
||||
</Await>
|
||||
@ -44,7 +90,10 @@ fn Ready(data: InitialData) -> impl leptos::IntoView {
|
||||
|
||||
let grid_classes = format!("grid grid-rows-{} grid-cols-{} gap-2", data.wall.rows, data.wall.cols);
|
||||
|
||||
view! { <div class=move || { grid_classes.clone() }>{holds}</div> }
|
||||
view! {
|
||||
<div>
|
||||
<p class="my-4 font-semibold">"Click hold to replace image"</p>
|
||||
<div class=move || { grid_classes.clone() }>{holds}</div> </div>}
|
||||
}
|
||||
|
||||
#[component]
|
||||
@ -98,15 +147,13 @@ fn Hold(hold: models::Hold) -> impl leptos::IntoView {
|
||||
let img = move || {
|
||||
hold.read().image.as_ref().map(|img| {
|
||||
let src = format!("/files/holds/{}", img.filename);
|
||||
view! {
|
||||
<img class="object-cover w-full h-full" src=src />
|
||||
}
|
||||
view! { <img class="object-cover w-full h-full" src=src /> }
|
||||
})
|
||||
};
|
||||
|
||||
view! {
|
||||
<button on:click=open_camera>
|
||||
<div class="bg-indigo-100 aspect-square rounded">{ img }</div>
|
||||
<div class="bg-indigo-100 aspect-square rounded">{img}</div>
|
||||
</button>
|
||||
|
||||
<input
|
||||
|
@ -1,5 +1,7 @@
|
||||
use crate::codec::ron::RonCodec;
|
||||
use crate::components::header::Header;
|
||||
use crate::components::header::HeaderItem;
|
||||
use crate::components::header::HeaderItems;
|
||||
use crate::models;
|
||||
use crate::models::HoldRole;
|
||||
use leptos::prelude::*;
|
||||
@ -15,10 +17,22 @@ pub fn Wall() -> impl leptos::IntoView {
|
||||
load_initial_data().await.unwrap()
|
||||
};
|
||||
|
||||
let header_items = HeaderItems {
|
||||
left: vec![],
|
||||
middle: vec![HeaderItem {
|
||||
text: "Ascend".to_string(),
|
||||
link: None,
|
||||
}],
|
||||
right: vec![HeaderItem {
|
||||
text: "Edit wall".to_string(),
|
||||
link: Some("/wall/edit".to_string()),
|
||||
}],
|
||||
};
|
||||
|
||||
leptos::view! {
|
||||
<div class="min-w-screen min-h-screen bg-slate-900">
|
||||
<div class="container mx-auto">
|
||||
<Header />
|
||||
<Header items=header_items />
|
||||
<Await future=load let:data>
|
||||
<Ready data=data.deref().to_owned() />
|
||||
</Await>
|
||||
@ -43,7 +57,7 @@ fn Ready(data: InitialData) -> impl leptos::IntoView {
|
||||
let role = move || current_problem.get().and_then(|problem| problem.holds.get(&hold_position).copied());
|
||||
let role = Signal::derive(role);
|
||||
|
||||
let cell = view! { <Hold role hold=hold.clone()/> };
|
||||
let cell = view! { <Hold role hold=hold.clone() /> };
|
||||
cells.push(cell);
|
||||
}
|
||||
|
||||
@ -63,7 +77,8 @@ fn Hold(hold: models::Hold, #[prop(into)] role: Signal<Option<HoldRole>>) -> imp
|
||||
Some(HoldRole::Normal) => Some("outline outline-offset-2 outline-blue-500"),
|
||||
Some(HoldRole::Zone) => Some("outline outline-offset-2 outline-amber-500"),
|
||||
Some(HoldRole::End) => Some("outline outline-offset-2 outline-red-500"),
|
||||
None => Some("brightness-50"),
|
||||
// None => Some("brightness-50"),
|
||||
None => None,
|
||||
};
|
||||
let mut s = "bg-indigo-100 aspect-square rounded".to_string();
|
||||
if let Some(c) = role_classes {
|
||||
@ -75,12 +90,10 @@ fn Hold(hold: models::Hold, #[prop(into)] role: Signal<Option<HoldRole>>) -> imp
|
||||
|
||||
let img = hold.image.map(|img| {
|
||||
let src = format!("/files/holds/{}", img.filename);
|
||||
view! {
|
||||
<img class="hover:object-scale-down object-cover w-full h-full" src=src />
|
||||
}
|
||||
view! { <img class="hover:object-scale-down object-cover w-full h-full" src=src /> }
|
||||
});
|
||||
|
||||
view! { <div class=class>{ img }</div> }
|
||||
view! { <div class=class>{img}</div> }
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
|
Loading…
x
Reference in New Issue
Block a user