ifixkart-storefront/components/store/SalesNotification.tsx

91 lines
2.9 KiB
TypeScript

/**
* @component SalesNotification
* @purpose Live purchase toast notification popup matching Screenshots 1, 4 & reference specs.
* @a11y Accessible dismissal button
*/
'use client';
import { useState, useEffect } from 'react';
import Image from 'next/image';
import { X, CheckCircle } from 'lucide-react';
export function SalesNotification() {
const [visible, setVisible] = useState(false);
const [currentNotification, setCurrentNotification] = useState({
name: 'Swaraa (California)',
item: 'HP LaserJet P1108 Mono Single Function Laser Printer',
time: '46 minutes ago',
image: '',
});
const notifications = [
{
name: 'Swaraa (California)',
item: 'HP LaserJet P1108 Mono Single Function Laser Printer',
time: '46 minutes ago',
image: '',
},
{
name: 'Nia (London)',
item: 'Apple Airpods Pro (2nd Gen) with MagSafe Charging Case',
time: '25 minutes ago',
image: '',
},
{
name: 'Liam (New York)',
item: 'Sony WH-1000XM5 Wireless Headphones',
time: '12 minutes ago',
image: '',
},
];
useEffect(() => {
let index = 0;
const interval = setInterval(() => {
index = (index + 1) % notifications.length;
setCurrentNotification(notifications[index]);
setVisible(true);
setTimeout(() => setVisible(false), 5000);
}, 12000);
// Initial show after 3 seconds
const initialTimer = setTimeout(() => {
setVisible(true);
setTimeout(() => setVisible(false), 5000);
}, 3000);
return () => {
clearInterval(interval);
clearTimeout(initialTimer);
};
}, []);
if (!visible) return null;
return (
<div className="fixed bottom-4 left-4 z-40 bg-white rounded-xl border border-gray-200 p-3 shadow-xl max-w-xs flex items-center gap-3 animate-in slide-in-from-bottom-5 duration-300">
<div className="relative w-12 h-12 rounded-lg border border-gray-100 overflow-hidden bg-gray-50 shrink-0">
<Image src={currentNotification.image} alt={currentNotification.item} fill className="object-cover" />
</div>
<div className="flex-1 min-w-0 text-[11px]">
<div className="text-gray-500 font-medium">
<strong className="text-gray-900 font-bold">{currentNotification.name}</strong> purchased
</div>
<div className="font-bold text-[#1877f2] truncate">{currentNotification.item}</div>
<div className="text-[9px] text-gray-400 flex items-center gap-1 mt-0.5">
<span>{currentNotification.time}</span>
<span></span>
<span className="text-[#01b574] font-semibold flex items-center gap-0.5">
<CheckCircle className="w-2.5 h-2.5" /> Verified
</span>
</div>
</div>
<button
onClick={() => setVisible(false)}
className="p-1 text-gray-400 hover:text-gray-600 rounded-full hover:bg-gray-100 transition-colors"
>
<X className="w-3.5 h-3.5" />
</button>
</div>
);
}