feat: add delete all notifications feature in NotificationController and update NotificationBell component
This commit is contained in:
parent
22c9a4cf2a
commit
ae376342af
@ -67,4 +67,11 @@ public function markAllAsRead(Request $request): JsonResponse
|
|||||||
|
|
||||||
return response()->json(['message' => 'All notifications marked as read.']);
|
return response()->json(['message' => 'All notifications marked as read.']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function deleteAll(Request $request): JsonResponse
|
||||||
|
{
|
||||||
|
$request->user()->notifications()->delete();
|
||||||
|
|
||||||
|
return response()->json(['message' => 'All notifications deleted.']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { router } from '@inertiajs/react';
|
import { router } from '@inertiajs/react';
|
||||||
import { Bell, Check, Trash2 } from 'lucide-react';
|
import { Bell, Check, CheckCheck, Trash2 } from 'lucide-react';
|
||||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import { Badge } from '@/components/ui/badge';
|
import { Badge } from '@/components/ui/badge';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
@ -121,6 +121,22 @@ export function NotificationBell() {
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const deleteAll = useCallback(async () => {
|
||||||
|
try {
|
||||||
|
await fetch('/api/notifications', {
|
||||||
|
method: 'DELETE',
|
||||||
|
headers: {
|
||||||
|
'X-Requested-With': 'XMLHttpRequest',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
setNotifications([]);
|
||||||
|
setUnreadCount(0);
|
||||||
|
} catch {
|
||||||
|
// Silently fail
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// eslint-disable-next-line react-hooks/set-state-in-effect -- initial data fetch is safe
|
// eslint-disable-next-line react-hooks/set-state-in-effect -- initial data fetch is safe
|
||||||
void fetchUnreadCount();
|
void fetchUnreadCount();
|
||||||
@ -165,16 +181,34 @@ export function NotificationBell() {
|
|||||||
<DropdownMenuContent align="end" className="max-h-[350px] w-80">
|
<DropdownMenuContent align="end" className="max-h-[350px] w-80">
|
||||||
<div className="flex items-center justify-between border-b px-4 py-2">
|
<div className="flex items-center justify-between border-b px-4 py-2">
|
||||||
<span className="text-sm font-semibold">Notifikasi</span>
|
<span className="text-sm font-semibold">Notifikasi</span>
|
||||||
{unreadCount > 0 && (
|
<div className="flex items-center gap-1">
|
||||||
<button
|
{unreadCount > 0 && (
|
||||||
onClick={() => {
|
<Button
|
||||||
void markAllAsRead();
|
variant="ghost"
|
||||||
}}
|
size="icon"
|
||||||
className="text-xs text-muted-foreground hover:text-foreground"
|
className="h-6 w-6"
|
||||||
>
|
title="Tandai semua sudah dibaca"
|
||||||
Tandai semua dibaca
|
onClick={() => {
|
||||||
</button>
|
void markAllAsRead();
|
||||||
)}
|
}}
|
||||||
|
>
|
||||||
|
<CheckCheck className="h-3.5 w-3.5" />
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
{notifications.length > 0 && (
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="icon"
|
||||||
|
className="h-6 w-6 text-destructive hover:text-destructive"
|
||||||
|
title="Hapus semua notifikasi"
|
||||||
|
onClick={() => {
|
||||||
|
void deleteAll();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Trash2 className="h-3.5 w-3.5" />
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{notifications.length === 0 ? (
|
{notifications.length === 0 ? (
|
||||||
<div className="px-4 py-6 text-center text-sm text-muted-foreground">
|
<div className="px-4 py-6 text-center text-sm text-muted-foreground">
|
||||||
|
|||||||
@ -41,3 +41,7 @@
|
|||||||
Route::patch('/notifications/read-all', [NotificationController::class, 'markAllAsRead'])
|
Route::patch('/notifications/read-all', [NotificationController::class, 'markAllAsRead'])
|
||||||
->middleware(['web', 'auth', 'verified'])
|
->middleware(['web', 'auth', 'verified'])
|
||||||
->name('notifications.mark-all-as-read');
|
->name('notifications.mark-all-as-read');
|
||||||
|
|
||||||
|
Route::delete('/notifications', [NotificationController::class, 'deleteAll'])
|
||||||
|
->middleware(['web', 'auth', 'verified'])
|
||||||
|
->name('notifications.delete-all');
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user