Improve public pages
This commit is contained in:
@@ -196,7 +196,7 @@ export const Footer = forwardRef<FooterRef, FooterProps>(({
|
|||||||
links: [
|
links: [
|
||||||
{ id: 'about', label: t('common:footer.links.about', 'Acerca de'), href: '/about' },
|
{ id: 'about', label: t('common:footer.links.about', 'Acerca de'), href: '/about' },
|
||||||
{ id: 'blog', label: t('common:footer.links.blog', 'Blog'), href: '/blog' },
|
{ id: 'blog', label: t('common:footer.links.blog', 'Blog'), href: '/blog' },
|
||||||
{ id: 'careers', label: t('common:footer.links.careers', 'Carreras'), href: '/careers' },
|
{ id: 'careers', label: t('common:footer.links.careers', 'Empleo'), href: '/careers' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,481 +0,0 @@
|
|||||||
import React, { forwardRef } from 'react';
|
|
||||||
import { clsx } from 'clsx';
|
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
import { Button } from '../../ui';
|
|
||||||
import {
|
|
||||||
Heart,
|
|
||||||
ExternalLink,
|
|
||||||
Mail,
|
|
||||||
Phone,
|
|
||||||
MapPin,
|
|
||||||
Github,
|
|
||||||
Twitter,
|
|
||||||
Linkedin,
|
|
||||||
Globe,
|
|
||||||
Shield,
|
|
||||||
FileText,
|
|
||||||
HelpCircle,
|
|
||||||
MessageSquare
|
|
||||||
} from 'lucide-react';
|
|
||||||
|
|
||||||
export interface FooterLink {
|
|
||||||
id: string;
|
|
||||||
label: string;
|
|
||||||
href: string;
|
|
||||||
external?: boolean;
|
|
||||||
icon?: React.ComponentType<{ className?: string }>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface FooterSection {
|
|
||||||
id: string;
|
|
||||||
title: string;
|
|
||||||
links: FooterLink[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SocialLink {
|
|
||||||
id: string;
|
|
||||||
label: string;
|
|
||||||
href: string;
|
|
||||||
icon: React.ComponentType<{ className?: string }>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CompanyInfo {
|
|
||||||
name: string;
|
|
||||||
description?: string;
|
|
||||||
logo?: React.ReactNode;
|
|
||||||
email?: string;
|
|
||||||
phone?: string;
|
|
||||||
address?: string;
|
|
||||||
website?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface FooterProps {
|
|
||||||
className?: string;
|
|
||||||
/**
|
|
||||||
* Company information
|
|
||||||
*/
|
|
||||||
companyInfo?: CompanyInfo;
|
|
||||||
/**
|
|
||||||
* Footer sections with links
|
|
||||||
*/
|
|
||||||
sections?: FooterSection[];
|
|
||||||
/**
|
|
||||||
* Social media links
|
|
||||||
*/
|
|
||||||
socialLinks?: SocialLink[];
|
|
||||||
/**
|
|
||||||
* Copyright text (auto-generated if not provided)
|
|
||||||
*/
|
|
||||||
copyrightText?: string;
|
|
||||||
/**
|
|
||||||
* Show version info
|
|
||||||
*/
|
|
||||||
showVersion?: boolean;
|
|
||||||
/**
|
|
||||||
* Version string
|
|
||||||
*/
|
|
||||||
version?: string;
|
|
||||||
/**
|
|
||||||
* Show language selector
|
|
||||||
*/
|
|
||||||
showLanguageSelector?: boolean;
|
|
||||||
/**
|
|
||||||
* Available languages
|
|
||||||
*/
|
|
||||||
languages?: Array<{ code: string; name: string }>;
|
|
||||||
/**
|
|
||||||
* Current language
|
|
||||||
*/
|
|
||||||
currentLanguage?: string;
|
|
||||||
/**
|
|
||||||
* Language change handler
|
|
||||||
*/
|
|
||||||
onLanguageChange?: (language: string) => void;
|
|
||||||
/**
|
|
||||||
* Show theme toggle
|
|
||||||
*/
|
|
||||||
showThemeToggle?: boolean;
|
|
||||||
/**
|
|
||||||
* Theme toggle handler
|
|
||||||
*/
|
|
||||||
onThemeToggle?: () => void;
|
|
||||||
/**
|
|
||||||
* Show privacy links
|
|
||||||
*/
|
|
||||||
showPrivacyLinks?: boolean;
|
|
||||||
/**
|
|
||||||
* Compact mode (smaller footer)
|
|
||||||
*/
|
|
||||||
compact?: boolean;
|
|
||||||
/**
|
|
||||||
* Custom content
|
|
||||||
*/
|
|
||||||
children?: React.ReactNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface FooterRef {
|
|
||||||
scrollIntoView: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Footer - Application footer with links and copyright info
|
|
||||||
*
|
|
||||||
* Features:
|
|
||||||
* - Company information and branding
|
|
||||||
* - Organized link sections for easy navigation
|
|
||||||
* - Social media links with proper icons
|
|
||||||
* - Copyright notice with automatic year
|
|
||||||
* - Version information display
|
|
||||||
* - Language selector for i18n
|
|
||||||
* - Privacy and legal links
|
|
||||||
* - Responsive design with mobile adaptations
|
|
||||||
* - Accessible link handling with external indicators
|
|
||||||
* - Customizable sections and content
|
|
||||||
*/
|
|
||||||
export const Footer = forwardRef<FooterRef, FooterProps>(({
|
|
||||||
className,
|
|
||||||
companyInfo,
|
|
||||||
sections,
|
|
||||||
socialLinks,
|
|
||||||
copyrightText,
|
|
||||||
showVersion = true,
|
|
||||||
version = '2.0.0',
|
|
||||||
showLanguageSelector = false,
|
|
||||||
languages = [],
|
|
||||||
currentLanguage = 'es',
|
|
||||||
onLanguageChange,
|
|
||||||
showThemeToggle = false,
|
|
||||||
onThemeToggle,
|
|
||||||
showPrivacyLinks = true,
|
|
||||||
compact = false,
|
|
||||||
children,
|
|
||||||
}, ref) => {
|
|
||||||
const footerRef = React.useRef<HTMLDivElement>(null);
|
|
||||||
const currentYear = new Date().getFullYear();
|
|
||||||
|
|
||||||
// Default company info
|
|
||||||
const defaultCompanyInfo: CompanyInfo = {
|
|
||||||
name: 'Panadería IA',
|
|
||||||
description: 'Sistema inteligente de gestión para panaderías. Optimiza tu producción, inventario y ventas con inteligencia artificial.',
|
|
||||||
email: 'contacto@panaderia-ia.com',
|
|
||||||
website: 'https://panaderia-ia.com',
|
|
||||||
};
|
|
||||||
|
|
||||||
const company = companyInfo || defaultCompanyInfo;
|
|
||||||
|
|
||||||
// Default sections
|
|
||||||
const defaultSections: FooterSection[] = [
|
|
||||||
{
|
|
||||||
id: 'product',
|
|
||||||
title: 'Producto',
|
|
||||||
links: [
|
|
||||||
{ id: 'dashboard', label: 'Dashboard', href: '/dashboard' },
|
|
||||||
{ id: 'inventory', label: 'Inventario', href: '/inventory' },
|
|
||||||
{ id: 'production', label: 'Producción', href: '/production' },
|
|
||||||
{ id: 'sales', label: 'Ventas', href: '/sales' },
|
|
||||||
{ id: 'forecasting', label: 'Predicciones', href: '/forecasting' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'support',
|
|
||||||
title: 'Soporte',
|
|
||||||
links: [
|
|
||||||
{ id: 'help', label: 'Centro de Ayuda', href: '/help', icon: HelpCircle },
|
|
||||||
{ id: 'docs', label: 'Documentación', href: '/help/docs', icon: FileText },
|
|
||||||
{ id: 'contact', label: 'Contacto', href: '/help/support', icon: MessageSquare },
|
|
||||||
{ id: 'feedback', label: 'Feedback', href: '/help/feedback' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'company',
|
|
||||||
title: 'Empresa',
|
|
||||||
links: [
|
|
||||||
{ id: 'about', label: 'Acerca de', href: '/about', external: true },
|
|
||||||
{ id: 'blog', label: 'Blog', href: 'https://blog.panaderia-ia.com', external: true },
|
|
||||||
{ id: 'careers', label: 'Carreras', href: 'https://careers.panaderia-ia.com', external: true },
|
|
||||||
{ id: 'press', label: 'Prensa', href: '/press', external: true },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const footerSections = sections || defaultSections;
|
|
||||||
|
|
||||||
// Default social links
|
|
||||||
const defaultSocialLinks: SocialLink[] = [
|
|
||||||
{
|
|
||||||
id: 'github',
|
|
||||||
label: 'GitHub',
|
|
||||||
href: 'https://github.com/panaderia-ia',
|
|
||||||
icon: Github,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'twitter',
|
|
||||||
label: 'Twitter',
|
|
||||||
href: 'https://twitter.com/panaderia_ia',
|
|
||||||
icon: Twitter,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'linkedin',
|
|
||||||
label: 'LinkedIn',
|
|
||||||
href: 'https://linkedin.com/company/panaderia-ia',
|
|
||||||
icon: Linkedin,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const socialLinksToShow = socialLinks || defaultSocialLinks;
|
|
||||||
|
|
||||||
// Privacy links
|
|
||||||
const privacyLinks: FooterLink[] = [
|
|
||||||
{ id: 'privacy', label: 'Privacidad', href: '/privacy', icon: Shield },
|
|
||||||
{ id: 'terms', label: 'Términos', href: '/terms', icon: FileText },
|
|
||||||
{ id: 'cookies', label: 'Cookies', href: '/cookies' },
|
|
||||||
];
|
|
||||||
|
|
||||||
// Scroll into view
|
|
||||||
const scrollIntoView = React.useCallback(() => {
|
|
||||||
footerRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// Expose ref methods
|
|
||||||
React.useImperativeHandle(ref, () => ({
|
|
||||||
scrollIntoView,
|
|
||||||
}), [scrollIntoView]);
|
|
||||||
|
|
||||||
// Render link
|
|
||||||
const renderLink = (link: FooterLink) => {
|
|
||||||
const LinkIcon = link.icon;
|
|
||||||
|
|
||||||
const linkContent = (
|
|
||||||
<span className="flex items-center gap-2 text-sm text-[var(--text-secondary)] hover:text-[var(--text-primary)] transition-colors duration-200">
|
|
||||||
{LinkIcon && <LinkIcon className="w-4 h-4" />}
|
|
||||||
{link.label}
|
|
||||||
{link.external && <ExternalLink className="w-3 h-3" />}
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
|
|
||||||
if (link.external) {
|
|
||||||
return (
|
|
||||||
<a
|
|
||||||
key={link.id}
|
|
||||||
href={link.href}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="hover:underline focus:outline-none focus:underline"
|
|
||||||
>
|
|
||||||
{linkContent}
|
|
||||||
</a>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Link
|
|
||||||
key={link.id}
|
|
||||||
to={link.href}
|
|
||||||
className="hover:underline focus:outline-none focus:underline"
|
|
||||||
>
|
|
||||||
{linkContent}
|
|
||||||
</Link>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Render social link
|
|
||||||
const renderSocialLink = (social: SocialLink) => {
|
|
||||||
const SocialIcon = social.icon;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<a
|
|
||||||
key={social.id}
|
|
||||||
href={social.href}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="p-2 rounded-lg text-[var(--text-secondary)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-secondary)] transition-colors duration-200"
|
|
||||||
aria-label={social.label}
|
|
||||||
>
|
|
||||||
<SocialIcon className="w-5 h-5" />
|
|
||||||
</a>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<footer
|
|
||||||
ref={footerRef}
|
|
||||||
className={clsx(
|
|
||||||
'bg-[var(--bg-secondary)] border-t border-[var(--border-primary)]',
|
|
||||||
'mt-auto', // Push to bottom when using flex layout
|
|
||||||
compact ? 'py-6' : 'py-12',
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
role="contentinfo"
|
|
||||||
>
|
|
||||||
<div className="max-w-7xl mx-auto px-4 lg:px-6">
|
|
||||||
{!compact && (
|
|
||||||
<>
|
|
||||||
{/* Main footer content */}
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8 mb-8">
|
|
||||||
{/* Company info */}
|
|
||||||
<div className="lg:col-span-2">
|
|
||||||
<div className="flex items-center gap-3 mb-4">
|
|
||||||
{company.logo || (
|
|
||||||
<div className="w-8 h-8 bg-gradient-to-br from-[var(--color-primary)] to-[var(--color-primary-dark)] rounded-lg flex items-center justify-center text-white font-bold text-sm">
|
|
||||||
PI
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<span className="text-lg font-semibold text-[var(--text-primary)]">
|
|
||||||
{company.name}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{company.description && (
|
|
||||||
<p className="text-sm text-[var(--text-secondary)] mb-4 max-w-md">
|
|
||||||
{company.description}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Contact info */}
|
|
||||||
<div className="space-y-2">
|
|
||||||
{company.email && (
|
|
||||||
<a
|
|
||||||
href={`mailto:${company.email}`}
|
|
||||||
className="flex items-center gap-2 text-sm text-[var(--text-secondary)] hover:text-[var(--text-primary)] transition-colors duration-200"
|
|
||||||
>
|
|
||||||
<Mail className="w-4 h-4" />
|
|
||||||
{company.email}
|
|
||||||
</a>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{company.phone && (
|
|
||||||
<a
|
|
||||||
href={`tel:${company.phone}`}
|
|
||||||
className="flex items-center gap-2 text-sm text-[var(--text-secondary)] hover:text-[var(--text-primary)] transition-colors duration-200"
|
|
||||||
>
|
|
||||||
<Phone className="w-4 h-4" />
|
|
||||||
{company.phone}
|
|
||||||
</a>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{company.address && (
|
|
||||||
<div className="flex items-center gap-2 text-sm text-[var(--text-secondary)]">
|
|
||||||
<MapPin className="w-4 h-4" />
|
|
||||||
{company.address}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{company.website && (
|
|
||||||
<a
|
|
||||||
href={company.website}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="flex items-center gap-2 text-sm text-[var(--text-secondary)] hover:text-[var(--text-primary)] transition-colors duration-200"
|
|
||||||
>
|
|
||||||
<Globe className="w-4 h-4" />
|
|
||||||
{company.website}
|
|
||||||
<ExternalLink className="w-3 h-3" />
|
|
||||||
</a>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Footer sections */}
|
|
||||||
{footerSections.map(section => (
|
|
||||||
<div key={section.id}>
|
|
||||||
<h3 className="text-sm font-semibold text-[var(--text-primary)] mb-4">
|
|
||||||
{section.title}
|
|
||||||
</h3>
|
|
||||||
<ul className="space-y-3">
|
|
||||||
{section.links.map(link => (
|
|
||||||
<li key={link.id}>
|
|
||||||
{renderLink(link)}
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Social links */}
|
|
||||||
{socialLinksToShow.length > 0 && (
|
|
||||||
<div className="flex items-center justify-center lg:justify-start gap-2 mb-8">
|
|
||||||
{socialLinksToShow.map(renderSocialLink)}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Custom children */}
|
|
||||||
{children && (
|
|
||||||
<div className="mb-8">
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Bottom bar */}
|
|
||||||
<div className={clsx(
|
|
||||||
'flex flex-col sm:flex-row items-center justify-between gap-4',
|
|
||||||
!compact && 'pt-8 border-t border-[var(--border-primary)]'
|
|
||||||
)}>
|
|
||||||
{/* Copyright and version */}
|
|
||||||
<div className="flex flex-col sm:flex-row items-center gap-4 text-sm text-[var(--text-tertiary)]">
|
|
||||||
<div className="flex items-center gap-1">
|
|
||||||
<span>© {currentYear}</span>
|
|
||||||
<span>{company.name}</span>
|
|
||||||
<Heart className="w-4 h-4 text-red-500 mx-1" />
|
|
||||||
<span>Hecho en España</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{showVersion && (
|
|
||||||
<div className="flex items-center gap-1">
|
|
||||||
<span>v{version}</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Right side utilities */}
|
|
||||||
<div className="flex items-center gap-4">
|
|
||||||
{/* Language selector */}
|
|
||||||
{showLanguageSelector && languages.length > 0 && (
|
|
||||||
<select
|
|
||||||
value={currentLanguage}
|
|
||||||
onChange={(e) => onLanguageChange?.(e.target.value)}
|
|
||||||
className="text-sm bg-transparent border-none text-[var(--text-secondary)] hover:text-[var(--text-primary)] cursor-pointer focus:outline-none"
|
|
||||||
>
|
|
||||||
{languages.map(lang => (
|
|
||||||
<option key={lang.code} value={lang.code}>
|
|
||||||
{lang.name}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Theme toggle */}
|
|
||||||
{showThemeToggle && (
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
size="sm"
|
|
||||||
onClick={onThemeToggle}
|
|
||||||
className="text-sm text-[var(--text-secondary)] hover:text-[var(--text-primary)]"
|
|
||||||
>
|
|
||||||
Cambiar tema
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Privacy links */}
|
|
||||||
{showPrivacyLinks && (
|
|
||||||
<div className="flex items-center gap-4">
|
|
||||||
{privacyLinks.map(link => renderLink(link))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Copyright text override */}
|
|
||||||
{copyrightText && (
|
|
||||||
<div className="text-center text-sm text-[var(--text-tertiary)] mt-4 pt-4 border-t border-[var(--border-primary)]">
|
|
||||||
{copyrightText}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
Footer.displayName = 'Footer';
|
|
||||||
@@ -371,7 +371,7 @@
|
|||||||
"feedback": "Feedback",
|
"feedback": "Feedback",
|
||||||
"about": "Acerca de",
|
"about": "Acerca de",
|
||||||
"blog": "Blog",
|
"blog": "Blog",
|
||||||
"careers": "Carreras",
|
"careers": "Empleo",
|
||||||
"press": "Prensa",
|
"press": "Prensa",
|
||||||
"privacy": "Privacidad",
|
"privacy": "Privacidad",
|
||||||
"terms": "Términos",
|
"terms": "Términos",
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ import {
|
|||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
|
|
||||||
const FeaturesPage: React.FC = () => {
|
const FeaturesPage: React.FC = () => {
|
||||||
const { t } = useTranslation('features');
|
const { t } = useTranslation(['features', 'about']);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
// Automatic System Timeline Steps
|
// Automatic System Timeline Steps
|
||||||
@@ -913,57 +913,30 @@ const FeaturesPage: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Final CTA */}
|
{/* Final CTA - Replicated from AboutPage */}
|
||||||
<section className="relative overflow-hidden py-24 bg-[var(--bg-secondary)] border-y border-[var(--border-primary)]">
|
<section className="py-20 bg-gradient-to-r from-[var(--color-primary)] to-orange-600">
|
||||||
{/* Background Pattern */}
|
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
|
||||||
<div className="absolute inset-0 bg-pattern opacity-30"></div>
|
<h2 className="text-3xl lg:text-4xl font-bold text-white mb-6">
|
||||||
|
{t('about:cta.title')}
|
||||||
<div className="relative max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
|
</h2>
|
||||||
<ScrollReveal variant="fadeUp">
|
<p className="text-xl text-white/90 mb-8 leading-relaxed">
|
||||||
<div className="text-center space-y-6">
|
{t('about:cta.subtitle')}
|
||||||
<div className="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-[var(--color-primary)]/10 dark:bg-[var(--color-primary)]/20 border border-[var(--color-primary)]/20 dark:border-[var(--color-primary)]/30 mb-4">
|
</p>
|
||||||
<Sparkles className="w-5 h-5 text-[var(--color-primary)]" />
|
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
||||||
<span className="text-sm font-medium text-[var(--color-primary)]">{t('cta.badge', 'Prueba Gratuita Disponible')}</span>
|
<Link
|
||||||
</div>
|
to="/register"
|
||||||
|
className="inline-flex items-center justify-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"
|
||||||
<h2 className="text-4xl lg:text-5xl font-extrabold text-[var(--text-primary)] mb-6 leading-tight">
|
>
|
||||||
{t('cta.title', 'Ver Bakery-IA en Acción')}
|
<span>{t('about:cta.primary')}</span>
|
||||||
</h2>
|
<ArrowRight className="w-5 h-5" />
|
||||||
|
</Link>
|
||||||
<p className="text-xl lg:text-2xl text-[var(--text-secondary)] mb-8 max-w-2xl mx-auto leading-relaxed">
|
<Link
|
||||||
{t('cta.subtitle', 'Solicita una demo personalizada para tu panadería')}
|
to="/demo"
|
||||||
</p>
|
className="inline-flex items-center justify-center gap-2 px-8 py-4 border-2 border-white text-white rounded-xl font-bold hover:bg-white hover:text-[var(--color-primary)] transition-all"
|
||||||
|
>
|
||||||
<div className="flex flex-col sm:flex-row items-center justify-center gap-4 pt-4">
|
<span>{t('about:cta.secondary')}</span>
|
||||||
<Link to={getDemoUrl()} className="w-full sm:w-auto">
|
</Link>
|
||||||
<Button
|
</div>
|
||||||
size="xl"
|
|
||||||
variant="primary"
|
|
||||||
className="w-full sm:w-auto px-12 py-6 text-xl font-bold shadow-2xl hover:shadow-orange-500/20 transform hover:scale-105 transition-all group"
|
|
||||||
>
|
|
||||||
<Sparkles className="mr-2 w-6 h-6" />
|
|
||||||
{t('cta.button', 'Solicitar Demo')}
|
|
||||||
<ArrowRight className="ml-3 w-6 h-6 group-hover:translate-x-1 transition-transform" />
|
|
||||||
</Button>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex items-center justify-center gap-8 pt-8 text-sm text-[var(--text-tertiary)]">
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<CheckCircle2 className="w-5 h-5 text-[var(--color-success)]" />
|
|
||||||
<span>{t('cta.feature1', 'Sin compromiso')}</span>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<CheckCircle2 className="w-5 h-5 text-[var(--color-success)]" />
|
|
||||||
<span>{t('cta.feature2', 'Configuración en minutos')}</span>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<CheckCircle2 className="w-5 h-5 text-[var(--color-success)]" />
|
|
||||||
<span>{t('cta.feature3', 'Soporte dedicado')}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ScrollReveal>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</PublicLayout>
|
</PublicLayout>
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import {
|
|||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
|
|
||||||
const LandingPage: React.FC = () => {
|
const LandingPage: React.FC = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation(['landing', 'about']);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -671,33 +671,30 @@ const LandingPage: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Final CTA */}
|
{/* Final CTA - Replicated from AboutPage */}
|
||||||
<section className="py-24 bg-[var(--bg-secondary)] border-y border-[var(--border-primary)]">
|
<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">
|
||||||
<ScrollReveal variant="fadeUp">
|
<h2 className="text-3xl lg:text-4xl font-bold text-white mb-6">
|
||||||
<h2 className="text-3xl lg:text-5xl font-extrabold text-[var(--text-primary)] mb-6">
|
{t('about:cta.title')}
|
||||||
{t('landing:final_cta.title', 'Deja de Perder €2,000 al Mes en Desperdicios')}
|
</h2>
|
||||||
</h2>
|
<p className="text-xl text-white/90 mb-8 leading-relaxed">
|
||||||
<p className="text-xl text-[var(--text-secondary)] mb-10 max-w-2xl mx-auto">
|
{t('about:cta.subtitle')}
|
||||||
{t('landing:final_cta.subtitle', 'Únete a las primeras 20 panaderías. Solo quedan 12 plazas.')}
|
</p>
|
||||||
</p>
|
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
||||||
<div className="flex flex-col sm:flex-row gap-4 justify-center items-center">
|
<Link
|
||||||
<Link to={getRegisterUrl()} className="w-full sm:w-auto">
|
to="/register"
|
||||||
<Button
|
className="inline-flex items-center justify-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"
|
||||||
size="xl"
|
>
|
||||||
variant="primary"
|
<span>{t('about:cta.primary')}</span>
|
||||||
className="w-full sm:w-auto px-12 py-6 text-xl font-bold shadow-2xl hover:shadow-orange-500/20 transform hover:scale-105 transition-all"
|
<ArrowRight className="w-5 h-5" />
|
||||||
>
|
</Link>
|
||||||
{t('landing:final_cta.button', 'Comenzar Ahora')}
|
<Link
|
||||||
<ArrowRight className="ml-3 w-6 h-6" />
|
to="/demo"
|
||||||
</Button>
|
className="inline-flex items-center justify-center gap-2 px-8 py-4 border-2 border-white text-white rounded-xl font-bold hover:bg-white hover:text-[var(--color-primary)] transition-all"
|
||||||
</Link>
|
>
|
||||||
</div>
|
<span>{t('about:cta.secondary')}</span>
|
||||||
<p className="mt-8 text-[var(--text-tertiary)] text-sm font-medium">
|
</Link>
|
||||||
<CheckCircle2 className="inline-block w-4 h-4 mr-2 text-green-500" />
|
</div>
|
||||||
{t('landing:final_cta.guarantee', 'Tarjeta requerida. Sin cargo por 3 meses. Cancela cuando quieras.')}
|
|
||||||
</p>
|
|
||||||
</ScrollReveal>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</PublicLayout>
|
</PublicLayout>
|
||||||
|
|||||||
Reference in New Issue
Block a user