refactor(apps): replace inline SVGs with Phosphor icons across 19 apps

Migrate inline SVG icon paths to Phosphor components in chat, zitare,
times, citycorners, inventar, manacore, todo, playground, presi, and
more. Part of repo-wide icon unification effort.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-03-31 12:18:20 +02:00
parent 3f2e6a3ee5
commit f58d58ff99
30 changed files with 179 additions and 687 deletions

View file

@ -3,6 +3,7 @@
import { conversationsStore } from '$lib/stores/conversations.svelte';
import { useArchivedConversations } from '$lib/data/queries';
import { PageHeader } from '@manacore/shared-ui';
import { Archive, ArrowUUpLeft, Trash } from '@manacore/shared-icons';
import type { Conversation } from '@chat/types';
const archivedConvs = useArchivedConversations();
@ -47,19 +48,7 @@
{#if conversations.length === 0}
<!-- Empty State -->
<div class="text-center py-16">
<svg
class="w-16 h-16 text-muted-foreground mx-auto mb-4"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="1.5"
d="M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4"
/>
</svg>
<Archive size={64} class="text-muted-foreground mx-auto mb-4" />
<h3 class="text-lg font-medium text-foreground mb-1">Keine archivierten Konversationen</h3>
<p class="text-muted-foreground">Archivierte Gespräche erscheinen hier.</p>
</div>
@ -74,19 +63,7 @@
<button onclick={() => handleConversationClick(conv.id)} class="w-full p-4 text-left">
<div class="flex items-center justify-between mb-2">
<div class="flex items-center gap-2">
<svg
class="w-5 h-5 text-muted-foreground"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4"
/>
</svg>
<Archive size={20} class="text-muted-foreground" />
<h3 class="font-semibold text-foreground">
{conv.title || 'Unbenannte Konversation'}
</h3>
@ -112,14 +89,7 @@
hover:text-primary hover:bg-primary/10
rounded-lg transition-colors"
>
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6"
/>
</svg>
<ArrowUUpLeft size={16} />
Wiederherstellen
</button>
<button
@ -128,14 +98,7 @@
hover:text-destructive hover:bg-destructive/10
rounded-lg transition-colors"
>
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
/>
</svg>
<Trash size={16} />
Löschen
</button>
</div>

View file

@ -4,6 +4,7 @@
import { authStore } from '$lib/stores/auth.svelte';
import { documentService } from '$lib/services/document';
import { PageHeader } from '@manacore/shared-ui';
import { ArrowsClockwise, FileText } from '@manacore/shared-icons';
import type { DocumentWithConversation } from '@chat/types';
let documents = $state<DocumentWithConversation[]>([]);
@ -92,14 +93,7 @@
hover:bg-muted rounded-lg transition-colors"
aria-label="Aktualisieren"
>
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
/>
</svg>
<ArrowsClockwise size={20} />
</button>
{/snippet}
</PageHeader>
@ -114,19 +108,7 @@
{:else if documents.length === 0}
<!-- Empty State -->
<div class="text-center py-16">
<svg
class="w-16 h-16 text-muted-foreground mx-auto mb-4"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="1.5"
d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
/>
</svg>
<FileText size={64} class="text-muted-foreground mx-auto mb-4" />
<h3 class="text-lg font-medium text-foreground mb-1">Keine Dokumente gefunden</h3>
<p class="text-muted-foreground max-w-sm mx-auto">
Erstelle ein neues Dokument in einer Konversation mit aktiviertem Dokumentmodus.

View file

@ -2,6 +2,15 @@
import { onMount } from 'svelte';
import { userSettings } from '$lib/stores/user-settings.svelte';
import { APP_VERSION } from '$lib/version';
import {
Bell,
DeviceMobile,
Envelope,
ShieldCheck,
Key,
Trash,
Info,
} from '@manacore/shared-icons';
import {
SettingsPage,
SettingsSection,
@ -34,14 +43,7 @@
<!-- Notifications Section -->
<SettingsSection title="Benachrichtigungen">
{#snippet icon()}
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"
/>
</svg>
<Bell />
{/snippet}
<SettingsCard>
@ -53,14 +55,7 @@
disabled
>
{#snippet icon()}
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24" class="opacity-50">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z"
/>
</svg>
<DeviceMobile class="opacity-50" />
{/snippet}
</SettingsToggle>
@ -73,14 +68,7 @@
border={false}
>
{#snippet icon()}
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24" class="opacity-50">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
/>
</svg>
<Envelope class="opacity-50" />
{/snippet}
</SettingsToggle>
@ -93,14 +81,7 @@
<!-- Privacy & Security Section -->
<SettingsSection title="Datenschutz & Sicherheit">
{#snippet icon()}
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"
/>
</svg>
<ShieldCheck />
{/snippet}
<SettingsCard>
@ -110,14 +91,7 @@
href="/profile"
>
{#snippet icon()}
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z"
/>
</svg>
<Key />
{/snippet}
</SettingsRow>
</SettingsCard>

View file

@ -4,6 +4,7 @@
import { authStore } from '$lib/stores/auth.svelte';
import { spacesStore } from '$lib/stores/spaces.svelte';
import { PageHeader } from '@manacore/shared-ui';
import { Plus, UsersThree } from '@manacore/shared-icons';
import SpaceCard from '$lib/components/spaces/SpaceCard.svelte';
import SpaceForm from '$lib/components/spaces/SpaceForm.svelte';
import type { Space } from '@chat/types';
@ -99,14 +100,7 @@
class="flex items-center gap-2 px-4 py-2 bg-primary text-primary-foreground rounded-lg font-medium
hover:bg-primary/90 transition-colors"
>
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 4v16m8-8H4"
/>
</svg>
<Plus size={20} />
Neuen Space erstellen
</button>
{/snippet}
@ -122,19 +116,7 @@
{:else if spacesStore.spaces.length === 0}
<!-- Empty State -->
<div class="text-center py-16">
<svg
class="w-16 h-16 text-muted-foreground mx-auto mb-4"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="1.5"
d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"
/>
</svg>
<UsersThree size={64} class="text-muted-foreground mx-auto mb-4" />
<h3 class="text-lg font-medium text-foreground mb-1">Keine Spaces gefunden</h3>
<p class="text-muted-foreground mb-4">
Erstelle einen neuen Space oder frage nach einer Einladung
@ -144,14 +126,7 @@
class="inline-flex items-center gap-2 px-4 py-2 bg-primary text-primary-foreground rounded-lg font-medium
hover:bg-primary/90 transition-colors"
>
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 4v16m8-8H4"
/>
</svg>
<Plus size={20} />
Ersten Space erstellen
</button>
</div>

View file

@ -5,6 +5,7 @@
import { templatesStore } from '$lib/stores/templates.svelte';
import { conversationService } from '$lib/services/conversation';
import { PageHeader } from '@manacore/shared-ui';
import { Plus, FileText } from '@manacore/shared-icons';
import TemplateCard from '$lib/components/templates/TemplateCard.svelte';
import TemplateForm from '$lib/components/templates/TemplateForm.svelte';
import type { Template } from '@chat/types';
@ -111,14 +112,7 @@
class="flex items-center gap-2 px-4 py-2 bg-primary text-primary-foreground rounded-lg font-medium
hover:bg-primary/90 transition-colors"
>
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 4v16m8-8H4"
/>
</svg>
<Plus size={20} />
Neue Vorlage
</button>
{/snippet}
@ -128,19 +122,7 @@
{#if templates.length === 0}
<!-- Empty State -->
<div class="text-center py-16">
<svg
class="w-16 h-16 text-muted-foreground mx-auto mb-4"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="1.5"
d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
/>
</svg>
<FileText size={64} class="text-muted-foreground mx-auto mb-4" />
<h3 class="text-lg font-medium text-foreground mb-1">Keine Vorlagen vorhanden</h3>
<p class="text-muted-foreground mb-4">Erstelle deine erste Vorlage, um loszulegen</p>
<button
@ -148,14 +130,7 @@
class="inline-flex items-center gap-2 px-4 py-2 bg-primary text-primary-foreground rounded-lg font-medium
hover:bg-primary/90 transition-colors"
>
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 4v16m8-8H4"
/>
</svg>
<Plus size={20} />
Erste Vorlage erstellen
</button>
</div>

View file

@ -22,6 +22,7 @@
import { getPillAppItems, getManaApp } from '@manacore/shared-branding';
import { getLanguageDropdownItems, getCurrentLanguageLabel } from '@manacore/shared-i18n';
import { setLocale, supportedLocales } from '$lib/i18n';
import { List, X } from '@manacore/shared-icons';
import { api } from '$lib/api';
let appItems = $derived(
@ -295,23 +296,9 @@
title={showNav ? $_('nav.hideNav') : $_('nav.showNav')}
>
{#if !showNav}
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24" class="fab-icon">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M4 6h16M4 12h16M4 18h16"
/>
</svg>
<List size={24} class="fab-icon" />
{:else}
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24" class="fab-icon">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M6 18L18 6M6 6l12 12"
/>
</svg>
<X size={24} class="fab-icon" />
{/if}
</button>

View file

@ -1,4 +1,5 @@
<script lang="ts">
import { Plus, MapPin, User } from '@manacore/shared-icons';
import { _ } from 'svelte-i18n';
import { goto } from '$app/navigation';
import { authStore } from '$lib/stores/auth.svelte';
@ -38,9 +39,7 @@
class="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-primary text-white shadow-md transition-all hover:bg-primary/90 hover:shadow-lg"
title={$_('cities.add')}
>
<svg class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
</svg>
<Plus size={20} weight="bold" />
</a>
{/if}
</header>
@ -142,38 +141,14 @@
<span
class="inline-flex items-center gap-1 rounded-full bg-primary/10 px-2 py-0.5 text-xs text-primary"
>
<svg
class="h-3 w-3"
fill="none"
stroke="currentColor"
stroke-width="2"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M15 10.5a3 3 0 11-6 0 3 3 0 016 0zM19.5 10.5c0 7.142-7.5 11.25-7.5 11.25S4.5 17.642 4.5 10.5a7.5 7.5 0 1115 0z"
/>
</svg>
<MapPin size={12} />
{count}
</span>
{#if cityStats.contributorCount > 0}
<span
class="inline-flex items-center gap-1 rounded-full bg-amber-500/10 px-2 py-0.5 text-xs text-amber-600 dark:text-amber-400"
>
<svg
class="h-3 w-3"
fill="none"
stroke="currentColor"
stroke-width="2"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M15.75 6a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0zM4.501 20.118a7.5 7.5 0 0114.998 0"
/>
</svg>
<User size={12} />
{cityStats.contributorCount}
</span>
{/if}

View file

@ -1,5 +1,6 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { CaretLeft } from '@manacore/shared-icons';
import { _ } from 'svelte-i18n';
import { authStore } from '$lib/stores/auth.svelte';
import { cityCollection, type LocalCity } from '$lib/data/local-store';
@ -116,9 +117,7 @@
<header class="mb-6">
<div class="flex items-center gap-2 mb-1">
<a href="/" class="text-foreground-secondary hover:text-primary transition-colors">
<svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5L8.25 12l7.5-7.5" />
</svg>
<CaretLeft size={16} />
</a>
<h1 class="text-2xl font-bold text-foreground">{$_('cityAdd.title')}</h1>
</div>

View file

@ -1,5 +1,6 @@
<script lang="ts">
import { onMount } from 'svelte';
import { Heart } from '@manacore/shared-icons';
import { _ } from 'svelte-i18n';
import { authStore } from '$lib/stores/auth.svelte';
import { favoritesStore } from '$lib/stores/favorites.svelte';

View file

@ -9,6 +9,7 @@
import { setLocale, supportedLocales } from '$lib/i18n';
import { PillNavigation } from '@manacore/shared-ui';
import { SyncIndicator } from '@manacore/shared-ui';
import { User, SignOut, Plus } from '@manacore/shared-icons';
import { getPillAppItems, getManaApp } from '@manacore/shared-branding';
import { AuthGate, GuestWelcomeModal } from '@manacore/shared-auth-ui';
import { shouldShowGuestWelcome } from '@manacore/shared-auth-ui';
@ -128,14 +129,7 @@
href="/profile"
class="rounded-lg p-1.5 text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))]"
>
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"
/>
</svg>
<User size={20} />
</a>
<button
@ -143,14 +137,7 @@
class="rounded-lg p-1.5 text-[hsl(var(--muted-foreground))] hover:text-red-500"
title="Abmelden"
>
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"
/>
</svg>
<SignOut size={20} />
</button>
</div>
</div>
@ -183,9 +170,7 @@
onclick={() => goto('/items?action=new')}
class="fixed bottom-6 right-6 z-50 flex h-14 w-14 items-center justify-center rounded-full bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))] shadow-lg transition-transform hover:scale-105 md:hidden"
>
<svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
</svg>
<Plus size={24} />
</button>
<!-- Guest Welcome Modal -->

View file

@ -1,5 +1,6 @@
<script lang="ts">
import { _ } from 'svelte-i18n';
import { Plus } from '@manacore/shared-icons';
import { getContext } from 'svelte';
import { categoriesStore } from '$lib/stores/categories.svelte';
import type { Category } from '@inventar/shared';
@ -69,9 +70,7 @@
onclick={startCreate}
class="flex items-center gap-2 rounded-lg bg-[hsl(var(--primary))] px-4 py-2 text-sm font-medium text-[hsl(var(--primary-foreground))]"
>
<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
</svg>
<Plus size={16} />
{$_('category.create')}
</button>
</div>

View file

@ -2,6 +2,7 @@
import { page } from '$app/stores';
import { goto } from '$app/navigation';
import { _ } from 'svelte-i18n';
import { CaretLeft, PencilSimple, Plus, Trash } from '@manacore/shared-icons';
import { getContext } from 'svelte';
import { itemsStore } from '$lib/stores/items.svelte';
import { viewStore } from '$lib/stores/view.svelte';
@ -63,14 +64,7 @@
<div class="flex items-center justify-between">
<div class="flex items-center gap-3">
<a href="/" class="text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))]">
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M15 19l-7-7 7-7"
/>
</svg>
<CaretLeft size={20} />
</a>
<span class="text-2xl">{collection.icon || '📁'}</span>
<div>
@ -86,27 +80,13 @@
href="/collections/{collection.id}/edit"
class="rounded-lg border border-[hsl(var(--border))] p-2 text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))]"
>
<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"
/>
</svg>
<PencilSimple size={16} />
</a>
<button
onclick={() => (showNewItem = !showNewItem)}
class="flex items-center gap-2 rounded-lg bg-[hsl(var(--primary))] px-4 py-2 text-sm font-medium text-[hsl(var(--primary-foreground))]"
>
<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 4v16m8-8H4"
/>
</svg>
<Plus size={16} />
{$_('item.create')}
</button>
</div>
@ -249,14 +229,7 @@
onclick={(e) => deleteItem(e, item.id)}
class="text-[hsl(var(--muted-foreground))] hover:text-red-500"
>
<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
/>
</svg>
<Trash size={16} />
</button>
</td>
</tr>
@ -302,14 +275,7 @@
onclick={(e) => deleteItem(e, item.id)}
class="text-[hsl(var(--muted-foreground))] opacity-0 hover:text-red-500 group-hover:opacity-100"
>
<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
/>
</svg>
<Trash size={16} />
</button>
</div>
{/each}

View file

@ -2,6 +2,7 @@
import { page } from '$app/stores';
import { goto } from '$app/navigation';
import { _ } from 'svelte-i18n';
import { CaretLeft } from '@manacore/shared-icons';
import { getContext } from 'svelte';
import { collectionsStore } from '$lib/stores/collections.svelte';
import { getCollectionById } from '$lib/data/queries';
@ -57,14 +58,7 @@
onclick={() => goto(`/collections/${collection.id}`)}
class="text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))]"
>
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M15 19l-7-7 7-7"
/>
</svg>
<CaretLeft size={20} />
</button>
<h1 class="text-2xl font-bold text-[hsl(var(--foreground))]">{$_('collection.edit')}</h1>
</div>

View file

@ -7,6 +7,13 @@
AuditLog,
SessionManager,
} from '@manacore/shared-auth-ui';
import {
User,
CurrencyCircleDollar,
ShieldCheck,
FileText,
CaretRight,
} from '@manacore/shared-icons';
import { authStore } from '$lib/stores/auth.svelte';
import { creditsService } from '$lib/api/credits';
import type { CreditBalance } from '$lib/api/credits';
@ -107,14 +114,7 @@
<div
class="flex h-10 w-10 items-center justify-center rounded-full bg-primary/10 text-primary"
>
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"
/>
</svg>
<User size={20} />
</div>
<div>
<h2 class="text-lg font-semibold">Profil</h2>
@ -181,14 +181,7 @@
<div
class="flex h-10 w-10 items-center justify-center rounded-full bg-yellow-100 dark:bg-yellow-900/20 text-yellow-600 dark:text-yellow-400"
>
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
<CurrencyCircleDollar size={20} />
</div>
<div>
<h2 class="text-lg font-semibold">Credits</h2>
@ -245,14 +238,7 @@
<div
class="flex h-10 w-10 items-center justify-center rounded-full bg-blue-100 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400"
>
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"
/>
</svg>
<ShieldCheck size={20} />
</div>
<div>
<h2 class="text-lg font-semibold">Konto</h2>
@ -368,14 +354,7 @@
<div
class="flex h-10 w-10 items-center justify-center rounded-full bg-purple-100 dark:bg-purple-900/20 text-purple-600 dark:text-purple-400"
>
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
/>
</svg>
<FileText size={20} />
</div>
<div>
<h2 class="text-lg font-semibold">Meine Daten (DSGVO)</h2>
@ -396,14 +375,7 @@
class="inline-flex items-center gap-2 rounded-lg bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors"
>
Meine Daten
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 5l7 7-7 7"
/>
</svg>
<CaretRight size={16} />
</a>
</div>

View file

@ -1,5 +1,6 @@
<script lang="ts">
import { Card, Button, PageHeader } from '@manacore/shared-ui';
import { Plus } from '@manacore/shared-icons';
import type { PageData } from './$types';
let { data }: { data: PageData } = $props();
@ -22,14 +23,7 @@
<PageHeader title="Teams" description="Manage your teams and collaborate with members" size="lg">
{#snippet actions()}
<Button variant="primary">
<svg class="mr-2 h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 4v16m8-8H4"
/>
</svg>
<Plus size={20} class="mr-2" />
Create Team
</Button>
{/snippet}

View file

@ -4,6 +4,7 @@
import type { Snippet } from 'svelte';
import { authStore } from '$lib/stores/auth.svelte';
import { theme } from '$lib/stores/theme';
import { Sun, Moon } from '@manacore/shared-icons';
let { children }: { children: Snippet } = $props();
let isDark = $derived(theme.isDark);
@ -34,23 +35,9 @@
aria-label="Toggle dark mode"
>
{#if isDark}
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"
/>
</svg>
<Sun size={20} />
{:else}
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"
/>
</svg>
<Moon size={20} />
{/if}
</button>

View file

@ -1,6 +1,7 @@
<script lang="ts">
import { chatStore } from '$lib/stores/chat.svelte';
import { comparisonStore } from '$lib/stores/comparison.svelte';
import { Stop, PaperPlaneRight } from '@manacore/shared-icons';
let input = $state('');
let textareaEl: HTMLTextAreaElement | undefined = $state();
@ -62,9 +63,7 @@
class="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg transition-colors"
style="background-color: var(--color-error);"
>
<svg class="h-5 w-5" fill="currentColor" viewBox="0 0 24 24">
<rect x="6" y="6" width="12" height="12" rx="1" />
</svg>
<Stop size={20} weight="fill" />
</button>
{:else}
<button
@ -74,14 +73,7 @@
class="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg transition-colors disabled:opacity-50"
style="background-color: var(--color-primary);"
>
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8"
/>
</svg>
<PaperPlaneRight size={20} />
</button>
{/if}
</div>

View file

@ -2,6 +2,7 @@
import { getHealth } from '$lib/api/llm';
import { authStore } from '$lib/stores/auth.svelte';
import { onMount } from 'svelte';
import { ArrowsClockwise } from '@manacore/shared-icons';
let healthStatus = $state<'loading' | 'healthy' | 'error'>('loading');
let healthDetails = $state<string>('');
@ -67,14 +68,7 @@
class="rounded p-1.5 transition-colors hover:bg-white/10"
title="Refresh health status"
>
<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
/>
</svg>
<ArrowsClockwise size={16} />
</button>
<button
onclick={() => authStore.signOut()}

View file

@ -5,6 +5,7 @@
import ModelComparisonSelector from '$lib/components/comparison/ModelComparisonSelector.svelte';
import { chatStore } from '$lib/stores/chat.svelte';
import { modelsStore } from '$lib/stores/models.svelte';
import { Trash, Export } from '@manacore/shared-icons';
function handleExport() {
const data = chatStore.exportMessages();
@ -47,14 +48,7 @@
class="flex flex-1 items-center justify-center gap-2 rounded-lg px-3 py-2 text-sm font-medium transition-colors disabled:opacity-50"
style="background-color: var(--color-bg);"
>
<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
/>
</svg>
<Trash size={16} />
Clear
</button>
<button
@ -63,14 +57,7 @@
class="flex flex-1 items-center justify-center gap-2 rounded-lg px-3 py-2 text-sm font-medium transition-colors disabled:opacity-50"
style="background-color: var(--color-bg);"
>
<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12"
/>
</svg>
<Export size={16} />
Export
</button>
</div>

View file

@ -15,6 +15,7 @@
SettingsDangerButton,
GlobalSettingsSection,
} from '@manacore/shared-ui';
import { User, Envelope, ShieldCheck, Sun, Moon, Monitor, SignOut } from '@manacore/shared-icons';
function handleLogout() {
auth.logout();
@ -38,39 +39,18 @@
<!-- Account Section -->
<SettingsSection title="Account">
{#snippet icon()}
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"
/>
</svg>
<User />
{/snippet}
<SettingsCard>
<SettingsRow label="Email" description={auth.user?.email || 'Not available'}>
{#snippet icon()}
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
/>
</svg>
<Envelope />
{/snippet}
</SettingsRow>
<SettingsRow label="User ID" description={auth.user?.id || 'Not available'} border={false}>
{#snippet icon()}
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"
/>
</svg>
<ShieldCheck />
{/snippet}
<span class="font-mono text-xs text-[hsl(var(--muted-foreground))]"
>{auth.user?.id || '-'}</span
@ -82,14 +62,7 @@
<!-- Appearance Section -->
<SettingsSection title="Appearance">
{#snippet icon()}
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"
/>
</svg>
<Sun />
{/snippet}
<SettingsCard>
@ -104,19 +77,7 @@
? 'border-[hsl(var(--primary))] bg-[hsl(var(--primary)/0.1)]'
: 'border-[hsl(var(--border))]'}"
>
<svg
class="w-6 h-6 text-amber-500"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"
/>
</svg>
<Sun size={24} class="text-amber-500" />
<span class="text-sm font-medium text-[hsl(var(--foreground))]">Light</span>
</button>
<button
@ -126,19 +87,7 @@
? 'border-[hsl(var(--primary))] bg-[hsl(var(--primary)/0.1)]'
: 'border-[hsl(var(--border))]'}"
>
<svg
class="w-6 h-6 text-indigo-500"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"
/>
</svg>
<Moon size={24} class="text-indigo-500" />
<span class="text-sm font-medium text-[hsl(var(--foreground))]">Dark</span>
</button>
<button
@ -148,19 +97,7 @@
? 'border-[hsl(var(--primary))] bg-[hsl(var(--primary)/0.1)]'
: 'border-[hsl(var(--border))]'}"
>
<svg
class="w-6 h-6 text-[hsl(var(--muted-foreground))]"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
/>
</svg>
<Monitor size={24} class="text-[hsl(var(--muted-foreground))]" />
<span class="text-sm font-medium text-[hsl(var(--foreground))]">System</span>
</button>
</div>
@ -181,14 +118,7 @@
border={false}
>
{#snippet icon()}
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"
/>
</svg>
<SignOut />
{/snippet}
</SettingsDangerButton>
</SettingsDangerZone>

View file

@ -9,6 +9,7 @@
import TimerIndicator from '$lib/components/TimerIndicator.svelte';
import { theme } from '$lib/stores/theme';
import { setLocale, supportedLocales } from '$lib/i18n';
import { Clock, User, SignOut, Play } from '@manacore/shared-icons';
import { SyncIndicator } from '@manacore/shared-ui';
import { getPillAppItems, getManaApp } from '@manacore/shared-branding';
import { AuthGate, GuestWelcomeModal } from '@manacore/shared-auth-ui';
@ -103,14 +104,7 @@
<div
class="flex h-8 w-8 items-center justify-center rounded-lg bg-[hsl(var(--primary))]"
>
<svg class="h-4 w-4 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
<Clock size={16} class="text-white" />
</div>
<span class="text-lg font-bold text-[hsl(var(--foreground))]">Times</span>
</a>
@ -149,14 +143,7 @@
href="/profile"
class="rounded-lg p-1.5 text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))]"
>
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"
/>
</svg>
<User size={20} />
</a>
<button
@ -164,14 +151,7 @@
class="rounded-lg p-1.5 text-[hsl(var(--muted-foreground))] hover:text-red-500"
title="Abmelden"
>
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"
/>
</svg>
<SignOut size={20} />
</button>
</div>
</div>
@ -204,9 +184,7 @@
onclick={() => goto('/?action=start')}
class="fixed bottom-6 right-6 z-50 flex h-14 w-14 items-center justify-center rounded-full bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))] shadow-lg transition-transform hover:scale-105 md:hidden"
>
<svg class="h-6 w-6" fill="currentColor" viewBox="0 0 24 24">
<polygon points="5 3 19 12 5 21 5 3" />
</svg>
<Play size={24} weight="fill" />
</button>
<GuestWelcomeModal

View file

@ -9,6 +9,7 @@
formatDurationCompact,
formatDurationDecimal,
} from '$lib/data/queries';
import { CaretLeft } from '@manacore/shared-icons';
import EntryList from '$lib/components/EntryList.svelte';
import type { Project, Client, TimeEntry } from '@times/shared';
@ -58,14 +59,7 @@
href="/clients"
class="mb-3 inline-flex items-center gap-1 text-sm text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))]"
>
<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M15 19l-7-7 7-7"
/>
</svg>
<CaretLeft size={16} />
{$_('nav.clients')}
</a>

View file

@ -10,6 +10,7 @@
formatDurationCompact,
formatDurationDecimal,
} from '$lib/data/queries';
import { CaretLeft } from '@manacore/shared-icons';
import EntryList from '$lib/components/EntryList.svelte';
import type { Project, Client, TimeEntry } from '@times/shared';
import { PROJECT_COLORS } from '@times/shared/constants';
@ -98,14 +99,7 @@
href="/projects"
class="mb-3 inline-flex items-center gap-1 text-sm text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))]"
>
<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M15 19l-7-7 7-7"
/>
</svg>
<CaretLeft size={16} />
{$_('nav.projects')}
</a>

View file

@ -3,6 +3,7 @@
import { _ } from 'svelte-i18n';
import { templateCollection, timeEntryCollection } from '$lib/data/local-store';
import { timerStore } from '$lib/stores/timer.svelte';
import { X } from '@manacore/shared-icons';
import type { EntryTemplate, Project, Client } from '@times/shared';
const allTemplates = getContext<{ value: EntryTemplate[] }>('templates');
@ -181,14 +182,7 @@
onclick={() => deleteTemplate(template.id)}
class="rounded-lg p-1.5 text-[hsl(var(--muted-foreground))] hover:text-red-500"
>
<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M6 18L18 6M6 6l12 12"
/>
</svg>
<X size={16} />
</button>
</div>
{/each}

View file

@ -2,6 +2,7 @@
import { goto } from '$app/navigation';
import { _ } from 'svelte-i18n';
import { authStore } from '$lib/stores/auth.svelte';
import { Clock } from '@manacore/shared-icons';
import { getPillAppItems } from '@manacore/shared-branding';
let email = $state('');
@ -106,14 +107,7 @@
<div
class="mx-auto mb-3 flex h-16 w-16 items-center justify-center rounded-2xl bg-[hsl(var(--primary))]"
>
<svg class="h-8 w-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
<Clock size={32} class="text-white" />
</div>
<h1 class="text-2xl font-bold text-[hsl(var(--foreground))]">Times</h1>
<p class="mt-1 text-sm text-[hsl(var(--muted-foreground))]">Zeiterfassung</p>

View file

@ -139,17 +139,18 @@
.view-column {
min-height: 250px;
max-height: calc(100vh - 280px);
background: rgba(255, 255, 255, 0.5);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid rgba(0, 0, 0, 0.08);
border-radius: 1.5rem;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);
background: #fffef5;
border-radius: 0.375rem;
box-shadow:
0 2px 8px rgba(0, 0, 0, 0.08),
0 0 0 1px rgba(0, 0, 0, 0.04);
}
:global(.dark) .view-column {
background: rgba(255, 255, 255, 0.08);
border: 1px solid rgba(255, 255, 255, 0.1);
background: #252220;
box-shadow:
0 2px 8px rgba(0, 0, 0, 0.25),
0 0 0 1px rgba(255, 255, 255, 0.06);
}
.tasks-container {
@ -185,7 +186,7 @@
:global(.drop-target) {
outline: 2px dashed #8b5cf6;
outline-offset: -2px;
border-radius: 1.5rem;
background: rgba(139, 92, 246, 0.05);
border-radius: 0.375rem;
background: rgba(139, 92, 246, 0.04);
}
</style>

View file

@ -29,6 +29,36 @@
SettingsDangerButton,
GlobalSettingsSection,
} from '@manacore/shared-ui';
import {
User,
EnvelopeSimple,
ShieldCheck,
Rows,
ListBullets,
ClipboardText,
SortAscending,
Clock,
FolderSimple,
Archive,
Lightning,
Trash,
SquaresFour,
House,
Hash,
ChartBar,
Columns,
Tag,
WarningCircle,
Bell,
Eye,
Timer,
SealCheck,
Fire,
GraduationCap,
Key,
Info,
SignOut,
} from '@manacore/shared-icons';
// Use shared priority options (without color)
const priorityOptions = PRIORITY_OPTIONS.map((p) => ({ value: p.value, label: p.label }));
@ -102,40 +132,19 @@
<!-- Account Section -->
<SettingsSection title="Konto">
{#snippet icon()}
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"
/>
</svg>
<User size={20} />
{/snippet}
<SettingsCard>
<SettingsRow label="E-Mail" description={authStore.user?.email || 'Nicht angemeldet'}>
{#snippet icon()}
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
/>
</svg>
<EnvelopeSimple size={20} />
{/snippet}
</SettingsRow>
<SettingsRow label="Konto-Status" description="Dein aktueller Kontostatus" border={false}>
{#snippet icon()}
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"
/>
</svg>
<ShieldCheck size={20} />
{/snippet}
<span
class="rounded-full bg-green-100 px-3 py-1 text-xs font-medium text-green-800 dark:bg-green-900/20 dark:text-green-400"

View file

@ -41,6 +41,7 @@
import { shouldShowGuestWelcome } from '@manacore/shared-auth-ui';
import { QUOTES, type Quote } from '@zitare/content';
import { zitareStore } from '$lib/data/local-store';
import { List as ListIcon, X } from '@manacore/shared-icons';
const allTags = useAllSharedTags();
setContext('tags', allTags);
@ -350,23 +351,9 @@
title={zitareSettings.pillNavCollapsed ? $_('nav.showNav') : $_('nav.hideNav')}
>
{#if zitareSettings.pillNavCollapsed}
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24" class="fab-icon">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M4 6h16M4 12h16M4 18h16"
/>
</svg>
<ListIcon size={24} class="fab-icon" />
{:else}
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24" class="fab-icon">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M6 18L18 6M6 6l12 12"
/>
</svg>
<X size={24} class="fab-icon" />
{/if}
</button>
{/if}

View file

@ -10,6 +10,14 @@
import { toast } from '$lib/stores/toast.svelte';
import { QUOTES, type Quote } from '@zitare/content';
import QuoteCard from '$lib/components/QuoteCard.svelte';
import {
MagnifyingGlass,
X,
PencilSimple,
Plus,
ListBullets,
Trash,
} from '@manacore/shared-icons';
const allQuotes = QUOTES;
const allLists: { readonly value: QuoteList[] } = getContext('lists');
@ -198,23 +206,11 @@
<div class="header-actions">
{#if listQuotes.length > 0}
<button class="icon-btn" onclick={toggleSearch} aria-label={$_('common.search')}>
<svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor">
{#if isSearchOpen}
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M6 18L18 6M6 6l12 12"
/>
{:else}
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
/>
{/if}
</svg>
{#if isSearchOpen}
<X size={20} />
{:else}
<MagnifyingGlass size={20} />
{/if}
</button>
{/if}
@ -223,14 +219,7 @@
onclick={openEditModal}
aria-label={$_('lists.detail.editModal.title')}
>
<svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"
/>
</svg>
<PencilSimple size={20} />
</button>
<button
@ -238,14 +227,7 @@
onclick={openAddQuotesModal}
aria-label={$_('lists.detail.addQuotes')}
>
<svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 4v16m8-8H4"
/>
</svg>
<Plus size={20} weight="bold" />
</button>
</div>
</div>
@ -266,52 +248,19 @@
{#if listQuotes.length === 0}
<div class="empty-state">
<div class="empty-icon">
<svg
xmlns="http://www.w3.org/2000/svg"
width="64"
height="64"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.5"
>
<line x1="8" y1="6" x2="21" y2="6"></line>
<line x1="8" y1="12" x2="21" y2="12"></line>
<line x1="8" y1="18" x2="21" y2="18"></line>
<line x1="3" y1="6" x2="3.01" y2="6"></line>
<line x1="3" y1="12" x2="3.01" y2="12"></line>
<line x1="3" y1="18" x2="3.01" y2="18"></line>
</svg>
<ListBullets size={64} />
</div>
<h3>{$_('lists.detail.emptyTitle')}</h3>
<p>{$_('lists.detail.emptyDescription')}</p>
<button class="cta-button" onclick={openAddQuotesModal}>
<svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 4v16m8-8H4"
/>
</svg>
<Plus size={20} weight="bold" />
{$_('lists.detail.addQuotes')}
</button>
</div>
{:else if filteredQuotes.length === 0}
<div class="empty-state">
<div class="empty-icon">
<svg
xmlns="http://www.w3.org/2000/svg"
width="64"
height="64"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.5"
>
<circle cx="11" cy="11" r="8"></circle>
<path d="m21 21-4.35-4.35"></path>
</svg>
<MagnifyingGlass size={64} />
</div>
<h3>{$_('lists.detail.noSearchResults')}</h3>
<p>{$_('lists.detail.noSearchResultsDescription')}</p>
@ -332,14 +281,7 @@
class="w-4 h-4 border-2 border-red-400 border-t-transparent rounded-full animate-spin"
></div>
{:else}
<svg width="16" height="16" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M6 18L18 6M6 6l12 12"
/>
</svg>
<X size={16} />
{/if}
{$_('lists.detail.remove')}
</button>

View file

@ -5,6 +5,7 @@
import { quotesStore } from '$lib/stores/quotes.svelte';
import { zitareSettings } from '$lib/stores/settings.svelte';
import QuoteCard from '$lib/components/QuoteCard.svelte';
import { MagnifyingGlass, X } from '@manacore/shared-icons';
let searchTerm = $state('');
let lastTrackedTerm = $state('');
@ -61,19 +62,9 @@
<!-- Search Input -->
<div class="relative mb-4">
<svg
class="absolute left-4 top-1/2 -translate-y-1/2 w-5 h-5 text-foreground-muted"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
/>
</svg>
<div class="absolute left-4 top-1/2 -translate-y-1/2 text-foreground-muted">
<MagnifyingGlass size={20} />
</div>
<input
type="text"
placeholder={$_('search.placeholder')}
@ -85,14 +76,7 @@
onclick={clearSearch}
class="absolute right-4 top-1/2 -translate-y-1/2 p-1 text-foreground-muted hover:text-foreground transition-colors"
>
<svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M6 18L18 6M6 6l12 12"
/>
</svg>
<X size={20} />
</button>
{/if}
</div>
@ -133,20 +117,9 @@
{#if searchTerm.length >= 2}
{#if results.length === 0}
<div class="text-center py-12">
<svg
class="w-16 h-16 mx-auto text-foreground-muted mb-4"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<circle cx="11" cy="11" r="8" stroke-width="1.5"></circle>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="1.5"
d="m21 21-4.35-4.35"
></path>
</svg>
<div class="w-16 h-16 mx-auto text-foreground-muted mb-4 flex items-center justify-center">
<MagnifyingGlass size={64} />
</div>
<p class="text-foreground-secondary">{$_('search.noResults')}</p>
</div>
{:else}
@ -167,16 +140,11 @@
<p class="text-center text-foreground-muted py-8">{$_('search.minChars')}</p>
{:else}
<div class="text-center py-12">
<svg
class="w-16 h-16 mx-auto text-foreground-muted mb-4 opacity-50"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
<div
class="w-16 h-16 mx-auto text-foreground-muted mb-4 opacity-50 flex items-center justify-center"
>
<circle cx="11" cy="11" r="8" stroke-width="1.5"></circle>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="m21 21-4.35-4.35"
></path>
</svg>
<MagnifyingGlass size={64} />
</div>
<p class="text-foreground-secondary">{$_('search.hint')}</p>
</div>
{/if}