Update help/docs pages to use i18n translations

- Update locales/index.ts to import help namespace for all languages
- Convert DocumentationPage.tsx to use useTranslation('help')
  * All sections now use translation keys from help.json
  * Difficulty labels, categories, and articles fully internationalized
  * UI strings (titles, buttons, placeholders) use translations
- Convert HelpCenterPage.tsx to use useTranslation('help')
  * Categories loaded from translations
  * FAQs loaded dynamically from help.json array
  * All UI strings internationalized (search, titles, contact info)
- Both pages now support Spanish, English, and Basque languages
- Maintains full backward compatibility with existing Spanish content

Result: Complete i18n implementation for /help and /help/docs routes
This commit is contained in:
Claude
2025-11-18 12:07:37 +00:00
parent c41ba0030e
commit d98fed0cd0
3 changed files with 128 additions and 209 deletions

View File

@@ -17,6 +17,7 @@ import reasoningEs from './es/reasoning.json';
import wizardsEs from './es/wizards.json'; import wizardsEs from './es/wizards.json';
import subscriptionEs from './es/subscription.json'; import subscriptionEs from './es/subscription.json';
import purchaseOrdersEs from './es/purchase_orders.json'; import purchaseOrdersEs from './es/purchase_orders.json';
import helpEs from './es/help.json';
// English translations // English translations
import commonEn from './en/common.json'; import commonEn from './en/common.json';
@@ -37,6 +38,7 @@ import reasoningEn from './en/reasoning.json';
import wizardsEn from './en/wizards.json'; import wizardsEn from './en/wizards.json';
import subscriptionEn from './en/subscription.json'; import subscriptionEn from './en/subscription.json';
import purchaseOrdersEn from './en/purchase_orders.json'; import purchaseOrdersEn from './en/purchase_orders.json';
import helpEn from './en/help.json';
// Basque translations // Basque translations
import commonEu from './eu/common.json'; import commonEu from './eu/common.json';
@@ -57,6 +59,7 @@ import reasoningEu from './eu/reasoning.json';
import wizardsEu from './eu/wizards.json'; import wizardsEu from './eu/wizards.json';
import subscriptionEu from './eu/subscription.json'; import subscriptionEu from './eu/subscription.json';
import purchaseOrdersEu from './eu/purchase_orders.json'; import purchaseOrdersEu from './eu/purchase_orders.json';
import helpEu from './eu/help.json';
// Translation resources by language // Translation resources by language
export const resources = { export const resources = {
@@ -79,6 +82,7 @@ export const resources = {
wizards: wizardsEs, wizards: wizardsEs,
subscription: subscriptionEs, subscription: subscriptionEs,
purchase_orders: purchaseOrdersEs, purchase_orders: purchaseOrdersEs,
help: helpEs,
}, },
en: { en: {
common: commonEn, common: commonEn,
@@ -99,6 +103,7 @@ export const resources = {
wizards: wizardsEn, wizards: wizardsEn,
subscription: subscriptionEn, subscription: subscriptionEn,
purchase_orders: purchaseOrdersEn, purchase_orders: purchaseOrdersEn,
help: helpEn,
}, },
eu: { eu: {
common: commonEu, common: commonEu,
@@ -119,6 +124,7 @@ export const resources = {
wizards: wizardsEu, wizards: wizardsEu,
subscription: subscriptionEu, subscription: subscriptionEu,
purchase_orders: purchaseOrdersEu, purchase_orders: purchaseOrdersEu,
help: helpEu,
}, },
}; };
@@ -155,7 +161,7 @@ export const languageConfig = {
}; };
// Namespaces available in translations // Namespaces available in translations
export const namespaces = ['common', 'auth', 'inventory', 'foodSafety', 'suppliers', 'orders', 'recipes', 'errors', 'dashboard', 'production', 'equipment', 'landing', 'settings', 'ajustes', 'reasoning', 'wizards', 'subscription', 'purchase_orders'] as const; export const namespaces = ['common', 'auth', 'inventory', 'foodSafety', 'suppliers', 'orders', 'recipes', 'errors', 'dashboard', 'production', 'equipment', 'landing', 'settings', 'ajustes', 'reasoning', 'wizards', 'subscription', 'purchase_orders', 'help'] as const;
export type Namespace = typeof namespaces[number]; export type Namespace = typeof namespaces[number];
// Helper function to get language display name // Helper function to get language display name
@@ -169,7 +175,7 @@ export const isSupportedLanguage = (language: string): language is SupportedLang
}; };
// Export individual language modules for direct imports // Export individual language modules for direct imports
export { commonEs, authEs, inventoryEs, foodSafetyEs, suppliersEs, ordersEs, recipesEs, errorsEs, equipmentEs, landingEs, settingsEs, ajustesEs, reasoningEs, wizardsEs, wizardsEn, wizardsEu }; export { commonEs, authEs, inventoryEs, foodSafetyEs, suppliersEs, ordersEs, recipesEs, errorsEs, equipmentEs, landingEs, settingsEs, ajustesEs, reasoningEs, wizardsEs, wizardsEn, wizardsEu, helpEs, helpEn, helpEu };
// Default export with all translations // Default export with all translations
export default resources; export default resources;

View File

@@ -39,129 +39,129 @@ interface DocArticle {
} }
const DocumentationPage: React.FC = () => { const DocumentationPage: React.FC = () => {
const { t } = useTranslation(); const { t } = useTranslation('help');
const [activeSection, setActiveSection] = useState<string>('getting-started'); const [activeSection, setActiveSection] = useState<string>('getting-started');
const sections: DocSection[] = [ const sections: DocSection[] = [
{ {
id: 'getting-started', id: 'getting-started',
title: 'Primeros Pasos', title: t('categories.gettingStarted.title'),
description: 'Todo lo que necesitas para comenzar', description: t('categories.gettingStarted.description'),
icon: Rocket, icon: Rocket,
articles: [ articles: [
{ {
id: 'quick-start', id: 'quick-start',
title: 'Guía de Inicio Rápido', title: t('articles.gettingStarted.quickStart.title'),
description: 'Configura tu cuenta en 10 minutos', description: t('articles.gettingStarted.quickStart.description'),
readTime: '5 min', readTime: `${t('articles.gettingStarted.quickStart.readTime')} ${t('docs.readTime')}`,
difficulty: 'beginner', difficulty: 'beginner',
}, },
{ {
id: 'import-data', id: 'import-data',
title: 'Importar Datos Históricos', title: t('articles.gettingStarted.importData.title'),
description: 'Cómo subir tu historial de ventas desde Excel o TPV', description: t('articles.gettingStarted.importData.description'),
readTime: '8 min', readTime: `${t('articles.gettingStarted.importData.readTime')} ${t('docs.readTime')}`,
difficulty: 'beginner', difficulty: 'beginner',
}, },
{ {
id: 'products-catalog', id: 'products-catalog',
title: 'Configurar Catálogo de Productos', title: t('articles.gettingStarted.productsCatalog.title'),
description: 'Añade tus productos, recetas e ingredientes', description: t('articles.gettingStarted.productsCatalog.description'),
readTime: '6 min', readTime: `${t('articles.gettingStarted.productsCatalog.readTime')} ${t('docs.readTime')}`,
difficulty: 'beginner', difficulty: 'beginner',
}, },
{ {
id: 'first-prediction', id: 'first-prediction',
title: 'Tu Primera Predicción', title: t('articles.gettingStarted.firstPrediction.title'),
description: 'Interpreta y ajusta las predicciones de demanda', description: t('articles.gettingStarted.firstPrediction.description'),
readTime: '10 min', readTime: `${t('articles.gettingStarted.firstPrediction.readTime')} ${t('docs.readTime')}`,
difficulty: 'beginner', difficulty: 'beginner',
}, },
], ],
}, },
{ {
id: 'features', id: 'features',
title: 'Funcionalidades', title: t('categories.features.title'),
description: 'Guías detalladas de cada módulo', description: t('categories.features.description'),
icon: Package, icon: Package,
articles: [ articles: [
{ {
id: 'demand-forecasting', id: 'demand-forecasting',
title: 'Predicción de Demanda con IA', title: t('articles.features.demandForecasting.title'),
description: 'Cómo funciona el algoritmo y cómo sacarle el máximo partido', description: t('articles.features.demandForecasting.description'),
readTime: '12 min', readTime: `${t('articles.features.demandForecasting.readTime')} ${t('docs.readTime')}`,
difficulty: 'intermediate', difficulty: 'intermediate',
}, },
{ {
id: 'production-planning', id: 'production-planning',
title: 'Planificación de Producción', title: t('articles.features.productionPlanning.title'),
description: 'Optimiza tu horneado diario basándote en predicciones', description: t('articles.features.productionPlanning.description'),
readTime: '10 min', readTime: `${t('articles.features.productionPlanning.readTime')} ${t('docs.readTime')}`,
difficulty: 'intermediate', difficulty: 'intermediate',
}, },
{ {
id: 'inventory-management', id: 'inventory-management',
title: 'Gestión de Inventario', title: t('articles.features.inventoryManagement.title'),
description: 'Controla stock, proveedores y compras', description: t('articles.features.inventoryManagement.description'),
readTime: '9 min', readTime: `${t('articles.features.inventoryManagement.readTime')} ${t('docs.readTime')}`,
difficulty: 'intermediate', difficulty: 'intermediate',
}, },
{ {
id: 'pos-integration', id: 'pos-integration',
title: 'Punto de Venta (TPV)', title: t('articles.features.posIntegration.title'),
description: 'Registra ventas y sincroniza con predicciones', description: t('articles.features.posIntegration.description'),
readTime: '8 min', readTime: `${t('articles.features.posIntegration.readTime')} ${t('docs.readTime')}`,
difficulty: 'beginner', difficulty: 'beginner',
}, },
{ {
id: 'waste-tracking', id: 'waste-tracking',
title: 'Seguimiento de Desperdicios', title: t('articles.features.wasteTracking.title'),
description: 'Mide, analiza y reduce el desperdicio alimentario', description: t('articles.features.wasteTracking.description'),
readTime: '7 min', readTime: `${t('articles.features.wasteTracking.readTime')} ${t('docs.readTime')}`,
difficulty: 'beginner', difficulty: 'beginner',
}, },
], ],
}, },
{ {
id: 'analytics', id: 'analytics',
title: 'Análisis e Insights', title: t('categories.analytics.title'),
description: 'Interpreta tus datos y métricas', description: t('categories.analytics.description'),
icon: BarChart3, icon: BarChart3,
articles: [ articles: [
{ {
id: 'dashboard-overview', id: 'dashboard-overview',
title: 'Panel de Control', title: t('articles.analytics.dashboardOverview.title'),
description: 'Entiende todas las métricas clave de un vistazo', description: t('articles.analytics.dashboardOverview.description'),
readTime: '8 min', readTime: `${t('articles.analytics.dashboardOverview.readTime')} ${t('docs.readTime')}`,
difficulty: 'beginner', difficulty: 'beginner',
}, },
{ {
id: 'reports', id: 'reports',
title: 'Informes y Reportes', title: t('articles.analytics.reports.title'),
description: 'Genera y exporta informes personalizados', description: t('articles.analytics.reports.description'),
readTime: '10 min', readTime: `${t('articles.analytics.reports.readTime')} ${t('docs.readTime')}`,
difficulty: 'intermediate', difficulty: 'intermediate',
}, },
{ {
id: 'ai-insights', id: 'ai-insights',
title: 'Insights de IA', title: t('articles.analytics.aiInsights.title'),
description: 'Descubre patrones y oportunidades automáticamente', description: t('articles.analytics.aiInsights.description'),
readTime: '12 min', readTime: `${t('articles.analytics.aiInsights.readTime')} ${t('docs.readTime')}`,
difficulty: 'advanced', difficulty: 'advanced',
}, },
{ {
id: 'performance-metrics', id: 'performance-metrics',
title: 'Métricas de Rendimiento', title: t('articles.analytics.performanceMetrics.title'),
description: 'KPIs clave: márgenes, rotación, precisión de predicciones', description: t('articles.analytics.performanceMetrics.description'),
readTime: '15 min', readTime: `${t('articles.analytics.performanceMetrics.readTime')} ${t('docs.readTime')}`,
difficulty: 'intermediate', difficulty: 'intermediate',
}, },
], ],
}, },
{ {
id: 'account', id: 'account',
title: 'Gestión de Cuenta', title: t('categories.account.title'),
description: 'Administra tu perfil y equipo', description: t('categories.account.description'),
icon: Settings, icon: Settings,
articles: [ articles: [
{ {
@@ -196,8 +196,8 @@ const DocumentationPage: React.FC = () => {
}, },
{ {
id: 'billing', id: 'billing',
title: 'Facturación y Planes', title: t('categories.billing.title'),
description: 'Suscripciones, pagos y facturas', description: t('categories.billing.description'),
icon: CreditCard, icon: CreditCard,
articles: [ articles: [
{ {
@@ -232,8 +232,8 @@ const DocumentationPage: React.FC = () => {
}, },
{ {
id: 'privacy', id: 'privacy',
title: 'Privacidad y Seguridad', title: t('categories.privacy.title'),
description: 'RGPD, datos y cumplimiento', description: t('categories.privacy.description'),
icon: Shield, icon: Shield,
articles: [ articles: [
{ {
@@ -284,16 +284,7 @@ const DocumentationPage: React.FC = () => {
}; };
const getDifficultyLabel = (difficulty: string) => { const getDifficultyLabel = (difficulty: string) => {
switch (difficulty) { return t(`difficulty.${difficulty}` as any) || difficulty;
case 'beginner':
return 'Principiante';
case 'intermediate':
return 'Intermedio';
case 'advanced':
return 'Avanzado';
default:
return difficulty;
}
}; };
return ( return (
@@ -313,14 +304,13 @@ const DocumentationPage: React.FC = () => {
<div className="text-center max-w-4xl mx-auto"> <div className="text-center max-w-4xl mx-auto">
<div className="inline-flex items-center gap-2 bg-[var(--color-primary)]/10 text-[var(--color-primary)] px-4 py-2 rounded-full text-sm font-medium mb-6"> <div className="inline-flex items-center gap-2 bg-[var(--color-primary)]/10 text-[var(--color-primary)] px-4 py-2 rounded-full text-sm font-medium mb-6">
<FileText className="w-4 h-4" /> <FileText className="w-4 h-4" />
<span>Documentación</span> <span>{t('docs.subtitle')}</span>
</div> </div>
<h1 className="text-4xl lg:text-6xl font-extrabold text-[var(--text-primary)] mb-6"> <h1 className="text-4xl lg:text-6xl font-extrabold text-[var(--text-primary)] mb-6">
Guías Completas Para {t('docs.title')}
<span className="block text-[var(--color-primary)]">Dominar Panadería IA</span>
</h1> </h1>
<p className="text-xl text-[var(--text-secondary)] leading-relaxed mb-8"> <p className="text-xl text-[var(--text-secondary)] leading-relaxed mb-8">
Tutoriales paso a paso, mejores prácticas y trucos para aprovechar al máximo la plataforma {t('docs.description')}
</p> </p>
{/* Quick Actions */} {/* Quick Actions */}
@@ -331,14 +321,14 @@ const DocumentationPage: React.FC = () => {
className="inline-flex items-center gap-2 px-6 py-3 bg-[var(--color-primary)] text-white rounded-xl font-bold hover:shadow-xl transition-all hover:scale-105" className="inline-flex items-center gap-2 px-6 py-3 bg-[var(--color-primary)] text-white rounded-xl font-bold hover:shadow-xl transition-all hover:scale-105"
> >
<Rocket className="w-5 h-5" /> <Rocket className="w-5 h-5" />
<span>Comenzar</span> <span>{t('docs.getStarted')}</span>
</a> </a>
<Link <Link
to="/help" to="/help"
className="inline-flex items-center gap-2 px-6 py-3 border-2 border-[var(--border-primary)] text-[var(--text-primary)] rounded-xl font-medium hover:border-[var(--color-primary)] transition-all" className="inline-flex items-center gap-2 px-6 py-3 border-2 border-[var(--border-primary)] text-[var(--text-primary)] rounded-xl font-medium hover:border-[var(--color-primary)] transition-all"
> >
<HelpCircle className="w-5 h-5" /> <HelpCircle className="w-5 h-5" />
<span>Centro de Ayuda</span> <span>{t('docs.backToHelp')}</span>
</Link> </Link>
</div> </div>
</div> </div>
@@ -353,7 +343,7 @@ const DocumentationPage: React.FC = () => {
<div className="lg:col-span-1"> <div className="lg:col-span-1">
<div className="sticky top-8"> <div className="sticky top-8">
<h3 className="text-lg font-bold text-[var(--text-primary)] mb-4"> <h3 className="text-lg font-bold text-[var(--text-primary)] mb-4">
Secciones {t('docs.sectionsTitle')}
</h3> </h3>
<nav className="space-y-2"> <nav className="space-y-2">
{sections.map((section) => ( {sections.map((section) => (
@@ -374,7 +364,7 @@ const DocumentationPage: React.FC = () => {
activeSection === section.id ? 'text-white/80' : 'text-[var(--text-tertiary)]' activeSection === section.id ? 'text-white/80' : 'text-[var(--text-tertiary)]'
}`} }`}
> >
{section.articles.length} artículos {section.articles.length} {t('docs.articlesCount')}
</div> </div>
</div> </div>
</button> </button>
@@ -384,7 +374,7 @@ const DocumentationPage: React.FC = () => {
{/* Quick Links */} {/* Quick Links */}
<div className="mt-8 p-4 bg-[var(--bg-secondary)] rounded-xl border border-[var(--border-primary)]"> <div className="mt-8 p-4 bg-[var(--bg-secondary)] rounded-xl border border-[var(--border-primary)]">
<h4 className="font-bold text-[var(--text-primary)] mb-3 text-sm"> <h4 className="font-bold text-[var(--text-primary)] mb-3 text-sm">
Enlaces Rápidos {t('docs.quickLinks')}
</h4> </h4>
<div className="space-y-2 text-sm"> <div className="space-y-2 text-sm">
<Link <Link
@@ -392,21 +382,21 @@ const DocumentationPage: React.FC = () => {
className="flex items-center gap-2 text-[var(--text-secondary)] hover:text-[var(--color-primary)] transition-colors" className="flex items-center gap-2 text-[var(--text-secondary)] hover:text-[var(--color-primary)] transition-colors"
> >
<HelpCircle className="w-4 h-4" /> <HelpCircle className="w-4 h-4" />
<span>Centro de Ayuda</span> <span>{t('docs.backToHelp')}</span>
</Link> </Link>
<Link <Link
to="/help/support" to="/help/support"
className="flex items-center gap-2 text-[var(--text-secondary)] hover:text-[var(--color-primary)] transition-colors" className="flex items-center gap-2 text-[var(--text-secondary)] hover:text-[var(--color-primary)] transition-colors"
> >
<ExternalLink className="w-4 h-4" /> <ExternalLink className="w-4 h-4" />
<span>Contactar Soporte</span> <span>{t('docs.contactSupport')}</span>
</Link> </Link>
<a <a
href="#" href="#"
className="flex items-center gap-2 text-[var(--text-secondary)] hover:text-[var(--color-primary)] transition-colors" className="flex items-center gap-2 text-[var(--text-secondary)] hover:text-[var(--color-primary)] transition-colors"
> >
<Download className="w-4 h-4" /> <Download className="w-4 h-4" />
<span>Descargar PDF</span> <span>{t('docs.downloadPdf')}</span>
</a> </a>
</div> </div>
</div> </div>
@@ -473,10 +463,10 @@ const DocumentationPage: React.FC = () => {
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-12"> <div className="text-center mb-12">
<h2 className="text-3xl lg:text-4xl font-extrabold text-[var(--text-primary)] mb-4"> <h2 className="text-3xl lg:text-4xl font-extrabold text-[var(--text-primary)] mb-4">
Tutoriales en Vídeo {t('docs.videoTutorialsTitle')}
</h2> </h2>
<p className="text-xl text-[var(--text-secondary)]"> <p className="text-xl text-[var(--text-secondary)]">
Aprende viendo (próximamente) {t('docs.videoTutorialsSubtitle')}
</p> </p>
</div> </div>
@@ -524,7 +514,7 @@ const DocumentationPage: React.FC = () => {
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-12"> <div className="text-center mb-12">
<h2 className="text-3xl lg:text-4xl font-extrabold text-[var(--text-primary)] mb-4"> <h2 className="text-3xl lg:text-4xl font-extrabold text-[var(--text-primary)] mb-4">
Recursos Adicionales {t('docs.additionalResourcesTitle')}
</h2> </h2>
</div> </div>
@@ -532,39 +522,39 @@ const DocumentationPage: React.FC = () => {
<div className="bg-blue-50 dark:bg-blue-900/20 rounded-2xl p-6 border-2 border-blue-200 dark:border-blue-800"> <div className="bg-blue-50 dark:bg-blue-900/20 rounded-2xl p-6 border-2 border-blue-200 dark:border-blue-800">
<Info className="w-8 h-8 text-blue-600 mb-4" /> <Info className="w-8 h-8 text-blue-600 mb-4" />
<h3 className="text-lg font-bold text-[var(--text-primary)] mb-2"> <h3 className="text-lg font-bold text-[var(--text-primary)] mb-2">
Glosario de Términos {t('resources.glossary.title')}
</h3> </h3>
<p className="text-sm text-[var(--text-secondary)] mb-4"> <p className="text-sm text-[var(--text-secondary)] mb-4">
Definiciones de conceptos clave y terminología técnica {t('resources.glossary.description')}
</p> </p>
<a href="#glossary" className="text-blue-600 hover:underline font-medium text-sm"> <a href="#glossary" className="text-blue-600 hover:underline font-medium text-sm">
Ver Glosario {t('resources.glossary.action')}
</a> </a>
</div> </div>
<div className="bg-amber-50 dark:bg-amber-900/20 rounded-2xl p-6 border-2 border-amber-200 dark:border-amber-800"> <div className="bg-amber-50 dark:bg-amber-900/20 rounded-2xl p-6 border-2 border-amber-200 dark:border-amber-800">
<AlertCircle className="w-8 h-8 text-amber-600 mb-4" /> <AlertCircle className="w-8 h-8 text-amber-600 mb-4" />
<h3 className="text-lg font-bold text-[var(--text-primary)] mb-2"> <h3 className="text-lg font-bold text-[var(--text-primary)] mb-2">
Solución de Problemas {t('resources.troubleshooting.title')}
</h3> </h3>
<p className="text-sm text-[var(--text-secondary)] mb-4"> <p className="text-sm text-[var(--text-secondary)] mb-4">
Errores comunes y cómo resolverlos rápidamente {t('resources.troubleshooting.description')}
</p> </p>
<Link to="/help" className="text-amber-600 hover:underline font-medium text-sm"> <Link to="/help" className="text-amber-600 hover:underline font-medium text-sm">
Ver Soluciones {t('resources.troubleshooting.action')}
</Link> </Link>
</div> </div>
<div className="bg-green-50 dark:bg-green-900/20 rounded-2xl p-6 border-2 border-green-200 dark:border-green-800"> <div className="bg-green-50 dark:bg-green-900/20 rounded-2xl p-6 border-2 border-green-200 dark:border-green-800">
<CheckCircle2 className="w-8 h-8 text-green-600 mb-4" /> <CheckCircle2 className="w-8 h-8 text-green-600 mb-4" />
<h3 className="text-lg font-bold text-[var(--text-primary)] mb-2"> <h3 className="text-lg font-bold text-[var(--text-primary)] mb-2">
Mejores Prácticas {t('resources.bestPractices.title')}
</h3> </h3>
<p className="text-sm text-[var(--text-secondary)] mb-4"> <p className="text-sm text-[var(--text-secondary)] mb-4">
Tips y consejos de expertos para optimizar tu uso {t('resources.bestPractices.description')}
</p> </p>
<a href="#best-practices" className="text-green-600 hover:underline font-medium text-sm"> <a href="#best-practices" className="text-green-600 hover:underline font-medium text-sm">
Leer Tips {t('resources.bestPractices.action')}
</a> </a>
</div> </div>
</div> </div>
@@ -575,16 +565,16 @@ const DocumentationPage: React.FC = () => {
<section className="py-20 bg-gradient-to-r from-[var(--color-primary)] to-orange-600"> <section className="py-20 bg-gradient-to-r from-[var(--color-primary)] to-orange-600">
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 text-center"> <div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
<h2 className="text-3xl lg:text-4xl font-bold text-white mb-6"> <h2 className="text-3xl lg:text-4xl font-bold text-white mb-6">
¿Listo Para Empezar? {t('docs.ctaTitle')}
</h2> </h2>
<p className="text-xl text-white/90 mb-8"> <p className="text-xl text-white/90 mb-8">
Regístrate en el programa piloto y obtén 3 meses gratis {t('docs.ctaSubtitle')}
</p> </p>
<Link <Link
to="/register" to="/register"
className="inline-flex items-center gap-2 px-8 py-4 bg-white text-[var(--color-primary)] rounded-xl font-bold hover:shadow-2xl transition-all hover:scale-105" className="inline-flex items-center gap-2 px-8 py-4 bg-white text-[var(--color-primary)] rounded-xl font-bold hover:shadow-2xl transition-all hover:scale-105"
> >
<span>Crear Cuenta Gratis</span> <span>{t('docs.ctaButton')}</span>
<ChevronRight className="w-5 h-5" /> <ChevronRight className="w-5 h-5" />
</Link> </Link>
</div> </div>

View File

@@ -37,132 +37,56 @@ interface HelpCategory {
} }
const HelpCenterPage: React.FC = () => { const HelpCenterPage: React.FC = () => {
const { t } = useTranslation(); const { t } = useTranslation('help');
const [searchQuery, setSearchQuery] = useState(''); const [searchQuery, setSearchQuery] = useState('');
const [expandedFAQ, setExpandedFAQ] = useState<number | null>(null); const [expandedFAQ, setExpandedFAQ] = useState<number | null>(null);
const categories: HelpCategory[] = [ const categories: HelpCategory[] = [
{ {
id: 'getting-started', id: 'getting-started',
title: 'Primeros Pasos', title: t('categories.gettingStarted.title'),
description: 'Configura tu cuenta y aprende los conceptos básicos', description: t('categories.gettingStarted.description'),
icon: BookOpen, icon: BookOpen,
link: '/help/docs#getting-started', link: '/help/docs#getting-started',
}, },
{ {
id: 'features', id: 'features',
title: 'Funcionalidades', title: t('categories.features.title'),
description: 'Guías completas sobre todas las características', description: t('categories.features.description'),
icon: Package, icon: Package,
link: '/help/docs#features', link: '/help/docs#features',
}, },
{ {
id: 'billing', id: 'billing',
title: 'Facturación y Planes', title: t('categories.billing.title'),
description: 'Información sobre precios, pagos y suscripciones', description: t('categories.billing.description'),
icon: CreditCard, icon: CreditCard,
link: '/help/docs#billing', link: '/help/docs#billing',
}, },
{ {
id: 'account', id: 'account',
title: 'Gestión de Cuenta', title: t('categories.account.title'),
description: 'Administra tu perfil, equipo y configuración', description: t('categories.account.description'),
icon: Settings, icon: Settings,
link: '/help/docs#account', link: '/help/docs#account',
}, },
{ {
id: 'privacy', id: 'privacy',
title: 'Privacidad y Seguridad', title: t('categories.privacy.title'),
description: 'RGPD, seguridad de datos y cumplimiento', description: t('categories.privacy.description'),
icon: Shield, icon: Shield,
link: '/help/docs#privacy', link: '/help/docs#privacy',
}, },
{ {
id: 'analytics', id: 'analytics',
title: 'Análisis y Predicciones', title: t('categories.analytics.title'),
description: 'Interpreta datos e insights de IA', description: t('categories.analytics.description'),
icon: TrendingUp, icon: TrendingUp,
link: '/help/docs#analytics', link: '/help/docs#analytics',
}, },
]; ];
const faqs: FAQItem[] = [ const faqs: FAQItem[] = t('faqs', { returnObjects: true }) as FAQItem[];
{
category: 'general',
question: '¿Qué es Panadería IA y cómo funciona?',
answer: 'Panadería IA es una plataforma de gestión inteligente para panaderías. Utiliza inteligencia artificial para predecir la demanda de tus productos, optimizar la producción, reducir desperdicios y aumentar la rentabilidad. Conectas tus datos de ventas históricas y el sistema aprende tus patrones para hacer predicciones precisas.',
},
{
category: 'general',
question: '¿Cuánto tiempo toma configurar el sistema?',
answer: 'La configuración inicial toma entre 10-15 minutos. Necesitas: 1) Crear tu cuenta, 2) Subir tu catálogo de productos, 3) Importar historial de ventas (opcional pero recomendado), 4) Configurar preferencias básicas. El sistema empieza a generar predicciones desde el primer día, mejorando su precisión con el tiempo.',
},
{
category: 'general',
question: '¿Necesito conocimientos técnicos para usarlo?',
answer: 'No. Panadería IA está diseñado para panaderos, no para ingenieros. La interfaz es intuitiva, con tutoriales paso a paso. Si sabes usar WhatsApp o un correo electrónico, puedes usar nuestra plataforma. Además, ofrecemos soporte 24/7 en español.',
},
{
category: 'pricing',
question: '¿Cuánto cuesta el programa piloto?',
answer: 'El programa piloto es GRATIS durante los primeros 3 meses. Después, pagas solo €49/mes con un 20% de descuento de por vida (precio normal: €79/mes). Sin contratos de permanencia, cancela cuando quieras. Las primeras 20 panaderías obtienen este beneficio.',
},
{
category: 'pricing',
question: '¿Necesito tarjeta de crédito para empezar el piloto?',
answer: 'SÍ, necesitas registrar una tarjeta, pero NO se te cobrará durante los 3 meses de prueba gratuita. Esto nos ayuda a asegurar que solo participan panaderías realmente interesadas. Puedes cancelar antes de que termine el periodo gratuito sin ningún cargo.',
},
{
category: 'pricing',
question: '¿Qué pasa después de los 3 meses gratis?',
answer: 'Tienes 3 opciones: 1) Continuar con el plan Basic (€49/mes con tu descuento del 20%), 2) Actualizar a un plan superior, 3) Cancelar sin penalización. Te avisaremos 7 días antes de que termine tu periodo gratuito.',
},
{
category: 'technical',
question: '¿Cómo importo mis datos históricos de ventas?',
answer: 'Aceptamos varios formatos: Excel (.xlsx), CSV, o exportaciones directas de tu TPV si es compatible. También puedes introducir datos manualmente si prefieres. Cuanto más historial proporciones (recomendamos mínimo 3 meses), más precisas serán las predicciones.',
},
{
category: 'technical',
question: '¿El sistema se integra con mi TPV actual?',
answer: 'Actualmente estamos trabajando en integraciones directas con los principales TPV del mercado español. Por ahora, puedes exportar datos de tu TPV e importarlos manualmente (es más fácil de lo que suena). Las integraciones automáticas llegarán en Q2 2025.',
},
{
category: 'technical',
question: '¿Qué pasa si mis predicciones no son precisas?',
answer: 'El sistema mejora con el tiempo. Las primeras semanas puede tener un margen de error del 15-20%. Después del primer mes, esto baja al 10%. Con 3+ meses de datos, alcanzamos >90% de precisión. Puedes ajustar manualmente las predicciones y el sistema aprende de tus correcciones.',
},
{
category: 'privacy',
question: '¿Dónde se almacenan mis datos?',
answer: 'TODOS tus datos se almacenan en servidores físicamente ubicados en España (Barcelona y Madrid), cumpliendo 100% con RGPD. Nunca compartimos, vendemos ni transferimos tus datos fuera de la UE. Tienes control total y puedes exportar o eliminar tus datos en cualquier momento.',
},
{
category: 'privacy',
question: '¿Quién puede ver mis datos de ventas?',
answer: 'Solo TÚ y los miembros de tu equipo que tú autorices. Ni siquiera nuestro equipo técnico puede acceder a tus datos sin tu permiso explícito (y solo lo haríamos para soporte técnico con tu aprobación). Los datos están encriptados end-to-end.',
},
{
category: 'support',
question: '¿Qué tipo de soporte ofrecen?',
answer: 'Soporte 24/7 en español por: Email (respuesta en <4h), Chat en vivo (9:00-21:00), Videollamada (con cita previa). Durante el piloto, también tienes acceso directo a los fundadores por WhatsApp. Además, biblioteca completa de tutoriales en vídeo.',
},
{
category: 'support',
question: '¿Puedo hablar con alguien antes de registrarme?',
answer: 'Por supuesto. Agenda una videollamada de 15 minutos con nuestro equipo para ver el producto en acción, hacer todas tus preguntas y confirmar que es adecuado para tu panadería. Sin compromiso. Contacto: hola@panaderia-ia.com o el formulario de contacto.',
},
{
category: 'general',
question: '¿Funciona para obradores centrales con múltiples puntos de venta?',
answer: 'SÍ. Nuestro sistema está diseñado para adaptarse a ambos modelos: producción local (un solo punto) y obrador central con distribución a múltiples puntos de venta. Para obradores centrales, ofrecemos predicción de demanda agregada y granular por cada POS, gestión de distribución multi-ubicación, y un dashboard centralizado con visibilidad por punto de venta. La IA optimiza tanto la producción total como la distribución entre ubicaciones.',
},
{
category: 'general',
question: '¿Qué modelo de negocio es mejor para mi panadería?',
answer: 'Depende de tus objetivos. Producción Local es ideal si valoras máximo control, flexibilidad y frescura instantánea, o si estás empezando. Obrador Central + Puntos de Venta es mejor si quieres escalar a múltiples ubicaciones, aprovechar economías de escala, o tener presencia en varios barrios/ciudades. Lo bueno: nuestro sistema funciona para ambos modelos y puede evolucionar contigo si decides cambiar o crecer.',
},
];
const filteredFAQs = searchQuery const filteredFAQs = searchQuery
? faqs.filter( ? faqs.filter(
@@ -193,14 +117,13 @@ const HelpCenterPage: React.FC = () => {
<div className="text-center max-w-4xl mx-auto"> <div className="text-center max-w-4xl mx-auto">
<div className="inline-flex items-center gap-2 bg-[var(--color-primary)]/10 text-[var(--color-primary)] px-4 py-2 rounded-full text-sm font-medium mb-6"> <div className="inline-flex items-center gap-2 bg-[var(--color-primary)]/10 text-[var(--color-primary)] px-4 py-2 rounded-full text-sm font-medium mb-6">
<HelpCircle className="w-4 h-4" /> <HelpCircle className="w-4 h-4" />
<span>Centro de Ayuda</span> <span>{t('helpCenter.subtitle')}</span>
</div> </div>
<h1 className="text-4xl lg:text-6xl font-extrabold text-[var(--text-primary)] mb-6"> <h1 className="text-4xl lg:text-6xl font-extrabold text-[var(--text-primary)] mb-6">
¿Cómo Podemos {t('helpCenter.title')}
<span className="block text-[var(--color-primary)]">Ayudarte Hoy?</span>
</h1> </h1>
<p className="text-xl text-[var(--text-secondary)] leading-relaxed mb-8"> <p className="text-xl text-[var(--text-secondary)] leading-relaxed mb-8">
Encuentra respuestas rápidas, guías completas y contacto directo con nuestro equipo {t('helpCenter.description')}
</p> </p>
{/* Search Bar */} {/* Search Bar */}
@@ -209,7 +132,7 @@ const HelpCenterPage: React.FC = () => {
<Search className="absolute left-4 top-1/2 -translate-y-1/2 w-5 h-5 text-[var(--text-tertiary)]" /> <Search className="absolute left-4 top-1/2 -translate-y-1/2 w-5 h-5 text-[var(--text-tertiary)]" />
<input <input
type="text" type="text"
placeholder="Buscar en la ayuda... (ej: ¿cómo importo datos?)" placeholder={t('helpCenter.searchPlaceholder')}
value={searchQuery} value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)} onChange={(e) => setSearchQuery(e.target.value)}
className="w-full pl-12 pr-4 py-4 bg-[var(--bg-primary)] border-2 border-[var(--border-primary)] rounded-xl text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:border-[var(--color-primary)] transition-colors" className="w-full pl-12 pr-4 py-4 bg-[var(--bg-primary)] border-2 border-[var(--border-primary)] rounded-xl text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:border-[var(--color-primary)] transition-colors"
@@ -225,10 +148,10 @@ const HelpCenterPage: React.FC = () => {
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-12"> <div className="text-center mb-12">
<h2 className="text-3xl lg:text-4xl font-extrabold text-[var(--text-primary)] mb-4"> <h2 className="text-3xl lg:text-4xl font-extrabold text-[var(--text-primary)] mb-4">
Explora por Categoría {t('helpCenter.categoriesTitle')}
</h2> </h2>
<p className="text-xl text-[var(--text-secondary)]"> <p className="text-xl text-[var(--text-secondary)]">
Encuentra lo que necesitas más rápido {t('helpCenter.categoriesSubtitle')}
</p> </p>
</div> </div>
@@ -261,11 +184,11 @@ const HelpCenterPage: React.FC = () => {
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8"> <div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-12"> <div className="text-center mb-12">
<h2 className="text-3xl lg:text-4xl font-extrabold text-[var(--text-primary)] mb-4"> <h2 className="text-3xl lg:text-4xl font-extrabold text-[var(--text-primary)] mb-4">
Preguntas Frecuentes {t('helpCenter.faqTitle')}
</h2> </h2>
<p className="text-xl text-[var(--text-secondary)]"> <p className="text-xl text-[var(--text-secondary)]">
{filteredFAQs.length} {filteredFAQs.length === 1 ? 'respuesta' : 'respuestas'}{' '} {t('helpCenter.faqResultsCount', { count: filteredFAQs.length })}{' '}
{searchQuery && 'encontradas'} {searchQuery && t('helpCenter.faqFound')}
</p> </p>
</div> </div>
@@ -301,9 +224,9 @@ const HelpCenterPage: React.FC = () => {
<div className="text-center py-12"> <div className="text-center py-12">
<HelpCircle className="w-16 h-16 text-[var(--text-tertiary)] mx-auto mb-4" /> <HelpCircle className="w-16 h-16 text-[var(--text-tertiary)] mx-auto mb-4" />
<p className="text-[var(--text-secondary)] text-lg"> <p className="text-[var(--text-secondary)] text-lg">
No encontramos resultados para "{searchQuery}".{' '} {t('helpCenter.noResultsTitle')} "{searchQuery}".{' '}
<Link to="/help/support" className="text-[var(--color-primary)] hover:underline"> <Link to="/help/support" className="text-[var(--color-primary)] hover:underline">
Contacta con soporte {t('helpCenter.noResultsAction')}
</Link> </Link>
</p> </p>
</div> </div>
@@ -316,10 +239,10 @@ const HelpCenterPage: React.FC = () => {
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-12"> <div className="text-center mb-12">
<h2 className="text-3xl lg:text-4xl font-extrabold text-[var(--text-primary)] mb-4"> <h2 className="text-3xl lg:text-4xl font-extrabold text-[var(--text-primary)] mb-4">
¿No Encuentras lo Que Buscas? {t('helpCenter.contactTitle')}
</h2> </h2>
<p className="text-xl text-[var(--text-secondary)]"> <p className="text-xl text-[var(--text-secondary)]">
Nuestro equipo está aquí para ayudarte {t('helpCenter.contactSubtitle')}
</p> </p>
</div> </div>
@@ -332,31 +255,31 @@ const HelpCenterPage: React.FC = () => {
<MessageSquare className="w-8 h-8 text-[var(--color-primary)] group-hover:text-white transition-colors" /> <MessageSquare className="w-8 h-8 text-[var(--color-primary)] group-hover:text-white transition-colors" />
</div> </div>
<h3 className="text-xl font-bold text-[var(--text-primary)] mb-2"> <h3 className="text-xl font-bold text-[var(--text-primary)] mb-2">
Chat en Vivo {t('contact.liveChat.title')}
</h3> </h3>
<p className="text-sm text-[var(--text-secondary)] mb-4"> <p className="text-sm text-[var(--text-secondary)] mb-4">
Respuesta inmediata de 9:00 a 21:00 {t('contact.liveChat.description')}
</p> </p>
<span className="text-[var(--color-primary)] font-medium group-hover:underline"> <span className="text-[var(--color-primary)] font-medium group-hover:underline">
Iniciar Chat {t('contact.liveChat.action')}
</span> </span>
</Link> </Link>
<a <a
href="mailto:soporte@panaderia-ia.com" href={`mailto:${t('contact.email.address')}`}
className="bg-[var(--bg-secondary)] rounded-2xl p-8 border border-[var(--border-primary)] hover:border-[var(--color-primary)] hover:shadow-xl transition-all text-center group" className="bg-[var(--bg-secondary)] rounded-2xl p-8 border border-[var(--border-primary)] hover:border-[var(--color-primary)] hover:shadow-xl transition-all text-center group"
> >
<div className="w-16 h-16 bg-[var(--color-primary)]/10 rounded-full flex items-center justify-center mx-auto mb-4 group-hover:bg-[var(--color-primary)] transition-colors"> <div className="w-16 h-16 bg-[var(--color-primary)]/10 rounded-full flex items-center justify-center mx-auto mb-4 group-hover:bg-[var(--color-primary)] transition-colors">
<Mail className="w-8 h-8 text-[var(--color-primary)] group-hover:text-white transition-colors" /> <Mail className="w-8 h-8 text-[var(--color-primary)] group-hover:text-white transition-colors" />
</div> </div>
<h3 className="text-xl font-bold text-[var(--text-primary)] mb-2"> <h3 className="text-xl font-bold text-[var(--text-primary)] mb-2">
Email {t('contact.email.title')}
</h3> </h3>
<p className="text-sm text-[var(--text-secondary)] mb-4"> <p className="text-sm text-[var(--text-secondary)] mb-4">
Respuesta en menos de 4 horas {t('contact.email.description')}
</p> </p>
<span className="text-[var(--color-primary)] font-medium group-hover:underline"> <span className="text-[var(--color-primary)] font-medium group-hover:underline">
Enviar Email {t('contact.email.action')}
</span> </span>
</a> </a>
@@ -368,13 +291,13 @@ const HelpCenterPage: React.FC = () => {
<FileText className="w-8 h-8 text-[var(--color-primary)] group-hover:text-white transition-colors" /> <FileText className="w-8 h-8 text-[var(--color-primary)] group-hover:text-white transition-colors" />
</div> </div>
<h3 className="text-xl font-bold text-[var(--text-primary)] mb-2"> <h3 className="text-xl font-bold text-[var(--text-primary)] mb-2">
Documentación {t('contact.documentation.title')}
</h3> </h3>
<p className="text-sm text-[var(--text-secondary)] mb-4"> <p className="text-sm text-[var(--text-secondary)] mb-4">
Guías completas y tutoriales {t('contact.documentation.description')}
</p> </p>
<span className="text-[var(--color-primary)] font-medium group-hover:underline"> <span className="text-[var(--color-primary)] font-medium group-hover:underline">
Ver Docs {t('contact.documentation.action')}
</span> </span>
</Link> </Link>
</div> </div>
@@ -389,12 +312,12 @@ const HelpCenterPage: React.FC = () => {
<Clock className="w-6 h-6 text-[var(--color-primary)] flex-shrink-0 mt-1" /> <Clock className="w-6 h-6 text-[var(--color-primary)] flex-shrink-0 mt-1" />
<div> <div>
<h3 className="text-lg font-bold text-[var(--text-primary)] mb-2"> <h3 className="text-lg font-bold text-[var(--text-primary)] mb-2">
Horario de Atención {t('helpCenter.contactHours')}
</h3> </h3>
<div className="space-y-1 text-sm text-[var(--text-secondary)]"> <div className="space-y-1 text-sm text-[var(--text-secondary)]">
<p><strong>Chat en Vivo:</strong> Lunes a Viernes 9:00 - 21:00, Sábados 10:00 - 18:00</p> <p><strong>{t('contact.liveChat.title')}:</strong> {t('contact.hours.liveChat')}</p>
<p><strong>Email:</strong> 24/7 (respuesta en menos de 4 horas en horario laboral)</p> <p><strong>{t('contact.email.title')}:</strong> {t('contact.hours.email')}</p>
<p><strong>Teléfono:</strong> Lunes a Viernes 10:00 - 19:00 (solo para clientes activos)</p> <p><strong>Teléfono:</strong> {t('contact.hours.phone')}</p>
</div> </div>
</div> </div>
</div> </div>