Skip to content

Commit fced844

Browse files
authored
Improve accessibility and SEO in components and pages (#72)
* feat: Improve accessibility and SEO in components and pages * feat: Improved links and added icons to the footer * feat: Refactor Carrousel component and improve accessibility with alt text
1 parent 0fa5788 commit fced844

File tree

14 files changed

+475
-182
lines changed

14 files changed

+475
-182
lines changed

src/components/CardBase.astro

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,29 @@ const { title, image, modality, description } = Astro.props;
1010
---
1111
<div
1212
class="bg-white rounded-xl shadow-lg overflow-hidden hover:shadow-xl transition-shadow duration-300"
13+
aria-labelledby={`card-title-${title.toLowerCase().replace(/\s+/g, '-')}`}
1314
>
1415
<div class="h-48 overflow-hidden relative">
1516
<img
1617
src={image}
17-
alt={title}
18+
alt={`Imagen representativa de ${title}`}
1819
class="w-full h-full object-cover transform hover:scale-105 transition-transform duration-300"
20+
loading="lazy"
21+
decoding="async"
1922
/>
2023
{
2124
modality && (
2225
<div class="absolute top-4 right-4">
2326
<span
2427
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"
28+
modality === "Hybrid"
29+
? "bg-purple-100 text-purple-800"
30+
: modality === "Virtual"
31+
? "bg-green-100 text-green-800"
32+
: "bg-blue-100 text-blue-800"
3033
}`}
34+
role="status"
35+
aria-label={`Modalidad: ${modality}`}
3136
>
3237
{modality}
3338
</span>
@@ -39,9 +44,13 @@ const { title, image, modality, description } = Astro.props;
3944
<!-- Title and description -->
4045
<div class="flex flex-col">
4146
<div class="flex justify-between items-start mb-3">
42-
<h2 class="text-xl font-bold text-gray-800">{title}</h2>
47+
<h2 id={`card-title-${title.toLowerCase().replace(/\s+/g, '-')}`} class="text-xl font-bold text-gray-800">
48+
{title}
49+
</h2>
4350
</div>
44-
<p class="text-gray-600 mb-4 line-clamp-2">{description}</p>
51+
<p class="text-gray-600 mb-4 line-clamp-2">
52+
{description}
53+
</p>
4554
</div>
4655
<!-- Custom info -->
4756
<slot />

src/components/CardEvent.astro

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,34 @@ const { id, title, description, date, place, modality, image, attendees } =
77
88
const eventHeaderProps = { id, title, image, modality, description };
99
const justDate = date.split("T");
10+
const formattedDate = new Date(date).toLocaleDateString("es-EC", {
11+
weekday: "long",
12+
year: "numeric",
13+
month: "long",
14+
day: "numeric",
15+
});
1016
---
1117

1218
<CardBase {...eventHeaderProps}>
13-
<!-- Event Date, Location and Atendees -->
14-
<div class="space-y-2 text-sm text-gray-500">
15-
<div class="flex items-center gap-2">
19+
<div
20+
class="space-y-2 text-sm text-gray-500"
21+
itemscope
22+
itemtype="http://schema.org/Event"
23+
>
24+
<meta itemprop="name" content={title} />
25+
<meta itemprop="description" content={description} />
26+
<meta itemprop="image" content={image} />
27+
<meta itemprop="startDate" content={date} />
28+
<meta itemprop="location" content={place} />
29+
<meta itemprop="eventAttendanceMode" content={modality === "Virtual" ? "OnlineEventAttendanceMode" : "OfflineEventAttendanceMode"} />
30+
31+
<div class="flex items-center gap-2" aria-label="Fecha del evento">
1632
<svg
1733
class="w-4 h-4"
1834
fill="none"
1935
stroke="currentColor"
2036
viewBox="0 0 24 24"
37+
aria-hidden="true"
2138
>
2239
<path
2340
stroke-linecap="round"
@@ -27,24 +44,18 @@ const justDate = date.split("T");
2744
>
2845
</path>
2946
</svg>
30-
<span>
31-
{
32-
new Date(justDate[0]).toLocaleDateString("es-EC", {
33-
weekday: "long",
34-
year: "numeric",
35-
month: "long",
36-
day: "numeric",
37-
timeZone: "ECT",
38-
})
39-
}
40-
</span>
47+
<time datetime={date} itemprop="startDate">
48+
{formattedDate}
49+
</time>
4150
</div>
42-
<div class="flex items-center gap-2">
51+
52+
<div class="flex items-center gap-2" aria-label="Ubicación del evento">
4353
<svg
4454
class="w-4 h-4"
4555
fill="none"
4656
stroke="currentColor"
4757
viewBox="0 0 24 24"
58+
aria-hidden="true"
4859
>
4960
<path
5061
stroke-linecap="round"
@@ -61,14 +72,16 @@ const justDate = date.split("T");
6172
>
6273
</path>
6374
</svg>
64-
<span>{place}</span>
75+
<span itemprop="location">{place}</span>
6576
</div>
66-
<div class="flex items-center gap-2">
77+
78+
<div class="flex items-center gap-2" aria-label="Número de asistentes">
6779
<svg
6880
class="w-4 h-4"
6981
fill="none"
7082
stroke="currentColor"
7183
viewBox="0 0 24 24"
84+
aria-hidden="true"
7285
>
7386
<path
7487
stroke-linecap="round"
@@ -80,7 +93,14 @@ const justDate = date.split("T");
8093
</svg>
8194
<span>{attendees} asistentes</span>
8295
</div>
83-
<a href={`/event/${id}`} class="details-button">Ver detalles</a>
96+
97+
<a
98+
href={`/event/${id}`}
99+
class="details-button"
100+
aria-label={`Ver más detalles sobre ${title}`}
101+
>
102+
Ver detalles
103+
</a>
84104
</div>
85105
</CardBase>
86106

src/components/CommitementsCarrousel/Carrousel.astro

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -15,53 +15,53 @@ const { commitements } = Astro.props;
1515
1616
const commitementsLength = commitements.length;
1717
---
18+
1819
<div class="flex justify-start overflow-hidden">
19-
<div
20-
x-data="{
20+
<div
21+
x-data="{
2122
currentIndex: 0,
2223
getTranslatePercentage() {
2324
if (window.innerWidth < 640) { // (sm)
24-
return 32;
25+
return 32;
2526
} else if (window.innerWidth < 1024) { // (md)
26-
return 30;
27+
return 30;
2728
} else { // (lg and xl)
2829
return 30;
2930
}
3031
}
3132
}"
32-
;
33-
class="relative w-full px-3 md:px-0"
34-
>
35-
<div class="">
36-
<div
37-
class="flex w-fit xl:w-full transition-transform duration-300 ease-in-out"
38-
:style="`transform: translateX(-${currentIndex * getTranslatePercentage()}%)`"
39-
>
40-
{
41-
commitements.map((item: Commitement) => (
42-
<CarrouselItem {...item}/>
43-
))
44-
}
45-
</div>
46-
</div>
47-
48-
<!-- Slider buttons -->
49-
<button
50-
@click={`currentIndex = currentIndex - 1 >= 0 ? currentIndex - 1 : ${commitementsLength} - 1`}
51-
class="absolute -left-1 md:left-2 top-1/2 transform -translate-y-1/2 bg-white opacity-70 text-blue-600 px-2 rounded-xl"
33+
;
34+
class="relative w-full px-3 md:px-0"
5235
>
53-
<a class="p-1">
54-
<Fragment set:html={leftIcon} />
55-
</a>
56-
57-
</button>
58-
<button
59-
@click={`currentIndex = currentIndex + 1 < ${commitementsLength} ? currentIndex + 1 : 0`}
60-
class="absolute right-1 md:right-2 top-1/2 rotate-180 transform -translate-y-1/2 bg-white opacity-70 text-blue-600 px-2 rounded-xl"
61-
>
62-
<a class="p-1">
63-
<Fragment set:html={leftIcon} />
64-
</a>
65-
</button>
66-
</div>
36+
<div class="">
37+
<div
38+
class="flex w-fit xl:w-full transition-transform duration-300 ease-in-out"
39+
:style="`transform: translateX(-${currentIndex * getTranslatePercentage()}%)`"
40+
>
41+
{
42+
commitements.map((item: Commitement) => (
43+
<CarrouselItem {...item} />
44+
))
45+
}
46+
</div>
47+
</div>
48+
49+
<!-- Slider buttons -->
50+
<button
51+
@click={`currentIndex = currentIndex - 1 >= 0 ? currentIndex - 1 : ${commitementsLength} - 1`}
52+
class="absolute -left-1 md:left-2 top-1/2 transform -translate-y-1/2 bg-white opacity-70 text-blue-600 px-2 rounded-xl"
53+
>
54+
<div class="py-5">
55+
<Fragment set:html={leftIcon} />
56+
</div>
57+
</button>
58+
<button
59+
@click={`currentIndex = currentIndex + 1 < ${commitementsLength} ? currentIndex + 1 : 0`}
60+
class="absolute right-1 md:right-2 top-1/2 rotate-180 transform -translate-y-1/2 bg-white opacity-70 text-blue-600 px-2 rounded-xl"
61+
>
62+
<div class="py-5">
63+
<Fragment set:html={leftIcon} />
64+
</div>
65+
</button>
66+
</div>
6767
</div>

src/components/CommitementsCarrousel/CarrouselItem.astro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const { image, title, description, cta, link, icon } = Astro.props;
99
<img
1010
src={image}
1111
class="object-cover rounded-xl w-[300px] h-[400px] mr-4 md:mr-0"
12+
alt={ `Imagen representativa sobre: ${title}` }
1213
/>
1314
<div
1415
class="bg-white w-[600px] h-[400px] p-6 rounded-xl border-2 mx-0 mr-4 md:mx-4 flex flex-col align-top justify-between"

src/components/CommunityCard/CommunityCard.astro

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,41 @@ const {
1313
} = Astro.props as Community;
1414
---
1515

16-
<div class="bg-white rounded-2xl p-6 max-w-lg drop-shadow-md">
16+
<div
17+
class="bg-white rounded-2xl p-6 max-w-lg drop-shadow-md"
18+
itemscope
19+
itemtype="http://schema.org/Organization"
20+
>
21+
<meta itemprop="name" content={name} />
22+
<meta itemprop="description" content={description} />
23+
<meta itemprop="image" content={image} />
24+
{links?.website && <meta itemprop="url" content={links.website} />}
25+
1726
<div class="flex items-start gap-8">
18-
<Avatar logoUrl={image} title={name} />
27+
<Avatar logoUrl={image} title={`Logo de ${name}`} />
1928
<div class="flex-1 space-y-3">
2029
<div>
2130
<h3 class="text-xl font-semibold text-gray-900 mb-1">
22-
<a href={links?.website}>{name}</a>
31+
{links?.website ? (
32+
<a
33+
href={links.website}
34+
itemprop="url"
35+
target="_blank"
36+
rel="noopener noreferrer"
37+
aria-label={`Visitar sitio web de ${name}`}
38+
>
39+
{name}
40+
</a>
41+
) : (
42+
<span>{name}</span>
43+
)}
2344
</h3>
24-
<p class="text-gray-600 text-sm leading-relaxed">{description}</p>
45+
<p
46+
class="text-gray-600 text-sm leading-relaxed"
47+
itemprop="description"
48+
>
49+
{description}
50+
</p>
2551
</div>
2652

2753
<Tags tags={tags} />

0 commit comments

Comments
 (0)