Skip to content

Commit 1ec8ba3

Browse files
committed
feat: add location, description and twitter of the user
1 parent 2d92428 commit 1ec8ba3

File tree

8 files changed

+110
-9
lines changed

8 files changed

+110
-9
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ playwright/.cache/
2020
pnpm-lock.yaml
2121
.idea/
2222
settings.json
23+
style/

Cargo.lock

+3-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ console_log = { version = "1"}
1818
console_error_panic_hook = { version = "0.1"}
1919
rand = "0.8.5"
2020
mod_use = "0.2.1"
21+
futures = "0.3.28"
2122

2223
[dev-dependencies]
2324
rusty-hook = "^0.11.2"

src/components/cards/contributor_card.rs

+33-6
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,55 @@
11
use leptos::*;
22

3-
use crate::components::icons::GithubIcon;
3+
use crate::components::icons::{GithubIcon, TwitterIcon, LocationIcon};
44

55
#[component]
66
pub fn ContributorCard(
77
#[prop(into)] name: String,
8-
#[prop(into)] description: String,
8+
#[prop(into)] description: Option<String>,
9+
#[prop(into)] twitter: Option<String>,
10+
#[prop(into)] location: Option<String>,
911
#[prop(into)] link: String,
1012
#[prop(into)] brand_src: String,
1113
) -> impl IntoView {
14+
1215
view! {
1316
<article>
1417
<a
15-
href=link
18+
href=link.clone()
1619
target="_blank"
17-
class="group flex flex-col gap-y-6 border border-black p-6 hover:bg-orange-500 bg-orange-100 drop-shadow-[0_0_0_rgba(0,0,0)] hover:drop-shadow-[-4px_-4px_0_rgba(0,0,0)] transition justify-between h-full"
20+
class="group flex flex-col gap-y-6 border border-black p-4 hover:bg-orange-500 bg-orange-100 drop-shadow-[0_0_0_rgba(0,0,0)] hover:drop-shadow-[-4px_-4px_0_rgba(0,0,0)] transition justify-between h-full"
1821
>
1922
<div class="flex flex-col gap-y-2">
2023
<img src=brand_src width="60" class="rounded-full mb-4" alt=name.clone()/>
2124
<h2 class="font-work-sans text-black text-xl">{name.clone()}</h2>
25+
{if let Some(location) = location.clone() {
26+
view! {
27+
<div class="flex gap-2 items-center bg-slate-200/20 rounded-md p-1">
28+
<LocationIcon size=16/>
29+
<p class="font-work-sans text-black text-sm">{location}</p>
30+
</div>
31+
}
32+
} else {
33+
view! { <div class="hidden"></div> }
34+
}}
35+
2236
<p class="font-work-sans text-black">{description}</p>
2337
</div>
24-
<span class="ml-auto">
25-
<GithubIcon size=30/>
38+
<span class="ml-auto flex">
39+
{if let Some(twitter) = twitter {
40+
view! {
41+
<div>
42+
<a href=format!("https://twitter.com/{}", twitter) target="_blank">
43+
<TwitterIcon size=30/>
44+
</a>
45+
</div>
46+
}
47+
} else {
48+
view! { <div></div> }
49+
}}
50+
<a href=link.clone() target="_blank">
51+
<GithubIcon size=30/>
52+
</a>
2653
</span>
2754
</a>
2855
</article>

src/components/icons/location_icon.rs

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
2+
use leptos::*;
3+
4+
#[component]
5+
pub fn LocationIcon(
6+
#[prop(default = 40)] size: u32,
7+
#[prop(default = "fill-black")] class: &'static str,
8+
) -> impl IntoView {
9+
view! {
10+
<svg
11+
width=size
12+
height=size
13+
viewBox="0 0 16 16"
14+
class=class
15+
xmlns="http://www.w3.org/2000/svg"
16+
>
17+
<path d="m12.596 11.596-3.535 3.536a1.5 1.5 0 0 1-2.122 0l-3.535-3.536a6.5 6.5 0 1 1 9.192-9.193 6.5 6.5 0 0 1 0 9.193Zm-1.06-8.132v-.001a5 5 0 1 0-7.072 7.072L8 14.07l3.536-3.534a5 5 0 0 0 0-7.072ZM8 9a2 2 0 1 1-.001-3.999A2 2 0 0 1 8 9Z"></path>
18+
</svg>
19+
}
20+
}

src/components/icons/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,7 @@ mod_use![
44
discord_icon,
55
github_icon,
66
telegram_icon,
7+
twitter_icon,
8+
location_icon,
79
next
810
];

src/components/icons/twitter_icon.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
use leptos::*;
2+
3+
#[component]
4+
pub fn TwitterIcon(
5+
#[prop(default = 40)] size: u32,
6+
#[prop(default = "fill-black")] class: &'static str,
7+
) -> impl IntoView {
8+
view! {
9+
<svg
10+
width=size
11+
height=size
12+
viewBox="0 0 512 512"
13+
class=class
14+
xmlns="http://www.w3.org/2000/svg"
15+
>
16+
<path d="M160.768 460.8c193.126 0 298.803-160.154 298.803-298.803 0-4.506 0-9.011-.205-13.517 20.48-14.746 38.298-33.382 52.43-54.477-18.842 8.397-39.118 13.927-60.417 16.589 21.709-12.902 38.298-33.587 46.285-58.163-20.275 12.083-42.803 20.685-66.765 25.395-19.251-20.48-46.49-33.178-76.595-33.178-57.958 0-105.062 47.104-105.062 105.063 0 8.192 1.024 16.179 2.662 23.961-87.245-4.3-164.66-46.284-216.474-109.772-9.01 15.564-14.13 33.587-14.13 52.838 0 36.454 18.636 68.608 46.694 87.45a106.224 106.224 0 01-47.514-13.108v1.434c0 50.79 36.25 93.389 84.173 103.014-8.807 2.458-18.023 3.687-27.648 3.687-6.759 0-13.312-.615-19.661-1.843 13.312 41.779 52.224 72.09 98.1 72.908-36.046 28.263-81.306 45.056-130.458 45.056-8.397 0-16.794-.41-24.986-1.433C46.285 443.392 101.58 460.8 160.768 460.8"></path>
17+
</svg>
18+
}
19+
}

src/pages/contributors.rs

+31-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use futures::future::join_all;
12
use leptos::{error::Result, *};
23
use serde::{Deserialize, Serialize};
34

@@ -8,6 +9,9 @@ pub struct Contributor {
89
login: String,
910
avatar_url: String,
1011
html_url: String,
12+
bio: Option<String>,
13+
twitter_username: Option<String>,
14+
location: Option<String>,
1115
}
1216

1317
async fn fetch_contributors() -> Result<Vec<Contributor>> {
@@ -18,6 +22,30 @@ async fn fetch_contributors() -> Result<Vec<Contributor>> {
1822
.await?
1923
.json::<Vec<Contributor>>()
2024
.await?;
25+
26+
let response = join_all(
27+
response
28+
.into_iter()
29+
.map(|contributor| fetch_contributor_info(contributor.login.clone())),
30+
).await;
31+
32+
let response = response
33+
.into_iter()
34+
.filter_map(|contributor| contributor.ok())
35+
.collect::<Vec<Contributor>>();
36+
37+
Ok(response)
38+
}
39+
40+
async fn fetch_contributor_info(username: String) -> Result<Contributor> {
41+
let response = reqwasm::http::Request::get(&format!(
42+
"https://api.github.com/users/{}",
43+
username
44+
))
45+
.send()
46+
.await?
47+
.json::<Contributor>()
48+
.await?;
2149
Ok(response)
2250
}
2351

@@ -28,9 +56,11 @@ pub fn Contributors() -> impl IntoView {
2856
view! {
2957
<ContributorCard
3058
name=item.login.clone()
31-
description=""
59+
description=item.bio.clone()
3260
link=item.html_url.clone()
3361
brand_src=item.avatar_url.clone()
62+
twitter=item.twitter_username.clone()
63+
location=item.location.clone()
3464
/>
3565
}
3666
};

0 commit comments

Comments
 (0)