Skip to content

Commit 8816ff3

Browse files
committed
Add tags to the calendar
1 parent 37567d4 commit 8816ff3

File tree

10 files changed

+84
-7
lines changed

10 files changed

+84
-7
lines changed

src/lib/components/calendar/List/CalEventListBox.svelte

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import { stringify } from '$lib/utils/dates/custom';
77
import { Icon, MapPin } from 'svelte-hero-icons';
88
import Updates from '$lib/components/utils/Updates.svelte';
9+
import TagLabel from '$lib/components/tags/TagLabel.svelte';
910
1011
export let event: Calendar;
1112
@@ -24,7 +25,7 @@
2425
>
2526
<h4>{event.title}</h4>
2627

27-
<div class="grid grid-cols-2">
28+
<div class="grid grid-cols-2 gap-2">
2829
<span>
2930
{#if event.ending}
3031
<Store
@@ -57,6 +58,14 @@
5758
<Store store={i(`calendar.priority.${event.priority}`)} />
5859
</span>
5960
{/if}
61+
62+
{#if event.tags}
63+
<div class="flex flex-wrap gap-1">
64+
{#each event.tags as tag (tag.tag)}
65+
<TagLabel {tag} />
66+
{/each}
67+
</div>
68+
{/if}
6069
</div>
6170

6271
{#if event.summary}

src/lib/components/calendar/List/EditModal.svelte

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,25 @@
1818
export let showEditModal = false;
1919
export let event: Calendar;
2020
21+
const initialTitle = event.title;
22+
2123
const ts = (d: CustomDateTime | null) => {
2224
return customDateToNormal(d ?? UNIX_TIME_EPOCHE_START).getTime();
2325
};
2426
2527
$: beginningIsEarlierThenEnding = event.ending ? ts(event.beginning) < ts(event.ending) : true;
26-
2728
$: isEnabled = !!event.title && !!event.beginning && beginningIsEarlierThenEnding;
2829
</script>
2930

3031
<Modal bind:isOpen={showEditModal}>
32+
<div slot="title">
33+
<Store store={i('calendar.edit.title', { title: initialTitle })} />
34+
</div>
35+
3136
<div class="flex flex-col gap-2" slot="body">
3237
<NewInner
38+
className={event.class.name}
39+
schoolName={event.class.school.name}
3340
bind:title={event.title}
3441
bind:beginning={event.beginning}
3542
bind:ending={event.ending}
@@ -40,6 +47,7 @@
4047
event.location = detail;
4148
}}
4249
bind:priority={event.priority}
50+
bind:tags={event.tags}
4351
/>
4452

4553
<hr class="border-zinc-300 dark:border-zinc-700" />
@@ -55,14 +63,16 @@
5563
ending:
5664
safeMap(event.ending, (ending) => customDateToNormal(ending).getTime()) ?? undefined,
5765
location: event.location ?? undefined,
58-
priority: event.priority ?? undefined
66+
priority: event.priority ?? undefined,
67+
tags: event.tags
5968
})
6069
.then(() => {
6170
sendToast({
6271
type: 'success',
6372
content: i('calendar.update.success'),
6473
timeout: 5_000
6574
});
75+
showEditModal = false;
6676
invalidateAll();
6777
})
6878
.catch(sendDefaultErrorToast);

src/lib/components/calendar/SidePanel/New.svelte

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import NewInner from './NewInner.svelte';
1717
import { i } from '$lib/i18n/store';
1818
import Store from '$lib/components/utils/Store.svelte';
19+
import type { Tag } from '$lib/components/tags/types';
1920
2021
export let query: {
2122
school: string;
@@ -35,6 +36,7 @@
3536
let summary = '';
3637
let location = '';
3738
let priority: Priority | null = null;
39+
let tags: Tag[] = [];
3840
3941
const ts = (d: CustomDateTime | null) => {
4042
return customDateToNormal(d ?? UNIX_TIME_EPOCHE_START).getTime();
@@ -65,7 +67,17 @@
6567
<SingleClass bind:selectedClass school={query.school} filter={showClass} />
6668
{/if}
6769

68-
<NewInner bind:title bind:beginning bind:ending bind:summary bind:location bind:priority />
70+
<NewInner
71+
schoolName={query.school}
72+
className={selectedClass}
73+
bind:title
74+
bind:beginning
75+
bind:ending
76+
bind:summary
77+
bind:location
78+
bind:priority
79+
bind:tags
80+
/>
6981

7082
<hr class="border-zinc-300 dark:border-zinc-700" />
7183

@@ -75,6 +87,7 @@
7587
if (!selectedClass || !beginning) return;
7688

7789
createCalendar({
90+
tags,
7891
school: query.school,
7992
class: selectedClass,
8093
title: title,
@@ -90,6 +103,16 @@
90103
content: i('calendar.create.success'),
91104
timeout: 5_000
92105
});
106+
107+
title = '';
108+
beginning = null;
109+
ending = null;
110+
summary = '';
111+
location = '';
112+
priority = null;
113+
tags = [];
114+
115+
isOpen = false;
93116
return invalidateAll();
94117
})
95118
.catch(sendDefaultErrorToast);

src/lib/components/calendar/SidePanel/NewInner.svelte

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,19 @@
1111
import { type CustomDateTime } from '$lib/utils/dates/custom';
1212
import type { Priority } from '$lib/types/priority';
1313
import { createEventDispatcher } from 'svelte';
14+
import type { Tag } from '$lib/components/tags/types';
15+
import ChooseTag from '$lib/components/tags/ChooseTag.svelte';
16+
17+
export let className: string | null;
18+
export let schoolName: string;
1419
1520
export let title: string = '';
1621
export let beginning: CustomDateTime | null = null;
1722
export let ending: CustomDateTime | null = null;
1823
export let summary = '';
1924
export let location = '';
2025
export let priority: Priority | null = null;
26+
export let tags: Tag[] = [];
2127
2228
const dispatch = createEventDispatcher<{
2329
summary: string | null;
@@ -74,5 +80,11 @@
7480
}))}
7581
bind:value={priority}
7682
/>
83+
84+
{#if className}
85+
<!-- TODO: i18n -->
86+
<h4>Tags</h4>
87+
<ChooseTag bind:selected={tags} {className} {schoolName} />
88+
{/if}
7789
</div>
7890
</Collapseable>

src/lib/dlool/calendar/create.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Method, getApibase, getAuthHeader } from '$lib/utils/api';
22
import type { Priority } from '$lib/types/priority';
33
import { z } from 'zod';
4+
import type { Tag } from '$lib/components/tags/types';
45

56
const scheme = z.object({
67
status: z.literal('success'),
@@ -15,6 +16,7 @@ interface NewCalendarProps {
1516
class: string;
1617
title: string;
1718
beginning: number;
19+
tags?: Tag[];
1820
ending?: number;
1921
summary?: string;
2022
location?: string;
@@ -26,7 +28,7 @@ export async function createCalendar(props: NewCalendarProps) {
2628
method: Method.POST,
2729
body: JSON.stringify({
2830
...props,
29-
tags: []
31+
tags: props.tags?.map(({ tag }) => tag) ?? []
3032
}),
3133
headers: {
3234
Authorization: getAuthHeader(),

src/lib/dlool/calendar/list.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,12 @@ const calendarScheme = z.object({
6262
time: z.number().int()
6363
})
6464
),
65-
tags: z.array(z.unknown()),
65+
tags: z.array(
66+
z.object({
67+
tag: z.string(),
68+
color: z.string()
69+
})
70+
),
6671
id: z.string()
6772
});
6873

src/lib/dlool/calendar/update.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { Tag } from '$lib/components/tags/types';
12
import type { Priority } from '$lib/types/priority';
23
import { getApibase, getAuthHeader } from '$lib/utils/api';
34
import { z } from 'zod';
@@ -11,6 +12,7 @@ interface CalendarProps {
1112
ending?: number;
1213
location?: string;
1314
priority?: Priority;
15+
tags?: Tag[];
1416
}
1517

1618
const scheme = z.object({
@@ -26,7 +28,10 @@ export async function updateCalendar({ id, ...body }: CalendarProps) {
2628
'Content-Type': 'application/json'
2729
},
2830
method: 'PATCH',
29-
body: JSON.stringify(body)
31+
body: JSON.stringify({
32+
...body,
33+
tags: body.tags?.map(({ tag }) => tag) ?? []
34+
})
3035
}).then((r) => r.json());
3136

3237
return scheme.parse(res);

src/lib/locales/de.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,8 @@ const de = {
429429

430430
'calendar.noData': 'Es gibt keine Kalender Erreignisse',
431431

432+
'calendar.edit.title': 'Editiere das Kalendererreignis $title',
433+
432434
'settings.noneSelected': 'Wähle eine Kategorie aus',
433435
'settings.profile': 'Profil',
434436

src/lib/locales/en.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,8 @@ const en = {
419419

420420
'calendar.noData': 'There are no calendar events',
421421

422+
'calendar.edit.title': 'Edit the calendar event $title',
423+
422424
'settings.noneSelected': 'Select a category',
423425
'settings.profile': 'Account',
424426

src/routes/calendar/[id]/+page.svelte

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import EditModal from '$lib/components/calendar/List/EditModal.svelte';
1616
import MetaData from '$lib/components/utils/MetaData.svelte';
1717
import Updates from '$lib/components/utils/Updates.svelte';
18+
import TagLabel from '$lib/components/tags/TagLabel.svelte';
1819
1920
export let data: PageData;
2021
@@ -123,6 +124,12 @@
123124
<Updates updates={event.updates} />
124125
</div>
125126

127+
<div class="flex gap-1 empty:hidden">
128+
{#each event.tags as tag (tag.tag)}
129+
<TagLabel {tag} />
130+
{/each}
131+
</div>
132+
126133
{#if event.summary}
127134
<span>{event.summary}</span>
128135
{/if}

0 commit comments

Comments
 (0)