diff --git a/src/app/components/title.rs b/src/app/components/title.rs index b625c1d..e834a8d 100644 --- a/src/app/components/title.rs +++ b/src/app/components/title.rs @@ -1,4 +1,5 @@ use leptos::*; +use leptos_router::A; #[component] pub fn Title( @@ -8,7 +9,7 @@ pub fn Title( ) -> impl IntoView { view! {
- r"< Retour" + r"< Retour"

{title}

diff --git a/src/app/pages/posts.rs b/src/app/pages/posts.rs index 96c2242..1c6eb1a 100644 --- a/src/app/pages/posts.rs +++ b/src/app/pages/posts.rs @@ -9,12 +9,18 @@ use crate::app::{ }; #[server] -pub async fn get_posts() -> Result, ServerFnError> { +pub async fn get_posts( + tag: Option +) -> Result, ServerFnError> { leptos_actix::extract( |data: actix_web::web::Data| async move { let data = data.into_inner(); - data.posts - .iter() + let default = vec![]; + let posts = match tag { + Some(tag) => data.posts_by_tag.get(&tag).unwrap_or(&default), + None => &data.posts + }; + posts.iter() .map(|post| { Post { metadata: post.metadata.clone(), @@ -44,44 +50,72 @@ pub async fn get_post( .and_then(|post| post.ok_or_else(|| ServerFnError::ServerError("Post not found".to_string()))) } +#[component] +pub fn PostTags( + tags: Vec +) -> impl IntoView { + view! { +
+ { + tags.into_iter().map(|tag| view! { {tag}}).collect_view() + } +
+ } +} + +#[component] +pub fn PostListCard( + post: Post +) -> impl IntoView { + view! { +
+ format!("Image + + { + if post.metadata.draft { + Some(view!{ +
+ +
+ }) + } else { + None + } + } + +
+ +

{post.metadata.title.clone()}

+

{post.metadata.description.clone()}

+ {post.metadata.date.clone()} +
+
+ } +} + #[component] pub fn PostList() -> impl IntoView { - let posts = create_resource(|| (), |_| get_posts()); + let query = use_query_map(); + let tag = move || query.with(|query| query.get("tag").cloned()); + let posts = create_resource(move || tag(), move |_| get_posts(tag())); let posts_view = move || { posts.and_then(|posts| { posts.iter() - .map(|post| view! { - - format!("Image - - { - if post.metadata.draft { - Some(view!{ -
- -
- }) - } else { - None - } - } - -
-

{post.metadata.title.clone()}

-

{post.metadata.description.clone()}

- {post.metadata.date.clone()} -
-
- }) + .map(|post| view! { }) .collect_view() }) }; + let title = move || match tag() { + Some(tag) => view! { }, + None => view! { <Title href="/".to_string() title="Posts".to_string()/> } + }; + view! { <Suspense fallback=move || view! { <Loading title="Chargement des posts...".to_string() /> }> <main class="posts"> - <Title href="/".to_string() title="Posts".to_string()/> + { title } <div class="posts__cards">{posts_view}</div> </main> @@ -101,6 +135,7 @@ pub fn PostElement() -> impl IntoView { view! { <> <Title href="/posts".to_string() title=post.metadata.title.clone()/> + <PostTags tags=post.metadata.tags.clone()/> { if post.metadata.draft { Some(view!{ diff --git a/style/post.css b/style/post.css index d3823f5..0c7355e 100644 --- a/style/post.css +++ b/style/post.css @@ -42,13 +42,21 @@ & ol li { @apply list-decimal list-inside; } + + & blockquote { + @apply border-l-4 border-primary/50 dark:border-dark_primary/50 pl-3 my-3; + } + + & .tags_list { + @apply flex flex-row flex-wrap gap-2; + } } .posts { & > .posts__cards { @apply grid grid-cols-1 gap-5 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 m-5; - & > a { + & > div { @apply rounded-xl overflow-hidden relative; @apply bg-primary/10 dark:bg-dark_primary/10; @apply shadow-md shadow-primary/5 dark:shadow-dark_primary/5;