Add POI feature and imporve the overall backend implementation
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button } from '../../components/ui';
|
||||
import { Button, ScrollReveal, FloatingCTA, AnimatedCounter } from '../../components/ui';
|
||||
import { PublicLayout } from '../../components/layout';
|
||||
import { PricingSection } from '../../components/subscription';
|
||||
import { getRegisterUrl, getDemoUrl } from '../../utils/navigation';
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
|
||||
const LandingPage: React.FC = () => {
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<PublicLayout
|
||||
@@ -38,26 +39,42 @@ const LandingPage: React.FC = () => {
|
||||
variant: "default"
|
||||
}}
|
||||
>
|
||||
{/* Floating CTA - appears after scrolling */}
|
||||
<FloatingCTA
|
||||
text={t('landing:hero.cta_primary', 'Únete al Programa Piloto')}
|
||||
onClick={() => navigate(getRegisterUrl())}
|
||||
icon={<ArrowRight className="w-4 h-4" />}
|
||||
position="bottom-right"
|
||||
showAfterScroll={600}
|
||||
dismissible
|
||||
/>
|
||||
{/* Hero Section */}
|
||||
<section className="relative py-20 lg:py-32 bg-gradient-to-br from-[var(--bg-primary)] via-[var(--bg-secondary)] to-[var(--color-primary)]/5">
|
||||
<section className="relative py-20 lg:py-32 bg-gradient-to-br from-[var(--bg-primary)] via-[var(--bg-secondary)] to-[var(--color-primary)]/5 overflow-hidden">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="text-center">
|
||||
{/* Pre-headline */}
|
||||
<div className="mb-4">
|
||||
<p className="text-sm md:text-base font-medium text-[var(--text-tertiary)]">
|
||||
{t('landing:hero.pre_headline', 'Para Panaderías que Pierden €500-2,000/Mes en Desperdicios')}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Scarcity Badge */}
|
||||
<div className="mb-6 inline-block">
|
||||
<div className="bg-gradient-to-r from-amber-50 via-orange-50 to-amber-50 dark:from-amber-900/20 dark:via-orange-900/20 dark:to-amber-900/20 border-2 border-amber-400 dark:border-amber-500 rounded-full px-6 py-3 shadow-lg">
|
||||
<div className="mb-8 inline-block">
|
||||
<div className="bg-gradient-to-r from-amber-50 via-orange-50 to-amber-50 dark:from-amber-900/20 dark:via-orange-900/20 dark:to-amber-900/20 border-2 border-amber-400 dark:border-amber-500 rounded-full px-6 py-3 shadow-lg hover:shadow-xl transition-shadow">
|
||||
<p className="text-sm font-bold text-amber-700 dark:text-amber-300">
|
||||
🔥 {t('landing:hero.scarcity', 'Solo 12 plazas restantes de 20 • 3 meses GRATIS')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1 className="text-4xl tracking-tight font-extrabold text-[var(--text-primary)] sm:text-5xl lg:text-7xl">
|
||||
<span className="block">{t('landing:hero.title_line1', 'Aumenta Ganancias,')}</span>
|
||||
<span className="block text-[var(--color-primary)]">{t('landing:hero.title_line2', 'Reduce Desperdicios')}</span>
|
||||
<h1 className="text-4xl tracking-tight font-extrabold text-[var(--text-primary)] sm:text-5xl lg:text-7xl leading-tight">
|
||||
<span className="block">{t('landing:hero.title_option_a_line1', 'Ahorra €500-2,000 al Mes')}</span>
|
||||
<span className="block text-[var(--color-primary)] mt-2">{t('landing:hero.title_option_a_line2', 'Produciendo Exactamente Lo Que Venderás')}</span>
|
||||
</h1>
|
||||
|
||||
<p className="mt-6 max-w-3xl mx-auto text-lg text-[var(--text-secondary)] sm:text-xl">
|
||||
{t('landing:hero.subtitle', 'IA que predice demanda con datos de tu zona para que produzcas exactamente lo que vas a vender. Reduce desperdicios, mejora márgenes y ahorra tiempo.')}
|
||||
<p className="mt-8 max-w-3xl mx-auto text-lg text-[var(--text-secondary)] sm:text-xl leading-relaxed">
|
||||
{t('landing:hero.subtitle_option_a', 'La primera IA que conoce tu barrio: colegios cerca, clima local, tu competencia, eventos. Sistema automático cada mañana. Listo a las 6 AM.')}
|
||||
</p>
|
||||
|
||||
{/* CTA Buttons */}
|
||||
@@ -75,24 +92,48 @@ const LandingPage: React.FC = () => {
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Social Proof - New */}
|
||||
<div className="mt-12 max-w-3xl mx-auto">
|
||||
<div className="grid md:grid-cols-3 gap-6 text-left">
|
||||
<div className="flex items-start gap-3 bg-white/60 dark:bg-gray-800/60 backdrop-blur-sm p-4 rounded-xl shadow-sm border border-[var(--border-primary)]">
|
||||
<CheckCircle2 className="w-5 h-5 text-green-600 dark:text-green-400 mt-0.5 flex-shrink-0" />
|
||||
<span className="text-sm font-medium text-[var(--text-secondary)]">
|
||||
<AnimatedCounter value={20} className="inline font-bold" /> panaderías ya ahorran <AnimatedCounter value={1500} prefix="€" className="inline font-bold" />/mes de promedio
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-start gap-3 bg-white/60 dark:bg-gray-800/60 backdrop-blur-sm p-4 rounded-xl shadow-sm border border-[var(--border-primary)]">
|
||||
<Target className="w-5 h-5 text-blue-600 dark:text-blue-400 mt-0.5 flex-shrink-0" />
|
||||
<span className="text-sm font-medium text-[var(--text-secondary)]">
|
||||
Predicciones <AnimatedCounter value={92} suffix="%" className="inline font-bold" /> precisas (vs 60% sistemas genéricos)
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-start gap-3 bg-white/60 dark:bg-gray-800/60 backdrop-blur-sm p-4 rounded-xl shadow-sm border border-[var(--border-primary)]">
|
||||
<Clock className="w-5 h-5 text-amber-600 dark:text-amber-400 mt-0.5 flex-shrink-0" />
|
||||
<span className="text-sm font-medium text-[var(--text-secondary)]">
|
||||
{t('landing:hero.social_proof.setup', 'Configuración en 15 minutos')}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Trust Badges */}
|
||||
<div className="mt-12 flex flex-wrap items-center justify-center gap-x-8 gap-y-4 text-sm">
|
||||
<div className="flex items-center bg-white/60 dark:bg-gray-800/60 backdrop-blur-sm px-4 py-2 rounded-full shadow-sm border border-[var(--border-primary)]">
|
||||
<CheckCircle2 className="w-4 h-4 text-amber-600 dark:text-amber-400 mr-2" />
|
||||
<span className="font-medium text-[var(--text-secondary)]">
|
||||
{t('landing:hero.trust.card', 'Tarjeta requerida')}
|
||||
<div className="mt-8 flex flex-wrap items-center justify-center gap-x-8 gap-y-4 text-sm">
|
||||
<div className="flex items-center">
|
||||
<CheckCircle2 className="w-4 h-4 text-green-600 dark:text-green-400 mr-2" />
|
||||
<span className="font-medium text-[var(--text-tertiary)]">
|
||||
{t('landing:hero.trust.no_cc', '3 meses gratis')}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center bg-white/60 dark:bg-gray-800/60 backdrop-blur-sm px-4 py-2 rounded-full shadow-sm border border-[var(--border-primary)]">
|
||||
<div className="flex items-center">
|
||||
<Clock className="w-4 h-4 text-blue-600 dark:text-blue-400 mr-2" />
|
||||
<span className="font-medium text-[var(--text-secondary)]">
|
||||
{t('landing:hero.trust.quick', '3 meses gratis')}
|
||||
<span className="font-medium text-[var(--text-tertiary)]">
|
||||
{t('landing:hero.trust.quick', 'Configuración en 15 min')}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center bg-white/60 dark:bg-gray-800/60 backdrop-blur-sm px-4 py-2 rounded-full shadow-sm border border-[var(--border-primary)]">
|
||||
<Zap className="w-4 h-4 text-green-600 dark:text-green-400 mr-2" />
|
||||
<span className="font-medium text-[var(--text-secondary)]">
|
||||
{t('landing:hero.trust.setup', 'Configuración en 15 min')}
|
||||
<div className="flex items-center">
|
||||
<Shield className="w-4 h-4 text-purple-600 dark:text-purple-400 mr-2" />
|
||||
<span className="font-medium text-[var(--text-tertiary)]">
|
||||
{t('landing:hero.trust.card', 'Tarjeta requerida')}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -105,10 +146,11 @@ const LandingPage: React.FC = () => {
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="grid md:grid-cols-2 gap-12">
|
||||
{/* Problems */}
|
||||
<div>
|
||||
<h2 className="text-3xl font-bold text-[var(--text-primary)] mb-8">
|
||||
{t('landing:problems.title', '❌ Los Problemas Que Enfrentas')}
|
||||
</h2>
|
||||
<ScrollReveal variant="fadeRight" delay={0.1}>
|
||||
<div>
|
||||
<h2 className="text-3xl font-bold text-[var(--text-primary)] mb-8">
|
||||
{t('landing:problems.title', '❌ Los Problemas Que Enfrentas')}
|
||||
</h2>
|
||||
<div className="space-y-6">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="w-12 h-12 bg-red-100 dark:bg-red-900/20 rounded-lg flex items-center justify-center flex-shrink-0">
|
||||
@@ -150,13 +192,15 @@ const LandingPage: React.FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
|
||||
{/* Solutions */}
|
||||
<div>
|
||||
<h2 className="text-3xl font-bold text-[var(--text-primary)] mb-8">
|
||||
{t('landing:solutions.title', '✅ La Solución Con IA')}
|
||||
</h2>
|
||||
<ScrollReveal variant="fadeLeft" delay={0.2}>
|
||||
<div>
|
||||
<h2 className="text-3xl font-bold text-[var(--text-primary)] mb-8">
|
||||
{t('landing:solutions.title', '✅ La Solución Con IA')}
|
||||
</h2>
|
||||
<div className="space-y-6">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="w-12 h-12 bg-green-100 dark:bg-green-900/20 rounded-lg flex items-center justify-center flex-shrink-0">
|
||||
@@ -198,7 +242,8 @@ const LandingPage: React.FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -279,7 +324,7 @@ const LandingPage: React.FC = () => {
|
||||
|
||||
<div className="mt-6 bg-gradient-to-r from-[var(--color-primary)]/10 to-orange-500/10 rounded-lg p-4 border-l-4 border-[var(--color-primary)]">
|
||||
<p className="font-bold text-[var(--text-primary)]">
|
||||
{t('landing:pillar1.accuracy', '🎯 Precisión: 92% (vs 60-70% de sistemas genéricos)')}
|
||||
🎯 Precisión: <AnimatedCounter value={92} suffix="%" className="inline text-[var(--color-primary)]" /> (vs 60-70% de sistemas genéricos)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user