diff --git a/src/web/frontend/src/app.css b/src/web/frontend/src/app.css index 621f4d9..77db717 100644 --- a/src/web/frontend/src/app.css +++ b/src/web/frontend/src/app.css @@ -60,3 +60,12 @@ hr { border: none; border-bottom: 1px solid var(--bg-2); } + +a { + color: var(--on-primary); + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} diff --git a/src/web/frontend/src/components/ui/AccountAddButton.svelte b/src/web/frontend/src/components/ui/AccountAddButton.svelte new file mode 100644 index 0000000..0884570 --- /dev/null +++ b/src/web/frontend/src/components/ui/AccountAddButton.svelte @@ -0,0 +1,74 @@ + + +
+
+
+

Add Account

+
+ + diff --git a/src/web/frontend/src/components/ui/AccountListItem.svelte b/src/web/frontend/src/components/ui/AccountListItem.svelte index 840f5db..1d81150 100644 --- a/src/web/frontend/src/components/ui/AccountListItem.svelte +++ b/src/web/frontend/src/components/ui/AccountListItem.svelte @@ -1,25 +1,37 @@ -
+
-
-
-

{account.username}

- -
+
+
+

{account.username}

+ +
diff --git a/src/web/frontend/src/components/ui/Card.svelte b/src/web/frontend/src/components/ui/Card.svelte new file mode 100644 index 0000000..41ce19a --- /dev/null +++ b/src/web/frontend/src/components/ui/Card.svelte @@ -0,0 +1,19 @@ +
+ + diff --git a/src/web/frontend/src/components/ui/SidebarLink.svelte b/src/web/frontend/src/components/ui/SidebarLink.svelte new file mode 100644 index 0000000..786e9c0 --- /dev/null +++ b/src/web/frontend/src/components/ui/SidebarLink.svelte @@ -0,0 +1,45 @@ + + +{@render children()} + + diff --git a/src/web/frontend/src/components/ui/Skeleton.svelte b/src/web/frontend/src/components/ui/Skeleton.svelte new file mode 100644 index 0000000..8d56dd2 --- /dev/null +++ b/src/web/frontend/src/components/ui/Skeleton.svelte @@ -0,0 +1,37 @@ +
+ + diff --git a/src/web/frontend/src/components/ui/Toast.svelte b/src/web/frontend/src/components/ui/Toast.svelte index 427f4a0..a295c73 100644 --- a/src/web/frontend/src/components/ui/Toast.svelte +++ b/src/web/frontend/src/components/ui/Toast.svelte @@ -1,7 +1,7 @@ -
+
{text} {#if sticky}
{dispatch("dismiss")}} />
diff --git a/src/web/frontend/src/lib/account.ts b/src/web/frontend/src/lib/account.ts index 2221b6c..aa35ff5 100644 --- a/src/web/frontend/src/lib/account.ts +++ b/src/web/frontend/src/lib/account.ts @@ -1,5 +1,9 @@ -export interface Account { +import { writable } from "svelte/store"; + +export default interface Account { username: string, domain: string, mail_directory: string, } + +export let accounts = writable(null); diff --git a/src/web/frontend/src/lib/toasts.ts b/src/web/frontend/src/lib/toasts.ts index 00bc935..b60525c 100644 --- a/src/web/frontend/src/lib/toasts.ts +++ b/src/web/frontend/src/lib/toasts.ts @@ -19,25 +19,21 @@ export const DEFAULT_NOTIFICATION_TIMEOUT = 5000; export const toasts = writable([]); -export function pushToast(toast: Record) { +export function pushToast( + text: string, + type: ToastType, + sticky: boolean = false, + timeout: number = DEFAULT_NOTIFICATION_TIMEOUT, +) { const id = Math.floor(Math.random() * 1_000_000); - const defaults: Toast = { - id, - text: "", - type: ToastType.INFO, - sticky: false, - timeout: DEFAULT_NOTIFICATION_TIMEOUT, - }; + let toast: Toast = { id, text, type, sticky, timeout }; - toast = { ...defaults, ...toast }; - console.log(`adding toast ${toast.id} (timeout ${toast.timeout})...`); - toasts.update((toasts) => [...toasts, { ...defaults, ...toast }]); + toasts.update((toasts) => [...toasts, toast]); if (!toast.sticky) setTimeout(() => { dismissToast(id) }, toast.timeout); } export function dismissToast(id: number) { - console.log(`dismissing toast ${id}...`); toasts.update((toasts) => toasts.filter((toast) => toast.id !== id)); } diff --git a/src/web/frontend/src/routes/+layout.svelte b/src/web/frontend/src/routes/+layout.svelte index 00f249d..82eb574 100644 --- a/src/web/frontend/src/routes/+layout.svelte +++ b/src/web/frontend/src/routes/+layout.svelte @@ -4,6 +4,7 @@ import { LayoutDashboard, Mail, Settings, User } from '@lucide/svelte'; import { onMount } from 'svelte'; import ToastOverlay from '@jupiter/components/ui/ToastOverlay.svelte'; + import SidebarLink from '@jupiter/components/ui/SidebarLink.svelte'; let { children } = $props(); @@ -15,9 +16,9 @@
{@render children()} @@ -60,36 +61,4 @@ user-select: none; } - - .sidebar a { - margin-left: var(--sp-sm); - padding: .5em; - - display: flex; - flex-direction: row; - justify-content: start; - align-items: center; - gap: .5em; - - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - - color: var(--on-primary); - background-color: var(--bg-0); - text-decoration: none; - border: 1px solid var(--bg-2); - border-radius: var(--radius-0); - - box-shadow: calc(0px - var(--sp-sm)) 0 0 var(--on-primary); - user-select: none; - } - - .sidebar a:hover { - background-color: var(--bg-1); - } - - .sidebar a:active { - background-color: var(--bg-2); - } diff --git a/src/web/frontend/src/routes/+page.svelte b/src/web/frontend/src/routes/+page.svelte index c5daf83..dd0b6c6 100644 --- a/src/web/frontend/src/routes/+page.svelte +++ b/src/web/frontend/src/routes/+page.svelte @@ -1,6 +1,16 @@
@@ -8,6 +18,13 @@

Dashboard

+ +
+ +

Accounts

+

Active: {$accounts.length}

+
+
diff --git a/src/web/frontend/src/routes/accounts/+page.svelte b/src/web/frontend/src/routes/accounts/+page.svelte index 91c7fe9..73506ee 100644 --- a/src/web/frontend/src/routes/accounts/+page.svelte +++ b/src/web/frontend/src/routes/accounts/+page.svelte @@ -1,19 +1,23 @@
@@ -26,9 +30,21 @@

Click an account below to configure:


@@ -48,8 +64,15 @@ margin: 0; padding: 0; - display: grid; - grid-template-columns: 1fr 1fr; + display: flex; + flex-direction: row; + flex-wrap: wrap; gap: 1em; } + + .account-skeleton { + width: 480px; + height: var(--sp-xxxl); + padding: .5em; + } diff --git a/src/web/frontend/tsconfig.json b/src/web/frontend/tsconfig.json index 455b794..2c2ed3c 100644 --- a/src/web/frontend/tsconfig.json +++ b/src/web/frontend/tsconfig.json @@ -10,7 +10,7 @@ "skipLibCheck": true, "sourceMap": true, "strict": true, - "moduleResolution": "nodenext" + "moduleResolution": "bundler" } // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files