Skip to content

Commit b2175ad

Browse files
davcorteznsandoyaIvanM9bjgavilanes
authored
Feat: Event Details page (#47)
* Add event details page * Add button to redir to event detail page by id * refactor: Change banner image and adjust height * style: adjust the bottom padding of the parent container on the event page * style: adjust padding on events page * refactor!: Implement UI enhancements in `[id].astro` Reorganized page's layout, aiming a more responsive page: - Changed grid layout in main containers - Modified padding values, and text sizes Also, relocated event image into page's main card to avoid visual distortion when using the events images (due each community has their own graphic design workflow). This change is also an effort to merge this contribution style and the latest design proposal for this page * refactor!: Migrate CSS styles to Tailwind classes - Relocated all event details page styles into `globals.css` - Migrate CSS styles to Tailwind classes, due nested CSS styles were ignored by Astro * feat: Add `longDescription` field to `events.json` - `longDescription` field was created in `events.json` - Event interface was updated - `longDescription` was incorporated in `event/[id].astro` About section --------- Co-authored-by: nsandoya <[email protected]> Co-authored-by: Iván Manzaba <[email protected]> Co-authored-by: Brayen Gavilanes <[email protected]>
1 parent 8d09bd1 commit b2175ad

File tree

8 files changed

+388
-90
lines changed

8 files changed

+388
-90
lines changed

public/banner_events.png

978 KB
Loading

src/assets/events.json

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,22 @@
33
"id": "path-to-impact-1",
44
"title": "Path to Impact: Agustina Scandogliero",
55
"description": "Estrategias para impulsar tu carrera en IT",
6-
"link": "https://ecuadorintech.org/events",
7-
"date": "2025-01-17",
6+
"longDescription": "Construir una carrera en el mundo tech es un camino tan desafiante como lleno de oportunidades. Path to impact es una serie de charlas pensadas para acompañarte en el proceso, ofreciendo estrategias y consejos prácticos para que puedas sobresalir y dejar tu marca en un sector competitivo, sin importar tu nivel de experiencia o área de especialización. Descubrirás las habilidades y perfiles en demanda en empresas tech, y aprenderás métodos y consejos prácticos para comunicar tu experiencia de forma auténtica y proactiva. Si estás dando tu primer paso en el mundo IT o buscando un cambio en tu carrera, esta serie es para ti. ¡Únete y transforma tu camino profesional!",
7+
"link": "https://forms.gle/BHCDTkGfGBH8Rio49",
8+
"date": "2025-01-17T18:00",
89
"place": "Online",
910
"modality": "Virtual",
1011
"hostedBy": "Ecuador In Tech",
1112
"image": "/path_to_impact_1.jpeg",
12-
"attendees": 31
13+
"attendees": 33
1314
},
1415
{
1516
"id": "git-github-workshop",
1617
"title": "Git & GitHub",
1718
"description": "Hands-on Workshop para iniciantes.",
18-
"link": "https://ecuadorintech.org/events",
19-
"date": "2024-12-4",
19+
"longDescription": "¿Interesado en el mundo tech pero no sabes por dónde empezar? ¡Este taller es para ti! Únete a nosotros para aprender los fundamentos de Git y GitHub, las herramientas esenciales para la colaboración en cualquier proyecto digital.",
20+
"link": "https://forms.gle/BHCDTkGfGBH8Rio49",
21+
"date": "2024-12-04T19:00",
2022
"place": "Online",
2123
"modality": "Virtual",
2224
"hostedBy": "Ecuador In Tech",

src/components/CardBase.astro

Lines changed: 49 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,49 @@
1-
---
2-
interface Props {
3-
title: string;
4-
description: string;
5-
image: string;
6-
modality?: string;
7-
}
8-
9-
const { title, image, modality, description } = Astro.props;
10-
---
11-
<div
12-
class="bg-white rounded-xl shadow-lg overflow-hidden hover:shadow-xl transition-shadow duration-300 cursor-pointer"
13-
>
14-
<div class="h-48 overflow-hidden relative">
15-
<img
16-
src={image}
17-
alt={title}
18-
class="w-full h-full object-cover transform hover:scale-105 transition-transform duration-300"
19-
/>
20-
{
21-
modality && (
22-
<div class="absolute top-4 right-4">
23-
<span
24-
class={`px-3 py-1 rounded-full text-sm font-semibold ${
25-
modality === "Hybrid"
26-
? "bg-purple-100 text-purple-800"
27-
: modality === "Virtual"
28-
? "bg-green-100 text-green-800"
29-
: "bg-blue-100 text-blue-800"
30-
}`}
31-
>
32-
{modality}
33-
</span>
34-
</div>
35-
)
36-
}
37-
</div>
38-
<div class="p-6">
39-
<!-- Title and description -->
40-
<div class="flex flex-col">
41-
<div class="flex justify-between items-start mb-3">
42-
<h2 class="text-xl font-bold text-gray-800">{title}</h2>
43-
</div>
44-
<p class="text-gray-600 mb-4 line-clamp-2">{description}</p>
45-
</div>
46-
<!-- Custom info -->
47-
<slot />
48-
</div>
49-
</div>
1+
---
2+
interface Props {
3+
title: string;
4+
description: string;
5+
image: string;
6+
modality?: string;
7+
}
8+
9+
const { title, image, modality, description } = Astro.props;
10+
---
11+
<div
12+
class="bg-white rounded-xl shadow-lg overflow-hidden hover:shadow-xl transition-shadow duration-300"
13+
>
14+
<div class="h-48 overflow-hidden relative">
15+
<img
16+
src={image}
17+
alt={title}
18+
class="w-full h-full object-cover transform hover:scale-105 transition-transform duration-300"
19+
/>
20+
{
21+
modality && (
22+
<div class="absolute top-4 right-4">
23+
<span
24+
class={`px-3 py-1 rounded-full text-sm font-semibold ${
25+
modality === "Hybrid"
26+
? "bg-purple-100 text-purple-800"
27+
: modality === "Virtual"
28+
? "bg-green-100 text-green-800"
29+
: "bg-blue-100 text-blue-800"
30+
}`}
31+
>
32+
{modality}
33+
</span>
34+
</div>
35+
)
36+
}
37+
</div>
38+
<div class="p-6">
39+
<!-- Title and description -->
40+
<div class="flex flex-col">
41+
<div class="flex justify-between items-start mb-3">
42+
<h2 class="text-xl font-bold text-gray-800">{title}</h2>
43+
</div>
44+
<p class="text-gray-600 mb-4 line-clamp-2">{description}</p>
45+
</div>
46+
<!-- Custom info -->
47+
<slot />
48+
</div>
49+
</div>

src/components/CardEvent.astro

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,21 @@ import type { Event } from "../interfaces/events";
33
import CardBase from "./CardBase.astro";
44
55
const {
6-
title,
7-
description,
8-
link,
9-
date,
10-
place,
11-
modality,
12-
hostedBy,
13-
image,
14-
attendees,
6+
id,
7+
title,
8+
description,
9+
link,
10+
date,
11+
place,
12+
modality,
13+
hostedBy,
14+
image,
15+
attendees,
1516
} = Astro.props as Event;
1617
17-
const eventHeaderProps = { title, image, modality, description };
18+
const eventHeaderProps = { id, title, image, modality, description };
1819
---
20+
1921
<CardBase {...eventHeaderProps}>
2022
<!-- Event Date, Location and Atendees -->
2123
<div class="space-y-2 text-sm text-gray-500">
@@ -31,17 +33,17 @@ const eventHeaderProps = { title, image, modality, description };
3133
stroke-linejoin="round"
3234
stroke-width="2"
3335
d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"
34-
/>
36+
></path>
3537
</svg>
3638
<span>
3739
{
3840
new Date(date).toLocaleDateString("es", {
39-
weekday: "long",
40-
year: "numeric",
41-
month: "long",
42-
day: "numeric",
43-
timeZone: "ECT",
44-
})
41+
weekday: "long",
42+
year: "numeric",
43+
month: "long",
44+
day: "numeric",
45+
timeZone: "ECT",
46+
})
4547
}
4648
</span>
4749
</div>
@@ -57,13 +59,12 @@ const eventHeaderProps = { title, image, modality, description };
5759
stroke-linejoin="round"
5860
stroke-width="2"
5961
d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z"
60-
/>
62+
></path>
6163
<path
6264
stroke-linecap="round"
6365
stroke-linejoin="round"
6466
stroke-width="2"
65-
d="M15 11a3 3 0 11-6 0 3 3 0 016 0z"
66-
/>
67+
d="M15 11a3 3 0 11-6 0 3 3 0 016 0z"></path>
6768
</svg>
6869
<span>{place}</span>
6970
</div>
@@ -79,9 +80,27 @@ const eventHeaderProps = { title, image, modality, description };
7980
stroke-linejoin="round"
8081
stroke-width="2"
8182
d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"
82-
/>
83+
></path>
8384
</svg>
8485
<span>{attendees} attendees</span>
8586
</div>
87+
<a href={`/event/${id}`} class="details-button">View Details</a>
8688
</div>
8789
</CardBase>
90+
91+
<style>
92+
.details-button {
93+
display: inline-block;
94+
margin-top: 1rem;
95+
padding: 0.5rem 1rem;
96+
background-color: #2563eb;
97+
color: white;
98+
text-decoration: none;
99+
border-radius: 6px;
100+
transition: background-color 0.2s;
101+
}
102+
103+
.details-button:hover {
104+
background-color: #1d4ed8;
105+
}
106+
</style>

src/interfaces/events.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
export interface Event {
2+
id: string;
23
title: string;
34
description: string;
5+
longDescription: string;
46
link: string;
57
date: string;
68
place: string;

src/pages/event/[id].astro

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
---
2+
import Layout from "../../layouts/Layout.astro";
3+
import events from "../../assets/events.json";
4+
import banner from '../../../public/banner_events.png'
5+
6+
export function getStaticPaths() {
7+
return events.map(event => ({
8+
params: { id: event.id },
9+
props: { event },
10+
}));
11+
}
12+
13+
const { event } = Astro.props;
14+
15+
const formattedDate = new Date(event.date).toLocaleDateString('es-EC', {
16+
weekday: 'long',
17+
year: 'numeric',
18+
month: 'long',
19+
day: 'numeric'
20+
});
21+
22+
const formattedTime = new Date(event.date).toLocaleTimeString('es-EC', {
23+
hour: '2-digit',
24+
minute: '2-digit'
25+
});
26+
---
27+
28+
<Layout title={event.title}>
29+
<main class="event-main-card">
30+
<div class="event-hero">
31+
<img src={banner.src} alt={event.title} class="event-image" />
32+
<div class="event-overlay"></div>
33+
</div>
34+
35+
<div class="event-container">
36+
<div class="event-content">
37+
<nav class="breadcrumb" aria-label="breadcrumb">
38+
<a href="/events">Eventos</a>
39+
<span>/</span>
40+
<span>{event.title}</span>
41+
</nav>
42+
43+
<div class="event-header">
44+
<h1 class="event-header-title">{event.title}</h1>
45+
<p class="event-tagline">Organizado por <span class="host-name">{event.hostedBy}</span></p>
46+
</div>
47+
48+
<div class="event-grid ">
49+
<section class="event-ad">
50+
<img src={event.image} alt={event.title} class="rounded-xl">
51+
</section>
52+
53+
<section class="event-meta ">
54+
<div class="meta-item">
55+
<div class="meta-icon">📅</div>
56+
<div class="meta-content">
57+
<h3>Fecha y Hora</h3>
58+
<p>{formattedDate}</p>
59+
<p>{formattedTime}</p>
60+
</div>
61+
</div>
62+
63+
<div class="meta-item">
64+
<div class="meta-icon">📍</div>
65+
<div class="meta-content">
66+
<h3>Ubicación</h3>
67+
<p>{event.place}</p>
68+
</div>
69+
</div>
70+
71+
<div class="meta-item">
72+
<div class="meta-icon">👥</div>
73+
<div class="meta-content">
74+
<h3>Asistentes</h3>
75+
<p><span class="attendee-count">{event.attendees}</span> personas </p>
76+
</div>
77+
</div>
78+
79+
<aside class="event-sidebar">
80+
<div class="registration-card">
81+
<div class="card-content">
82+
<h3>¿Listo para unirte?</h3>
83+
84+
<p>Asegura tu lugar en este increíble evento</p>
85+
<a href={event.link} class="register-button" target="_blank" rel="noopener noreferrer">
86+
Inscríbete
87+
</a>
88+
<p class="registration-note">* Recibirás el link de acceso al registrarte</p>
89+
</div>
90+
</div>
91+
</aside>
92+
</section>
93+
94+
<section class="event-description">
95+
<h2 class="">Acerca de este evento</h2>
96+
<p>{event.longDescription}</p>
97+
</section>
98+
99+
100+
</div>
101+
</div>
102+
</div>
103+
</main>
104+
</Layout>

src/pages/events.astro

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
---
2-
import events from "../assets/events.json";
3-
import CardEvent from "../components/CardEvent.astro";
4-
import type { Event } from "../interfaces/events";
5-
import Layout from "../layouts/Layout.astro";
6-
---
7-
8-
<Layout title="Events - Ecuador In Tech">
9-
<div class="container mx-auto px-4 py-12" x-data="{ selectedEvent: null }">
10-
<h1 class="text-4xl font-bold mb-8">Eventos</h1>
11-
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
12-
{events.map((event: Event, index) => <CardEvent {...event} />)}
13-
</div>
14-
</div>
15-
</Layout>
1+
---
2+
import events from "../assets/events.json";
3+
import CardEvent from "../components/CardEvent.astro";
4+
import type { Event } from "../interfaces/events";
5+
import Layout from "../layouts/Layout.astro";
6+
---
7+
8+
<Layout title="Events - Ecuador In Tech">
9+
<div class="container mx-auto px-4 py-20" x-data="{ selectedEvent: null }">
10+
<h1 class="text-4xl font-bold mb-8">Eventos</h1>
11+
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
12+
{events.map((event: Event, index) => <CardEvent {...event} />)}
13+
</div>
14+
</div>
15+
</Layout>

0 commit comments

Comments
 (0)