first commit

This commit is contained in:
Michaël
2026-01-29 14:13:11 -03:00
commit 2302748c87
105 changed files with 93301 additions and 0 deletions

View File

@@ -0,0 +1,59 @@
import en from './locales/en.json';
import es from './locales/es.json';
// Type for available locales - easily extendable
export type Locale = 'en' | 'es';
// Add new languages here
export const locales: Record<Locale, typeof en> = {
en,
es,
};
// Language display names
export const localeNames: Record<Locale, string> = {
en: 'English',
es: 'Español',
};
// Language flags (emoji or use icons)
export const localeFlags: Record<Locale, string> = {
en: '🇺🇸',
es: '🇪🇸',
};
export const defaultLocale: Locale = 'en';
// Get nested translation value
function getNestedValue(obj: any, path: string): string {
return path.split('.').reduce((acc, part) => acc && acc[part], obj) || path;
}
// Translation function
export function t(locale: Locale, key: string, params?: Record<string, string | number>): string {
const translations = locales[locale] || locales[defaultLocale];
let value = getNestedValue(translations, key);
// Replace parameters
if (params) {
Object.entries(params).forEach(([paramKey, paramValue]) => {
value = value.replace(`{${paramKey}}`, String(paramValue));
});
}
return value;
}
// HOW TO ADD NEW LANGUAGES:
// 1. Create a new JSON file in locales/ (e.g., pt.json for Portuguese)
// 2. Add the locale to the Locale type above
// 3. Import and add to the locales object
// 4. Add display name to localeNames
// 5. Add flag to localeFlags
//
// Example for Portuguese:
// import pt from './locales/pt.json';
// export type Locale = 'en' | 'es' | 'pt';
// export const locales = { en, es, pt };
// export const localeNames = { en: 'English', es: 'Español', pt: 'Português' };
// export const localeFlags = { en: '🇺🇸', es: '🇪🇸', pt: '🇧🇷' };

View File

@@ -0,0 +1,321 @@
{
"common": {
"loading": "Loading...",
"error": "An error occurred",
"save": "Save",
"cancel": "Cancel",
"delete": "Delete",
"edit": "Edit",
"create": "Create",
"search": "Search",
"filter": "Filter",
"submit": "Submit",
"back": "Back",
"next": "Next",
"viewAll": "View All",
"learnMore": "Learn More",
"moreInfo": "More Info"
},
"nav": {
"home": "Home",
"events": "Events",
"community": "Community",
"contact": "Contact",
"faq": "FAQ",
"joinEvent": "Join Event",
"login": "Login",
"register": "Sign Up",
"logout": "Logout",
"admin": "Admin",
"dashboard": "My Account"
},
"home": {
"hero": {
"title": "Practice English & Spanish in Asunción",
"subtitle": "Meet people. Learn languages. Have fun.",
"cta": "Join Next Event"
},
"about": {
"title": "What is Spanglish?",
"description": "Spanglish is a language exchange community where Spanish and English speakers come together to practice, learn, and connect. Our monthly events create a friendly environment for language learning through real conversations.",
"feature1": "Monthly Events",
"feature1Desc": "Regular meetups at welcoming venues",
"feature2": "Native Speakers",
"feature2Desc": "Practice with native English and Spanish speakers",
"feature3": "All Levels",
"feature3Desc": "Beginners to advanced are welcome"
},
"nextEvent": {
"title": "Next Event",
"noEvents": "No upcoming events scheduled",
"stayTuned": "Stay tuned for announcements!"
},
"gallery": {
"title": "Our Community"
},
"newsletter": {
"title": "Stay Updated",
"description": "Subscribe to get notified about upcoming events",
"placeholder": "Enter your email",
"button": "Subscribe",
"success": "Thanks for subscribing!",
"error": "Subscription failed. Please try again."
}
},
"events": {
"title": "Events",
"upcoming": "Upcoming Events",
"past": "Past Events",
"noEvents": "No events found",
"details": {
"date": "Date",
"time": "Time",
"location": "Location",
"price": "Price",
"free": "Free",
"capacity": "Capacity",
"spotsLeft": "spots left",
"soldOut": "Sold Out",
"cancelled": "Cancelled",
"eventEnded": "Event Ended"
},
"booking": {
"join": "Join Event",
"book": "Book Now",
"register": "Register"
}
},
"booking": {
"title": "Book Your Spot",
"form": {
"personalInfo": "Your Information",
"fullName": "Full Name",
"fullNamePlaceholder": "Enter your full name",
"firstName": "First Name",
"firstNamePlaceholder": "Enter your first name",
"lastName": "Last Name",
"lastNamePlaceholder": "Enter your last name",
"email": "Email Address",
"emailPlaceholder": "your@email.com",
"phone": "Phone / WhatsApp",
"phonePlaceholder": "+595 XXX XXX XXX",
"preferredLanguage": "Preferred Language",
"paymentMethod": "Payment Method",
"ruc": "RUC (Tax ID)",
"rucPlaceholder": "12345678-9",
"rucOptional": "Optional - for invoice",
"reserveSpot": "Reserve My Spot",
"proceedPayment": "Proceed to Payment",
"termsNote": "By booking, you agree to our terms and conditions.",
"soldOutMessage": "This event is fully booked. Check back later or browse other events.",
"errors": {
"nameRequired": "Please enter your full name",
"firstNameRequired": "Please enter your first name",
"lastNameRequired": "Please enter your last name",
"emailInvalid": "Please enter a valid email address",
"phoneRequired": "Phone number is required",
"bookingFailed": "Booking failed. Please try again.",
"rucInvalidFormat": "Invalid format. Example: 12345678-9",
"rucInvalidCheckDigit": "Invalid RUC. Please verify the number."
}
},
"summary": {
"title": "Booking Summary",
"event": "Event",
"date": "Date",
"price": "Price",
"total": "Total"
},
"confirm": "Confirm Booking",
"success": {
"title": "Booking Confirmed!",
"message": "Your spot has been reserved successfully!",
"description": "We've sent a confirmation to your email.",
"event": "Event",
"date": "Date",
"time": "Time",
"location": "Location",
"ticketId": "Ticket ID",
"instructions": "Please save this ticket ID. You'll need it at check-in.",
"cashNote": "Payment Required",
"cashDescription": "Please bring the exact amount in cash to pay at the event entrance.",
"cardNote": "You will be redirected to complete your card payment shortly.",
"lightningNote": "A Lightning invoice will be generated for payment.",
"emailSent": "A confirmation email has been sent to your inbox.",
"browseEvents": "Browse More Events",
"backHome": "Back to Home"
}
},
"community": {
"title": "Join Our Community",
"subtitle": "Connect with us on social media and stay updated",
"whatsapp": {
"title": "WhatsApp Group",
"description": "Join our WhatsApp group for event updates and community chat",
"button": "Join WhatsApp"
},
"instagram": {
"title": "Instagram",
"description": "Follow us for photos, stories, and announcements",
"button": "Follow Us"
},
"telegram": {
"title": "Telegram Channel",
"description": "Join our Telegram channel for news and announcements",
"button": "Join Telegram"
},
"guidelines": {
"title": "Community Guidelines",
"items": [
"Be respectful to all participants",
"Help others practice - we're all learning",
"Speak in the language you're practicing",
"Have fun and be open to making new friends"
]
},
"volunteer": {
"title": "Become a Volunteer",
"description": "Help us organize events and grow the community",
"button": "Contact Us"
}
},
"contact": {
"title": "Contact Us",
"subtitle": "Have questions? We'd love to hear from you.",
"form": {
"name": "Your Name",
"email": "Your Email",
"message": "Your Message",
"submit": "Send Message"
},
"success": "Message sent successfully!",
"error": "Failed to send message. Please try again.",
"info": {
"email": "Email",
"social": "Social Media"
}
},
"auth": {
"login": {
"title": "Welcome Back",
"subtitle": "Sign in to your account",
"email": "Email",
"password": "Password",
"submit": "Sign In",
"noAccount": "Don't have an account?",
"register": "Sign Up"
},
"register": {
"title": "Create Account",
"subtitle": "Join the Spanglish community",
"name": "Full Name",
"email": "Email",
"password": "Password (min. 8 characters)",
"phone": "Phone (optional)",
"submit": "Create Account",
"hasAccount": "Already have an account?",
"login": "Sign In"
},
"errors": {
"invalidCredentials": "Invalid email or password",
"emailExists": "Email already registered"
}
},
"admin": {
"dashboard": {
"title": "Dashboard",
"welcome": "Welcome back",
"stats": {
"users": "Total Users",
"events": "Total Events",
"tickets": "Total Tickets",
"revenue": "Total Revenue"
}
},
"nav": {
"dashboard": "Dashboard",
"events": "Events",
"bookings": "Bookings",
"tickets": "Tickets",
"users": "Users",
"payments": "Payments",
"contacts": "Messages",
"emails": "Emails",
"gallery": "Gallery",
"settings": "Settings"
},
"events": {
"title": "Manage Events",
"create": "Create Event",
"edit": "Edit Event",
"delete": "Delete Event",
"publish": "Publish",
"unpublish": "Unpublish"
},
"tickets": {
"title": "Manage Tickets",
"checkin": "Check In",
"cancel": "Cancel Ticket",
"status": {
"pending": "Pending",
"confirmed": "Confirmed",
"cancelled": "Cancelled",
"checkedIn": "Checked In"
}
},
"users": {
"title": "Manage Users",
"role": "Role",
"roles": {
"admin": "Admin",
"organizer": "Organizer",
"staff": "Staff",
"marketing": "Marketing",
"user": "User"
}
},
"payments": {
"title": "Payments",
"confirm": "Confirm Payment",
"refund": "Refund",
"status": {
"pending": "Pending",
"paid": "Paid",
"refunded": "Refunded",
"failed": "Failed"
}
}
},
"footer": {
"tagline": "Language exchange community in Asunción",
"links": "Quick Links",
"social": "Follow Us",
"copyright": "© {year} Spanglish. All rights reserved.",
"legal": {
"title": "Legal",
"terms": "Terms & Conditions",
"privacy": "Privacy Policy",
"refund": "Refund Policy"
}
},
"linktree": {
"tagline": "Language Exchange Community",
"nextEvent": "Next Event",
"noEvents": "No upcoming events",
"bookNow": "Book Now",
"joinCommunity": "Join Our Community",
"visitWebsite": "Visit Our Website",
"whatsapp": {
"title": "WhatsApp Community",
"subtitle": "Chat & event updates"
},
"telegram": {
"title": "Telegram Channel",
"subtitle": "News & announcements"
},
"instagram": {
"title": "Instagram",
"subtitle": "Photos & stories"
}
}
}

View File

@@ -0,0 +1,321 @@
{
"common": {
"loading": "Cargando...",
"error": "Ocurrió un error",
"save": "Guardar",
"cancel": "Cancelar",
"delete": "Eliminar",
"edit": "Editar",
"create": "Crear",
"search": "Buscar",
"filter": "Filtrar",
"submit": "Enviar",
"back": "Volver",
"next": "Siguiente",
"viewAll": "Ver Todo",
"learnMore": "Saber Más",
"moreInfo": "Más Info"
},
"nav": {
"home": "Inicio",
"events": "Eventos",
"community": "Comunidad",
"contact": "Contacto",
"faq": "Preguntas Frecuentes",
"joinEvent": "Unirse al Evento",
"login": "Iniciar Sesión",
"register": "Registrarse",
"logout": "Cerrar Sesión",
"admin": "Admin",
"dashboard": "Mi Cuenta"
},
"home": {
"hero": {
"title": "Practica Inglés y Español en Asunción",
"subtitle": "Conoce gente. Aprende idiomas. Diviértete.",
"cta": "Unirse al Próximo Evento"
},
"about": {
"title": "¿Qué es Spanglish?",
"description": "Spanglish es una comunidad de intercambio de idiomas donde hablantes de español e inglés se reúnen para practicar, aprender y conectar. Nuestros eventos mensuales crean un ambiente amigable para el aprendizaje de idiomas a través de conversaciones reales.",
"feature1": "Eventos Mensuales",
"feature1Desc": "Encuentros regulares en lugares acogedores",
"feature2": "Hablantes Nativos",
"feature2Desc": "Practica con hablantes nativos de inglés y español",
"feature3": "Todos los Niveles",
"feature3Desc": "Desde principiantes hasta avanzados"
},
"nextEvent": {
"title": "Próximo Evento",
"noEvents": "No hay eventos programados",
"stayTuned": "¡Mantente atento a los anuncios!"
},
"gallery": {
"title": "Nuestra Comunidad"
},
"newsletter": {
"title": "Mantente Informado",
"description": "Suscríbete para recibir notificaciones sobre próximos eventos",
"placeholder": "Ingresa tu email",
"button": "Suscribirse",
"success": "¡Gracias por suscribirte!",
"error": "Error al suscribirse. Por favor intenta de nuevo."
}
},
"events": {
"title": "Eventos",
"upcoming": "Próximos Eventos",
"past": "Eventos Pasados",
"noEvents": "No se encontraron eventos",
"details": {
"date": "Fecha",
"time": "Hora",
"location": "Ubicación",
"price": "Precio",
"free": "Gratis",
"capacity": "Capacidad",
"spotsLeft": "lugares disponibles",
"soldOut": "Agotado",
"cancelled": "Cancelado",
"eventEnded": "Evento Finalizado"
},
"booking": {
"join": "Unirse al Evento",
"book": "Reservar Ahora",
"register": "Registrarse"
}
},
"booking": {
"title": "Reserva tu Lugar",
"form": {
"personalInfo": "Tu Información",
"fullName": "Nombre Completo",
"fullNamePlaceholder": "Ingresa tu nombre completo",
"firstName": "Nombre",
"firstNamePlaceholder": "Ingresa tu nombre",
"lastName": "Apellido",
"lastNamePlaceholder": "Ingresa tu apellido",
"email": "Correo Electrónico",
"emailPlaceholder": "tu@email.com",
"phone": "Teléfono / WhatsApp",
"phonePlaceholder": "+595 XXX XXX XXX",
"preferredLanguage": "Idioma Preferido",
"paymentMethod": "Método de Pago",
"ruc": "RUC",
"rucPlaceholder": "Ej: 12345678-9",
"rucOptional": "Opcional - para facturación",
"reserveSpot": "Reservar Mi Lugar",
"proceedPayment": "Proceder al Pago",
"termsNote": "Al reservar, aceptas nuestros términos y condiciones.",
"soldOutMessage": "Este evento está lleno. Vuelve más tarde o explora otros eventos.",
"errors": {
"nameRequired": "Por favor ingresa tu nombre completo",
"firstNameRequired": "Por favor ingresa tu nombre",
"lastNameRequired": "Por favor ingresa tu apellido",
"emailInvalid": "Por favor ingresa un correo electrónico válido",
"phoneRequired": "El número de teléfono es requerido",
"bookingFailed": "La reserva falló. Por favor intenta de nuevo.",
"rucInvalidFormat": "Formato inválido. Ej: 12345678-9",
"rucInvalidCheckDigit": "RUC inválido. Verifique el número."
}
},
"summary": {
"title": "Resumen de Reserva",
"event": "Evento",
"date": "Fecha",
"price": "Precio",
"total": "Total"
},
"confirm": "Confirmar Reserva",
"success": {
"title": "¡Reserva Confirmada!",
"message": "¡Tu lugar ha sido reservado exitosamente!",
"description": "Hemos enviado una confirmación a tu correo.",
"event": "Evento",
"date": "Fecha",
"time": "Hora",
"location": "Ubicación",
"ticketId": "ID del Ticket",
"instructions": "Por favor guarda este ID de ticket. Lo necesitarás en el check-in.",
"cashNote": "Pago Requerido",
"cashDescription": "Por favor trae el monto exacto en efectivo para pagar en la entrada del evento.",
"cardNote": "Serás redirigido para completar tu pago con tarjeta en breve.",
"lightningNote": "Se generará una factura Lightning para el pago.",
"emailSent": "Un correo de confirmación ha sido enviado a tu bandeja de entrada.",
"browseEvents": "Ver Más Eventos",
"backHome": "Volver al Inicio"
}
},
"community": {
"title": "Únete a Nuestra Comunidad",
"subtitle": "Conéctate con nosotros en redes sociales",
"whatsapp": {
"title": "Grupo de WhatsApp",
"description": "Únete a nuestro grupo de WhatsApp para actualizaciones y chat comunitario",
"button": "Unirse a WhatsApp"
},
"instagram": {
"title": "Instagram",
"description": "Síguenos para fotos, historias y anuncios",
"button": "Seguirnos"
},
"telegram": {
"title": "Canal de Telegram",
"description": "Únete a nuestro canal de Telegram para noticias y anuncios",
"button": "Unirse a Telegram"
},
"guidelines": {
"title": "Reglas de la Comunidad",
"items": [
"Sé respetuoso con todos los participantes",
"Ayuda a otros a practicar - todos estamos aprendiendo",
"Habla en el idioma que estás practicando",
"Diviértete y abierto a hacer nuevos amigos"
]
},
"volunteer": {
"title": "Conviértete en Voluntario",
"description": "Ayúdanos a organizar eventos y hacer crecer la comunidad",
"button": "Contáctanos"
}
},
"contact": {
"title": "Contáctanos",
"subtitle": "¿Tienes preguntas? Nos encantaría saber de ti.",
"form": {
"name": "Tu Nombre",
"email": "Tu Email",
"message": "Tu Mensaje",
"submit": "Enviar Mensaje"
},
"success": "¡Mensaje enviado exitosamente!",
"error": "Error al enviar el mensaje. Por favor intenta de nuevo.",
"info": {
"email": "Email",
"social": "Redes Sociales"
}
},
"auth": {
"login": {
"title": "Bienvenido de Nuevo",
"subtitle": "Inicia sesión en tu cuenta",
"email": "Email",
"password": "Contraseña",
"submit": "Iniciar Sesión",
"noAccount": "¿No tienes cuenta?",
"register": "Registrarse"
},
"register": {
"title": "Crear Cuenta",
"subtitle": "Únete a la comunidad Spanglish",
"name": "Nombre Completo",
"email": "Email",
"password": "Contraseña (mín. 8 caracteres)",
"phone": "Teléfono (opcional)",
"submit": "Crear Cuenta",
"hasAccount": "¿Ya tienes cuenta?",
"login": "Iniciar Sesión"
},
"errors": {
"invalidCredentials": "Email o contraseña inválidos",
"emailExists": "El email ya está registrado"
}
},
"admin": {
"dashboard": {
"title": "Panel de Control",
"welcome": "Bienvenido de nuevo",
"stats": {
"users": "Usuarios Totales",
"events": "Eventos Totales",
"tickets": "Tickets Totales",
"revenue": "Ingresos Totales"
}
},
"nav": {
"dashboard": "Panel",
"events": "Eventos",
"bookings": "Reservas",
"tickets": "Tickets",
"users": "Usuarios",
"payments": "Pagos",
"contacts": "Mensajes",
"emails": "Emails",
"gallery": "Galería",
"settings": "Configuración"
},
"events": {
"title": "Gestionar Eventos",
"create": "Crear Evento",
"edit": "Editar Evento",
"delete": "Eliminar Evento",
"publish": "Publicar",
"unpublish": "Despublicar"
},
"tickets": {
"title": "Gestionar Tickets",
"checkin": "Check In",
"cancel": "Cancelar Ticket",
"status": {
"pending": "Pendiente",
"confirmed": "Confirmado",
"cancelled": "Cancelado",
"checkedIn": "Check In Realizado"
}
},
"users": {
"title": "Gestionar Usuarios",
"role": "Rol",
"roles": {
"admin": "Administrador",
"organizer": "Organizador",
"staff": "Staff",
"marketing": "Marketing",
"user": "Usuario"
}
},
"payments": {
"title": "Pagos",
"confirm": "Confirmar Pago",
"refund": "Reembolsar",
"status": {
"pending": "Pendiente",
"paid": "Pagado",
"refunded": "Reembolsado",
"failed": "Fallido"
}
}
},
"footer": {
"tagline": "Comunidad de intercambio de idiomas en Asunción",
"links": "Enlaces Rápidos",
"social": "Síguenos",
"copyright": "© {year} Spanglish. Todos los derechos reservados.",
"legal": {
"title": "Legal",
"terms": "Términos y Condiciones",
"privacy": "Política de Privacidad",
"refund": "Política de Reembolso"
}
},
"linktree": {
"tagline": "Comunidad de Intercambio de Idiomas",
"nextEvent": "Próximo Evento",
"noEvents": "No hay eventos próximos",
"bookNow": "Reservar Ahora",
"joinCommunity": "Únete a Nuestra Comunidad",
"visitWebsite": "Visitar Nuestro Sitio",
"whatsapp": {
"title": "Comunidad WhatsApp",
"subtitle": "Chat y novedades"
},
"telegram": {
"title": "Canal de Telegram",
"subtitle": "Noticias y anuncios"
},
"instagram": {
"title": "Instagram",
"subtitle": "Fotos e historias"
}
}
}