~james/core

core/web/src/lib/components/notifications/NotificationToolbar.svelte -rw-r--r-- 2.5 KiB
452f17b7 — james chore(import): snapshot james.dad.town/core at f70c71c7696a 15 hours ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
<script lang="ts">
	import { resolve } from "$app/paths";
	import CheckCheck from "$icon/check-check";
	import Cog from "$icon/cog";
	import Glasses from "$icon/glasses";
	import Inbox from "$icon/inbox";
	import Button from "#lib/components/ui/Button.svelte";
	import Segment from "#lib/components/ui/Segment.svelte";
	import SegmentedControl from "#lib/components/ui/SegmentedControl.svelte";
	import type { CategoryFilter, ReadFilter } from "#lib/components/notifications/types.ts";

	interface Props {
		readFilter?: ReadFilter;
		categoryFilter?: CategoryFilter;
		hasNotifications?: boolean;
		preferences?: boolean;
		onReadFilter?: (filter: ReadFilter) => void;
		onCategoryFilter?: (filter: CategoryFilter) => void;
		onMarkAllRead?: () => void;
	}

	let {
		readFilter = "inbox",
		categoryFilter = "all",
		hasNotifications = true,
		preferences = true,
		onReadFilter,
		onCategoryFilter,
		onMarkAllRead
	}: Props = $props();

	const pageQuery = (read: ReadFilter, category: CategoryFilter) =>
		category === "all" ? `read=${read}` : `read=${read}&category=${category}`;

	const pageHref = (read: ReadFilter, category: CategoryFilter) =>
		resolve(`/notifications?${pageQuery(read, category)}` as "/");

	const categories: CategoryFilter[] = ["all", "work", "social"];
</script>

<div class="flex flex-wrap items-center justify-between gap-xs">
	<div class="flex flex-wrap items-center gap-xs">
		<SegmentedControl
			value={readFilter}
			href={onReadFilter ? undefined : (filter) => pageHref(filter, categoryFilter)}
			label="Read state"
		>
			<Segment value="inbox" icon={Inbox} onclick={() => onReadFilter?.("inbox")}
				>Inbox</Segment
			>
			<Segment value="unread" icon={Glasses} onclick={() => onReadFilter?.("unread")}
				>Unread</Segment
			>
		</SegmentedControl>

		{#if hasNotifications}
			<Button
				variant="ghost"
				icon={CheckCheck}
				onclick={() => onMarkAllRead?.()}
				aria-label="Mark all read"
			>
				<span class="hidden sm:inline" aria-hidden="true">Mark all read</span>
			</Button>
		{/if}
	</div>

	{#if onCategoryFilter}
		<SegmentedControl value={categoryFilter} label="Category">
			{#each categories as category (category)}
				<Segment
					value={category}
					class="capitalize"
					onclick={() => onCategoryFilter(category)}
				>
					{category}
				</Segment>
			{/each}
		</SegmentedControl>
	{/if}

	{#if preferences}
		<Button
			variant="ghost"
			icon={Cog}
			href={resolve("/settings/notifications" as "/")}
			aria-label="Preferences"
		>
			<span class="hidden md:inline" aria-hidden="true">Preferences</span>
		</Button>
	{/if}
</div>