From 56307a3dbbe4726ee2bd9ba7d35fbcdfb44e204a Mon Sep 17 00:00:00 2001 From: Till JS Date: Thu, 26 Mar 2026 13:01:02 +0100 Subject: [PATCH] feat(storage): add SVG empty state illustrations for all pages Replace plain text empty states with themed SVG illustrations: - files/folder: cloud folder with upload arrows - trash: empty bin with checkmark - favorites: star outline - search: magnifying glass - shared: connected nodes Reusable EmptyState component with snippet-based action slots. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../lib/components/files/EmptyState.svelte | 324 ++++++++++++++++++ .../web/src/routes/favorites/+page.svelte | 11 +- .../apps/web/src/routes/files/+page.svelte | 16 +- .../src/routes/files/[folderId]/+page.svelte | 16 +- .../apps/web/src/routes/search/+page.svelte | 21 +- .../apps/web/src/routes/shared/+page.svelte | 11 +- .../apps/web/src/routes/trash/+page.svelte | 11 +- 7 files changed, 371 insertions(+), 39 deletions(-) create mode 100644 apps/storage/apps/web/src/lib/components/files/EmptyState.svelte diff --git a/apps/storage/apps/web/src/lib/components/files/EmptyState.svelte b/apps/storage/apps/web/src/lib/components/files/EmptyState.svelte new file mode 100644 index 000000000..f7436189e --- /dev/null +++ b/apps/storage/apps/web/src/lib/components/files/EmptyState.svelte @@ -0,0 +1,324 @@ + + +
+
+ {#if type === 'files' || type === 'folder'} + + + + + + + + + + + {:else if type === 'trash'} + + + + + + + + + + + + + {:else if type === 'favorites'} + + + + + + + + + {:else if type === 'search'} + + + + + + + + + {:else if type === 'shared'} + + + + + + + + + + {/if} +
+ +

{title}

+

{description}

+ + {#if actions} +
+ {@render actions()} +
+ {/if} +
+ + diff --git a/apps/storage/apps/web/src/routes/favorites/+page.svelte b/apps/storage/apps/web/src/routes/favorites/+page.svelte index e8b06aa91..873ee890b 100644 --- a/apps/storage/apps/web/src/routes/favorites/+page.svelte +++ b/apps/storage/apps/web/src/routes/favorites/+page.svelte @@ -11,6 +11,7 @@ import FilePreviewModal from '$lib/components/files/FilePreviewModal.svelte'; import FileSkeletonGrid from '$lib/components/files/FileSkeletonGrid.svelte'; import FileSkeletonList from '$lib/components/files/FileSkeletonList.svelte'; + import EmptyState from '$lib/components/files/EmptyState.svelte'; let previewFile = $state(null); let files = $state([]); @@ -111,11 +112,11 @@ {:else if files.length === 0 && folders.length === 0} -
- -

Keine Favoriten

-

Markiere Dateien und Ordner als Favoriten, um sie hier schnell zu finden.

-
+ {:else if filesStore.viewMode === 'grid'} (null); let showUploadZone = $state(false); @@ -247,11 +248,12 @@ {:else if filesStore.files.length === 0 && filesStore.folders.length === 0} -
- -

Noch keine Dateien

-

Lade deine ersten Dateien hoch oder erstelle einen Ordner.

-
+ + {#snippet actions()} -
-
+ {/snippet} +
{:else if filesStore.viewMode === 'grid'} (null); let showUploadZone = $state(false); @@ -263,11 +264,12 @@ {:else if filesStore.files.length === 0 && filesStore.folders.length === 0} -
- -

Leerer Ordner

-

Dieser Ordner ist leer. Lade Dateien hoch oder erstelle Unterordner.

-
+ + {#snippet actions()} -
-
+ {/snippet} + {:else if filesStore.viewMode === 'grid'} Suche läuft...

{:else if searched && files.length === 0 && folders.length === 0} -
- -

Keine Ergebnisse

-

Keine Dateien oder Ordner für "{query}" gefunden.

-
+ {:else if searched}
{files.length + folders.length} Ergebnis(se) für "{query}" @@ -134,11 +135,11 @@ {/if} {:else} -
- -

Dateien durchsuchen

-

Gib einen Suchbegriff ein, um Dateien und Ordner zu finden.

-
+ {/if}
diff --git a/apps/storage/apps/web/src/routes/shared/+page.svelte b/apps/storage/apps/web/src/routes/shared/+page.svelte index 79121fb27..3e70202ec 100644 --- a/apps/storage/apps/web/src/routes/shared/+page.svelte +++ b/apps/storage/apps/web/src/routes/shared/+page.svelte @@ -5,6 +5,7 @@ import { StorageEvents } from '@manacore/shared-utils/analytics'; import type { Share } from '$lib/api/client'; import { toastStore } from '@manacore/shared-ui'; + import EmptyState from '$lib/components/files/EmptyState.svelte'; let shares = $state([]); let loading = $state(true); @@ -95,11 +96,11 @@ {:else if shares.length === 0} -
- -

Keine geteilten Links

-

Teile Dateien oder Ordner, um Links hier zu verwalten.

-
+ {:else}
{#each shares as share (share.id)} diff --git a/apps/storage/apps/web/src/routes/trash/+page.svelte b/apps/storage/apps/web/src/routes/trash/+page.svelte index c08bc6444..4e2918cf7 100644 --- a/apps/storage/apps/web/src/routes/trash/+page.svelte +++ b/apps/storage/apps/web/src/routes/trash/+page.svelte @@ -6,6 +6,7 @@ import type { StorageFile, StorageFolder } from '$lib/api/client'; import { toastStore } from '@manacore/shared-ui'; import FileSkeletonList from '$lib/components/files/FileSkeletonList.svelte'; + import EmptyState from '$lib/components/files/EmptyState.svelte'; let files = $state([]); let folders = $state([]); @@ -117,11 +118,11 @@
{:else if files.length === 0 && folders.length === 0} -
- -

Papierkorb ist leer

-

Gelöschte Dateien und Ordner erscheinen hier.

-
+ {:else}
{#each folders as folder (folder.id)}