use leptos::*; use leptos_router::*; use crate::app::{ models::Post, components::{ Title, Loading } }; #[server] pub async fn get_posts() -> Result, ServerFnError> { let posts = Post::get_all("posts") .map_err(|e| ServerFnError::ServerError(e.to_string()))?; Ok(posts) } #[server] pub async fn get_post( slug: String ) -> Result { let posts = Post::get_all("posts") .map_err(|e| ServerFnError::ServerError(e.to_string()))?; let post = posts.into_iter().find(|post| post.slug == slug) .ok_or(ServerFnError::ServerError("Post not found".to_string()))?; Ok(post) } #[component] pub fn PostList() -> impl IntoView { let posts = create_resource(|| (), |_| get_posts()); let posts_view = move || { posts.and_then(|posts| { posts.iter() .map(|post| view! { format!("Image

{post.metadata.title.clone()}

{post.metadata.description.clone()}

{post.metadata.date.clone()}
}) .collect_view() }) }; view! { }>
<div class="posts__cards">{posts_view}</div> </main> </Suspense> } } #[component] pub fn PostElement() -> impl IntoView { let params = use_params_map(); let slug = move || params.with(|params| params.get("slug").cloned().unwrap_or_default()); let post = create_resource(|| (), move |_| get_post(slug())); let post_view = move || { post.and_then(|post| { view! { <> <Title href="/posts".to_string() title=post.metadata.title.clone()/> { if post.metadata.draft { Some(view!{ <div class="bg-warning text-on_warning dark:bg-dark_warning dark:text-dart_on_warning rounded-md p-5"> r#" L'article est en cours d'écriture. La formulation peut ne pas être exacte et les phrases peuvent contenir des fautes. "# </div> }) } else { None } } <div inner_html={post.content.clone()}></div> </> } }) }; view! { <Suspense fallback=move || view! { <Loading title="Chargement du post...".to_string() /> }> <main class="post"> {post_view} <script>load();</script> </main> </Suspense> } }