ifixkart-storefront/components/store/StoreFooter.tsx

143 lines
6.5 KiB
TypeScript

/**
* @component StoreFooter
* @purpose Footer with dynamic CMS data — columns, contact info, social links, and payment icons
* loaded from /api/v1/storefront/footer-info. Gracefully falls back to static defaults.
* @dependencies storefrontService, lucide-react
*/
'use client';
import { useState, useEffect } from 'react';
import Link from 'next/link';
import { Phone, Globe, Share2, Link2, ExternalLink } from 'lucide-react';
import { storefrontService, FooterInfo } from '@/services/api/storefrontService';
const SOCIAL_ICONS: Record<string, React.ReactNode> = {
facebook: <Share2 className="w-4 h-4" />,
instagram: <Link2 className="w-4 h-4" />,
twitter: <ExternalLink className="w-4 h-4" />,
globe: <Globe className="w-4 h-4" />,
};
const FALLBACK_FOOTER: FooterInfo = {
phone: '+91 99999 99999',
email: 'support@ifixkart.com',
address: 'iFixKart Service Center, MG Road, Bengaluru, Karnataka - 560001',
copyright: '© 2026 iFixKart. All rights reserved.',
social_links: [
{ platform: 'Facebook', url: '#', icon: 'facebook' },
{ platform: 'Instagram', url: '#', icon: 'instagram' },
{ platform: 'Twitter', url: '#', icon: 'twitter' },
],
columns: [
{ title: 'Get to Know Us', links: [{ label: 'About Us', href: '/about' }, { label: 'Term & Policy', href: '/terms' }, { label: 'Careers', href: '/careers' }, { label: 'Contact Us', href: '/contact' }] },
{ title: 'Information', links: [{ label: 'Help Center', href: '/help' }, { label: 'FAQs', href: '/faqs' }, { label: 'Payments', href: '/payments' }] },
{ title: 'Orders & Returns',links: [{ label: 'Track Order', href: '/account' }, { label: 'Services', href: '/services' }, { label: 'Returns', href: '/returns' }] },
{ title: 'Our Store', links: [{ label: 'Best Seller', href: '/products?sort=best-sellers' }, { label: 'New Products', href: '/products?sort=newest' }, { label: 'On Sale', href: '/products?on_sale=true' }] },
],
payment_methods: [
{ name: 'Visa' }, { name: 'Mastercard' }, { name: 'UPI' }, { name: 'Razorpay' },
],
};
export function StoreFooter() {
const [footer, setFooter] = useState<FooterInfo | null>(null);
useEffect(() => {
storefrontService.getFooterInfo().then(setFooter).catch(() => setFooter(FALLBACK_FOOTER));
}, []);
const info = footer || FALLBACK_FOOTER;
// Support both new (columns[]) and legacy (get_to_know_us / information / orders_returns / our_store) formats
const navColumns: { title: string; links: { label: string; href: string }[] }[] =
info.columns && info.columns.length > 0
? info.columns
: [
{ title: 'Get to Know Us', links: info.get_to_know_us || [] },
{ title: 'Information', links: info.information || [] },
{ title: 'Orders & Returns', links: info.orders_returns || [] },
{ title: 'Our Store', links: info.our_store || [] },
].filter((c) => c.links.length > 0);
const socials = info.social_links || [];
const payments = info.payment_methods || [];
return (
<footer className="w-full bg-[#f5f6f8] text-[#555555] mt-12 border-t border-gray-200">
<div className="max-w-7xl mx-auto px-4 py-12">
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-5 gap-8 text-xs">
{/* Column 1: Contact Us */}
<div className="space-y-3">
<h4 className="font-extrabold text-gray-900 uppercase tracking-wider mb-2">Contact Us</h4>
<div className="text-lg font-black text-gray-900 flex items-center gap-2">
<Phone className="w-4 h-4 text-[#1877f2]" /> {info.phone}
</div>
<p className="text-gray-500 leading-relaxed text-[11px]">{info.address}</p>
<a href={`mailto:${info.email}`} className="text-[#1877f2] font-semibold hover:underline block">
{info.email}
</a>
{socials.length > 0 && (
<div className="flex items-center gap-3 pt-2 text-gray-600">
{socials.map((s, i) => (
<a key={i} href={s.url} target="_blank" rel="noopener noreferrer"
className="hover:text-[#1877f2] transition-colors" title={s.platform}>
{SOCIAL_ICONS[s.icon?.toLowerCase() || ''] || <Globe className="w-4 h-4" />}
</a>
))}
</div>
)}
</div>
{/* Dynamic Navigation Columns */}
{navColumns.map((col, ci) => (
<div key={ci}>
<h4 className="font-extrabold text-gray-900 uppercase tracking-wider mb-3">{col.title}</h4>
<ul className="space-y-2">
{col.links.map((item, li) => (
<li key={li}>
<Link href={item.href} className="hover:text-[#1877f2] transition-colors">
{item.label}
</Link>
</li>
))}
</ul>
</div>
))}
</div>
{/* Bottom Copyright & Payment Icons Bar */}
<div className="border-t border-gray-200 mt-10 pt-6 flex flex-col sm:flex-row items-center justify-between gap-4 text-xs text-gray-500 font-medium">
<p>{info.copyright}</p>
<div className="flex items-center gap-2 flex-wrap">
{payments.length > 0 ? (
payments.map((pm, i) =>
pm.icon_url ? (
/* eslint-disable-next-line @next/next/no-img-element */
<img
key={i}
src={pm.icon_url}
alt={pm.name}
className="h-6 max-w-[80px] object-contain"
onError={(e) => {
(e.target as HTMLElement).style.display = 'none';
}}
/>
) : (
<span key={i} className="bg-white px-2 py-1 rounded border border-gray-200 font-black text-[10px] text-blue-900">
{pm.name.toUpperCase()}
</span>
)
)
) : (
<>
<span className="bg-white px-2 py-1 rounded border border-gray-200 font-black text-[10px] text-blue-900">VISA</span>
<span className="bg-white px-2 py-1 rounded border border-gray-200 font-black text-[10px] text-amber-600">MASTERCARD</span>
<span className="bg-white px-2 py-1 rounded border border-gray-200 font-black text-[10px] text-blue-600">UPI</span>
</>
)}
</div>
</div>
</div>
</footer>
);
}