This repository has been archived on 2025-11-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
trafficcue-client/src/lib/components/lnv/sidebar/settings/CalendarSidebar.svelte
Jannik 372b31876d
All checks were successful
TrafficCue CI / check (push) Successful in 1m34s
TrafficCue CI / build (push) Successful in 10m30s
TrafficCue CI / build-android (push) Successful in 26m47s
style: run prettier
2025-10-21 15:46:50 +02:00

180 lines
4.6 KiB
Svelte

<script lang="ts">
import { m } from "$lang/messages";
import { CalendarPlusIcon } from "@lucide/svelte";
import SidebarHeader from "../SidebarHeader.svelte";
import SettingsButton from "./SettingsButton.svelte";
import * as Drawer from "$lib/components/ui/drawer";
import { Button } from "$lib/components/ui/button";
import Input from "$lib/components/ui/input/input.svelte";
import {
fetchCalendars,
findScheme,
type AuthScheme,
type DAVCalendar,
type DAVCredentials,
} from "$lib/services/CalDAV";
import { onMount } from "svelte";
let calendars: (DAVCalendar & { credentials: DAVCredentials })[] = $state([]);
let calDavDrawerOpen = $state(false);
let calDavLoading = $state(false);
let calDavUrl = $state("");
let calDavUsername = $state("");
let calDavPassword = $state("");
let calDavCalendars: DAVCalendar[] = $state([]);
let calDavScheme: AuthScheme;
let calDavState = $state("");
async function fetchCalDav() {
calDavState = m["sidebar.calendar.probing-server"]();
calDavScheme = await findScheme(calDavUrl);
calDavState = m["sidebar.calendar.discovering-calendars"]();
calDavCalendars = await fetchCalendars(calDavUrl, {
scheme: calDavScheme,
username: calDavUsername,
password: calDavPassword,
});
calDavState = "";
}
onMount(() => {
if (localStorage.getItem("calendars")) {
calendars = JSON.parse(localStorage.getItem("calendars")!);
}
});
</script>
<SidebarHeader>
{m["sidebar.calendar.header"]()}
</SidebarHeader>
<Drawer.Root bind:open={calDavDrawerOpen}>
<Drawer.Content>
<Drawer.Header>
<Drawer.Title>{m["sidebar.calendar.connect"]()}</Drawer.Title>
</Drawer.Header>
<div class="p-4 pt-0 flex flex-col gap-2">
{#if calDavCalendars}
<Input
type="url"
placeholder="https://my-caldav-server.com/..."
disabled={calDavLoading}
bind:value={calDavUrl}
/>
<Input
type="text"
placeholder="Username"
disabled={calDavLoading}
bind:value={calDavUsername}
/>
<Input
type="password"
placeholder="Password"
disabled={calDavLoading}
bind:value={calDavPassword}
/>
{#if calDavState}
<span>{calDavState}</span>
{/if}
{/if}
{#if calDavCalendars.length > 0}
<h3 class="font-medium pt-4">{m["sidebar.calendar.choose"]()}</h3>
<ul class="max-h-48 overflow-y-auto">
{#each calDavCalendars as calendar (calendar.url)}
<li>
<Button
class="w-full"
variant="secondary"
onclick={() => {
if (localStorage.getItem("calendars")) {
const existing = JSON.parse(
localStorage.getItem("calendars")!,
);
existing.push({
name: calendar.name,
url: calendar.url,
credentials: {
username: calDavUsername,
password: calDavPassword,
scheme: calDavScheme,
},
});
localStorage.setItem("calendars", JSON.stringify(existing));
} else {
localStorage.setItem(
"calendars",
JSON.stringify([
{
name: calendar.name,
url: calendar.url,
credentials: {
username: calDavUsername,
password: calDavPassword,
scheme: calDavScheme,
},
},
]),
);
}
calendars.push({
name: calendar.name,
url: calendar.url,
credentials: {
username: calDavUsername,
password: calDavPassword,
scheme: calDavScheme,
},
});
}}
>
{calendar.name}
</Button>
</li>
{/each}
</ul>
{/if}
</div>
<Drawer.Footer>
{#if calDavCalendars.length === 0}
<Button
onclick={async () => {
calDavLoading = true;
await fetchCalDav().catch((e) => {
calDavState = e;
calDavLoading = false;
});
}}>{m.submit()}</Button
>
{/if}
<Drawer.Close>
{calDavCalendars.length === 0 ? m.done() : m.cancel()}
</Drawer.Close>
</Drawer.Footer>
</Drawer.Content>
</Drawer.Root>
{#each calendars as calendar (calendar.url)}
<div class="p-2 border rounded mb-2">
<h3 class="font-medium">{calendar.name}</h3>
<Button
variant="destructive"
size="sm"
class="mt-2"
onclick={() => {
calendars = calendars.filter((c) => c.url !== calendar.url);
localStorage.setItem("calendars", JSON.stringify(calendars));
}}>{m.delete()}</Button
>
</div>
{/each}
<SettingsButton
text={m["sidebar.calendar.connect"]()}
icon={CalendarPlusIcon}
onclick={() => {
calDavDrawerOpen = true;
}}
/>