feat: add withdraw category to notifications and improve UI sidebar layout
This commit is contained in:
@@ -11,7 +11,7 @@ import toast from 'react-hot-toast';
|
|||||||
|
|
||||||
interface Notification {
|
interface Notification {
|
||||||
id: string;
|
id: string;
|
||||||
category: 'kyc' | 'rental' | 'maintenance' | 'swap_station' | 'investor' | 'system';
|
category: 'kyc' | 'rental' | 'maintenance' | 'swap_station' | 'investor' | 'system' | 'withdraw';
|
||||||
priority: 'low' | 'medium' | 'high' | 'critical';
|
priority: 'low' | 'medium' | 'high' | 'critical';
|
||||||
title: string;
|
title: string;
|
||||||
message: string;
|
message: string;
|
||||||
@@ -51,7 +51,7 @@ const mockUsersList = [
|
|||||||
const initialNotifications: Notification[] = [
|
const initialNotifications: Notification[] = [
|
||||||
{
|
{
|
||||||
id: 'notif-inv-002',
|
id: 'notif-inv-002',
|
||||||
category: 'investor',
|
category: 'withdraw',
|
||||||
priority: 'high',
|
priority: 'high',
|
||||||
title: 'New Withdrawal Request',
|
title: 'New Withdrawal Request',
|
||||||
message: 'Investor Md. Hasan Mahmud (inv1) submitted a withdrawal request of ৳15,000 to bank account Islami Bank Bangladesh Ltd.',
|
message: 'Investor Md. Hasan Mahmud (inv1) submitted a withdrawal request of ৳15,000 to bank account Islami Bank Bangladesh Ltd.',
|
||||||
@@ -660,8 +660,7 @@ export default function AdminNotificationsPage() {
|
|||||||
<div className="flex border-b border-slate-200">
|
<div className="flex border-b border-slate-200">
|
||||||
<button
|
<button
|
||||||
onClick={() => { setActiveTab('inbox'); setFilter('all'); }}
|
onClick={() => { setActiveTab('inbox'); setFilter('all'); }}
|
||||||
className={`py-3 px-6 text-sm font-bold border-b-2 transition-all flex items-center gap-2 ${
|
className={`py-3 px-6 text-sm font-bold border-b-2 transition-all flex items-center gap-2 ${activeTab === 'inbox' ? 'border-accent text-accent' : 'border-transparent text-slate-500 hover:text-slate-800'
|
||||||
activeTab === 'inbox' ? 'border-accent text-accent' : 'border-transparent text-slate-500 hover:text-slate-800'
|
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<Bell className="w-4 h-4" /> Alert Inbox ({notifications.length})
|
<Bell className="w-4 h-4" /> Alert Inbox ({notifications.length})
|
||||||
@@ -671,8 +670,7 @@ export default function AdminNotificationsPage() {
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => { setActiveTab('outbox'); setFilter('all'); }}
|
onClick={() => { setActiveTab('outbox'); setFilter('all'); }}
|
||||||
className={`py-3 px-6 text-sm font-bold border-b-2 transition-all flex items-center gap-2 ${
|
className={`py-3 px-6 text-sm font-bold border-b-2 transition-all flex items-center gap-2 ${activeTab === 'outbox' ? 'border-accent text-accent' : 'border-transparent text-slate-500 hover:text-slate-800'
|
||||||
activeTab === 'outbox' ? 'border-accent text-accent' : 'border-transparent text-slate-500 hover:text-slate-800'
|
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<Send className="w-4 h-4" /> Broadcast History ({broadcasts.length})
|
<Send className="w-4 h-4" /> Broadcast History ({broadcasts.length})
|
||||||
@@ -725,7 +723,7 @@ export default function AdminNotificationsPage() {
|
|||||||
<div className="grid lg:grid-cols-4 gap-6 items-start">
|
<div className="grid lg:grid-cols-4 gap-6 items-start">
|
||||||
|
|
||||||
{/* Desktop Sidebar Filters: Kept for Desktop views */}
|
{/* Desktop Sidebar Filters: Kept for Desktop views */}
|
||||||
<div className="hidden lg:block lg:col-span-1 space-y-4">
|
<div className="hidden lg:block lg:col-span-1 space-y-4 sticky top-6">
|
||||||
<div className="bg-white p-4 rounded-xl border border-slate-100 shadow-sm space-y-4">
|
<div className="bg-white p-4 rounded-xl border border-slate-100 shadow-sm space-y-4">
|
||||||
<h3 className="font-bold text-slate-700 flex items-center gap-2"><Filter className="w-4 h-4 text-accent" /> Filter Inbox</h3>
|
<h3 className="font-bold text-slate-700 flex items-center gap-2"><Filter className="w-4 h-4 text-accent" /> Filter Inbox</h3>
|
||||||
|
|
||||||
@@ -738,8 +736,7 @@ export default function AdminNotificationsPage() {
|
|||||||
<button
|
<button
|
||||||
key={f.id}
|
key={f.id}
|
||||||
onClick={() => setFilter(f.id)}
|
onClick={() => setFilter(f.id)}
|
||||||
className={`w-full flex items-center justify-between px-3 py-2 text-sm font-semibold rounded-lg text-left transition-colors cursor-pointer ${
|
className={`w-full flex items-center justify-between px-3 py-2 text-sm font-semibold rounded-lg text-left transition-colors cursor-pointer ${filter === f.id ? 'bg-accent text-white' : 'text-slate-600 hover:bg-slate-50'
|
||||||
filter === f.id ? 'bg-accent text-white' : 'text-slate-600 hover:bg-slate-50'
|
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{f.label}
|
{f.label}
|
||||||
@@ -764,6 +761,7 @@ export default function AdminNotificationsPage() {
|
|||||||
{ id: 'maintenance', label: 'Vehicle Service' },
|
{ id: 'maintenance', label: 'Vehicle Service' },
|
||||||
{ id: 'swap_station', label: 'Cabinet Network' },
|
{ id: 'swap_station', label: 'Cabinet Network' },
|
||||||
{ id: 'investor', label: 'Investor Ledger' },
|
{ id: 'investor', label: 'Investor Ledger' },
|
||||||
|
{ id: 'withdraw', label: 'Withdrawal Requests' },
|
||||||
].map(cat => {
|
].map(cat => {
|
||||||
const catCount = cat.id === 'all'
|
const catCount = cat.id === 'all'
|
||||||
? notifications.length
|
? notifications.length
|
||||||
@@ -772,14 +770,12 @@ export default function AdminNotificationsPage() {
|
|||||||
<button
|
<button
|
||||||
key={cat.id}
|
key={cat.id}
|
||||||
onClick={() => setCategoryFilter(cat.id)}
|
onClick={() => setCategoryFilter(cat.id)}
|
||||||
className={`w-full flex items-center justify-between px-3 py-2 text-sm font-semibold rounded-lg text-left transition-colors cursor-pointer ${
|
className={`w-full flex items-center justify-between px-3 py-2 text-sm font-semibold rounded-lg text-left transition-colors cursor-pointer ${categoryFilter === cat.id ? 'bg-slate-100 text-slate-800' : 'text-slate-600 hover:bg-slate-50'
|
||||||
categoryFilter === cat.id ? 'bg-slate-100 text-slate-800' : 'text-slate-600 hover:bg-slate-50'
|
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<span>{cat.label}</span>
|
<span>{cat.label}</span>
|
||||||
{catCount > 0 && (
|
{catCount > 0 && (
|
||||||
<span className={`px-2 py-0.5 rounded-full text-xs font-bold ${
|
<span className={`px-2 py-0.5 rounded-full text-xs font-bold ${categoryFilter === cat.id ? 'bg-accent text-white' : 'bg-slate-100 text-slate-600 border border-slate-200'
|
||||||
categoryFilter === cat.id ? 'bg-accent text-white' : 'bg-slate-100 text-slate-600 border border-slate-200'
|
|
||||||
}`}>
|
}`}>
|
||||||
{catCount}
|
{catCount}
|
||||||
</span>
|
</span>
|
||||||
@@ -812,6 +808,7 @@ export default function AdminNotificationsPage() {
|
|||||||
{ id: 'maintenance', label: 'Vehicle Service' },
|
{ id: 'maintenance', label: 'Vehicle Service' },
|
||||||
{ id: 'swap_station', label: 'Cabinet Network' },
|
{ id: 'swap_station', label: 'Cabinet Network' },
|
||||||
{ id: 'investor', label: 'Investor Ledger' },
|
{ id: 'investor', label: 'Investor Ledger' },
|
||||||
|
{ id: 'withdraw', label: 'Withdrawal Requests' },
|
||||||
].map(cat => {
|
].map(cat => {
|
||||||
const catCount = cat.id === 'all'
|
const catCount = cat.id === 'all'
|
||||||
? notifications.length
|
? notifications.length
|
||||||
@@ -820,16 +817,14 @@ export default function AdminNotificationsPage() {
|
|||||||
<button
|
<button
|
||||||
key={cat.id}
|
key={cat.id}
|
||||||
onClick={() => setCategoryFilter(cat.id)}
|
onClick={() => setCategoryFilter(cat.id)}
|
||||||
className={`px-4 py-2 rounded-full text-xs font-bold border transition-colors shrink-0 whitespace-nowrap cursor-pointer flex items-center gap-1.5 ${
|
className={`px-4 py-2 rounded-full text-xs font-bold border transition-colors shrink-0 whitespace-nowrap cursor-pointer flex items-center gap-1.5 ${categoryFilter === cat.id
|
||||||
categoryFilter === cat.id
|
|
||||||
? 'bg-accent border-accent text-white shadow-sm'
|
? 'bg-accent border-accent text-white shadow-sm'
|
||||||
: 'bg-white border-slate-200 text-slate-600 hover:bg-slate-50'
|
: 'bg-white border-slate-200 text-slate-600 hover:bg-slate-50'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<span>{cat.label}</span>
|
<span>{cat.label}</span>
|
||||||
{catCount > 0 && (
|
{catCount > 0 && (
|
||||||
<span className={`px-1.5 py-0.5 rounded-full text-[10px] font-bold ${
|
<span className={`px-1.5 py-0.5 rounded-full text-[10px] font-bold ${categoryFilter === cat.id ? 'bg-white text-accent' : 'bg-slate-100 text-slate-500'
|
||||||
categoryFilter === cat.id ? 'bg-white text-accent' : 'bg-slate-100 text-slate-500'
|
|
||||||
}`}>
|
}`}>
|
||||||
{catCount}
|
{catCount}
|
||||||
</span>
|
</span>
|
||||||
@@ -867,8 +862,7 @@ export default function AdminNotificationsPage() {
|
|||||||
filteredNotifs.map(notif => (
|
filteredNotifs.map(notif => (
|
||||||
<div
|
<div
|
||||||
key={notif.id}
|
key={notif.id}
|
||||||
className={`p-4 flex gap-4 transition-colors relative hover:bg-slate-50/50 ${
|
className={`p-4 flex gap-4 transition-colors relative hover:bg-slate-50/50 ${!notif.read ? 'bg-accent-light/10 border-l-4 border-accent' : ''
|
||||||
!notif.read ? 'bg-accent-light/10 border-l-4 border-accent' : ''
|
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="flex-1 space-y-1.5 min-w-0 cursor-pointer" onClick={() => setSelectedNotif(notif)}>
|
<div className="flex-1 space-y-1.5 min-w-0 cursor-pointer" onClick={() => setSelectedNotif(notif)}>
|
||||||
@@ -936,8 +930,7 @@ export default function AdminNotificationsPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Status tag */}
|
{/* Status tag */}
|
||||||
<span className={`px-2 py-0.5 rounded text-[10px] font-bold uppercase tracking-wider ${
|
<span className={`px-2 py-0.5 rounded text-[10px] font-bold uppercase tracking-wider ${broad.status === 'scheduled' ? 'bg-amber-100 text-amber-800' : 'bg-green-100 text-green-800'
|
||||||
broad.status === 'scheduled' ? 'bg-amber-100 text-amber-800' : 'bg-green-100 text-green-800'
|
|
||||||
}`}>
|
}`}>
|
||||||
{broad.status}
|
{broad.status}
|
||||||
</span>
|
</span>
|
||||||
@@ -1010,8 +1003,7 @@ export default function AdminNotificationsPage() {
|
|||||||
key={ch.id}
|
key={ch.id}
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setComposeChannels(prev => ({ ...prev, [ch.id]: !enabled }))}
|
onClick={() => setComposeChannels(prev => ({ ...prev, [ch.id]: !enabled }))}
|
||||||
className={`flex flex-col items-center justify-center p-3 rounded-xl border-2 transition-all cursor-pointer text-center ${
|
className={`flex flex-col items-center justify-center p-3 rounded-xl border-2 transition-all cursor-pointer text-center ${enabled ? 'border-accent bg-accent-light/10 text-accent font-bold scale-[1.02]' : 'border-slate-200 text-slate-500 bg-white hover:border-slate-300'
|
||||||
enabled ? 'border-accent bg-accent-light/10 text-accent font-bold scale-[1.02]' : 'border-slate-200 text-slate-500 bg-white hover:border-slate-300'
|
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<ch.icon className={`w-5 h-5 mb-1.5 ${enabled ? 'text-accent' : 'text-slate-400'}`} />
|
<ch.icon className={`w-5 h-5 mb-1.5 ${enabled ? 'text-accent' : 'text-slate-400'}`} />
|
||||||
@@ -1035,8 +1027,7 @@ export default function AdminNotificationsPage() {
|
|||||||
key={t.id}
|
key={t.id}
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setComposeTargetType(t.id as any)}
|
onClick={() => setComposeTargetType(t.id as any)}
|
||||||
className={`py-2 px-3 text-xs font-semibold rounded-lg border text-center transition-all cursor-pointer ${
|
className={`py-2 px-3 text-xs font-semibold rounded-lg border text-center transition-all cursor-pointer ${composeTargetType === t.id ? 'bg-slate-900 border-slate-900 text-white' : 'bg-white border-slate-200 text-slate-600 hover:bg-slate-50'
|
||||||
composeTargetType === t.id ? 'bg-slate-900 border-slate-900 text-white' : 'bg-white border-slate-200 text-slate-600 hover:bg-slate-50'
|
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{t.label}
|
{t.label}
|
||||||
@@ -1146,8 +1137,7 @@ export default function AdminNotificationsPage() {
|
|||||||
isSelected ? prev.filter(id => id !== usr.id) : [...prev, usr.id]
|
isSelected ? prev.filter(id => id !== usr.id) : [...prev, usr.id]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
className={`flex items-center justify-between p-2 text-xs cursor-pointer hover:bg-slate-50 transition-colors ${
|
className={`flex items-center justify-between p-2 text-xs cursor-pointer hover:bg-slate-50 transition-colors ${isSelected ? 'bg-accent/5' : ''
|
||||||
isSelected ? 'bg-accent/5' : ''
|
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
|
|||||||
Reference in New Issue
Block a user