Skip to content

Commit

Permalink
refactor: move the cards showed in home page to a component
Browse files Browse the repository at this point in the history
  • Loading branch information
Phosphorus-M committed Dec 7, 2023
1 parent 385af89 commit 592f0ae
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 109 deletions.
103 changes: 103 additions & 0 deletions src/components/card_article.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
use crate::{
components::{icons::StrToIcon, markdown_render::MarkdownRender},
models::article::Article,
};
use leptos::{component, view, CollectView, IntoAttribute, IntoView};

#[component]
pub fn CardArticle(article: Article, is_home: bool) -> impl IntoView {
let article_link = get_link(&article, is_home);
let description = get_description(&article);

view! {
<>
<li class="group flex flex-col gap-y-1 border border-black p-2 sm:p-6 bg-orange-200 hover:bg-[#fdc686] drop-shadow-[0_0_0_rgba(0,0,0)] hover:drop-shadow-[-4px_-4px_0_rgba(0,0,0)] transition justify-between">
<a href=article_link.clone()>
<h3 class="text-xl font-semibold">{article.title}</h3>
</a>
<p>{article.date_string}</p>
<div class="text-sm markdown-container">
<MarkdownRender content=description/>
</div>
<div>
<span class="pt-4 font-bold">Tags:</span>
<TagsList tags=article.tags/>
</div>
<div class="flex justify-end items-end">
<a
class="bg-orange-500 hover:bg-orange-600 text-white font-semibold py-2 px-4 rounded flex items-center justify-between gap-2"
href=article_link
>
"Leer más"
<StrToIcon v="next" class="fill-white" size=16/>
</a>
</div>
</li>
</>
}
}

fn get_link(article: &Article, is_home: bool) -> String {
if is_home {
format!("./articles/{}.html", article.slug)
} else {
format!("./../articles/{}.html", article.slug)
}
}

fn get_description(article: &Article) -> String {
if article.description.is_empty() {
let binding = article.content.clone();
let mut content = binding
.split('\n')
.take(3)
.collect::<Vec<&str>>()
.join("\n");
if content.len() > 190 {
content = content[0..190].to_string();
content.push_str("...");
}
content
} else {
article.description.clone()
}
}

#[component]
pub fn TagsList(tags: Option<Vec<String>>) -> impl IntoView {
let tags = tags.unwrap_or_default();

view! {
<ul class="flex gap-1 py-4">
{tags.into_iter().map(|tag| TagButton(tag.into())).collect_view()}
</ul>
}
}

#[component]
pub fn TagButton(tag: String) -> impl IntoView {
let tag = tag.to_lowercase().replace(' ', "-");

view! {
<li class="inline-block text-sm font-bold text-orange-500 hover:text-orange-600">
<a
class="inline-block bg-white rounded-md p-1 drop-shadow-sm px-2"
href=format!("./tags/{}.html", tag)
>
{tag}
</a>
</li>
}
}

impl From<String> for TagButtonProps {
fn from(tag: String) -> Self {
TagButtonProps { tag }
}
}

impl From<(Article, bool)> for CardArticleProps {
fn from((article, is_home): (Article, bool)) -> Self {
CardArticleProps { article, is_home }
}
}
33 changes: 33 additions & 0 deletions src/components/markdown_render.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use leptos::*;
use leptos_mdx::mdx::{Components, Mdx, MdxComponentProps};

use crate::components::mdx::{
center::{Center, CenterProps},
youtube::{Youtube, YoutubeProps},
};

#[component]
pub fn MarkdownRender(content: String) -> impl IntoView {
let mut components = Components::new();
components.add_props(
"youtube".to_string(),
Youtube,
|props: MdxComponentProps| {
let video_id = props.attributes.get("video").unwrap().clone();
YoutubeProps {
video: video_id.unwrap(),
}
},
);
components.add_props("center".to_string(), Center, |props: MdxComponentProps| {
CenterProps {
children: props.children,
}
});

view! {
<>
<Mdx source=content components=components/>
</>
}
}
2 changes: 2 additions & 0 deletions src/components/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ pub mod icons;
pub mod layout;
pub mod mdx;

pub mod card_article;
pub mod feature_articles;
pub mod markdown_render;
112 changes: 3 additions & 109 deletions src/pages/home.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,14 @@
use crate::{
async_component::Async,
components::{
feature_articles::featured_articles,
icons::StrToIcon,
layout::Layout,
mdx::{
center::{Center, CenterProps},
youtube::{Youtube, YoutubeProps},
},
card_article::CardArticle, feature_articles::featured_articles, layout::Layout,
pagination_buttons::PaginationButtons,
},
models::article::Article,
ARTICLES,
};
use futures::executor::block_on;
use leptos::{component, view, CollectView, IntoAttribute, IntoView};
use leptos_mdx::mdx::{Components, Mdx, MdxComponentProps};
use leptos::{component, view, CollectView, IntoView};

async fn fetch_articles() -> Vec<Article> {
ARTICLES.read().await.clone()
Expand Down Expand Up @@ -83,106 +76,7 @@ fn grid_of_articles(articles: Vec<Article>, is_home: bool) -> impl IntoView {

view! {
<div class="grid sm:grid-cols-2 lg:grid-cols-3 sm:gap-x-8 gap-y-8 pb-5">
{articles
.map(|article| {
let description = if article.description.is_empty() {
let binding = article.content;
let mut content = binding
.split('\n')
.take(3)
.collect::<Vec<&str>>()
.join("\n");
if content.len() > 190 {
content = content[0..190].to_string();
content.push_str("...");
}
content
} else {
article.description.clone()
};
let mut components = Components::new();
components
.add_props(
"youtube".to_string(),
Youtube,
|props: MdxComponentProps| {
let video_id = props.attributes.get("video").unwrap().clone();
YoutubeProps {
video: video_id.unwrap(),
}
},
);
components
.add_props(
"center".to_string(),
Center,
|props: MdxComponentProps| {
CenterProps {
children: props.children,
}
},
);
view! {
<li class="group flex flex-col gap-y-1 border border-black p-2 sm:p-6 bg-orange-200 hover:bg-[#fdc686] drop-shadow-[0_0_0_rgba(0,0,0)] hover:drop-shadow-[-4px_-4px_0_rgba(0,0,0)] transition justify-between">
<a href=if is_home {
format!("./articles/{}.html", article.slug)
} else {
format!("./../articles/{}.html", article.slug)
}>
<h3 class="text-xl font-semibold">{article.title}</h3>
</a>
<p>{article.date_string}</p>
<div class="text-sm markdown-container">
<Mdx source=description components=components/>
</div>
<div>
<span class="pt-4 font-bold">Tags:</span>
<ul class="flex gap-1 py-4">
{article
.tags
.unwrap_or_default()
.into_iter()
.map(|tag| {
let tag = tag.to_lowercase().replace(' ', "-");
view! {
<>
<li class="inline-block text-sm font-bold text-orange-500 hover:text-orange-600">
<a
class="inline-block bg-white rounded-md p-1 drop-shadow-sm px-2"
href=if is_home {
format!("./tags/{}.html", tag)
} else {
format!("./../tags/{}.html", tag)
}
>

{tag}
</a>
</li>
</>
}
})
.collect_view()}
</ul>
</div>
<div class="flex justify-end items-end">
<a
class="bg-orange-500 hover:bg-orange-600 text-white font-semibold py-2 px-4 rounded flex items-center justify-between gap-2"
href=if is_home {
format!("./articles/{}.html", article.slug)
} else {
format!("./../articles/{}.html", article.slug)
}
>

"Leer más"
<StrToIcon v="next" class="fill-white" size=16/>
</a>
</div>
</li>
}
})
.collect_view()}
{articles.map(|article| CardArticle((article, is_home).into())).collect_view()}
</div>
}
}
Expand Down

0 comments on commit 592f0ae

Please sign in to comment.