feat: implement notification system

This commit is contained in:
Face 2025-06-11 18:37:03 +03:00
parent de3f8a4929
commit e61c41e414
19 changed files with 883 additions and 3196 deletions

View file

@ -30,7 +30,8 @@
ShieldCheck,
Hammer,
BookOpen,
Info
Info,
Bell
} from 'lucide-svelte';
import { mode, setMode } from 'mode-watcher';
import type { HTMLAttributes } from 'svelte/elements';
@ -46,6 +47,7 @@
import { goto } from '$app/navigation';
import { liveTradesStore, isLoadingTrades } from '$lib/stores/websocket';
import { onMount } from 'svelte';
import { UNREAD_COUNT, fetchNotifications } from '$lib/stores/notifications';
const data = {
navMain: [
@ -57,6 +59,7 @@
{ title: 'Portfolio', url: '/portfolio', icon: BriefcaseBusiness },
{ title: 'Treemap', url: '/treemap', icon: ChartColumn },
{ title: 'Create coin', url: '/coin/create', icon: Coins },
{ title: 'Notifications', url: '/notifications', icon: Bell },
{ title: 'About', url: '/about', icon: Info }
]
};
@ -70,6 +73,7 @@
onMount(() => {
if ($USER_DATA) {
fetchPortfolioSummary();
fetchNotifications();
} else {
PORTFOLIO_SUMMARY.set(null);
}
@ -177,10 +181,15 @@
<a
href={item.url || '/'}
onclick={() => handleNavClick(item.title)}
class={`${props.class}`}
class={`${props.class} ${item.title === 'Notifications' && !$USER_DATA ? 'pointer-events-none opacity-50' : ''}`}
>
<item.icon />
<span>{item.title}</span>
{#if item.title === 'Notifications' && $UNREAD_COUNT > 0 && $USER_DATA}
<Sidebar.MenuBadge class="bg-primary text-primary-foreground">
{$UNREAD_COUNT > 99 ? '99+' : $UNREAD_COUNT}
</Sidebar.MenuBadge>
{/if}
</a>
{/snippet}
</Sidebar.MenuButton>
@ -358,7 +367,8 @@
</div>
<div class="flex justify-between">
<span>Coins:</span>
<span class="font-mono">${formatCurrency($PORTFOLIO_SUMMARY.totalCoinValue)}</span>
<span class="font-mono">${formatCurrency($PORTFOLIO_SUMMARY.totalCoinValue)}</span
>
</div>
</div>
{/if}

View file

@ -0,0 +1,21 @@
<script lang="ts">
import { Skeleton } from '$lib/components/ui/skeleton';
</script>
<div class="space-y-1">
{#each Array(8) as _, i}
<div class="flex items-start gap-4 rounded-md p-3">
<Skeleton class="h-8 w-8 flex-shrink-0 rounded-full" />
<div class="min-w-0 flex-1 space-y-2">
<Skeleton class="h-4 w-48" />
<Skeleton class="h-3 w-full max-w-md" />
</div>
<div class="flex flex-shrink-0 flex-col items-end gap-1">
<Skeleton class="h-3 w-16" />
</div>
</div>
{#if i < 7}
<div class="border-border border-t"></div>
{/if}
{/each}
</div>