Skip to content

Commit e47dfcc

Browse files
committed
fix: restore github repositories dynamic listing and event clickability
1 parent faa076b commit e47dfcc

2 files changed

Lines changed: 99 additions & 72 deletions

File tree

src/components/sections/WorkSection.tsx

Lines changed: 97 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
import { community } from "@/config/community";
22
import { useI18n } from "@/i18n/useI18n.ts";
33
import { translations } from "@/i18n/translations";
4-
import { ChevronLeft, ChevronRight } from "lucide-react";
4+
import { ExternalLink, ChevronLeft, ChevronRight, Star } from "lucide-react";
5+
import { Badge } from "@/components/ui/badge";
56
import { motion, AnimatePresence } from "framer-motion";
67
import { useState, useEffect, useCallback, useRef } from "react";
8+
import { useGithubRepositories } from "@/hooks/useGithubRepositories";
79

810
const WorkSection = () => {
911
const { t, locale } = useI18n();
10-
const configEvents = community.events;
12+
const { projects, loading } = useGithubRepositories();
13+
const configEvents = community.events as readonly ({ readonly image: string; readonly link?: string })[];
1114
const events = translations[locale].events.items as readonly { title: string; date: string; description: string }[];
1215

1316
const [current, setCurrent] = useState(0);
@@ -69,71 +72,82 @@ const WorkSection = () => {
6972
{t("work.title")}
7073
</motion.h2>
7174

72-
{/* Projects — commented out until ready to announce */}
73-
{/*
74-
{community.projects.map((project, i) => (
75-
<motion.div
76-
key={project.title}
77-
initial={{ opacity: 0, y: 30 }}
78-
whileInView={{ opacity: 1, y: 0 }}
79-
viewport={{ once: true }}
80-
transition={{ duration: 0.5, delay: i * 0.1 }}
81-
className="group relative flex flex-col rounded-xl border border-border bg-card p-6 transition-all duration-300 hover:border-foreground/20"
82-
>
83-
<div className="mb-3 flex items-start justify-between">
84-
<h3 className="text-lg font-semibold text-foreground">{project.title}</h3>
85-
{project.link && (
86-
<a href={project.link} target="_blank" rel="noopener noreferrer" className="text-muted-foreground transition-colors hover:text-foreground">
87-
<ExternalLink className="h-4 w-4" />
88-
</a>
89-
)}
90-
</div>
91-
<p className="mb-4 flex-1 text-sm text-muted-foreground">{project.description}</p>
92-
<div className="flex flex-wrap gap-2">
93-
{project.tags.map((tag) => (
94-
<Badge key={tag} variant="secondary" className="border-border bg-secondary text-muted-foreground text-xs">
95-
{tag}
96-
</Badge>
97-
))}
98-
</div>
99-
</motion.div>
100-
))}
101-
*/}
102-
<div className="grid grid-cols-1 gap-6 md:grid-cols-2 mb-8">
103-
{[0, 1, 2, 3].map((i) => (
104-
<motion.div
105-
key={i}
106-
initial={{ opacity: 0, y: 30 }}
107-
whileInView={{ opacity: 1, y: 0 }}
108-
viewport={{ once: true }}
109-
transition={{ duration: 0.5, delay: i * 0.1 }}
110-
className="group relative flex flex-col rounded-xl border border-border bg-card p-6"
111-
>
112-
<div className="mb-3 flex items-start justify-between">
113-
<div className="h-4 w-2/5 rounded bg-border/60" />
114-
<div className="h-4 w-4 rounded bg-border/40" />
115-
</div>
116-
<div className="mb-2 h-3 w-full rounded bg-border/30" />
117-
<div className="mb-4 h-3 w-4/5 rounded bg-border/30" />
118-
<div className="flex gap-2">
119-
<div className="h-5 w-14 rounded-full bg-border/40" />
120-
<div className="h-5 w-14 rounded-full bg-border/40" />
121-
<div className="h-5 w-14 rounded-full bg-border/40" />
122-
</div>
123-
</motion.div>
124-
))}
125-
</div>
126-
127-
<motion.div
128-
initial={{ opacity: 0, y: 20 }}
129-
whileInView={{ opacity: 1, y: 0 }}
130-
viewport={{ once: true }}
131-
transition={{ duration: 0.6 }}
132-
className="mb-16 flex flex-col items-center gap-1 text-center"
133-
>
134-
<p className="text-base font-semibold text-foreground">{t("projects.stayTuned")}</p>
135-
<p className="text-sm text-muted-foreground">{t("projects.stayTunedSub")}</p>
136-
</motion.div>
75+
{/* Projects from GitHub */}
76+
{loading ? (
77+
<div className="grid grid-cols-1 gap-6 md:grid-cols-2 mb-8">
78+
{[0, 1, 2, 3].map((i) => (
79+
<motion.div
80+
key={i}
81+
initial={{ opacity: 0, y: 30 }}
82+
whileInView={{ opacity: 1, y: 0 }}
83+
viewport={{ once: true }}
84+
transition={{ duration: 0.5, delay: i * 0.1 }}
85+
className="group relative flex flex-col rounded-xl border border-border bg-card p-6"
86+
>
87+
<div className="mb-3 flex items-start justify-between">
88+
<div className="h-4 w-2/5 rounded bg-border/60" />
89+
<div className="h-4 w-4 rounded bg-border/40" />
90+
</div>
91+
<div className="mb-2 h-3 w-full rounded bg-border/30" />
92+
<div className="mb-4 h-3 w-4/5 rounded bg-border/30" />
93+
<div className="flex gap-2">
94+
<div className="h-5 w-14 rounded-full bg-border/40" />
95+
<div className="h-5 w-14 rounded-full bg-border/40" />
96+
<div className="h-5 w-14 rounded-full bg-border/40" />
97+
</div>
98+
</motion.div>
99+
))}
100+
</div>
101+
) : projects.length > 0 ? (
102+
<div className="grid grid-cols-1 gap-6 md:grid-cols-2 mb-8">
103+
{projects.map((project, i) => (
104+
<motion.a
105+
href={project.link}
106+
target="_blank"
107+
rel="noopener noreferrer"
108+
key={project.id}
109+
initial={{ opacity: 0, y: 30 }}
110+
whileInView={{ opacity: 1, y: 0 }}
111+
viewport={{ once: true }}
112+
transition={{ duration: 0.5, delay: i * 0.1 }}
113+
className="group relative flex flex-col rounded-xl border border-border bg-card p-6 transition-all duration-300 hover:border-foreground/20 hover:shadow-lg"
114+
>
115+
<div className="mb-3 flex items-start justify-between">
116+
<h3 className="text-lg font-semibold text-foreground max-w-xs">{project.title}</h3>
117+
<ExternalLink className="h-4 w-4 text-muted-foreground transition-colors group-hover:text-foreground flex-shrink-0" />
118+
</div>
119+
<p className="mb-4 flex-1 text-sm text-muted-foreground line-clamp-2">{project.description}</p>
120+
121+
<div className="flex items-center justify-between">
122+
<div className="flex flex-wrap gap-2">
123+
{project.tags.slice(0, 3).map((tag) => (
124+
<Badge key={tag} variant="secondary" className="border-border bg-secondary text-muted-foreground text-xs">
125+
{tag}
126+
</Badge>
127+
))}
128+
</div>
129+
{project.stars > 0 && (
130+
<div className="flex items-center gap-1 ml-2 text-xs text-muted-foreground">
131+
<Star className="h-3 w-3" fill="currentColor" />
132+
<span>{project.stars}</span>
133+
</div>
134+
)}
135+
</div>
136+
</motion.a>
137+
))}
138+
</div>
139+
) : (
140+
<motion.div
141+
initial={{ opacity: 0, y: 20 }}
142+
whileInView={{ opacity: 1, y: 0 }}
143+
viewport={{ once: true }}
144+
transition={{ duration: 0.6 }}
145+
className="mb-16 flex flex-col items-center gap-1 text-center"
146+
>
147+
<p className="text-base font-semibold text-foreground">{t("projects.stayTuned")}</p>
148+
<p className="text-sm text-muted-foreground">{t("projects.stayTunedSub")}</p>
149+
</motion.div>
150+
)}
137151

138152
{/* Events subtitle */}
139153
<motion.h3
@@ -157,15 +171,28 @@ const WorkSection = () => {
157171
animate="center"
158172
exit="exit"
159173
transition={{ duration: 0.4, ease: "easeInOut" }}
160-
className="flex flex-col md:flex-row"
174+
className="flex flex-col md:flex-row cursor-pointer group"
175+
onClick={() => {
176+
if (event.link) {
177+
window.open(event.link, '_blank', 'noopener,noreferrer');
178+
}
179+
}}
161180
>
162-
<div className="relative h-56 w-full md:h-auto md:w-1/2 shrink-0">
181+
<div className="relative h-56 w-full md:h-auto md:w-1/2 shrink-0 overflow-hidden">
163182
<img
164183
src={event.image}
165184
alt={translated?.title ?? ""}
166-
className="h-full w-full object-cover"
185+
className="h-full w-full object-cover transition-transform duration-300 group-hover:scale-105"
167186
loading="lazy"
168187
/>
188+
{event.link && (
189+
<div className="absolute inset-0 flex items-center justify-center bg-black/0 transition-colors duration-300 group-hover:bg-black/30 flex-col gap-2">
190+
<ExternalLink className="h-6 w-6 text-white opacity-0 transition-opacity duration-300 group-hover:opacity-100" />
191+
<span className="text-white text-sm font-semibold opacity-0 transition-opacity duration-300 group-hover:opacity-100">
192+
{t("common.viewMore") || "View More"}
193+
</span>
194+
</div>
195+
)}
169196
</div>
170197
<div className="flex flex-col justify-center p-6 md:p-10 flex-1">
171198
<span className="mb-2 text-xs font-medium uppercase tracking-widest text-muted-foreground">

src/config/community.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export const community = {
3030
{ name: "João Vitor", role: "Design and Branding Lead", photo: "https://avatars.githubusercontent.com/u/141349338?v=4", socials: { linkedin: "https://www.linkedin.com/in/joaovitor-reis/", github: "https://github.com/jotavedreis", instagram: "https://www.instagram.com/jotave_dev/" } },
3131
{ name: "Thaylan Fonseca", role: "Events and Workshops Lead", photo: "https://avatars.githubusercontent.com/u/196565378?v=4", socials: { linkedin: "https://www.linkedin.com/in/thaylanbf1/", github: "https://github.com/thaylanbf1", instagram: "" } },
3232
{ name: "Ryan Ricardo", role: "Partnership Lead", photo: "https://avatars.githubusercontent.com/u/140509330?v=4", socials: { linkedin: "https://www.linkedin.com/in/theunrealryan/", github: "https://github.com/theunrealryan", instagram: "" } },
33-
{ name: "Ryan Santana", role: "Community Manager", photo: "/public/photos/foto-ryansantana.jpg", socials: { linkedin: "https://www.linkedin.com/in/ryan-souza-santana-785a09293/", github: "https://github.com/Ryan-S-S", instagram: "" } },
33+
{ name: "Ryan Santana", role: "Community Manager", photo: "/photos/foto-ryansantana.jpg", socials: { linkedin: "https://www.linkedin.com/in/ryan-souza-santana-785a09293/", github: "https://github.com/Ryan-S-S", instagram: "" } },
3434
{ name: "Luis Felipe", role: "Tech Lead", photo: "/photos/foto-luisfelipe.jpg", socials: { linkedin: "https://www.linkedin.com/in/luis-mendes-66b245380/", github: "https://github.com/MendesFl", instagram: "https://www.instagram.com/mendes_.lfy/" } },
3535
{ name: "Lucas Rego", role: "Product Lead", photo: "/photos/foto-lucasrego.jpg", socials: { linkedin: "https://www.linkedin.com/in/lucas-rego-conduru-649a5a364/", github: "", instagram: ""} },
3636
{ name: "Suziane Silva", role: "Developer", photo: "/photos/foto-suzianesilva.jpg", socials: { linkedin: "https://www.linkedin.com/in/suziane-silva-610011256/", github: "", instagram: ""} },
@@ -45,7 +45,7 @@ export const community = {
4545
],
4646

4747
events: [
48-
{ image: "/public/photos/first-meetup-aws-cloud-club.jpg", link: "https://www.linkedin.com/posts/awscc-uepa_nosso-primeiro-encontro-da-aws-cloud-club-activity-7439630918862020608-w1eJ?utm_source=share&utm_medium=member_desktop&rcm=ACoAADxdpsABhdAEhrf1CtXAT6ZnC2jAKh-ruN4" },
48+
{ image: "/photos/first-meetup-aws-cloud-club.jpg", link: "https://www.linkedin.com/posts/awscc-uepa_nosso-primeiro-encontro-da-aws-cloud-club-activity-7439630918862020608-w1eJ?utm_source=share&utm_medium=member_desktop&rcm=ACoAADxdpsABhdAEhrf1CtXAT6ZnC2jAKh-ruN4" },
4949
],
5050

5151
partners: [

0 commit comments

Comments
 (0)