2025-12-26 13:12:37 +00:00

680 lines
32 KiB
TypeScript

// // app/brands/BrandsClient.tsx
// 'use client';
// import React, { useState, useEffect } from 'react';
// type Brand = {
// id: string;
// name: string;
// logo?: string;
// dropship: boolean;
// };
// export default function BrandsClient({ brands }: { brands: Brand[] }) {
// const [search, setSearch] = useState('');
// const [selectedIds, setSelectedIds] = useState<string[]>([]);
// const [toast, setToast] = useState('');
// const [isScrolled, setIsScrolled] = useState(false);
// const [showDropshipOnly, setShowDropshipOnly] = useState(false);
// useEffect(() => {
// const handleScroll = () => {
// setIsScrolled(window.scrollY > 10);
// };
// window.addEventListener('scroll', handleScroll);
// return () => window.removeEventListener('scroll', handleScroll);
// }, []);
// const filteredBrands = brands.filter((b) => {
// const matchesSearch = b.name.toLowerCase().includes(search.toLowerCase());
// const matchesDropship = showDropshipOnly ? b.dropship : true;
// return matchesSearch && matchesDropship;
// });
// const allFilteredSelected = filteredBrands.length > 0 && filteredBrands.every((b) => selectedIds.includes(b.id));
// const toggleSelect = (id: string) => {
// setSelectedIds((prev) => (prev.includes(id) ? prev.filter((i) => i !== id) : [...prev, id]));
// };
// const toggleSelectAll = () => {
// console.log('Toggling select all', filteredBrands);
// const ids = filteredBrands.map((b) => b.id);
// if (allFilteredSelected) {
// setSelectedIds((prev) => prev.filter((id) => !ids.includes(id)));
// } else {
// setSelectedIds((prev) => Array.from(new Set([...prev, ...ids])));
// }
// };
// const getSelectedStatusText = () => {
// if (selectedIds.length === 0) return 'No brands selected';
// if (selectedIds.length === 1) return '1 brand selected';
// return `${selectedIds.length} brands selected`;
// };
// const USER_ID = '6ac40b29-8c50-4800-9ece-62b44b69019a'; // static user id
// const handleSave = async () => {
// const payload = {
// userid: USER_ID,
// brands: brands
// .filter((b) => selectedIds.includes(b.id))
// .map((b) => ({
// id: b.id,
// name: b.name,
// logo: b.logo,
// dropship: b.dropship,
// })),
// };
// try {
// const res = await fetch('https://ebay.backend.data4autos.com/api/brands/bulk-insert', {
// method: 'POST',
// headers: {
// 'Content-Type': 'application/json',
// },
// body: JSON.stringify(payload),
// });
// const data = await res.json();
// console.log('Save response:', data);
// // Show beautiful message
// setToast(`${data.message} (Code: ${data.code}, User: ${data.userid})`);
// setTimeout(() => setToast(''), 4000);
// } catch (error) {
// console.error('Error saving brands:', error);
// setToast('Failed to save collections. Please try again.');
// setTimeout(() => setToast(''), 4000);
// }
// };
// // Function to generate filter status text
// const getFilterStatusText = () => {
// if (filteredBrands.length === brands.length && !search && !showDropshipOnly) {
// return `Showing all ${brands.length} brands`;
// }
// let status = `Showing ${filteredBrands.length} of ${brands.length} brands`;
// if (search && showDropshipOnly) {
// status += ` matching "${search}" and dropship only`;
// } else if (search) {
// status += ` matching "${search}"`;
// } else if (showDropshipOnly) {
// status += ` (dropship only)`;
// }
// return status;
// };
// return (
// <div className="min-h-screen bg-gradient-to-br from-slate-50 to-slate-200">
// {/* Enhanced Fixed Header */}
// <div className={`fixed top-0 left-0 w-full z-20 transition-all duration-300 ${isScrolled ? 'bg-white/95 backdrop-blur-md shadow-lg py-3' : 'bg-white/80 backdrop-blur-sm py-4'}`}>
// <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
// <div className="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
// <div className="flex flex-col">
// <h1 className="text-2xl font-bold bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent">Data4Autos Turn14 Brands</h1>
// <p className="text-sm text-gray-500 mt-1">{getFilterStatusText()}</p>
// <p className="text-sm font-medium text-blue-600 mt-1">{getSelectedStatusText()}</p>
// </div>
// <div className="flex flex-col sm:flex-row gap-3 items-stretch sm:items-center">
// <div className="relative flex-grow">
// <div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
// <svg className="h-5 w-5 text-gray-400" fill="currentColor" viewBox="0 0 20 20">
// <path
// fillRule="evenodd"
// d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z"
// clipRule="evenodd"
// />
// </svg>
// </div>
// <input
// type="text"
// value={search}
// onChange={(e) => setSearch(e.target.value)}
// placeholder="Search brands…"
// className="block w-full pl-10 pr-3 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors"
// />
// </div>
// <div className="flex flex-wrap items-center gap-3">
// <label className="flex items-center gap-2 text-sm font-medium text-gray-700 cursor-pointer select-none">
// <div className="relative">
// <input type="checkbox" checked={showDropshipOnly} onChange={() => setShowDropshipOnly(!showDropshipOnly)} className="sr-only" />
// <div className={`block w-10 h-6 rounded-full transition-colors ${showDropshipOnly ? 'bg-blue-600' : 'bg-gray-300'}`}></div>
// <div className={`absolute left-1 top-1 bg-white w-4 h-4 rounded-full transition-transform ${showDropshipOnly ? 'transform translate-x-4' : ''}`}></div>
// </div>
// Dropship Only
// </label>
// <label className="flex items-center gap-2 text-sm font-medium text-gray-700 cursor-pointer select-none">
// <div className="relative">
// <input type="checkbox" checked={allFilteredSelected} onChange={toggleSelectAll} className="sr-only" />
// <div className={`block w-10 h-6 rounded-full transition-colors ${allFilteredSelected ? 'bg-blue-600' : 'bg-gray-300'}`}></div>
// <div className={`absolute left-1 top-1 bg-white w-4 h-4 rounded-full transition-transform ${allFilteredSelected ? 'transform translate-x-4' : ''}`}></div>
// </div>
// Select All
// </label>
// <button
// onClick={handleSave}
// className="px-5 py-2.5 bg-gradient-to-r from-blue-600 to-purple-600 text-white font-medium rounded-lg hover:from-blue-700 hover:to-purple-700 transition-all duration-300 transform hover:-translate-y-0.5 disabled:opacity-50 disabled:transform-none disabled:cursor-not-allowed flex items-center gap-2 shadow-md hover:shadow-lg"
// >
// <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
// <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M5 13l4 4L19 7"></path>
// </svg>
// Save Collections
// </button>
// </div>
// </div>
// </div>
// </div>
// </div>
// {/* Brand Grid */}
// <div className="pt-32 pb-12 px-4 sm:px-6 lg:px-8 max-w-7xl mx-auto">
// {filteredBrands.length > 0 ? (
// <div className="grid grid-cols-1 xs:grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 gap-5">
// {/* {filteredBrands.map((brand, index) => ( */}
// {[...filteredBrands]
// .sort((a, b) => {
// const aSelected = selectedIds.includes(a.id);
// const bSelected = selectedIds.includes(b.id);
// if (aSelected && !bSelected) return -1;
// if (!aSelected && bSelected) return 1;
// return 0;
// })
// .map((brand, index) => (
// <div
// key={brand.id}
// className="bg-white rounded-xl shadow-md overflow-hidden hover:shadow-xl transition-all duration-300 transform hover:-translate-y-1.5 relative group"
// style={{ animationDelay: `${index * 0.05}s` }}
// onClick={() => toggleSelect(brand.id)}
// >
// <div className="absolute top-3 right-3 z-10">
// <label className="inline-flex items-center">
// <input type="checkbox" checked={selectedIds.includes(brand.id)} onChange={() => toggleSelect(brand.id)} className="absolute opacity-0 h-0 w-0" />
// <span
// className={`checkmark w-6 h-6 rounded-md border-2 flex items-center justify-center transition-all ${selectedIds.includes(brand.id) ? 'bg-blue-600 border-blue-600' : 'bg-white border-gray-300 group-hover:border-blue-400'}`}
// >
// {selectedIds.includes(brand.id) && (
// <svg className="w-4 h-4 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
// <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="3" d="M5 13l4 4L19 7"></path>
// </svg>
// )}
// </span>
// </label>
// </div>
// {brand.dropship && (
// <div className="absolute top-3 left-3 z-10">
// <span className="inline-flex items-center px-2 py-1 bg-green-100 text-green-800 text-xs font-medium rounded-md">Dropship</span>
// </div>
// )}
// <div className="p-5 flex flex-col items-center h-full">
// <div className="w-28 h-28 flex items-center justify-center p-2 bg-gray-50 rounded-lg mb-4">
// <img
// src={brand.logo || 'https://cdn.shopify.com/s/files/1/0757/9955/files/no-image_280x@2x.png'}
// alt={brand.name}
// className="max-w-full max-h-full object-contain"
// />
// </div>
// <p className="text-center font-medium text-gray-800 mt-auto">{brand.name}</p>
// </div>
// </div>
// ))}
// </div>
// ) : (
// <div className="text-center py-20">
// <div className="inline-block p-4 bg-white rounded-xl shadow-md">
// <svg className="w-16 h-16 mx-auto text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
// <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M9.172 16.172a4 4 0 015.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
// </svg>
// <h3 className="mt-4 text-xl font-medium text-gray-700">No brands found</h3>
// <p className="mt-2 text-gray-500">Try adjusting your search query or filter settings</p>
// </div>
// </div>
// )}
// </div>
// {/* Enhanced Toast Notification */}
// {/* {toast && (
// <div className="fixed bottom-6 right-6 bg-green-600 text-white px-6 py-3 rounded-xl shadow-lg z-30 animate-fade-in-up">
// <div className="flex items-center gap-3">
// <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
// <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M5 13l4 4L19 7"></path>
// </svg>
// <span>{toast}</span>
// </div>
// </div>
// )} */}
// {toast && (
// <div className="fixed bottom-6 right-6 bg-gradient-to-r from-green-500 to-emerald-600 text-white px-6 py-4 rounded-2xl shadow-2xl z-30 animate-fade-in-up">
// <div className="flex items-center gap-3">
// <svg className="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
// <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M5 13l4 4L19 7"></path>
// </svg>
// <span className="font-medium">{toast}</span>
// </div>
// </div>
// )}
// {/* Add custom animations */}
// <style jsx global>{`
// @keyframes fadeInUp {
// from {
// opacity: 0;
// transform: translate3d(0, 40px, 0);
// }
// to {
// opacity: 1;
// transform: translate3d(0, 0, 0);
// }
// }
// .animate-fade-in-up {
// animation: fadeInUp 0.5s ease-out;
// }
// .checkmark {
// transition: all 0.2s ease;
// }
// `}</style>
// </div>
// );
// }
'use client';
import { getAccessToken_client } from '@/utils/apiHelper_client';
import axios from 'axios';
import { useRouter } from 'next/navigation';
import React, { useState, useEffect } from 'react';
type Brand = {
id: string;
name: string;
logo?: string;
dropship: boolean;
};
async function fetchBrands(accessToken: string): Promise<Brand[]> {
const resp = await fetch('https://turn14.data4autos.com/v1/brands', {
headers: { Authorization: `Bearer ${accessToken}` },
cache: 'no-store',
});
if (!resp.ok) {
throw new Error(`Failed to fetch brands: ${resp.statusText}`);
}
const data = await resp.json();
return data.data || [];
}
export default function BrandsClient() {
const router = useRouter()
const [brands, setBrands] = useState<Brand[]>([]);
const [search, setSearch] = useState('');
const [selectedIds, setSelectedIds] = useState<string[]>([]);
const [toast, setToast] = useState('');
const [isScrolled, setIsScrolled] = useState(false);
const [showDropshipOnly, setShowDropshipOnly] = useState(false);
const [payment, setPayment] = useState<any>(null);
const userId = sessionStorage.getItem('USERID');
useEffect(() => {
const role = localStorage.getItem("user_role");
const sessionId = localStorage.getItem("payment_session");
// ✅ Admins and Partners can access directly (skip payment check)
if (role === "admin" || role === "partner") {
return;
}
// 🚫 If no payment session, redirect to pricing
if (!sessionId) {
router.push("/pricing");
return;
}
// ✅ Otherwise, check payment details
const fetchPaymentDetails = async () => {
try {
const res: any = await axios.get(
"https://ebay.backend.data4autos.com/api/payment/details",
{ params: { session_id: sessionId } }
);
setPayment(res.data.payment);
} catch (err) {
console.error("Error fetching payment details:", err);
}
};
fetchPaymentDetails();
}, [router]);
useEffect(() => {
const fetchUserBrands = async () => {
try {
//console.log('Fetching access token...'); // Debugging line
const accessToken = await getAccessToken_client();
//console.log('Access Token:', accessToken); // Debugging line
const brands = accessToken ? await fetchBrands(accessToken) : [];
setBrands(brands);
const res = await fetch(`https://ebay.backend.data4autos.com/api/brands/${userId}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
// Optionally add Authorization: `Bearer ${accessToken}` if needed
},
});
const data = await res.json();
console.log('GET response:', data);
// Extract selected brand IDs from the response
const userSelectedIds = data.map((b: any) => String(b.brandid)); // brandid from your response
setSelectedIds(userSelectedIds);
// Optional: show toast
setToast(`Loaded ${userSelectedIds.length} selected brands`);
setTimeout(() => setToast(''), 4000);
} catch (error) {
console.error('Error fetching brands:', error);
setToast('Failed to load user brands');
setTimeout(() => setToast(''), 4000);
}
};
fetchUserBrands();
}, []);
useEffect(() => {
const handleScroll = () => {
setIsScrolled(window.scrollY > 10);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
const filteredBrands = brands.filter((b) => {
const matchesSearch = b.name.toLowerCase().includes(search.toLowerCase());
const matchesDropship = showDropshipOnly ? b.dropship : true;
return matchesSearch && matchesDropship;
});
const allFilteredSelected = filteredBrands.length > 0 && filteredBrands.every((b) => selectedIds.includes(b.id));
const toggleSelect = (id: string) => {
setSelectedIds((prev) => (prev.includes(id) ? prev.filter((i) => i !== id) : [...prev, id]));
};
const toggleSelectAll = () => {
const ids = filteredBrands.map((b) => b.id);
if (allFilteredSelected) {
setSelectedIds((prev) => prev.filter((id) => !ids.includes(id)));
} else {
setSelectedIds((prev) => Array.from(new Set([...prev, ...ids])));
}
};
const getSelectedStatusText = () => {
if (selectedIds.length === 0) return 'No brands selected';
if (selectedIds.length === 1) return '1 brand selected';
return `${selectedIds.length} brands selected`;
};
//const userId = sessionStorage.getItem('USERID'); // dynamic user id
const handleSave = async () => {
const payload = {
userid: userId,
brands: brands
.filter((b) => selectedIds.includes(b.id))
.map((b) => ({
id: b.id,
name: b.name,
logo: b.logo,
dropship: b.dropship,
})),
};
try {
const res = await fetch('https://ebay.backend.data4autos.com/api/brands/bulk-insert', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});
const data = await res.json();
setToast(`${data.message} (Code: ${data.code}, User: ${data.userid})`);
setTimeout(() => setToast(''), 4000);
} catch (error) {
console.error('Error saving brands:', error);
setToast('Failed to save collections. Please try again.');
setTimeout(() => setToast(''), 4000);
}
};
const getFilterStatusText = () => {
if (filteredBrands.length === brands.length && !search && !showDropshipOnly) {
return `Showing all ${brands.length} brands`;
}
let status = `Showing ${filteredBrands.length} of ${brands.length} brands`;
if (search && showDropshipOnly) {
status += ` matching "${search}" and dropship only`;
} else if (search) {
status += ` matching "${search}"`;
} else if (showDropshipOnly) {
status += ` (dropship only)`;
}
return status;
};
return (
<div className="bg-gradient-to-br from-[#00d1ff]/10 via-white to-[#00d1ff]/20">
{/* Sticky Header (below default Header) */}
<div
className={`sticky top-14 z-10 transition-all duration-300 ${isScrolled ? 'bg-white/95 backdrop-blur-md shadow-lg py-3' : 'bg-white/80 backdrop-blur-sm py-4'
}`}
>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
<div className="flex flex-col">
<h1 className="text-2xl font-bold bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-[#00d1ff]">
Data4Autos Turn14 Brands
</h1>
<p className="text-sm text-gray-500 mt-1">{getFilterStatusText()}</p>
<p className="text-sm font-medium text-[#00d1ff] mt-1">{getSelectedStatusText()}</p>
</div>
<div className="flex flex-col sm:flex-row gap-3 items-stretch sm:items-center">
<div className="relative flex-grow">
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<svg className="h-5 w-5 text-gray-400" fill="currentColor" viewBox="0 0 20 20">
<path
fillRule="evenodd"
d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z"
clipRule="evenodd"
/>
</svg>
</div>
<input
type="text"
value={search}
onChange={(e) => setSearch(e.target.value)}
placeholder="Search brands…"
className="block w-full pl-10 pr-3 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors"
/>
</div>
<div className="flex flex-wrap items-center gap-3">
<label className="flex items-center gap-2 text-sm font-medium text-gray-700 cursor-pointer select-none">
<div className="relative">
<input
type="checkbox"
checked={showDropshipOnly}
onChange={() => setShowDropshipOnly(!showDropshipOnly)}
className="sr-only"
/>
<div className={`block w-10 h-6 rounded-full transition-colors ${showDropshipOnly ? 'bg-[#00d1ff]' : 'bg-gray-300'}`}></div>
<div
className={`absolute left-1 top-1 bg-white w-4 h-4 rounded-full transition-transform ${showDropshipOnly ? 'transform translate-x-4' : ''
}`}
></div>
</div>
Dropship Only
</label>
<label className="flex items-center gap-2 text-sm font-medium text-gray-700 cursor-pointer select-none">
<div className="relative">
<input type="checkbox" checked={allFilteredSelected} onChange={toggleSelectAll} className="sr-only" />
<div className={`block w-10 h-6 rounded-full transition-colors ${allFilteredSelected ? 'bg-[#00d1ff]' : 'bg-gray-300'}`}></div>
<div
className={`absolute left-1 top-1 bg-white w-4 h-4 rounded-full transition-transform ${allFilteredSelected ? 'transform translate-x-4' : ''
}`}
></div>
</div>
Select All
</label>
<button
onClick={handleSave}
className="px-5 py-2.5 bg-[#00d1ff] text-white font-medium rounded-lg hover:from-blue-700 hover:to-purple-700 transition-all duration-300 transform hover:-translate-y-0.5 disabled:opacity-50 disabled:transform-none disabled:cursor-not-allowed flex items-center gap-2 shadow-md hover:shadow-lg"
>
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M5 13l4 4L19 7"></path>
</svg>
Save Collections
</button>
</div>
</div>
</div>
</div>
</div>
{/* Brand Grid */}
<div className={`pb-12 px-4 sm:px-6 lg:px-8 max-w-7xl mx-auto ${isScrolled ? 'pt-[100px]' : 'pt-16'}`}>
{filteredBrands.length > 0 ? (
<div className="grid grid-cols-1 xs:grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 gap-5">
{[...filteredBrands]
.sort((a, b) => {
const aSelected = selectedIds.includes(a.id);
const bSelected = selectedIds.includes(b.id);
if (aSelected && !bSelected) return -1;
if (!aSelected && bSelected) return 1;
return 0;
})
.map((brand, index) => (
<div
key={brand.id}
className="bg-white rounded-xl shadow-md overflow-hidden hover:shadow-xl transition-all duration-300 transform hover:-translate-y-1.5 relative group"
style={{ animationDelay: `${index * 0.05}s` }}
onClick={() => toggleSelect(brand.id)}
>
<div className="absolute top-3 right-3 z-10">
<label className="inline-flex items-center">
<input
type="checkbox"
checked={selectedIds.includes(brand.id)}
onChange={() => toggleSelect(brand.id)}
className="absolute opacity-0 h-0 w-0"
/>
<span
className={`checkmark w-6 h-6 rounded-md border-2 flex items-center justify-center transition-all ${selectedIds.includes(brand.id) ? 'bg-[#00d1ff] border-[#00d1ff]' : 'bg-white border-gray-300 group-hover:border-blue-400'
}`}
>
{selectedIds.includes(brand.id) && (
<svg className="w-4 h-4 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="3" d="M5 13l4 4L19 7"></path>
</svg>
)}
</span>
</label>
</div>
{brand.dropship && (
<div className="absolute top-3 left-3 z-10">
<span className="inline-flex items-center px-2 py-1 bg-green-100 text-green-800 text-xs font-medium rounded-md">Dropship</span>
</div>
)}
<div className="p-5 flex flex-col items-center h-full">
<div className="w-28 h-28 flex items-center justify-center p-2 bg-gray-50 rounded-lg mb-4">
<img
src={brand.logo || 'https://cdn.shopify.com/s/files/1/0757/9955/files/no-image_280x@2x.png'}
alt={brand.name}
className="max-w-full max-h-full object-contain"
/>
</div>
<p className="text-center font-medium text-gray-800 mt-auto">{brand.name}</p>
<p className="text-center font-medium text-gray-800 mt-auto">ID : {brand.id}</p>
</div>
</div>
))}
</div>
) : (
<div className="text-center py-20">
<div className="inline-block p-4 bg-white rounded-xl shadow-md">
<svg className="w-16 h-16 mx-auto text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M9.172 16.172a4 4 0 015.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
<h3 className="mt-4 text-xl font-medium text-gray-700">No brands found</h3>
<p className="mt-2 text-gray-500">Try adjusting your search query or filter settings</p>
</div>
</div>
)}
</div>
{/* Toast Notification */}
{toast && (
<div className="fixed bottom-6 right-6 bg-gradient-to-r from-green-500 to-emerald-600 text-white px-6 py-4 rounded-2xl shadow-2xl z-30 animate-fade-in-up">
<div className="flex items-center gap-3">
<svg className="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M5 13l4 4L19 7"></path>
</svg>
<span className="font-medium">{toast}</span>
</div>
</div>
)}
{/* Custom Animations */}
<style jsx global>{`
@keyframes fadeInUp {
from {
opacity: 0;
transform: translate3d(0, 40px, 0);
}
to {
opacity: 1;
transform: translate3d(0, 0, 0);
}
}
.animate-fade-in-up {
animation: fadeInUp 0.5s ease-out;
}
.checkmark {
transition: all 0.2s ease;
}
`}</style>
</div>
);
}