-
Notifications
You must be signed in to change notification settings - Fork 0
YU_10 #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
YU_10 #11
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -4,6 +4,7 @@ import PhoneInput, { isValidPhoneNumber } from "react-phone-number-input"; | |||||||||||||||||||||
| import { Turnstile } from "@marsidev/react-turnstile"; | ||||||||||||||||||||||
| import type { TurnstileInstance } from "@marsidev/react-turnstile"; | ||||||||||||||||||||||
| import "react-phone-number-input/style.css"; | ||||||||||||||||||||||
| import { useTranslationsReact, getLangFromUrlReact } from '../i18n/react-utils'; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| type FormInputs = { | ||||||||||||||||||||||
| empresa: string; | ||||||||||||||||||||||
|
|
@@ -13,8 +14,15 @@ type FormInputs = { | |||||||||||||||||||||
| mensaje: string; | ||||||||||||||||||||||
| }; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| interface ContactFormProps { | ||||||||||||||||||||||
| lang?: string; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| export default function ContactForm() { | ||||||||||||||||||||||
| export default function ContactForm({ lang }: ContactFormProps = {}) { | ||||||||||||||||||||||
| // Detectar idioma desde la URL del navegador si no se proporciona | ||||||||||||||||||||||
| const currentLang = lang || getLangFromUrlReact(window.location.pathname); | ||||||||||||||||||||||
| const t = useTranslationsReact(currentLang as 'es' | 'en'); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
Comment on lines
+23
to
+25
|
||||||||||||||||||||||
| const currentLang = lang || getLangFromUrlReact(window.location.pathname); | |
| const t = useTranslationsReact(currentLang as 'es' | 'en'); | |
| const [currentLang, setCurrentLang] = React.useState<string>(lang || 'es'); | |
| React.useEffect(() => { | |
| if (!lang && typeof window !== 'undefined') { | |
| setCurrentLang(getLangFromUrlReact(window.location.pathname)); | |
| } | |
| }, [lang]); | |
| const t = useTranslationsReact(currentLang as 'es' | 'en'); |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,42 +1,47 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import Umbrella from '../components/svg/Umbrella.astro' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { getLangFromUrl, useTranslations } from '../i18n/utils'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { getRelativeLocaleUrl } from 'astro:i18n'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const lang = getLangFromUrl(Astro.url); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const t = useTranslations(lang); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div class="place-items-center mt-10 m-4"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div class="flex place-content-center"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <a href="/"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <a href={getRelativeLocaleUrl(lang, '')}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Umbrella/> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </a> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <p class="text-2xl text-white text-center">It's raining outside, take this</p> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <h1 class="text-6xl text-[#ffd300] font-bold text-center">Yellow Umbrella</h1> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <p class="text-2xl text-white text-center">{t('home.subtitle')}</p> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <h1 class="text-6xl text-[#ffd300] font-bold text-center">{t('home.title')}</h1> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <nav class="mt-5"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <ul class="flex flex-wrap justify-center gap-2"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <a href="/sobre-nosotros"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <a href={getRelativeLocaleUrl(lang, lang === 'es' ? 'sobre-nosotros' : 'about-us')}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <button class="relative inline-flex items-center justify-center w-32 h-16 p-[2px] mb-2 mr-4 overflow-hidden font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-[#ffd300] to-[#773376] group-hover:from-[#ffd300] group-hover:to-[#773376] hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-[#773376] dark:focus:ring-[#773376]"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <span class="relative w-full h-full px-2 py-1 transition-all ease-in duration-75 bg-white dark:bg-gray-900 rounded-[6px] group-hover:bg-opacity-0 flex items-center justify-center text-lg lg:text-base md:text-sm sm:text-xs text-center leading-tight"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ¿Quiénes somos? | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {t('home.nav.about')} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </span> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </button> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </a> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <a href="https://blog.yellowumbrella.dev" target="_blank" rel="noreferrer"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <button class="relative inline-flex items-center justify-center w-32 h-16 p-[2px] mb-2 mr-4 overflow-hidden font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-[#ffd300] to-[#773376] group-hover:from-[#ffd300] group-hover:to-[#773376] hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-[#773376] dark:focus:ring-[#773376]"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <span class="relative w-full h-full px-2 py-1 transition-all ease-in duration-75 bg-white dark:bg-gray-900 rounded-[6px] group-hover:bg-opacity-0 flex items-center justify-center text-xl lg:text-lg md:text-base sm:text-sm text-center leading-tight"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Blog | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {t('home.nav.blog')} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </span> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </button> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </a> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <a href="/redes-sociales"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <a href={getRelativeLocaleUrl(lang, lang === 'es' ? 'redes-sociales' : 'social-networks')}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <button class="relative inline-flex items-center justify-center w-32 h-16 p-[2px] mb-2 mr-4 overflow-hidden font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-[#ffd300] to-[#773376] group-hover:from-[#ffd300] group-hover:to-[#773376] hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-[#773376] dark:focus:ring-[#773376]"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <span class="relative w-full h-full px-2 py-1 transition-all ease-in duration-75 bg-white dark:bg-gray-900 rounded-[6px] group-hover:bg-opacity-0 flex items-center justify-center text-lg lg:text-base md:text-sm sm:text-xs text-center leading-tight"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Redes sociales | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {t('home.nav.social')} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </span> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </button> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </a> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <a href="/contacto"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <a href={getRelativeLocaleUrl(lang, lang === 'es' ? 'contacto' : 'contact')}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <button class="relative inline-flex items-center justify-center w-32 h-16 p-[2px] mb-2 mr-4 overflow-hidden font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-[#ffd300] to-[#773376] group-hover:from-[#ffd300] group-hover:to-[#773376] hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-[#773376] dark:focus:ring-[#773376]"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <span class="relative w-full h-full px-2 py-1 transition-all ease-in duration-75 bg-white dark:bg-gray-900 rounded-[6px] group-hover:bg-opacity-0 flex items-center justify-center text-xl lg:text-lg md:text-base sm:text-sm text-center leading-tight"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Contacto | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {t('home.nav.contact')} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </span> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </button> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </a> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+20
to
47
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix invalid nested interactive elements (button inside anchor) An anchor containing a button is invalid and harms accessibility. Style the anchor as a button instead. Apply this diff: - <a href={getRelativeLocaleUrl(lang, lang === 'es' ? 'sobre-nosotros' : 'about-us')}>
- <button class="relative inline-flex items-center justify-center w-32 h-16 p-[2px] mb-2 mr-4 overflow-hidden font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-[#ffd300] to-[#773376] group-hover:from-[#ffd300] group-hover:to-[#773376] hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-[#773376] dark:focus:ring-[#773376]">
- <span class="relative w-full h-full px-2 py-1 transition-all ease-in duration-75 bg-white dark:bg-gray-900 rounded-[6px] group-hover:bg-opacity-0 flex items-center justify-center text-lg lg:text-base md:text-sm sm:text-xs text-center leading-tight">
+ <a href={getRelativeLocaleUrl(lang, lang === 'es' ? 'sobre-nosotros' : 'about-us')}
+ class="relative inline-flex items-center justify-center w-32 h-16 p-[2px] mb-2 mr-4 overflow-hidden font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-[#ffd300] to-[#773376] group-hover:from-[#ffd300] group-hover:to-[#773376] hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-[#773376] dark:focus:ring-[#773376]">
+ <span class="relative w-full h-full px-2 py-1 transition-all ease-in duration-75 bg-white dark:bg-gray-900 rounded-[6px] group-hover:bg-opacity-0 flex items-center justify-center text-lg lg:text-base md:text-sm sm:text-xs text-center leading-tight">
{t('home.nav.about')}
</span>
- </button>
</a>
- <a href="https://blog.yellowumbrella.dev" target="_blank" rel="noreferrer">
- <button class="relative inline-flex items-center justify-center w-32 h-16 p-[2px] mb-2 mr-4 overflow-hidden font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-[#ffd300] to-[#773376] group-hover:from-[#ffd300] group-hover:to-[#773376] hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-[#773376] dark:focus:ring-[#773376]">
- <span class="relative w-full h-full px-2 py-1 transition-all ease-in duration-75 bg-white dark:bg-gray-900 rounded-[6px] group-hover:bg-opacity-0 flex items-center justify-center text-xl lg:text-lg md:text-base sm:text-sm text-center leading-tight">
+ <a href="https://blog.yellowumbrella.dev" target="_blank" rel="noopener noreferrer"
+ class="relative inline-flex items-center justify-center w-32 h-16 p-[2px] mb-2 mr-4 overflow-hidden font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-[#ffd300] to-[#773376] group-hover:from-[#ffd300] group-hover:to-[#773376] hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-[#773376] dark:focus:ring-[#773376]">
+ <span class="relative w-full h-full px-2 py-1 transition-all ease-in duration-75 bg-white dark:bg-gray-900 rounded-[6px] group-hover:bg-opacity-0 flex items-center justify-center text-xl lg:text-lg md:text-base sm:text-sm text-center leading-tight">
{t('home.nav.blog')}
</span>
- </button>
</a>
- <a href={getRelativeLocaleUrl(lang, lang === 'es' ? 'redes-sociales' : 'social-networks')}>
- <button class="relative inline-flex items-center justify-center w-32 h-16 p-[2px] mb-2 mr-4 overflow-hidden font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-[#ffd300] to-[#773376] group-hover:from-[#ffd300] group-hover:to-[#773376] hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-[#773376] dark:focus:ring-[#773376]">
- <span class="relative w-full h-full px-2 py-1 transition-all ease-in duration-75 bg-white dark:bg-gray-900 rounded-[6px] group-hover:bg-opacity-0 flex items-center justify-center text-lg lg:text-base md:text-sm sm:text-xs text-center leading-tight">
+ <a href={getRelativeLocaleUrl(lang, lang === 'es' ? 'redes-sociales' : 'social-networks')}
+ class="relative inline-flex items-center justify-center w-32 h-16 p-[2px] mb-2 mr-4 overflow-hidden font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-[#ffd300] to-[#773376] group-hover:from-[#ffd300] group-hover:to-[#773376] hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-[#773376] dark:focus:ring-[#773376]">
+ <span class="relative w-full h-full px-2 py-1 transition-all ease-in duration-75 bg-white dark:bg-gray-900 rounded-[6px] group-hover:bg-opacity-0 flex items-center justify-center text-lg lg:text-base md:text-sm sm:text-xs text-center leading-tight">
{t('home.nav.social')}
</span>
- </button>
</a>
- <a href={getRelativeLocaleUrl(lang, lang === 'es' ? 'contacto' : 'contact')}>
- <button class="relative inline-flex items-center justify-center w-32 h-16 p-[2px] mb-2 mr-4 overflow-hidden font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-[#ffd300] to-[#773376] group-hover:from-[#ffd300] group-hover:to-[#773376] hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-[#773376] dark:focus:ring-[#773376]">
- <span class="relative w-full h-full px-2 py-1 transition-all ease-in duration-75 bg-white dark:bg-gray-900 rounded-[6px] group-hover:bg-opacity-0 flex items-center justify-center text-xl lg:text-lg md:text-base sm:text-sm text-center leading-tight">
+ <a href={getRelativeLocaleUrl(lang, lang === 'es' ? 'contacto' : 'contact')}
+ class="relative inline-flex items-center justify-center w-32 h-16 p-[2px] mb-2 mr-4 overflow-hidden font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-[#ffd300] to-[#773376] group-hover:from-[#ffd300] group-hover:to-[#773376] hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-[#773376] dark:focus:ring-[#773376]">
+ <span class="relative w-full h-full px-2 py-1 transition-all ease-in duration-75 bg-white dark:bg-gray-900 rounded-[6px] group-hover:bg-opacity-0 flex items-center justify-center text-xl lg:text-lg md:text-base sm:text-sm text-center leading-tight">
{t('home.nav.contact')}
</span>
- </button>
</a>📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,57 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { languages } from '../i18n/ui'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { getLangFromUrl, useTranslatedPath, getRouteFromUrl } from '../i18n/utils'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { getRelativeLocaleUrl } from 'astro:i18n'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const lang = getLangFromUrl(Astro.url); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const translatePath = useTranslatedPath(lang); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Obtener la ruta actual sin el prefijo del idioma | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const currentRoute = getRouteFromUrl(Astro.url) || ''; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div class="fixed top-5 right-5 z-[1000]"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <select | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id="language-select" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| class="bg-gray-900 text-white border border-gray-600 rounded px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-[#ffd300] focus:border-transparent" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {Object.entries(languages).map(([langCode, label]) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const translatedRoute = translatePath(`/${currentRoute}`, langCode); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <option | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| value={langCode} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| selected={langCode === lang} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| data-url={translatedRoute} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {label} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </option> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| })} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </select> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <script> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function initLanguagePicker() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const select = document.getElementById('language-select') as HTMLSelectElement; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (select) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Remover event listeners previos para evitar duplicados | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const newSelect = select.cloneNode(true) as HTMLSelectElement; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| select.parentNode?.replaceChild(newSelect, select); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| newSelect.addEventListener('change', function() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const selectedOption = this.options[this.selectedIndex]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const url = selectedOption.getAttribute('data-url'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (url) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| window.location.href = url; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Inicializar cuando se carga la página | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| document.addEventListener('DOMContentLoaded', initLanguagePicker); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Reinicializar después de cada transición de página de Astro | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| document.addEventListener('astro:page-load', initLanguagePicker); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </script> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+33
to
+57
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove TypeScript from browser script to avoid runtime errors The script tag runs in the browser; TS assertions (as HTMLSelectElement) will break. Use plain JS and narrow via instanceof. Apply this diff: <script>
- function initLanguagePicker() {
- const select = document.getElementById('language-select') as HTMLSelectElement;
-
- if (select) {
- // Remover event listeners previos para evitar duplicados
- const newSelect = select.cloneNode(true) as HTMLSelectElement;
- select.parentNode?.replaceChild(newSelect, select);
-
- newSelect.addEventListener('change', function() {
- const selectedOption = this.options[this.selectedIndex];
- const url = selectedOption.getAttribute('data-url');
- if (url) {
- window.location.href = url;
- }
- });
- }
- }
-
- // Inicializar cuando se carga la página
- document.addEventListener('DOMContentLoaded', initLanguagePicker);
-
- // Reinicializar después de cada transición de página de Astro
- document.addEventListener('astro:page-load', initLanguagePicker);
+ function initLanguagePicker() {
+ const select = document.getElementById('language-select');
+ if (select && select instanceof HTMLSelectElement) {
+ // Remove previous listeners by cloning
+ const newSelect = select.cloneNode(true);
+ select.parentNode?.replaceChild(newSelect, select);
+ newSelect.addEventListener('change', (e) => {
+ const target = e.currentTarget;
+ if (target && target instanceof HTMLSelectElement) {
+ const option = target.options[target.selectedIndex];
+ const url = option.getAttribute('data-url');
+ if (url) window.location.assign(url);
+ }
+ });
+ }
+ }
+ document.addEventListener('DOMContentLoaded', initLanguagePicker);
+ document.addEventListener('astro:page-load', initLanguagePicker);
</script>📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| --- | ||
| import { getLangFromUrl, useTranslations } from '../i18n/utils'; | ||
| import { getRelativeLocaleUrl } from 'astro:i18n'; | ||
|
|
||
| const lang = getLangFromUrl(Astro.url); | ||
| const t = useTranslations(lang); | ||
|
|
||
| const menuItems = [ | ||
| { | ||
| path: '', | ||
| label: t('nav.home') | ||
| }, | ||
| { | ||
| path: lang === 'es' ? 'sobre-nosotros' : 'about-us', | ||
| label: t('nav.about') | ||
| }, | ||
| { | ||
| path: lang === 'es' ? 'contacto' : 'contact', | ||
| label: t('nav.contact') | ||
| }, | ||
| { | ||
| path: lang === 'es' ? 'redes-sociales' : 'social-networks', | ||
| label: t('nav.social') | ||
| }, | ||
| ]; | ||
| --- | ||
|
|
||
| <nav class="fixed top-20px left-20px z-1000 bg-white/5 backdrop-blur-md rounded-lg p-4"> | ||
| <ul class="flex flex-col gap-2"> | ||
| {menuItems.map((item) => ( | ||
| <li> | ||
| <a | ||
| href={getRelativeLocaleUrl(lang, item.path)} | ||
| class="text-white hover:text-yellow-400 transition-colors duration-200 block text-sm" | ||
| > | ||
| {item.label} | ||
| </a> | ||
| </li> | ||
| ))} | ||
| </ul> | ||
| </nav> | ||
|
|
||
| <style> | ||
| nav { | ||
| position: fixed; | ||
| top: 20px; | ||
| left: 20px; | ||
| z-index: 999; | ||
| } | ||
| </style> |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,13 @@ | ||||||||||||||||||||||||||||||||||||||||
| import { ui, defaultLang } from './ui'; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| export function useTranslationsReact(lang: keyof typeof ui) { | ||||||||||||||||||||||||||||||||||||||||
| return function t(key: keyof typeof ui[typeof defaultLang]) { | ||||||||||||||||||||||||||||||||||||||||
| return ui[lang][key] || ui[defaultLang][key]; | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| export function getLangFromUrlReact(url: string) { | ||||||||||||||||||||||||||||||||||||||||
| const [, lang] = url.split('/'); | ||||||||||||||||||||||||||||||||||||||||
| if (lang in ui) return lang as keyof typeof ui; | ||||||||||||||||||||||||||||||||||||||||
| return defaultLang; | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+9
to
+13
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Make URL language extraction robust for absolute URLs.
-export function getLangFromUrlReact(url: string) {
- const [, lang] = url.split('/');
- if (lang in ui) return lang as keyof typeof ui;
- return defaultLang;
-}
+export function getLangFromUrlReact(url: string) {
+ let pathname = url;
+ try {
+ // If absolute URL, extract pathname; otherwise assume it's already a path
+ if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(url)) {
+ pathname = new URL(url).pathname;
+ }
+ } catch {
+ // noop; fallback to given string
+ }
+ const first = pathname.replace(/^\/+/, '').split('/')[0] ?? '';
+ if (first && first in ui) return first as keyof typeof ui;
+ return defaultLang;
+}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment contains spelling errors. It should be 'más' (with accent) and 'documentación' (with accent).