Skip to content

Commit cc8c3c6

Browse files
committed
feat(accommodation): Actualizar página de alojamiento.
Añadida lista de barrios donde alojarse con distintas conexiones y más.
1 parent 54034ad commit cc8c3c6

4 files changed

Lines changed: 237 additions & 84 deletions

File tree

src/components/AccommodationPage.astro

Lines changed: 111 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,24 @@ interface Props {
88
99
const { lang } = Astro.props
1010
const t = accommodationTexts[lang as keyof typeof accommodationTexts]
11+
type AreaSlug =
12+
| 'eixampleEsquerra'
13+
| 'elRaval'
14+
| 'santAntoni'
15+
| 'ciutatVella'
16+
| 'sants'
17+
| 'poblenou22'
18+
| 'elClot'
19+
| 'lesCorts'
20+
| 'eixampleDreta'
21+
| 'collblanc'
22+
23+
const walkingAreas: AreaSlug[] = ['eixampleEsquerra', 'elRaval', 'santAntoni', 'ciutatVella']
24+
const directMetroAreas: AreaSlug[] = ['sants', 'poblenou22', 'elClot']
25+
const transferAreas: AreaSlug[] = ['lesCorts', 'eixampleDreta', 'collblanc']
26+
27+
const areaName = (slug: AreaSlug) => t[`accommodation.areas.${slug}.name` as keyof typeof t]
28+
const areaDesc = (slug: AreaSlug) => t[`accommodation.areas.${slug}.desc` as keyof typeof t]
1129
---
1230

1331
<div class="accommodation-container pb-20">
@@ -20,33 +38,91 @@ const t = accommodationTexts[lang as keyof typeof accommodationTexts]
2038
</p>
2139
</section>
2240

23-
<section
24-
class="max-w-4xl bg-white/5 backdrop-blur-md p-8 md:p-12 rounded-3xl border border-white/10 mb-16 shadow-2xl"
25-
>
26-
<p class="text-lg text-pycon-gray-25 leading-relaxed">
27-
{t['accommodation.intro']}
28-
</p>
41+
<!-- Areas -->
42+
<section class="mb-24" aria-labelledby="accommodation-areas-heading">
43+
<div class="flex items-center gap-4 mb-12">
44+
<div class="h-px bg-white/20 flex-1" aria-hidden="true"></div>
45+
<h2 id="accommodation-areas-heading" class="text-3xl font-bold text-white px-4">
46+
{t['accommodation.areas.title']}
47+
</h2>
48+
<div class="h-px bg-white/20 flex-1" aria-hidden="true"></div>
49+
</div>
50+
<div class="max-w-4xl space-y-4 mb-12 text-pycon-gray-25 leading-relaxed">
51+
<p class="text-lg">{t['accommodation.areas.transportIntro.p1']}</p>
52+
<p class="text-lg">{t['accommodation.areas.transportIntro.p2']}</p>
53+
<p class="text-lg">{t['accommodation.areas.transportIntro.p3']}</p>
54+
</div>
55+
56+
<div class="space-y-16">
57+
<div>
58+
<h3 class="text-2xl font-bold text-white mb-6">{t['accommodation.areas.category.walking']}</h3>
59+
<ul class="grid sm:grid-cols-2 lg:grid-cols-3 gap-8 list-none m-0 p-0">
60+
{
61+
walkingAreas.map((slug) => (
62+
<li class="bg-pycon-black/40 p-8 rounded-2xl border border-white/5 hover:border-pycon-orange/50 transition-all motion-safe:hover:-translate-y-2">
63+
<h4 class="text-xl font-bold text-pycon-orange mb-4 italic">{areaName(slug)}</h4>
64+
<p class="text-pycon-gray-25 text-sm leading-relaxed">{areaDesc(slug)}</p>
65+
</li>
66+
))
67+
}
68+
</ul>
69+
</div>
70+
<div>
71+
<h3 class="text-2xl font-bold text-white mb-6">{t['accommodation.areas.category.directMetro']}</h3>
72+
<ul class="grid sm:grid-cols-2 lg:grid-cols-3 gap-8 list-none m-0 p-0">
73+
{
74+
directMetroAreas.map((slug) => (
75+
<li class="bg-pycon-black/40 p-8 rounded-2xl border border-white/5 hover:border-pycon-orange/50 transition-all motion-safe:hover:-translate-y-2">
76+
<h4 class="text-xl font-bold text-pycon-orange mb-4 italic">{areaName(slug)}</h4>
77+
<p class="text-pycon-gray-25 text-sm leading-relaxed">{areaDesc(slug)}</p>
78+
</li>
79+
))
80+
}
81+
</ul>
82+
</div>
83+
<div>
84+
<h3 class="text-2xl font-bold text-white mb-6">{t['accommodation.areas.category.transferMetro']}</h3>
85+
<ul class="grid sm:grid-cols-2 lg:grid-cols-3 gap-8 list-none m-0 p-0">
86+
{
87+
transferAreas.map((slug) => (
88+
<li class="bg-pycon-black/40 p-8 rounded-2xl border border-white/5 hover:border-pycon-orange/50 transition-all motion-safe:hover:-translate-y-2">
89+
<h4 class="text-xl font-bold text-pycon-orange mb-4 italic">{areaName(slug)}</h4>
90+
<p class="text-pycon-gray-25 text-sm leading-relaxed">{areaDesc(slug)}</p>
91+
</li>
92+
))
93+
}
94+
</ul>
95+
</div>
96+
</div>
2997
</section>
3098

3199
<!-- Hotels Section -->
32-
<section class="mb-24">
100+
<section class="mb-24" aria-labelledby="accommodation-hotels-heading">
33101
<div class="flex items-center gap-4 mb-12">
34-
<div class="h-px bg-white/20 flex-1"></div>
35-
<h2 class="text-3xl font-bold text-white px-4">{t['accommodation.hotels.title']}</h2>
36-
<div class="h-px bg-white/20 flex-1"></div>
102+
<div class="h-px bg-white/20 flex-1" aria-hidden="true"></div>
103+
<h2 id="accommodation-hotels-heading" class="text-3xl font-bold text-white px-4">
104+
{t['accommodation.hotels.title']}
105+
</h2>
106+
<div class="h-px bg-white/20 flex-1" aria-hidden="true"></div>
37107
</div>
38108

39109
<div
40110
class="bg-pycon-gray-100/50 p-12 rounded-3xl border border-pycon-yellow/30 text-center relative overflow-hidden group"
41111
>
42112
<!-- Shine effect -->
43113
<div
44-
class="absolute -top-full -left-full w-[300%] h-[300%] bg-linear-to-br from-transparent via-pycon-yellow/5 to-transparent rotate-45 transition-transform duration-1000 group-hover:translate-x-[33%] group-hover:translate-y-[33%] pointer-events-none"
114+
class="absolute -top-full -left-full w-[300%] h-[300%] bg-linear-to-br from-transparent via-pycon-yellow/5 to-transparent rotate-45 transition-transform duration-1000 motion-safe:group-hover:translate-x-[33%] motion-safe:group-hover:translate-y-[33%] pointer-events-none"
115+
aria-hidden="true"
45116
>
46117
</div>
47118

48119
<div class="relative z-10">
49-
<StatusIcon type="construction" size="xl" role="img" aria-label="Construyendo" />
120+
<StatusIcon
121+
type="construction"
122+
size="xl"
123+
role="img"
124+
aria-label={t['accommodation.a11y.constructionIcon']}
125+
/>
50126
<h3 class="text-2xl font-bold text-pycon-yellow mb-4">{t['accommodation.hotels.subtitle']}</h3>
51127
<p class="text-xl text-white font-medium max-w-2xl mx-auto italic opacity-80">
52128
{t['accommodation.hotels.disclaimer']}
@@ -55,59 +131,36 @@ const t = accommodationTexts[lang as keyof typeof accommodationTexts]
55131
</div>
56132
</section>
57133

58-
<!-- Areas -->
59-
<section class="mb-24">
60-
<h2 class="text-3xl font-bold text-white mb-12 flex items-center gap-3">
61-
<span class="w-2 h-8 bg-pycon-red rounded-full"></span>
62-
{t['accommodation.areas.title']}
63-
</h2>
64-
<div class="grid md:grid-cols-3 gap-8">
65-
<div
66-
class="bg-pycon-black/40 p-8 rounded-2xl border border-white/5 hover:border-pycon-orange/50 transition-all hover:-translate-y-2"
67-
>
68-
<h3 class="text-xl font-bold text-pycon-orange mb-4 italic">
69-
{t['accommodation.areas.eixample.name']}
70-
</h3>
71-
<p class="text-pycon-gray-25 text-sm leading-relaxed">{t['accommodation.areas.eixample.desc']}</p>
72-
</div>
73-
<div
74-
class="bg-pycon-black/40 p-8 rounded-2xl border border-white/5 hover:border-pycon-orange/50 transition-all hover:-translate-y-2 text-center"
75-
>
76-
<h3 class="text-xl font-bold text-pycon-orange mb-4 italic">
77-
{t['accommodation.areas.gothic.name']}
78-
</h3>
79-
<p class="text-pycon-gray-25 text-sm leading-relaxed">{t['accommodation.areas.gothic.desc']}</p>
80-
</div>
81-
<div
82-
class="bg-pycon-black/40 p-8 rounded-2xl border border-white/5 hover:border-pycon-orange/50 transition-all hover:-translate-y-2 text-right"
83-
>
84-
<h3 class="text-xl font-bold text-pycon-orange mb-4 italic">
85-
{t['accommodation.areas.poblenou.name']}
86-
</h3>
87-
<p class="text-pycon-gray-25 text-sm leading-relaxed">{t['accommodation.areas.poblenou.desc']}</p>
88-
</div>
89-
</div>
90-
</section>
91-
92134
<!-- Apartments -->
93135
<section
94136
class="bg-linear-to-r from-pycon-red/20 to-pycon-orange/20 p-8 md:p-16 rounded-3xl border border-pycon-red/30"
137+
aria-labelledby="accommodation-apartments-heading"
95138
>
96139
<div class="flex flex-col md:flex-row gap-12 items-center">
97140
<div class="flex-1">
98-
<h2 class="text-3xl font-bold text-white mb-6 uppercase tracking-tight">
141+
<h2
142+
id="accommodation-apartments-heading"
143+
class="text-3xl font-bold text-white mb-6 uppercase tracking-tight"
144+
>
99145
{t['accommodation.apartments.title']}
100146
</h2>
101147
<p class="text-pycon-gray-25 text-lg mb-8 leading-relaxed">
102148
{t['accommodation.apartments.text']}
103149
</p>
104150
<a
105-
href="https://meet.barcelona/es/alojarse-en-barcelona"
151+
href={t['accommodation.apartments.linkUrl']}
106152
target="_blank"
107-
class="inline-flex items-center gap-2 bg-white text-pycon-red font-bold px-6 py-3 rounded-lg hover:scale-105 transition-transform no-underline"
153+
rel="noopener noreferrer"
154+
class="inline-flex items-center gap-2 bg-white text-pycon-red font-bold px-6 py-3 rounded-lg motion-safe:hover:scale-105 transition-transform no-underline focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-pycon-yellow"
108155
>
109156
{t['accommodation.apartments.link']}
110-
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"
157+
<span class="sr-only"> ({t['accommodation.a11y.linkOpensNewTab']})</span>
158+
<svg
159+
class="w-5 h-5 shrink-0"
160+
fill="none"
161+
stroke="currentColor"
162+
viewBox="0 0 24 24"
163+
aria-hidden="true"
111164
><path
112165
stroke-linecap="round"
113166
stroke-linejoin="round"
@@ -118,8 +171,9 @@ const t = accommodationTexts[lang as keyof typeof accommodationTexts]
118171
</div>
119172
<div
120173
class="w-48 h-48 bg-white/10 rounded-full flex items-center justify-center border border-white/20 shadow-2xl backdrop-blur-xl shrink-0"
174+
aria-hidden="true"
121175
>
122-
<StatusIcon type="city" size="xl" role="img" aria-label="Ubicación" />
176+
<StatusIcon type="city" size="xl" />
123177
</div>
124178
</div>
125179
</section>
@@ -140,4 +194,10 @@ const t = accommodationTexts[lang as keyof typeof accommodationTexts]
140194
transform: translateY(0);
141195
}
142196
}
197+
198+
@media (prefers-reduced-motion: reduce) {
199+
.accommodation-container {
200+
animation: none;
201+
}
202+
}
143203
</style>

src/i18n/accommodation/ca.ts

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,55 @@ export const ca = {
22
'accommodation.title': 'Allotjament',
33
'accommodation.hero.title': 'On allotjar-se',
44
'accommodation.hero.subtitle': 'Recomanacions per a la teva estada a Barcelona',
5-
'accommodation.intro':
6-
"Barcelona és una de les ciutats amb més oferta hotelera d'Europa. Per a la PyConES 2026, recomanem buscar allotjament al districte de l'Eixample o a Ciutat Vella per estar a pocs minuts a peu de la seu (UB Edifici Històric).",
75
'accommodation.hotels.title': 'Hotels Recomanats',
86
'accommodation.hotels.subtitle': 'Convenis i opcions properes',
97
'accommodation.hotels.disclaimer':
108
'Estem treballant per tancar convenis exclusius amb descomptes per als assistents. Torna aviat per veure els codis promocionals!',
119
'accommodation.areas.title': 'Millors Zones',
12-
'accommodation.areas.eixample.name': "L'Eixample",
13-
'accommodation.areas.eixample.desc':
14-
'La zona més segura i elegant, amb arquitectura modernista i a un pas de la seu.',
15-
'accommodation.areas.gothic.name': 'Barri Gòtic',
16-
'accommodation.areas.gothic.desc':
17-
'El centre històric, amb carrers màgics i molta vida nocturna, a 10 min de la UB.',
18-
'accommodation.areas.poblenou.name': 'Poblenou / 22@',
19-
'accommodation.areas.poblenou.desc':
20-
'El hub tecnològic. Un poc més allunyat però molt ben connectat per metro (L1).',
10+
'accommodation.areas.transportIntro.p1':
11+
'Si has de tornar a casa en tren, les millors opcions són Sants, Eixample Esquerra o Les Corts (per anar a Sants Estació).',
12+
'accommodation.areas.transportIntro.p2':
13+
"Si tornes en avió, et recomanem els barris d'El Raval, Sant Antoni, Eixample Esquerra (Aerobús), Sants (tren Rodalies R2) o Les Corts i Collblanc (L9 Sud). Tanmateix hi ha una parada de l'autobús directe a l'aeroport (Aerobús) davant de la seu.",
14+
'accommodation.areas.transportIntro.p3':
15+
'Tindrem servei de consigna, així que si marxes el diumenge pots fer check-out i deixar les maletes aquí.',
16+
'accommodation.areas.category.walking': 'A peu',
17+
'accommodation.areas.category.directMetro': 'Metro directe',
18+
'accommodation.areas.category.transferMetro': 'Metro amb transbord',
19+
'accommodation.areas.eixampleEsquerra.name': 'Eixample Esquerra',
20+
'accommodation.areas.eixampleEsquerra.desc':
21+
"Costat esquerre de l'eixample, modernista i molt a prop de la UB a peu; bona opció si també fas servir Sants.",
22+
'accommodation.areas.elRaval.name': 'El Raval',
23+
'accommodation.areas.elRaval.desc':
24+
'Barri cèntric i multicultural, a poca distància a peu de la seu; l’Aerobús enllaça bé amb l’aeroport.',
25+
'accommodation.areas.santAntoni.name': 'Sant Antoni',
26+
'accommodation.areas.santAntoni.desc':
27+
'Mercat i terrasses, ambient de barri i una passejada còmoda fins a la universitat.',
28+
'accommodation.areas.ciutatVella.name': 'Ciutat Vella',
29+
'accommodation.areas.ciutatVella.desc':
30+
'Nucli històric (Gòtic, Born…): ambient únic i ubicacions a prop de l’esdeveniment.',
31+
'accommodation.areas.sants.name': 'Sants',
32+
'accommodation.areas.sants.desc':
33+
'Al costat de l’estació de Sants: ideal per trens de llarg recorregut i Rodalies cap a l’aeroport.',
34+
'accommodation.areas.poblenou22.name': 'Poblenou / 22@',
35+
'accommodation.areas.poblenou22.desc':
36+
'Districte 22@ i platja; ben connectat per metro en línia directa al centre i la UB.',
37+
'accommodation.areas.elClot.name': 'El Clot',
38+
'accommodation.areas.elClot.desc':
39+
'Barri consolidat amb bon accés en metro directe al centre on hi ha la seu.',
40+
'accommodation.areas.lesCorts.name': 'Les Corts',
41+
'accommodation.areas.lesCorts.desc':
42+
'A prop de la L9 Sud a l’aeroport; per arribar a la seu sol cal transbord en metro.',
43+
'accommodation.areas.eixampleDreta.name': 'Eixample Dreta',
44+
'accommodation.areas.eixampleDreta.desc':
45+
'Eixample dret: emblemàtic i ben comunicat, amb enllaços que sovint impliquen una correspondència.',
46+
'accommodation.areas.collblanc.name': 'Collblanc',
47+
'accommodation.areas.collblanc.desc':
48+
'L9 Sud a l’aeroport; per arribar a la UB normalment faràs transbord.',
2149
'accommodation.apartments.title': 'Apartaments Turístics',
2250
'accommodation.apartments.text':
2351
"Si prefereixes un apartament, assegura't que compti amb llicència turística oficial (HUTB). Barcelona és molt estricta amb la regulació d'allotjaments.",
2452
'accommodation.apartments.link': "Veure guia d'allotjament segur a Barcelona",
53+
'accommodation.apartments.linkUrl': 'https://meet.barcelona.cat/habitatgesturistics/ca',
54+
'accommodation.a11y.constructionIcon': 'En construcció',
55+
'accommodation.a11y.linkOpensNewTab': "s'obre en una pestanya nova",
2556
} as const

src/i18n/accommodation/en.ts

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,55 @@ export const en = {
22
'accommodation.title': 'Accommodation',
33
'accommodation.hero.title': 'Where to stay',
44
'accommodation.hero.subtitle': 'Recommendations for your stay in Barcelona',
5-
'accommodation.intro':
6-
'Barcelona offers one of the largest hotel selections in Europe. For PyConES 2026, we recommend looking for accommodation in the Eixample district or Ciutat Vella to be within walking distance of the venue (UB Historic Building).',
75
'accommodation.hotels.title': 'Recommended Hotels',
86
'accommodation.hotels.subtitle': 'Agreements and nearby options',
97
'accommodation.hotels.disclaimer':
108
'We are working on exclusive discounts for attendees. Check back soon for promo codes!',
119
'accommodation.areas.title': 'Best Areas',
12-
'accommodation.areas.eixample.name': "L'Eixample",
13-
'accommodation.areas.eixample.desc':
14-
'The safest and most elegant area, with modernist architecture and very close to the venue.',
15-
'accommodation.areas.gothic.name': 'Gothic Quarter',
16-
'accommodation.areas.gothic.desc':
17-
'The historical center, with magical streets and vibrant nightlife, 10 min from UB.',
18-
'accommodation.areas.poblenou.name': 'Poblenou / 22@',
19-
'accommodation.areas.poblenou.desc':
20-
'The tech hub. Slightly further away but very well connected by metro (L1).',
10+
'accommodation.areas.transportIntro.p1':
11+
'If you are heading home by train, the best options are Sants, Eixample Esquerra, or Les Corts (for reaching Sants Estació).',
12+
'accommodation.areas.transportIntro.p2':
13+
'If you fly out, we suggest El Raval, Sant Antoni, Eixample Esquerra (Aerobús), Sants (Rodalies R2 to the airport), or Les Corts and Collblanc (L9 Sud). There is also a direct airport bus (Aerobús) stop in front of the venue.',
14+
'accommodation.areas.transportIntro.p3':
15+
'We will provide a luggage room, so if you leave on Sunday you can check out and leave your bags with us.',
16+
'accommodation.areas.category.walking': 'On foot',
17+
'accommodation.areas.category.directMetro': 'Direct metro',
18+
'accommodation.areas.category.transferMetro': 'Metro with a change',
19+
'accommodation.areas.eixampleEsquerra.name': 'Eixample Esquerra',
20+
'accommodation.areas.eixampleEsquerra.desc':
21+
'The left side of the Eixample: modernist and very close to UB on foot; a strong pick if you also use Sants.',
22+
'accommodation.areas.elRaval.name': 'El Raval',
23+
'accommodation.areas.elRaval.desc':
24+
'A central, multicultural area within walking distance of the venue; Aerobús links well to the airport.',
25+
'accommodation.areas.santAntoni.name': 'Sant Antoni',
26+
'accommodation.areas.santAntoni.desc':
27+
'Market halls and terraces, a lively neighbourhood feel, and an easy walk to the university.',
28+
'accommodation.areas.ciutatVella.name': 'Ciutat Vella',
29+
'accommodation.areas.ciutatVella.desc':
30+
'The old city (Gòtic, Born…): unique atmosphere and locations close to the event.',
31+
'accommodation.areas.sants.name': 'Sants',
32+
'accommodation.areas.sants.desc':
33+
'Next to Sants station: ideal for long-distance trains and Rodalies to the airport.',
34+
'accommodation.areas.poblenou22.name': 'Poblenou / 22@',
35+
'accommodation.areas.poblenou22.desc':
36+
'The 22@ district by the beach; direct metro lines to the centre and UB.',
37+
'accommodation.areas.elClot.name': 'El Clot',
38+
'accommodation.areas.elClot.desc':
39+
'An established neighbourhood with a direct metro ride to the city centre where the venue is.',
40+
'accommodation.areas.lesCorts.name': 'Les Corts',
41+
'accommodation.areas.lesCorts.desc':
42+
'Near L9 Sud to the airport; reaching the venue usually means one metro change.',
43+
'accommodation.areas.eixampleDreta.name': 'Eixample Dreta',
44+
'accommodation.areas.eixampleDreta.desc':
45+
'The right side of the Eixample: iconic and well connected, often with one interchange.',
46+
'accommodation.areas.collblanc.name': 'Collblanc',
47+
'accommodation.areas.collblanc.desc':
48+
'L9 Sud to the airport; you will typically change lines to get to UB.',
2149
'accommodation.apartments.title': 'Tourist Apartments',
2250
'accommodation.apartments.text':
2351
'If you prefer an apartment, make sure it has an official tourist license (HUTB). Barcelona is very strict regarding accommodation regulations.',
2452
'accommodation.apartments.link': 'View safe accommodation guide in Barcelona',
53+
'accommodation.apartments.linkUrl': 'https://meet.barcelona.cat/habitatgesturistics/en',
54+
'accommodation.a11y.constructionIcon': 'Under construction',
55+
'accommodation.a11y.linkOpensNewTab': 'opens in a new tab',
2556
} as const

0 commit comments

Comments
 (0)