Add frontend support for user

This commit is contained in:
Sami Abuzakuk
2025-11-01 16:05:52 +01:00
parent 374558d30f
commit e9d94f706c
14 changed files with 521 additions and 285 deletions

View File

@@ -1,11 +1,11 @@
<script lang="ts">
import { deleteNotification, setViewed, fetchSubscriptionNotifications } from '$lib/api';
import type { Notification, Subscription } from '$lib/api';
let { data } = $props();
export let data: { notifications: Notification[]; subscription: Subscription };
let notifications: Notification[] = data.notifications;
let selectedNotification: Notification | null = null;
let subscription: Subscription | null = $state(data.subscription);
let notifications: Notification[] = $state(data.notifications);
let selectedNotification: Notification | null = $state(null);
// Delete all notifications for this subscription
async function handleDeleteAllNotifications() {
@@ -25,9 +25,9 @@
// Pagination state
let limit = 20;
let offset = notifications.length;
let loadingMore = false;
let allLoaded = notifications.length < limit;
let offset = $derived(notifications.length);
let loadingMore = $state(false);
let allLoaded = $derived(notifications.length < limit);
async function openNotificationPopup(notification: Notification) {
if (!notification.viewed) {
@@ -45,7 +45,9 @@
selectedNotification = null;
}
async function handleDeleteNotification(id: number) {
async function handleDeleteNotification(e, id: number) {
e.stopPropagation();
try {
await deleteNotification(id);
notifications = notifications.filter((notification) => notification.id !== id);
@@ -74,11 +76,7 @@
async function loadMoreNotifications() {
loadingMore = true;
try {
const more = await fetchSubscriptionNotifications(
data.subscription.id.toString(),
limit,
offset
);
const more = await fetchSubscriptionNotifications(subscription.id.toString(), limit, offset);
notifications = [...notifications, ...more];
offset += more.length;
if (more.length < limit) {
@@ -92,17 +90,17 @@
</script>
<main class="p-4">
<h1 class="text-2xl font-bold mb-4">Notifications for {data.subscription.topic}:</h1>
<h1 class="text-2xl font-bold mb-4">Notifications for {subscription.topic}:</h1>
<div class="flex justify-between items-center mb-4">
<a href="/notifications" class="text-blue-500 hover:underline">← Return to Subscriptions</a>
<div class="flex gap-2">
<button class="bg-blue-500 text-white px-4 py-2 rounded" on:click={markAllViewed}>
<button class="bg-blue-500 text-white px-4 py-2 rounded" onclick={markAllViewed}>
Mark All Viewed
</button>
<button
class="bg-red-500 text-white px-4 py-2 rounded"
on:click={handleDeleteAllNotifications}
onclick={handleDeleteAllNotifications}
disabled={notifications.length === 0}
>
Delete All Notifications
@@ -119,7 +117,7 @@
class="p-2 rounded flex justify-between items-center border-s-slate-400 border-1"
class:bg-green-200={notification.viewed}
>
<button class="p-2 w-full text-left" on:click={() => openNotificationPopup(notification)}>
<button class="p-2 w-full text-left" onclick={() => openNotificationPopup(notification)}>
<div>
<p class="font-semibold">{notification.title}</p>
<p class="text-sm text-gray-500">
@@ -129,7 +127,7 @@
</button>
<button
class="px-2 py-1 bg-red-500 text-white rounded hover:bg-red-600 block"
on:click|stopPropagation={() => handleDeleteNotification(notification.id)}
onclick={(e) => handleDeleteNotification(e, notification.id)}
>
Delete
</button>
@@ -141,7 +139,7 @@
<div class="flex justify-center mt-6">
<button
class="bg-gray-200 px-4 py-2 rounded hover:bg-gray-300"
on:click={loadMoreNotifications}
onclick={loadMoreNotifications}
disabled={loadingMore}
>
{loadingMore ? 'Loading...' : 'Load More'}
@@ -175,7 +173,7 @@
</div>
<button
class="mt-4 px-4 py-2 bg-red-500 text-white rounded hover:bg-red-600"
on:click={closeNotificationPopup}
onclick={closeNotificationPopup}
>
Close
</button>