From 86ef0e2d75f1f5e592036f58a42a387fab20f7ac Mon Sep 17 00:00:00 2001 From: DavidHerran Date: Wed, 8 Apr 2026 12:47:26 -0500 Subject: [PATCH] agregar idiomas a parts --- messages/de.json | 53 ++++++++++++++++--- messages/en.json | 53 ++++++++++++++++--- messages/es.json | 53 ++++++++++++++++--- messages/it.json | 53 ++++++++++++++++--- messages/vec.json | 53 ++++++++++++++++--- .../[locale]/parts/_components/AuthModal.tsx | 39 +++++++------- .../parts/_components/ComponentGrid.tsx | 31 ++++++----- .../parts/_components/PartDetailsModal.tsx | 11 ++-- 8 files changed, 270 insertions(+), 76 deletions(-) diff --git a/messages/de.json b/messages/de.json index 3848779..98d420f 100644 --- a/messages/de.json +++ b/messages/de.json @@ -12,12 +12,6 @@ "description1": "Innovationen vorantreiben, wo andere zögern", "description2": "RF-Lösungen der nächsten Generation mit unübertroffener Präzision und europäischer Exzellenz." }, - "SpareParts": { - "title1": "Komponenten-", - "title2": "Matrix.", - "description": "Original FLUX Ersatzteile und Upgrades. Gewährleisten Sie maximale Leistung und Langlebigkeit für Ihre RF-Anlagen.", - "quoteBased": "Auf Anfrage" - }, "CartDrawer": { "titleSupport": "Technischer Support", "titleCart": "Warenkorb", @@ -165,5 +159,50 @@ "companyStory": "Unsere Geschichte", "companyMap": "Globales Netzwerk", "companyNews": "Inside Flux" - } + }, + "SpareParts": { + "title1": "Komponenten-", + "title2": "Matrix.", + "description": "Original FLUX Ersatzteile und Upgrades. Gewährleisten Sie maximale Leistung und Langlebigkeit für Ihre RF-Anlagen.", + "quoteBased": "Auf Anfrage", + "searchPlaceholder": "Suche nach SKU, Name oder Spezifikation...", + "componentsFound": "Komponenten gefunden", + "componentFound": "Komponente gefunden", + "noComponents": "Keine Komponenten gefunden", + "clearSearch": "Suche löschen", + "accessRestricted": "Zugriff eingeschränkt", + "accessDescription": "Die FLUX Komponenten-Matrix ist ein exklusives B2B-Portal. Bitte melden Sie sich mit Ihrem Geschäftskonto an oder fordern Sie Zugriff an, um Komponenten, Preise und technische Datenblätter einzusehen.", + "signIn": "Anmelden", + "requestAccess": "Zugriff anfordern", + "b2bLogin": "B2B-Login", + "addToCart": "Zum Warenkorb hinzufügen", + "unitPrice": "Stückpreis", + "productOverview": "Produktübersicht", + "techSpecs": "Technische Spezifikationen", + "noMedia": "Keine Medien verfügbar", + "mediaGallery": "Mediengalerie", + "page": "Seite", + "of": "von" + }, + "AuthModal": { + "b2bPortal": "B2B-Portal", + "signIn": "Anmelden", + "requestAccess": "Zugriff anfordern", + "corporateEmail": "Geschäftliche E-Mail", + "password": "Passwort", + "accessPortal": "Sicheres Portal betreten", + "fullName": "Vollständiger Name", + "companyName": "Firmenname", + "workEmail": "Arbeits-E-Mail", + "createPassword": "Passwort erstellen", + "submitRequest": "Anfrage absenden", + "successMessage": "Zugriff erfolgreich angefordert. Wir benachrichtigen Sie per E-Mail nach technischer Prüfung.", + "updateCredentials": "Sicherheitsdaten aktualisieren", + "currentPassword": "Aktuelles Passwort", + "newPassword": "Neues Passwort", + "changePassword": "Passwort ändern", + "passwordUpdated": "Passwort sicher aktualisiert.", + "secureLogout": "Sicherer Logout", + "invalidCredentials": "Ungültige Anmeldedaten." + } } \ No newline at end of file diff --git a/messages/en.json b/messages/en.json index 016a3b6..9521fcf 100644 --- a/messages/en.json +++ b/messages/en.json @@ -12,12 +12,6 @@ "description1": "Driving innovation where others hesitate", "description2": "Crafting Next-Gen RF Solutions With Unmatched Precision and European Excellence." }, - "SpareParts": { - "title1": "Component", - "title2": "Matrix.", - "description": "Original FLUX replacement parts and upgrades. Ensure maximum performance and longevity for your RF equipment.", - "quoteBased": "Quote Based" - }, "CartDrawer": { "titleSupport": "Tech Support", "titleCart": "Operations Cart", @@ -165,5 +159,50 @@ "companyStory": "Our Story", "companyMap": "Global Network", "companyNews": "Inside Flux" - } + }, + "SpareParts": { + "title1": "Component", + "title2": "Matrix.", + "description": "Original FLUX replacement parts and upgrades. Ensure maximum performance and longevity for your RF equipment.", + "quoteBased": "Quote Based", + "searchPlaceholder": "Search by SKU, name or spec...", + "componentsFound": "components found", + "componentFound": "component found", + "noComponents": "No components found", + "clearSearch": "Clear search", + "accessRestricted": "Access Restricted", + "accessDescription": "The FLUX Component Matrix is an exclusive B2B portal. Please sign in with your corporate account or request access to view components, pricing, and technical datasheets.", + "signIn": "Sign In", + "requestAccess": "Request Access", + "b2bLogin": "B2B Login", + "addToCart": "Add to Operations Cart", + "unitPrice": "Unit Price", + "productOverview": "Product Overview", + "techSpecs": "Technical Specifications", + "noMedia": "No Media Available", + "mediaGallery": "Media Gallery", + "page": "Page", + "of": "of" +}, +"AuthModal": { + "b2bPortal": "B2B Portal", + "signIn": "Sign In", + "requestAccess": "Request Access", + "corporateEmail": "Corporate Email", + "password": "Password", + "accessPortal": "Access Secure Portal", + "fullName": "Full Name", + "companyName": "Company Name", + "workEmail": "Work Email", + "createPassword": "Create Password", + "submitRequest": "Submit Request", + "successMessage": "Access requested successfully. We will notify you via email upon engineering approval.", + "updateCredentials": "Update Security Credentials", + "currentPassword": "Current Password", + "newPassword": "New Password", + "changePassword": "Change Password", + "passwordUpdated": "Password updated securely.", + "secureLogout": "Secure Logout", + "invalidCredentials": "Invalid credentials." +} } \ No newline at end of file diff --git a/messages/es.json b/messages/es.json index 1e6e66e..97fc889 100644 --- a/messages/es.json +++ b/messages/es.json @@ -12,12 +12,6 @@ "description1": "Impulsando la innovación donde otros dudan", "description2": "Creando soluciones de RF de última generación con precisión inigualable y excelencia europea." }, - "SpareParts": { - "title1": "Matriz de", - "title2": "Componentes.", - "description": "Repuestos y actualizaciones originales de FLUX. Asegure el máximo rendimiento y longevidad para su equipo de RF.", - "quoteBased": "Bajo Cotización" - }, "CartDrawer": { "titleSupport": "Soporte Técnico", "titleCart": "Carrito de Operaciones", @@ -165,5 +159,50 @@ "companyStory": "Nuestra Historia", "companyMap": "Red Global", "companyNews": "Inside Flux" - } + }, + "SpareParts": { + "title1": "Matriz de", + "title2": "Componentes.", + "description": "Repuestos y actualizaciones originales de FLUX. Asegure el máximo rendimiento y longevidad para su equipo de RF.", + "quoteBased": "Bajo Cotización", + "searchPlaceholder": "Buscar por SKU, nombre o especificación...", + "componentsFound": "componentes encontrados", + "componentFound": "componente encontrado", + "noComponents": "No se encontraron componentes", + "clearSearch": "Limpiar búsqueda", + "accessRestricted": "Acceso Restringido", + "accessDescription": "La Matriz de Componentes FLUX es un portal exclusivo B2B. Por favor, inicie sesión con su cuenta corporativa o solicite acceso para ver componentes, precios y fichas técnicas.", + "signIn": "Iniciar Sesión", + "requestAccess": "Solicitar Acceso", + "b2bLogin": "Login B2B", + "addToCart": "Añadir al Carrito de Operaciones", + "unitPrice": "Precio Unitario", + "productOverview": "Descripción del Producto", + "techSpecs": "Especificaciones Técnicas", + "noMedia": "No hay archivos multimedia", + "mediaGallery": "Galería de Medios", + "page": "Página", + "of": "de" + }, + "AuthModal": { + "b2bPortal": "Portal B2B", + "signIn": "Iniciar Sesión", + "requestAccess": "Solicitar Acceso", + "corporateEmail": "Correo Corporativo", + "password": "Contraseña", + "accessPortal": "Acceder al Portal Seguro", + "fullName": "Nombre Completo", + "companyName": "Nombre de la Empresa", + "workEmail": "Correo de Trabajo", + "createPassword": "Crear Contraseña", + "submitRequest": "Enviar Solicitud", + "successMessage": "Acceso solicitado con éxito. Le notificaremos por correo tras la aprobación de ingeniería.", + "updateCredentials": "Actualizar Credenciales de Seguridad", + "currentPassword": "Contraseña Actual", + "newPassword": "Nueva Contraseña", + "changePassword": "Cambiar Contraseña", + "passwordUpdated": "Contraseña actualizada de forma segura.", + "secureLogout": "Cierre de Sesión Seguro", + "invalidCredentials": "Credenciales inválidas." + } } \ No newline at end of file diff --git a/messages/it.json b/messages/it.json index 67e9357..98f8716 100644 --- a/messages/it.json +++ b/messages/it.json @@ -12,12 +12,6 @@ "description1": "Guidare l'innovazione dove altri esitano", "description2": "Creare soluzioni RF di prossima generazione con precisione impareggiabile ed eccellenza europea." }, - "SpareParts": { - "title1": "Matrice", - "title2": "Componenti.", - "description": "Ricambi e aggiornamenti originali FLUX. Garantite la massima resa e longevità alle vostre apparecchiature RF.", - "quoteBased": "Su Preventivo" - }, "CartDrawer": { "titleSupport": "Supporto Tecnico", "titleCart": "Carrello Operazioni", @@ -165,5 +159,50 @@ "companyStory": "La nostra Storia", "companyMap": "Rete Globale", "companyNews": "Dentro Flux" - } + }, + "SpareParts": { + "title1": "Matrice", + "title2": "Componenti.", + "description": "Ricambi e aggiornamenti originali FLUX. Garantite la massima resa e longevità alle vostre apparecchiature RF.", + "quoteBased": "Su Preventivo", + "searchPlaceholder": "Cerca per SKU, nome o specifica...", + "componentsFound": "componenti trovati", + "componentFound": "componente trovato", + "noComponents": "Nessun componente trovato", + "clearSearch": "Cancella ricerca", + "accessRestricted": "Accesso Limitato", + "accessDescription": "La Matrice Componenti FLUX è un portale esclusivo B2B. Accedi con il tuo account aziendale o richiedi l'accesso per visualizzare componenti, prezzi e schede tecniche.", + "signIn": "Accedi", + "requestAccess": "Richiedi Accesso", + "b2bLogin": "Login B2B", + "addToCart": "Aggiungi al Carrello Operazioni", + "unitPrice": "Prezzo Unitario", + "productOverview": "Panoramica Prodotto", + "techSpecs": "Specifiche Tecniche", + "noMedia": "Nessun file multimediale", + "mediaGallery": "Galleria Media", + "page": "Pagina", + "of": "di" + }, + "AuthModal": { + "b2bPortal": "Portale B2B", + "signIn": "Accedi", + "requestAccess": "Richiedi Accesso", + "corporateEmail": "Email Aziendale", + "password": "Password", + "accessPortal": "Accedi al Portale Sicuro", + "fullName": "Nome Completo", + "companyName": "Ragione Sociale", + "workEmail": "Email di Lavoro", + "createPassword": "Crea Password", + "submitRequest": "Invia Richiesta", + "successMessage": "Accesso richiesto con successo. Ti informeremo via email previa approvazione tecnica.", + "updateCredentials": "Aggiorna Credenziali di Sicurezza", + "currentPassword": "Password Attuale", + "newPassword": "Nuova Password", + "changePassword": "Cambia Password", + "passwordUpdated": "Password aggiornata con successo.", + "secureLogout": "Logout Sicuro", + "invalidCredentials": "Credenziali non valide." + } } \ No newline at end of file diff --git a/messages/vec.json b/messages/vec.json index 34bf151..9792ec7 100644 --- a/messages/vec.json +++ b/messages/vec.json @@ -12,12 +12,6 @@ "description1": "Spingemo l'inovaçion dove i altri i se ferma", "description2": "Solusion RF de nova generasiòn con na preciçion mai vista e l'ecełensa de casa nostra." }, - "SpareParts": { - "title1": "Matriçe dei", - "title2": "Pessi.", - "description": "Pessi de ricambio e agiornamenti par omini veri firmà FLUX. Par far ndar la machina de RF sempre a tura e par tanto tempo.", - "quoteBased": "Dimanda el preso" - }, "CartDrawer": { "titleSupport": "Asistensa Tecnica", "titleCart": "Careło Operasion", @@ -165,5 +159,50 @@ "companyStory": "La nostra Storia", "companyMap": "Rede Global", "companyNews": "Drento Flux" - } + }, + "SpareParts": { + "title1": "Matriçe dei", + "title2": "Pessi.", + "description": "Pessi de ricambio e agiornamenti par omini veri firmà FLUX. Par far ndar la machina de RF sempre a tura e par tanto tempo.", + "quoteBased": "Dimanda el preso", + "searchPlaceholder": "Serca par SKU, nome o detajo...", + "componentsFound": "pessi catà", + "componentFound": "pesso catà", + "noComponents": "No go catà gnente", + "clearSearch": "Scanceła la riserca", + "accessRestricted": "No te poi entrar", + "accessDescription": "La Matriçe dei Pessi FLUX la xe solo par i laoradori. Par piaçer, meti drento i to dati o dimanda de entrar par vedar i pessi, i presi e le carte tecniche.", + "signIn": "Entra chive", + "requestAccess": "Dimanda de entrar", + "b2bLogin": "Login par ditte", + "addToCart": "Meti drento el careło", + "unitPrice": "Preso par pesso", + "productOverview": "Cossa che el xe", + "techSpecs": "Detaji tecnici", + "noMedia": "No go foto da mostrare", + "mediaGallery": "Gałeria de foto", + "page": "Pagina", + "of": "de" + }, + "AuthModal": { + "b2bPortal": "Portal par ditte", + "signIn": "Entra chive", + "requestAccess": "Dimanda de entrar", + "corporateEmail": "Email de la ditta", + "password": "Ciave (Password)", + "accessPortal": "Entra nel portal sicuro", + "fullName": "Nome e cognome", + "companyName": "Nome de la ditta", + "workEmail": "Email de lavoro", + "createPassword": "Fà na ciave nova", + "submitRequest": "Manda la dimanda", + "successMessage": "Te go meso in lista. Te mandemo na mail quando che i ingegneri i ga dito de sì.", + "updateCredentials": "Inpissà i dati de sicuressa", + "currentPassword": "Ciave de desso", + "newPassword": "Ciave nova", + "changePassword": "Cambia la ciave", + "passwordUpdated": "Ciave agiornà al sicuro.", + "secureLogout": "Va fora col seguro", + "invalidCredentials": "Dati no giusti." + } } \ No newline at end of file diff --git a/src/app/[locale]/parts/_components/AuthModal.tsx b/src/app/[locale]/parts/_components/AuthModal.tsx index d969ab5..0a9ce52 100644 --- a/src/app/[locale]/parts/_components/AuthModal.tsx +++ b/src/app/[locale]/parts/_components/AuthModal.tsx @@ -5,6 +5,7 @@ import { motion, AnimatePresence } from "framer-motion"; import { X, KeyRound, Building2, User, Mail, LogOut, ShieldCheck, Sparkles, Loader2, Lock } from "lucide-react"; import { loginClient, registerClientRequest, logoutClient, updateClientPassword } from "@/app/actions/clientAuth"; import { useRouter } from "next/navigation"; +import { useTranslations } from "next-intl"; export default function AuthModal({ session }: { session: any }) { const [isOpen, setIsOpen] = useState(false); @@ -13,6 +14,7 @@ export default function AuthModal({ session }: { session: any }) { const [error, setError] = useState(null); const [success, setSuccess] = useState(null); const router = useRouter(); + const t = useTranslations("AuthModal"); useEffect(() => { const handleOpen = (e: Event) => { @@ -57,7 +59,7 @@ export default function AuthModal({ session }: { session: any }) { if (res.error) { setError(res.error); } else { - setSuccess("Access requested successfully. We will notify you via email upon engineering approval."); + setSuccess(t("successMessage")); form.reset(); } setIsLoading(false); @@ -75,7 +77,7 @@ export default function AuthModal({ session }: { session: any }) { if (res.error) { setError(res.error); } else { - setSuccess("Password updated securely."); + setSuccess(t("passwordUpdated")); form.reset(); } setIsLoading(false); @@ -104,7 +106,6 @@ export default function AuthModal({ session }: { session: any }) { exit={{ opacity: 0, scale: 0.95 }} className="relative w-full max-w-md bg-white dark:bg-[#111] rounded-[2rem] shadow-2xl overflow-hidden border border-black/5 dark:border-white/10" > - {/* 🔥 FIX: Z-INDEX 100 PARA EVITAR BLOQUEOS */} - + + )} @@ -138,15 +139,15 @@ export default function AuthModal({ session }: { session: any }) { {mode === "LOGIN" && !session && (
- +
- +
)} @@ -154,23 +155,23 @@ export default function AuthModal({ session }: { session: any }) { {mode === "REGISTER" && !session && (
- +
- +
- +
- +
)} @@ -188,15 +189,15 @@ export default function AuthModal({ session }: { session: any }) {
-

Update Security Credentials

- - +

{t("updateCredentials")}

+ +
)} diff --git a/src/app/[locale]/parts/_components/ComponentGrid.tsx b/src/app/[locale]/parts/_components/ComponentGrid.tsx index 3caab41..e447c5f 100644 --- a/src/app/[locale]/parts/_components/ComponentGrid.tsx +++ b/src/app/[locale]/parts/_components/ComponentGrid.tsx @@ -16,7 +16,7 @@ interface ComponentGridProps { currentPage: number; totalPages: number; totalItems: number; - session: any | null; // 🔥 LA SESIÓN DETERMINA TODO + session: any | null; } export default function ComponentGrid({ initialParts, locale, query, currentPage, totalPages, totalItems, session }: ComponentGridProps) { @@ -33,7 +33,7 @@ export default function ComponentGrid({ initialParts, locale, query, currentPage useEffect(() => { const timeoutId = setTimeout(() => { - if (searchTerm !== query && session) { // Solo busca si hay sesión + if (searchTerm !== query && session) { const params = new URLSearchParams(searchParams.toString()); if (searchTerm) { params.set('q', searchTerm); params.set('page', '1'); } else { params.delete('q'); } @@ -57,7 +57,6 @@ export default function ComponentGrid({ initialParts, locale, query, currentPage router.push(`${pathname}?${params.toString()}`); }; - // 🔥 EVENTO PARA ABRIR MODAL const openAuth = (mode: "LOGIN" | "REGISTER") => { window.dispatchEvent(new CustomEvent('flux:open-auth', { detail: { mode } })); }; @@ -66,48 +65,48 @@ export default function ComponentGrid({ initialParts, locale, query, currentPage <> - {/* 🔥 BOTÓN FLOTANTE DE PERFIL / LOGIN (Arriba a la derecha) */} + {/* Floating profile / login button */}
- {/* 🛑 ESTADO BLOQUEADO (Visitantes sin sesión) */} + {/* Locked state (visitors without session) */} {!session ? (
-

Access Restricted

+

{t("accessRestricted")}

- The FLUX Component Matrix is an exclusive B2B portal. Please sign in with your corporate account or request access to view components, pricing, and technical datasheets. + {t("accessDescription")}

- - + +
) : ( - /* ✅ ESTADO DESBLOQUEADO (Catálogo Completo) */ + /* Unlocked state (full catalog) */ <>
- setSearchTerm(e.target.value)} placeholder="Search by SKU, name or spec..." className="w-full bg-white dark:bg-[#111] border border-black/10 dark:border-white/10 rounded-full pl-12 pr-10 py-3.5 text-sm text-[#1D1D1F] dark:text-white outline-none focus:border-[#0066CC] dark:focus:border-amber-500 transition-colors shadow-sm" /> + setSearchTerm(e.target.value)} placeholder={t("searchPlaceholder")} className="w-full bg-white dark:bg-[#111] border border-black/10 dark:border-white/10 rounded-full pl-12 pr-10 py-3.5 text-sm text-[#1D1D1F] dark:text-white outline-none focus:border-[#0066CC] dark:focus:border-amber-500 transition-colors shadow-sm" /> {searchTerm && }
-
{totalItems} {totalItems === 1 ? "component found" : "components found"}
+
{totalItems} {totalItems === 1 ? t("componentFound") : t("componentsFound")}
{initialParts.length === 0 ? (
-

No components found

- +

{t("noComponents")}

+
) : (
@@ -137,7 +136,7 @@ export default function ComponentGrid({ initialParts, locale, query, currentPage {totalPages > 1 && (
- Page {currentPage} of {totalPages} + {t("page")} {currentPage} {t("of")} {totalPages}
)} diff --git a/src/app/[locale]/parts/_components/PartDetailsModal.tsx b/src/app/[locale]/parts/_components/PartDetailsModal.tsx index 7e2c164..0161ba3 100644 --- a/src/app/[locale]/parts/_components/PartDetailsModal.tsx +++ b/src/app/[locale]/parts/_components/PartDetailsModal.tsx @@ -97,7 +97,7 @@ export default function PartDetailsModal({ part, isOpen, onClose }: PartDetailsM ) : (
-

No Media Available

+

{t("noMedia")}

)}
@@ -140,7 +140,7 @@ export default function PartDetailsModal({ part, isOpen, onClose }: PartDetailsM
-

Unit Price

+

{t("unitPrice")}

{part.showPrice && part.price ? (

€{part.price.toFixed(2)}

) : ( @@ -157,10 +157,9 @@ export default function PartDetailsModal({ part, isOpen, onClose }: PartDetailsM {part.description && part.description !== "Draft description..." && (

- Product Overview + {t("productOverview")}

- {/* 🔥 APLICAMOS TU PARSER AQUÍ 🔥 */} {renderMarkdown(part.description)}
@@ -170,7 +169,7 @@ export default function PartDetailsModal({ part, isOpen, onClose }: PartDetailsM {specs.length > 0 && (

- Technical Specifications + {t("techSpecs")}

{specs.map((spec, idx) => ( @@ -190,7 +189,7 @@ export default function PartDetailsModal({ part, isOpen, onClose }: PartDetailsM onClick={handleAddToCart} className="w-full bg-[#1D1D1F] dark:bg-amber-500 text-white dark:text-black py-4 rounded-xl font-semibold flex items-center justify-center gap-2 transition-transform active:scale-[0.98] hover:shadow-lg dark:hover:shadow-[0_0_20px_rgba(245,158,11,0.3)]" > - Add to Operations Cart + {t("addToCart")}