143 lines
6.5 KiB
TypeScript
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>
|
|
);
|
|
}
|