fix notifications page

This commit is contained in:
maxDorninger
2025-07-01 23:13:18 +02:00
parent 82ddadf8f7
commit 18edeba089

View File

@@ -2,6 +2,11 @@
import { onMount } from 'svelte';
import { env } from '$env/dynamic/public';
import { Button } from '$lib/components/ui/button/index.js';
import {Separator} from "$lib/components/ui/separator";
import * as Sidebar from '$lib/components/ui/sidebar/index.js';
import * as Breadcrumb from '$lib/components/ui/breadcrumb/index.js';
import { Check } from 'lucide-svelte';
const apiUrl = env.PUBLIC_API_URL;
interface NotificationResponse {
@@ -63,7 +68,6 @@
});
if (response.ok) {
// Move from unread to read
const notification = unreadNotifications.find((n) => n.id === notificationId);
if (notification) {
notification.read = true;
@@ -87,7 +91,6 @@
});
if (response.ok) {
// Move from read to unread
const notification = readNotifications.find((n) => n.id === notificationId);
if (notification) {
notification.read = false;
@@ -166,36 +169,9 @@
return date.toLocaleDateString();
}
function getNotificationIcon(message: string): string {
const lowerMessage = message.toLowerCase();
if (lowerMessage.includes('downloaded') || lowerMessage.includes('successfully')) {
return '✅';
}
if (
lowerMessage.includes('error') ||
lowerMessage.includes('failed') ||
lowerMessage.includes('failure')
) {
return '❌';
}
if (lowerMessage.includes('missing') || lowerMessage.includes('not found')) {
return '⚠️';
}
if (lowerMessage.includes('api')) {
return '🔌';
}
if (lowerMessage.includes('indexer')) {
return '🔍';
}
return '📢';
}
onMount(() => {
fetchNotifications();
// Refresh notifications every 30 seconds
const interval = setInterval(fetchNotifications, 30000);
return () => clearInterval(interval);
});
@@ -205,20 +181,42 @@
<title>Notifications - MediaManager</title>
</svelte:head>
<header class="flex h-16 shrink-0 items-center gap-2">
<div class="flex items-center gap-2 px-4">
<Sidebar.Trigger class="-ml-1" />
<Separator class="mr-2 h-4" orientation="vertical" />
<Breadcrumb.Root>
<Breadcrumb.List>
<Breadcrumb.Item class="hidden md:block">
<Breadcrumb.Link href="/dashboard">MediaManager</Breadcrumb.Link>
</Breadcrumb.Item>
<Breadcrumb.Separator class="hidden md:block" />
<Breadcrumb.Item>
<Breadcrumb.Link href="/dashboard">Home</Breadcrumb.Link>
</Breadcrumb.Item>
<Breadcrumb.Separator class="hidden md:block" />
<Breadcrumb.Item>
<Breadcrumb.Page>Notifications</Breadcrumb.Page>
</Breadcrumb.Item>
</Breadcrumb.List>
</Breadcrumb.Root>
</div>
</header>
<div class="container mx-auto px-4 py-8">
<div class="mb-6 flex items-center justify-between">
<h1 class="text-3xl font-bold text-gray-900 dark:text-white">Notifications</h1>
{#if unreadNotifications.length > 0}
<button
on:click={markAllAsRead}
<Button
onclick={() => markAllAsRead()}
disabled={markingAllAsRead}
class="flex items-center gap-2 rounded-lg bg-blue-600 px-4 py-2 text-white hover:bg-blue-700 disabled:cursor-not-allowed disabled:opacity-50"
class="flex items-center"
>
{#if markingAllAsRead}
<div class="h-4 w-4 animate-spin rounded-full border-b-2 border-white"></div>
{/if}
Mark All as Read
</button>
</Button>
{/if}
</div>
@@ -230,19 +228,17 @@
<!-- Unread Notifications -->
<div class="mb-8">
<div class="mb-4 flex items-center gap-2">
<h2 class="text-xl font-semibold text-gray-900 dark:text-white">Unread Notifications</h2>
{#if unreadNotifications.length > 0}
<span class="rounded-full bg-red-500 px-2 py-1 text-xs text-white">
{unreadNotifications.length}
</span>
{/if}
<h2 class="text-xl font-semibold text-gray-900 dark:text-white">
Unread Notifications{#if unreadNotifications.length > 0}:
{unreadNotifications.length}
{/if}
</h2>
</div>
{#if unreadNotifications.length === 0}
<div
class="rounded-lg border border-green-200 bg-green-50 p-6 text-center dark:border-green-800 dark:bg-green-900/20"
>
<div class="mb-2 text-4xl text-green-600 dark:text-green-400"></div>
<p class="font-medium text-green-800 dark:text-green-200">All caught up!</p>
<p class="text-sm text-green-600 dark:text-green-400">No unread notifications</p>
</div>
@@ -254,7 +250,6 @@
>
<div class="flex items-start justify-between gap-4">
<div class="flex flex-1 items-start gap-3">
<span class="text-2xl">{getNotificationIcon(notification.message)}</span>
<div class="flex-1">
<p class="font-medium text-gray-900 dark:text-white">
{notification.message}
@@ -269,6 +264,8 @@
onclick={() => markAsRead(notification.id)}
class="rounded-lg p-2 text-blue-600 transition-colors hover:bg-blue-100 dark:hover:bg-blue-800"
title="Mark as read"
variant="outline"
>
<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
@@ -279,20 +276,6 @@
></path>
</svg>
</Button>
<Button
onclick={() => deleteNotification(notification.id)}
class="rounded-lg p-2 text-red-600 transition-colors hover:bg-red-100 dark:hover:bg-red-800"
title="Delete notification"
>
<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
></path>
</svg>
</Button>
</div>
</div>
</div>
@@ -337,9 +320,6 @@
>
<div class="flex items-start justify-between gap-4">
<div class="flex flex-1 items-start gap-3">
<span class="text-2xl opacity-50"
>{getNotificationIcon(notification.message)}</span
>
<div class="flex-1">
<p class="text-gray-700 dark:text-gray-300">
{notification.message}
@@ -354,6 +334,7 @@
onclick={() => markAsUnread(notification.id)}
class="rounded-lg p-2 text-blue-600 transition-colors hover:bg-blue-100 dark:hover:bg-blue-800"
title="Mark as unread"
variant="outline"
>
<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
@@ -364,20 +345,6 @@
></path>
</svg>
</Button>
<Button
onclick={() => deleteNotification(notification.id)}
class="rounded-lg p-2 text-red-600 transition-colors hover:bg-red-100 dark:hover:bg-red-800"
title="Delete notification"
>
<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
></path>
</svg>
</Button>
</div>
</div>
</div>