103 lines
No EOL
3.3 KiB
Rust
103 lines
No EOL
3.3 KiB
Rust
use leptos::*;
|
|
use leptos_router::*;
|
|
use crate::app::{
|
|
models::Post,
|
|
components::{
|
|
Title, Loading
|
|
}
|
|
};
|
|
|
|
#[server]
|
|
pub async fn get_posts() -> Result<Vec<Post>, 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<Post, ServerFnError> {
|
|
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! {
|
|
<a href=format!("posts/{}", post.slug.clone())>
|
|
<img src={post.metadata.image_path.clone()} alt=format!("Image {}", post.metadata.title)/>
|
|
|
|
<div>
|
|
<h2>{post.metadata.title.clone()}</h2>
|
|
<p>{post.metadata.description.clone()}</p>
|
|
<span>{post.metadata.date.clone()}</span>
|
|
</div>
|
|
</a>
|
|
})
|
|
.collect_view()
|
|
})
|
|
};
|
|
|
|
view! {
|
|
<Suspense fallback=move || view! { <Loading title="Chargement des posts...".to_string() /> }>
|
|
<main class="posts">
|
|
<Title href="/".to_string() title="Posts".to_string()/>
|
|
|
|
<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>
|
|
}
|
|
} |