♻️ refactor: migrate all web apps to Phosphor icons

Replace lucide-svelte with @manacore/shared-icons across all web apps
for consistent icon usage throughout the monorepo.

Apps migrated:
- calendar (12 files)
- contacts (1 file)
- matrix (16 files)
- nutriphi (7 files)
- presi (6 files)
- questions (9 files)
- skilltree (9 files)
- storage (16 files)
- todo (package.json only)

Key icon mappings:
- Trash2 → Trash
- ChevronLeft/Right/Up/Down → CaretLeft/Right/Up/Down
- Search → MagnifyingGlass
- Settings → Gear
- Loader2 → CircleNotch
- AlertCircle → WarningCircle
- ExternalLink → ArrowSquareOut
- LogOut → SignOut
This commit is contained in:
Till-JS 2026-01-29 13:15:13 +01:00
parent c21f780581
commit b89749deed
86 changed files with 1736 additions and 904 deletions

View file

@ -52,7 +52,6 @@
"@neodrag/svelte": "^2.3.3",
"d3-force": "^3.0.0",
"date-fns": "^4.1.0",
"lucide-svelte": "^0.559.0",
"suncalc": "^1.9.0",
"svelte-dnd-action": "^0.9.68",
"svelte-i18n": "^4.0.1"

View file

@ -1,5 +1,5 @@
<script lang="ts">
import { Calendar, CheckSquare, Filter } from 'lucide-svelte';
import { Calendar, CheckSquare, Funnel } from '@manacore/shared-icons';
import { FilterDropdown, type FilterDropdownOption } from '@manacore/shared-ui';
interface Props {
@ -53,7 +53,7 @@
<div class="filter-group">
<div class="range-selector">
<Filter size={14} />
<Funnel size={14} />
<FilterDropdown
options={rangeOptions}
value={timeRange}

View file

@ -6,7 +6,7 @@
import { todosStore } from '$lib/stores/todos.svelte';
import TodoCheckbox from '$lib/components/todo/TodoCheckbox.svelte';
import PriorityBadge from '$lib/components/todo/PriorityBadge.svelte';
import { Calendar, MapPin, Clock } from 'lucide-svelte';
import { Calendar, MapPin, Clock } from '@manacore/shared-icons';
import { format } from 'date-fns';
import { de } from 'date-fns/locale';
import { toDate } from '$lib/utils/eventDateHelpers';

View file

@ -2,7 +2,7 @@
import { env } from '$env/dynamic/public';
import type { BirthdayEvent } from '$lib/api/birthdays';
import { settingsStore } from '$lib/stores/settings.svelte';
import { X, User, ExternalLink, Cake } from 'lucide-svelte';
import { X, User, ArrowSquareOut, Cake } from '@manacore/shared-icons';
import { format, parseISO } from 'date-fns';
import { de } from 'date-fns/locale';
@ -124,7 +124,7 @@
<a href={contactUrl} target="_blank" rel="noopener noreferrer" class="action-btn primary">
<User size={16} />
<span>Kontakt öffnen</span>
<ExternalLink size={14} class="external-icon" />
<ArrowSquareOut size={14} class="external-icon" />
</a>
</div>
</div>

View file

@ -2,7 +2,7 @@
import type { Task } from '$lib/api/todos';
import { todosStore } from '$lib/stores/todos.svelte';
import { _ } from 'svelte-i18n';
import { CheckSquare, Square } from 'lucide-svelte';
import { CheckSquare, Square } from '@manacore/shared-icons';
interface Props {
task: Task;

View file

@ -4,7 +4,7 @@
import { PRIORITY_COLORS } from '$lib/api/todos';
import TodoCheckbox from '$lib/components/todo/TodoCheckbox.svelte';
import TodoDetailModal from '$lib/components/todo/TodoDetailModal.svelte';
import { Check } from 'lucide-svelte';
import { Check } from '@manacore/shared-icons';
interface Props {
date: Date;

View file

@ -4,7 +4,7 @@
import TodoItem from '$lib/components/todo/TodoItem.svelte';
import TodoDetailModal from '$lib/components/todo/TodoDetailModal.svelte';
import QuickAddTodo from '$lib/components/todo/QuickAddTodo.svelte';
import { ChevronDown, ChevronRight, Plus, CheckSquare, AlertTriangle } from 'lucide-svelte';
import { CaretDown, CaretRight, Plus, CheckSquare, Warning } from '@manacore/shared-icons';
import { goto } from '$app/navigation';
import { onMount } from 'svelte';
@ -67,9 +67,9 @@
<button type="button" class="header-toggle" onclick={toggleExpanded}>
<div class="header-left">
{#if isExpanded}
<ChevronDown size={16} />
<CaretDown size={16} />
{:else}
<ChevronRight size={16} />
<CaretRight size={16} />
{/if}
<CheckSquare size={16} class="section-icon" />
<span class="section-title">Aufgaben</span>
@ -78,7 +78,7 @@
{/if}
{#if overdueCount > 0}
<span class="overdue-badge" title="{overdueCount} überfällig">
<AlertTriangle size={12} />
<Warning size={12} />
</span>
{/if}
</div>
@ -98,7 +98,7 @@
<div class="section-content">
{#if !todosStore.serviceAvailable}
<div class="service-unavailable">
<AlertTriangle size={16} />
<Warning size={16} />
<span>Todo-Service nicht erreichbar</span>
</div>
{:else if todosStore.loading}

View file

@ -2,7 +2,7 @@
import type { EventAttendee, AttendeeStatus } from '@calendar/shared';
import type { ContactSummary, ContactOrManual, ManualContactEntry } from '@manacore/shared-types';
import { ContactSelector, ContactAvatar } from '@manacore/shared-ui';
import { Check, X, HelpCircle, Clock, ChevronDown } from 'lucide-svelte';
import { Check, X, Question, Clock, CaretDown } from '@manacore/shared-icons';
import { contactsStore } from '$lib/stores/contacts.svelte';
interface Props {
@ -178,12 +178,12 @@
{:else if attendee.status === 'declined'}
<X size={12} />
{:else if attendee.status === 'tentative'}
<HelpCircle size={12} />
<Question size={12} />
{:else}
<Clock size={12} />
{/if}
<span class="hidden sm:inline">{getStatusLabel(attendee.status)}</span>
<ChevronDown size={12} />
<CaretDown size={12} />
</button>
{#if showStatusDropdown === attendee.email}
@ -213,7 +213,7 @@
{:else if option.value === 'declined'}
<X size={12} />
{:else if option.value === 'tentative'}
<HelpCircle size={12} />
<Question size={12} />
{:else}
<Clock size={12} />
{/if}

View file

@ -18,7 +18,7 @@
FilterDropdown,
type FilterDropdownOption,
} from '@manacore/shared-ui';
import { Users } from 'lucide-svelte';
import { Users } from '@manacore/shared-icons';
import { format, addMinutes } from 'date-fns';
import { de } from 'date-fns/locale';
import { toDate } from '$lib/utils/eventDateHelpers';

View file

@ -2,7 +2,7 @@
import type { ResponsiblePerson } from '@calendar/shared';
import type { ContactSummary, ContactOrManual, ManualContactEntry } from '@manacore/shared-types';
import { ContactSelector, ContactAvatar } from '@manacore/shared-ui';
import { X, ExternalLink } from 'lucide-svelte';
import { X, ArrowSquareOut } from '@manacore/shared-icons';
import { contactsStore } from '$lib/stores/contacts.svelte';
interface Props {
@ -139,7 +139,7 @@
"
title="Kontakt öffnen"
>
<ExternalLink size={16} />
<ArrowSquareOut size={16} />
</button>
{/if}

View file

@ -1,6 +1,6 @@
<script lang="ts">
import { todosStore } from '$lib/stores/todos.svelte';
import { Plus, X } from 'lucide-svelte';
import { Plus, X } from '@manacore/shared-icons';
interface Props {
placeholder?: string;

View file

@ -1,5 +1,5 @@
<script lang="ts">
import { Check } from 'lucide-svelte';
import { Check } from '@manacore/shared-icons';
interface Props {
checked: boolean;

View file

@ -11,12 +11,12 @@
Clock,
Folder,
Tag,
Trash2,
Trash,
CheckSquare,
AlertCircle,
CalendarClock,
WarningCircle,
CalendarCheck,
Timer,
} from 'lucide-svelte';
} from '@manacore/shared-icons';
import { format, parseISO } from 'date-fns';
import { de } from 'date-fns/locale';
@ -239,7 +239,7 @@
<!-- Time-Blocking Section -->
<div class="form-section">
<span class="section-label">
<CalendarClock size={16} />
<CalendarCheck size={16} />
Zeitplanung (Time-Blocking)
</span>
<div class="form-row">
@ -313,7 +313,7 @@
<!-- Time-Blocking Display -->
{#if task.scheduledDate}
<div class="detail-item scheduled">
<CalendarClock size={16} />
<CalendarCheck size={16} />
<span>
Geplant: {formatDisplayDate(task.scheduledDate)}
{#if task.scheduledStartTime}
@ -334,7 +334,7 @@
{/if}
<div class="detail-item">
<AlertCircle size={16} />
<WarningCircle size={16} />
<PriorityBadge {priority} variant="pill" showLabel />
</div>
@ -397,7 +397,7 @@
</button>
{:else}
<button type="button" class="btn btn-danger" onclick={handleDelete} disabled={isDeleting}>
<Trash2 size={16} />
<Trash size={16} />
{#if isDeleting}
Löschen...
{:else}

View file

@ -53,7 +53,6 @@
"d3-selection": "^3.0.0",
"d3-zoom": "^3.0.0",
"date-fns": "^4.1.0",
"lucide-svelte": "^0.556.0",
"svelte-i18n": "^4.0.1"
},
"type": "module"

View file

@ -2,7 +2,7 @@
import { _ } from 'svelte-i18n';
import { onMount } from 'svelte';
import { PillViewSwitcher, FilterDropdown, type FilterDropdownOption } from '@manacore/shared-ui';
import { X } from 'lucide-svelte';
import { X } from '@manacore/shared-icons';
import { contactsFilterStore } from '$lib/stores/filter.svelte';
import { tagsApi, type ContactTag, type Contact } from '$lib/api/contacts';
import type { ContactFilter, BirthdayFilter } from '$lib/components/FilterBar.svelte';

View file

@ -13,7 +13,7 @@ A minimal, privacy-focused Matrix client that connects to your self-hosted Synap
| Frontend | SvelteKit 2, Svelte 5 (runes), Tailwind CSS 4 |
| Matrix SDK | matrix-js-sdk |
| State Management | Svelte 5 runes ($state, $derived) |
| Icons | lucide-svelte |
| Icons | @manacore/shared-icons (Phosphor) |
| Date Handling | date-fns |
## Project Structure

View file

@ -39,7 +39,6 @@
"@manacore/shared-tailwind": "workspace:*",
"@manacore/shared-i18n": "workspace:*",
"@manacore/shared-icons": "workspace:*",
"lucide-svelte": "^0.509.0",
"date-fns": "^4.1.0",
"svelte-i18n": "^4.0.1"
}

View file

@ -1,6 +1,6 @@
<script lang="ts">
import { matrixStore } from '$lib/matrix';
import { X, Users, MessageCircle, Lock, Globe, Loader2 } from 'lucide-svelte';
import { X, Users, ChatCircle, Lock, Globe, CircleNotch } from '@manacore/shared-icons';
interface Props {
open: boolean;
@ -102,7 +102,10 @@
{#if open}
<!-- Backdrop -->
<div class="fixed inset-0 z-50 flex items-center justify-center bg-black/50" onclick={handleClose}>
<div
class="fixed inset-0 z-50 flex items-center justify-center bg-black/50"
onclick={handleClose}
>
<!-- Dialog -->
<div
class="w-full max-w-md rounded-xl bg-base-100 shadow-xl"
@ -128,7 +131,7 @@
class:btn-ghost={!isDirect}
onclick={() => (isDirect = true)}
>
<MessageCircle class="h-4 w-4" />
<ChatCircle class="h-4 w-4" />
Direktnachricht
</button>
<button
@ -182,11 +185,7 @@
Öffentlicher Raum
{/if}
</span>
<input
type="checkbox"
class="toggle"
bind:checked={isPrivate}
/>
<input type="checkbox" class="toggle" bind:checked={isPrivate} />
</label>
<p class="text-xs text-base-content/60 ml-1">
{isPrivate
@ -213,7 +212,7 @@
placeholder="@benutzer:server.de oder Name"
/>
{#if searching}
<Loader2 class="absolute right-3 top-1/2 h-4 w-4 -translate-y-1/2 animate-spin" />
<CircleNotch class="absolute right-3 top-1/2 h-4 w-4 -translate-y-1/2 animate-spin" />
{/if}
</div>
@ -222,10 +221,7 @@
<ul class="menu mt-2 max-h-40 overflow-y-auto rounded-lg bg-base-200 p-2">
{#each searchResults as user}
<li>
<button
class="flex items-center gap-2"
onclick={() => selectUser(user)}
>
<button class="flex items-center gap-2" onclick={() => selectUser(user)}>
<div class="avatar placeholder">
<div class="w-8 rounded-full bg-neutral text-neutral-content">
{#if user.avatarUrl}
@ -275,7 +271,7 @@
<button class="btn btn-ghost" onclick={handleClose}>Abbrechen</button>
<button class="btn btn-primary" onclick={handleCreate} disabled={loading}>
{#if loading}
<Loader2 class="h-4 w-4 animate-spin" />
<CircleNotch class="h-4 w-4 animate-spin" />
{/if}
{isDirect ? 'Chat starten' : 'Raum erstellen'}
</button>

View file

@ -4,17 +4,17 @@
import { format, isToday, isYesterday } from 'date-fns';
import { de } from 'date-fns/locale';
import {
Reply,
Pencil,
Trash2,
MoreHorizontal,
Download,
FileIcon,
ArrowBendUpLeft,
PencilSimple,
Trash,
DotsThree,
DownloadSimple,
File as FileIcon,
Play,
Image as ImageIcon,
Lock,
AlertTriangle,
} from 'lucide-svelte';
Warning,
} from '@manacore/shared-icons';
interface Props {
message: SimpleMessage;
@ -141,7 +141,7 @@
<div
class="mb-1 flex items-center gap-2 rounded border-l-2 border-primary/50 bg-muted px-2 py-1 text-sm"
>
<Reply class="h-3 w-3 flex-shrink-0 text-muted-foreground" />
<ArrowBendUpLeft class="h-3 w-3 flex-shrink-0 text-muted-foreground" />
<span class="truncate text-muted-foreground">{message.replyToBody}</span>
</div>
{/if}
@ -153,7 +153,7 @@
{:else if isDecryptionError}
<!-- Decryption error -->
<div class="flex items-center gap-2 rounded-lg bg-warning/10 px-3 py-2 text-warning">
<AlertTriangle class="h-4 w-4 flex-shrink-0" />
<Warning class="h-4 w-4 flex-shrink-0" />
<span class="text-sm">
Nachricht kann nicht entschlüsselt werden. Möglicherweise fehlen Schlüssel.
</span>
@ -224,7 +224,7 @@
{/if}
</p>
</div>
<Download class="h-5 w-5 flex-shrink-0 text-muted-foreground" />
<DownloadSimple class="h-5 w-5 flex-shrink-0 text-muted-foreground" />
</a>
{:else if message.type === 'm.emote'}
<p class="italic text-muted-foreground">* {message.senderName} {message.body}</p>
@ -251,16 +251,16 @@
class="absolute -top-2 right-2 flex items-center gap-1 rounded-lg border border-border bg-surface p-1 shadow-sm"
>
<button class="btn-ghost rounded p-1" title="Antworten" onclick={() => onReply?.(message)}>
<Reply class="h-4 w-4" />
<ArrowBendUpLeft class="h-4 w-4" />
</button>
{#if message.isOwn && message.type === 'm.text'}
<button class="btn-ghost rounded p-1" title="Bearbeiten" onclick={() => onEdit?.(message)}>
<Pencil class="h-4 w-4" />
<PencilSimple class="h-4 w-4" />
</button>
{/if}
{#if message.isOwn}
<button class="btn-ghost rounded p-1 text-error" title="Löschen" onclick={handleDelete}>
<Trash2 class="h-4 w-4" />
<Trash class="h-4 w-4" />
</button>
{/if}
</div>

View file

@ -1,6 +1,14 @@
<script lang="ts">
import { matrixStore, type SimpleMessage } from '$lib/matrix';
import { Send, Paperclip, Smile, X, Image, File, Loader2 } from 'lucide-svelte';
import {
PaperPlaneTilt,
Paperclip,
Smiley,
X,
Image,
File,
CircleNotch,
} from '@manacore/shared-icons';
interface Props {
replyTo?: SimpleMessage | null;
@ -163,7 +171,7 @@
<!-- Upload Progress -->
{#if uploading}
<div class="flex items-center gap-3 px-4 py-2">
<Loader2 class="h-5 w-5 animate-spin text-primary" />
<CircleNotch class="h-5 w-5 animate-spin text-primary" />
<div class="flex-1">
<div class="h-2 overflow-hidden rounded-full bg-base-300">
<div
@ -242,7 +250,7 @@
title="Emoji hinzufügen"
disabled
>
<Smile class="h-5 w-5" />
<Smiley class="h-5 w-5" />
</button>
</div>
@ -253,7 +261,7 @@
disabled={!message.trim() || uploading}
title={editMessage ? 'Speichern' : 'Senden'}
>
<Send class="h-5 w-5" />
<PaperPlaneTilt class="h-5 w-5" />
</button>
</div>

View file

@ -1,15 +1,15 @@
<script lang="ts">
import { matrixStore } from '$lib/matrix';
import {
Menu,
List,
Phone,
Video,
VideoCamera,
Info,
LockOpen,
ShieldCheck,
ShieldAlert,
ShieldWarning,
Users,
} from 'lucide-svelte';
} from '@manacore/shared-icons';
interface Props {
onMenuClick?: () => void;
@ -44,7 +44,7 @@
<header class="flex items-center gap-3 border-b border-border bg-surface px-4 py-3">
<!-- Mobile menu button -->
<button class="btn-ghost rounded p-2 lg:hidden" onclick={onMenuClick}>
<Menu class="h-5 w-5" />
<List class="h-5 w-5" />
</button>
<!-- Room avatar -->
@ -72,7 +72,7 @@
class="flex-shrink-0"
title="Verschlüsselt - {encryptionStatus.unverifiedDevices} unverifizierte Geräte"
>
<ShieldAlert class="h-4 w-4 text-warning" />
<ShieldWarning class="h-4 w-4 text-warning" />
</div>
{/if}
{:else}
@ -99,7 +99,7 @@
<Phone class="h-5 w-5" />
</button>
<button class="btn-ghost rounded p-2" title="Videoanruf" disabled>
<Video class="h-5 w-5" />
<VideoCamera class="h-5 w-5" />
</button>
<button class="btn-ghost rounded p-2" title="Rauminfo" onclick={onInfoClick}>
<Info class="h-5 w-5" />

View file

@ -2,7 +2,7 @@
import type { SimpleRoom } from '$lib/matrix';
import { formatDistanceToNow } from 'date-fns';
import { de } from 'date-fns/locale';
import { Lock, Users } from 'lucide-svelte';
import { Lock, Users } from '@manacore/shared-icons';
interface Props {
room: SimpleRoom;

View file

@ -1,7 +1,7 @@
<script lang="ts">
import { matrixStore } from '$lib/matrix';
import RoomItem from './RoomItem.svelte';
import { Search, Plus, Users, MessageCircle } from 'lucide-svelte';
import { MagnifyingGlass, Plus, Users, ChatCircle } from '@manacore/shared-icons';
interface Props {
onCreateRoom?: () => void;
@ -23,7 +23,9 @@
<!-- Search -->
<div class="p-3">
<div class="relative">
<Search class="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-base-content/50" />
<MagnifyingGlass
class="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-base-content/50"
/>
<input
type="text"
bind:value={search}
@ -36,7 +38,7 @@
<!-- Tabs -->
<div class="tabs tabs-boxed mx-3 mb-2">
<button class="tab flex-1" class:tab-active={showDMs} onclick={() => (showDMs = true)}>
<MessageCircle class="mr-1 h-4 w-4" />
<ChatCircle class="mr-1 h-4 w-4" />
Direct
{#if matrixStore.directRooms.length > 0}
<span class="badge badge-sm ml-1">{matrixStore.directRooms.length}</span>
@ -62,10 +64,10 @@
{:else}
<div class="flex flex-col items-center justify-center p-8 text-base-content/50">
{#if search}
<Search class="mb-2 h-8 w-8" />
<MagnifyingGlass class="mb-2 h-8 w-8" />
<p>No rooms match "{search}"</p>
{:else}
<MessageCircle class="mb-2 h-8 w-8" />
<ChatCircle class="mb-2 h-8 w-8" />
<p>No {showDMs ? 'direct messages' : 'rooms'} yet</p>
{/if}
</div>

View file

@ -3,15 +3,15 @@
import {
X,
Users,
Settings,
Gear,
UserPlus,
LogOut,
SignOut,
Crown,
Shield,
Bell,
BellOff,
Loader2,
} from 'lucide-svelte';
BellSlash,
CircleNotch,
} from '@manacore/shared-icons';
interface Props {
open: boolean;
@ -79,7 +79,9 @@
{#if open && room}
<!-- Slide-in Panel -->
<div class="fixed inset-y-0 right-0 z-40 flex w-80 flex-col border-l border-base-300 bg-base-100 shadow-xl">
<div
class="fixed inset-y-0 right-0 z-40 flex w-80 flex-col border-l border-base-300 bg-base-100 shadow-xl"
>
<!-- Header -->
<header class="flex items-center justify-between border-b border-base-300 px-4 py-3">
<h2 class="font-semibold">Raum-Details</h2>
@ -126,7 +128,7 @@
class:tab-active={activeTab === 'settings'}
onclick={() => (activeTab = 'settings')}
>
<Settings class="mr-1 h-4 w-4" />
<Gear class="mr-1 h-4 w-4" />
Einstellungen
</button>
</div>
@ -145,7 +147,7 @@
placeholder="Benutzer einladen..."
/>
{#if searching}
<Loader2 class="absolute right-3 top-1/2 h-4 w-4 -translate-y-1/2 animate-spin" />
<CircleNotch class="absolute right-3 top-1/2 h-4 w-4 -translate-y-1/2 animate-spin" />
{/if}
</div>
@ -215,7 +217,7 @@
<!-- Leave Room -->
<button class="btn btn-ghost w-full justify-start text-error" onclick={leaveRoom}>
<LogOut class="h-4 w-4" />
<SignOut class="h-4 w-4" />
Raum verlassen
</button>
</div>

View file

@ -3,7 +3,7 @@
import Message from './Message.svelte';
import TypingIndicator from './TypingIndicator.svelte';
import { onMount, tick } from 'svelte';
import { Loader2, ArrowDown } from 'lucide-svelte';
import { CircleNotch, ArrowDown } from '@manacore/shared-icons';
interface Props {
onReply?: (message: SimpleMessage) => void;
@ -87,7 +87,7 @@
<!-- Loading indicator at top -->
{#if loadingMore}
<div class="flex justify-center py-4">
<Loader2 class="h-6 w-6 animate-spin text-base-content/50" />
<CircleNotch class="h-6 w-6 animate-spin text-base-content/50" />
</div>
{/if}

View file

@ -1,7 +1,7 @@
<script lang="ts">
import { matrixStore } from '$lib/matrix';
import type { VerificationRequest, SasVerification } from '$lib/matrix/types';
import { Check, X, Loader2, ShieldCheck } from 'lucide-svelte';
import { Check, X, CircleNotch, ShieldCheck } from '@manacore/shared-icons';
interface Props {
request: VerificationRequest;
@ -82,7 +82,7 @@
<div class="space-y-6">
{#if phase === 'waiting'}
<div class="flex flex-col items-center gap-4 py-8">
<Loader2 class="h-12 w-12 animate-spin text-primary" />
<CircleNotch class="h-12 w-12 animate-spin text-primary" />
<p class="text-center text-muted-foreground">Warte auf Antwort vom anderen Gerät...</p>
<p class="text-sm text-muted-foreground/70">
Öffne die Verifizierungsanfrage auf deinem anderen Gerät.
@ -128,7 +128,7 @@
</div>
{:else if phase === 'confirming'}
<div class="flex flex-col items-center gap-4 py-8">
<Loader2 class="h-12 w-12 animate-spin text-primary" />
<CircleNotch class="h-12 w-12 animate-spin text-primary" />
<p class="text-center text-muted-foreground">Bestätige Verifizierung...</p>
</div>
{:else if phase === 'done'}

View file

@ -4,13 +4,13 @@
import {
X,
Key,
Download,
DownloadSimple,
Copy,
Check,
Loader2,
AlertTriangle,
CircleNotch,
Warning,
ShieldCheck,
} from 'lucide-svelte';
} from '@manacore/shared-icons';
interface Props {
open: boolean;
@ -185,7 +185,7 @@
</p>
<div class="flex items-start gap-3 rounded-lg bg-warning/10 p-3 text-warning">
<AlertTriangle class="h-5 w-5 flex-shrink-0 mt-0.5" />
<Warning class="h-5 w-5 flex-shrink-0 mt-0.5" />
<span class="text-sm">
Ohne Recovery Key verlierst du den Zugriff auf deine verschlüsselten Nachrichten,
wenn du dich abmeldest.
@ -267,7 +267,7 @@
{:else if step === 'show-key'}
<div class="space-y-4">
<div class="flex items-start gap-3 rounded-lg bg-warning/10 p-3 text-warning">
<AlertTriangle class="h-5 w-5 flex-shrink-0 mt-0.5" />
<Warning class="h-5 w-5 flex-shrink-0 mt-0.5" />
<span class="text-sm">
Speichere diesen Schlüssel an einem sicheren Ort. Du benötigst ihn, um deine
Nachrichten wiederherzustellen.
@ -298,7 +298,7 @@
class="btn-secondary flex-1 flex items-center justify-center gap-2"
onclick={downloadKey}
>
<Download class="h-4 w-4" />
<DownloadSimple class="h-4 w-4" />
Herunterladen
</button>
</div>
@ -333,7 +333,7 @@
disabled={loading}
>
{#if loading}
<Loader2 class="h-4 w-4 animate-spin" />
<CircleNotch class="h-4 w-4 animate-spin" />
{/if}
Weiter
</button>
@ -344,7 +344,7 @@
disabled={loading || !inputRecoveryKey.trim()}
>
{#if loading}
<Loader2 class="h-4 w-4 animate-spin" />
<CircleNotch class="h-4 w-4 animate-spin" />
{/if}
Wiederherstellen
</button>
@ -357,7 +357,7 @@
disabled={loading || !passphrase || passphrase !== passphraseConfirm}
>
{#if loading}
<Loader2 class="h-4 w-4 animate-spin" />
<CircleNotch class="h-4 w-4 animate-spin" />
{/if}
Schlüssel erstellen
</button>

View file

@ -6,12 +6,12 @@
X,
Shield,
ShieldCheck,
ShieldAlert,
Smartphone,
ShieldWarning,
DeviceMobile,
Monitor,
Loader2,
RefreshCw,
} from 'lucide-svelte';
CircleNotch,
ArrowsClockwise,
} from '@manacore/shared-icons';
import EmojiVerification from './EmojiVerification.svelte';
interface Props {
@ -98,7 +98,7 @@
name.includes('android') ||
name.includes('ios')
) {
return Smartphone;
return DeviceMobile;
}
return Monitor;
}
@ -151,7 +151,7 @@
{#if loading}
<div class="flex justify-center py-8">
<Loader2 class="h-8 w-8 animate-spin text-primary" />
<CircleNotch class="h-8 w-8 animate-spin text-primary" />
</div>
{:else if devices.length === 0}
<div class="py-8 text-center text-muted-foreground">
@ -175,12 +175,12 @@
{:else if device.blocked}
<div class="relative">
<DeviceIcon class="h-10 w-10 text-muted-foreground" />
<ShieldAlert class="absolute -right-1 -bottom-1 h-5 w-5 text-error" />
<ShieldWarning class="absolute -right-1 -bottom-1 h-5 w-5 text-error" />
</div>
{:else}
<div class="relative">
<DeviceIcon class="h-10 w-10 text-muted-foreground" />
<ShieldAlert class="absolute -right-1 -bottom-1 h-5 w-5 text-warning" />
<ShieldWarning class="absolute -right-1 -bottom-1 h-5 w-5 text-warning" />
</div>
{/if}
</div>
@ -225,7 +225,7 @@
onclick={loadDevices}
disabled={loading}
>
<RefreshCw class={`h-4 w-4 ${loading ? 'animate-spin' : ''}`} />
<ArrowsClockwise class={`h-4 w-4 ${loading ? 'animate-spin' : ''}`} />
Aktualisieren
</button>
</div>

View file

@ -3,7 +3,7 @@
import { goto } from '$app/navigation';
import { onMount, onDestroy } from 'svelte';
import type { Snippet } from 'svelte';
import { Loader2, AlertCircle, RefreshCw } from 'lucide-svelte';
import { CircleNotch, WarningCircle, ArrowsClockwise } from '@manacore/shared-icons';
interface Props {
children: Snippet;
@ -60,7 +60,7 @@
{#if loading}
<!-- Loading State -->
<div class="flex h-screen flex-col items-center justify-center gap-4">
<Loader2 class="h-12 w-12 animate-spin text-primary" />
<CircleNotch class="h-12 w-12 animate-spin text-primary" />
<div class="text-center">
<p class="font-medium">Connecting to Matrix...</p>
<p class="text-sm text-base-content/60">
@ -80,7 +80,7 @@
<!-- Error State -->
<div class="flex h-screen flex-col items-center justify-center gap-4 p-4">
<div class="rounded-full bg-error/10 p-4">
<AlertCircle class="h-12 w-12 text-error" />
<WarningCircle class="h-12 w-12 text-error" />
</div>
<div class="text-center">
<h2 class="text-xl font-semibold">Connection Failed</h2>
@ -88,7 +88,7 @@
</div>
<div class="flex gap-2">
<button class="btn btn-primary" onclick={retry}>
<RefreshCw class="h-4 w-4" />
<ArrowsClockwise class="h-4 w-4" />
Retry
</button>
<button class="btn btn-ghost" onclick={logout}> Sign Out </button>

View file

@ -4,7 +4,7 @@
import CreateRoomDialog from '$lib/components/chat/CreateRoomDialog.svelte';
import RoomSettingsPanel from '$lib/components/chat/RoomSettingsPanel.svelte';
import { goto } from '$app/navigation';
import { Settings, LogOut, MessageSquare, Plus } from 'lucide-svelte';
import { Gear, SignOut, ChatCircle, Plus } from '@manacore/shared-icons';
let sidebarOpen = $state(true);
let showCreateRoom = $state(false);
@ -48,7 +48,7 @@
<!-- Sidebar Header -->
<header class="flex items-center justify-between border-b border-base-300 p-4">
<div class="flex items-center gap-2">
<MessageSquare class="h-6 w-6 text-primary" />
<ChatCircle class="h-6 w-6 text-primary" />
<h1 class="text-xl font-bold">Mana Matrix</h1>
</div>
<div class="flex items-center gap-1">
@ -61,7 +61,7 @@
</button>
<div class="dropdown dropdown-end">
<button tabindex="0" class="btn btn-ghost btn-sm btn-circle">
<Settings class="h-5 w-5" />
<Gear class="h-5 w-5" />
</button>
<ul
tabindex="0"
@ -69,13 +69,13 @@
>
<li>
<a href="/settings">
<Settings class="h-4 w-4" />
<Gear class="h-4 w-4" />
Einstellungen
</a>
</li>
<li>
<button onclick={handleLogout} class="text-error">
<LogOut class="h-4 w-4" />
<SignOut class="h-4 w-4" />
Abmelden
</button>
</li>
@ -121,7 +121,7 @@
{:else}
<!-- No Room Selected -->
<div class="flex flex-1 flex-col items-center justify-center gap-4 p-8 text-base-content/50">
<MessageSquare class="h-16 w-16" />
<ChatCircle class="h-16 w-16" />
<div class="text-center">
<h2 class="text-xl font-semibold text-base-content">Willkommen bei Mana Matrix</h2>
<p class="mt-2">

View file

@ -7,14 +7,14 @@
Bell,
Palette,
Shield,
LogOut,
Server,
SignOut,
HardDrive,
ShieldCheck,
ShieldAlert,
ShieldWarning,
Key,
Smartphone,
Loader2,
} from 'lucide-svelte';
DeviceMobile,
CircleNotch,
} from '@manacore/shared-icons';
import { VerificationDialog, RecoveryKeyDialog } from '$lib/components/crypto';
let verificationDialogOpen = $state(false);
@ -77,7 +77,7 @@
<section class="card">
<div class="space-y-4">
<h2 class="flex items-center gap-2 text-lg font-semibold">
<Server class="h-5 w-5" />
<HardDrive class="h-5 w-5" />
Server
</h2>
<div class="space-y-2 text-sm">
@ -109,7 +109,7 @@
{#if !cryptoReady}
<div class="flex items-center gap-3 text-warning">
<Loader2 class="h-5 w-5 animate-spin" />
<CircleNotch class="h-5 w-5 animate-spin" />
<span>Verschlüsselung wird initialisiert...</span>
</div>
{:else}
@ -120,7 +120,7 @@
{#if verificationStatus === 'verified'}
<ShieldCheck class="h-8 w-8 text-success" />
{:else}
<ShieldAlert class="h-8 w-8 text-warning" />
<ShieldWarning class="h-8 w-8 text-warning" />
{/if}
<div>
<p class="font-medium">
@ -137,7 +137,7 @@
class="btn-primary flex items-center gap-2 text-sm"
onclick={() => (verificationDialogOpen = true)}
>
<Smartphone class="h-4 w-4" />
<DeviceMobile class="h-4 w-4" />
Geräte
</button>
</div>
@ -208,7 +208,7 @@
class="flex w-full items-center justify-center gap-2 rounded-lg bg-error p-3 text-white hover:brightness-90"
onclick={handleLogout}
>
<LogOut class="h-5 w-5" />
<SignOut class="h-5 w-5" />
Abmelden
</button>
</section>

View file

@ -2,7 +2,16 @@
import { goto } from '$app/navigation';
import { browser } from '$app/environment';
import { loginWithPassword, discoverHomeserver, checkHomeserver, matrixStore } from '$lib/matrix';
import { Eye, EyeOff, Loader2, Server, User, Lock, AlertCircle, LogIn } from 'lucide-svelte';
import {
Eye,
EyeSlash,
CircleNotch,
HardDrive,
User,
Lock,
WarningCircle,
SignIn,
} from '@manacore/shared-icons';
// Form state
let homeserver = $state('matrix.mana.how');
@ -100,7 +109,7 @@
<!-- Error Alert -->
{#if error}
<div class="alert alert-error mb-4">
<AlertCircle class="h-5 w-5" />
<WarningCircle class="h-5 w-5" />
<span>{error}</span>
</div>
{/if}
@ -111,12 +120,12 @@
<div class="form-control">
<label class="label" for="homeserver">
<span class="label-text flex items-center gap-2">
<Server class="h-4 w-4" />
<HardDrive class="h-4 w-4" />
Homeserver
</span>
{#if checkingServer}
<span class="label-text-alt">
<Loader2 class="h-4 w-4 animate-spin" />
<CircleNotch class="h-4 w-4 animate-spin" />
</span>
{:else if serverValid === true}
<span class="label-text-alt text-success">Connected</span>
@ -182,7 +191,7 @@
tabindex={-1}
>
{#if showPassword}
<EyeOff class="h-5 w-5" />
<EyeSlash class="h-5 w-5" />
{:else}
<Eye class="h-5 w-5" />
{/if}
@ -193,7 +202,7 @@
<!-- Submit Button -->
<button type="submit" class="btn btn-primary w-full" disabled={loading}>
{#if loading}
<Loader2 class="h-5 w-5 animate-spin" />
<CircleNotch class="h-5 w-5 animate-spin" />
Signing in...
{:else}
Sign In
@ -212,10 +221,10 @@
disabled={loadingSSO}
>
{#if loadingSSO}
<Loader2 class="h-5 w-5 animate-spin" />
<CircleNotch class="h-5 w-5 animate-spin" />
Redirecting...
{:else}
<LogIn class="h-5 w-5" />
<SignIn class="h-5 w-5" />
Sign in with Mana Core
{/if}
</button>

View file

@ -3,7 +3,7 @@
import { onMount } from 'svelte';
import { browser } from '$app/environment';
import { matrixStore } from '$lib/matrix';
import { Loader2 } from 'lucide-svelte';
import { CircleNotch } from '@manacore/shared-icons';
let checking = $state(true);
@ -27,7 +27,7 @@
<div class="flex h-screen items-center justify-center">
<div class="text-center">
<Loader2 class="mx-auto h-8 w-8 animate-spin text-primary" />
<CircleNotch class="mx-auto h-8 w-8 animate-spin text-primary" />
<p class="mt-4 text-base-content/60">Loading...</p>
</div>
</div>

View file

@ -52,7 +52,6 @@
"@manacore/shared-ui": "workspace:*",
"@manacore/shared-utils": "workspace:*",
"date-fns": "^4.1.0",
"lucide-svelte": "^0.559.0",
"svelte-i18n": "^4.0.1"
},
"type": "module"

View file

@ -1,5 +1,5 @@
<script lang="ts">
import { Camera, PenLine, Plus, X } from 'lucide-svelte';
import { Camera, PencilLine, Plus, X } from '@manacore/shared-icons';
import { goto } from '$app/navigation';
let isOpen = $state(false);
@ -43,7 +43,7 @@
onclick={handleText}
class="flex items-center gap-3 px-5 py-3 bg-[var(--color-background-card)] border border-[var(--color-border)] rounded-full shadow-lg hover:bg-[var(--color-background-elevated)] transition-all"
>
<PenLine class="w-5 h-5 text-[var(--color-secondary)]" />
<PencilLine class="w-5 h-5 text-[var(--color-secondary)]" />
<span class="text-[var(--color-text-primary)] font-medium">Text</span>
</button>
</div>

View file

@ -2,7 +2,7 @@
import { mealsStore } from '$lib/stores/meals.svelte';
import { onMount } from 'svelte';
import ProgressRing from './ProgressRing.svelte';
import { AlertCircle, RefreshCw } from 'lucide-svelte';
import { WarningCircle, ArrowsClockwise } from '@manacore/shared-icons';
onMount(() => {
mealsStore.fetchDailySummary();
@ -30,10 +30,10 @@
<div
class="bg-red-500/10 border border-red-500/20 rounded-xl p-3 flex items-center gap-2 text-red-400 text-sm"
>
<AlertCircle class="w-4 h-4 flex-shrink-0" />
<WarningCircle class="w-4 h-4 flex-shrink-0" />
<span class="flex-1">{mealsStore.summaryError}</span>
<button onclick={retry} class="p-1 hover:bg-red-500/20 rounded transition-colors">
<RefreshCw class="w-4 h-4" />
<ArrowsClockwise class="w-4 h-4" />
</button>
</div>
{:else if mealsStore.summaryLoading}

View file

@ -1,5 +1,5 @@
<script lang="ts">
import { Settings } from 'lucide-svelte';
import { Gear } from '@manacore/shared-icons';
</script>
<header
@ -19,7 +19,7 @@
class="p-2 rounded-lg hover:bg-[var(--color-background-card)] transition-colors"
title="Einstellungen"
>
<Settings class="w-5 h-5 text-[var(--color-text-secondary)]" />
<Gear class="w-5 h-5 text-[var(--color-text-secondary)]" />
</a>
</div>
</div>

View file

@ -2,7 +2,14 @@
import { mealsStore } from '$lib/stores/meals.svelte';
import { onMount } from 'svelte';
import { MEAL_TYPE_LABELS } from '@nutriphi/shared';
import { Trash2, Camera, PenLine, AlertCircle, RefreshCw, Loader2 } from 'lucide-svelte';
import {
Trash,
Camera,
PencilLine,
WarningCircle,
ArrowsClockwise,
CircleNotch,
} from '@manacore/shared-icons';
let deleting = $state<string | null>(null);
@ -34,10 +41,10 @@
<div
class="bg-red-500/10 border border-red-500/20 rounded-xl p-4 flex items-center gap-3 text-red-400"
>
<AlertCircle class="w-5 h-5 flex-shrink-0" />
<WarningCircle class="w-5 h-5 flex-shrink-0" />
<span class="flex-1 text-sm">{mealsStore.error}</span>
<button onclick={retry} class="p-2 hover:bg-red-500/20 rounded-lg transition-colors">
<RefreshCw class="w-4 h-4" />
<ArrowsClockwise class="w-4 h-4" />
</button>
</div>
{/if}
@ -46,7 +53,7 @@
<div
class="bg-red-500/10 border border-red-500/20 rounded-xl p-3 flex items-center gap-2 text-red-400 text-sm"
>
<AlertCircle class="w-4 h-4 flex-shrink-0" />
<WarningCircle class="w-4 h-4 flex-shrink-0" />
<span>{mealsStore.deleteError}</span>
</div>
{/if}
@ -71,7 +78,7 @@
{#if meal.inputType === 'photo'}
<Camera class="w-4 h-4 text-[var(--color-text-muted)]" />
{:else}
<PenLine class="w-4 h-4 text-[var(--color-text-muted)]" />
<PencilLine class="w-4 h-4 text-[var(--color-text-muted)]" />
{/if}
<span class="text-xs text-[var(--color-text-muted)] uppercase tracking-wide">
{MEAL_TYPE_LABELS[meal.mealType as keyof typeof MEAL_TYPE_LABELS]?.de ??
@ -104,9 +111,9 @@
class="p-2 rounded-lg hover:bg-[var(--color-background-elevated)] text-[var(--color-text-muted)] hover:text-red-400 transition-colors disabled:opacity-50"
>
{#if deleting === meal.id}
<Loader2 class="w-4 h-4 animate-spin" />
<CircleNotch class="w-4 h-4 animate-spin" />
{:else}
<Trash2 class="w-4 h-4" />
<Trash class="w-4 h-4" />
{/if}
</button>
</div>

View file

@ -5,7 +5,7 @@
import DailySummary from '$lib/components/DailySummary.svelte';
import MealList from '$lib/components/MealList.svelte';
import AddMealButton from '$lib/components/AddMealButton.svelte';
import { Camera, PenLine } from 'lucide-svelte';
import { Camera, PencilLine } from '@manacore/shared-icons';
// Redirect to login if not authenticated
$effect(() => {

View file

@ -6,7 +6,7 @@
import { apiClient } from '$lib/api/client';
import { suggestMealType, MEAL_TYPE_LABELS } from '@nutriphi/shared';
import type { AIAnalysisResult } from '@nutriphi/shared';
import { Camera, ArrowLeft, Loader2, Check, AlertCircle, X } from 'lucide-svelte';
import { Camera, ArrowLeft, CircleNotch, Check, WarningCircle, X } from '@manacore/shared-icons';
let inputType = $derived($page.url.searchParams.get('type') || 'photo');
let mealType = $state(suggestMealType());
@ -180,7 +180,7 @@
<div
class="bg-red-500/10 border border-red-500/20 rounded-xl p-3 mb-4 flex items-center gap-2 text-red-400"
>
<AlertCircle class="w-4 h-4 flex-shrink-0" />
<WarningCircle class="w-4 h-4 flex-shrink-0" />
<span class="flex-1 text-sm">{error}</span>
<button
onclick={() => (error = '')}
@ -201,7 +201,7 @@
class="w-full py-3 bg-[var(--color-primary)] hover:bg-[var(--color-primary-hover)] text-white font-medium rounded-xl transition-colors disabled:opacity-50 flex items-center justify-center gap-2"
>
{#if analyzing}
<Loader2 class="w-5 h-5 animate-spin" />
<CircleNotch class="w-5 h-5 animate-spin" />
Analysiere...
{:else}
Analysieren
@ -273,7 +273,7 @@
class="w-full py-3 bg-[var(--color-primary)] hover:bg-[var(--color-primary-hover)] text-white font-medium rounded-xl transition-colors disabled:opacity-50 flex items-center justify-center gap-2"
>
{#if saving}
<Loader2 class="w-5 h-5 animate-spin" />
<CircleNotch class="w-5 h-5 animate-spin" />
Speichern...
{:else}
<Check class="w-5 h-5" />

View file

@ -4,7 +4,15 @@
import { authStore } from '$lib/stores/auth.svelte';
import { apiClient } from '$lib/api/client';
import { DEFAULT_DAILY_VALUES } from '@nutriphi/shared';
import { ArrowLeft, Save, Loader2, AlertCircle, LogOut, User, Target } from 'lucide-svelte';
import {
ArrowLeft,
FloppyDisk,
CircleNotch,
WarningCircle,
SignOut,
User,
Target,
} from '@manacore/shared-icons';
interface UserGoals {
dailyCalories: number;
@ -117,7 +125,7 @@
onclick={handleLogout}
class="w-full py-2.5 px-4 bg-[var(--color-background-elevated)] hover:bg-red-500/20 text-[var(--color-text-secondary)] hover:text-red-400 font-medium rounded-lg transition-colors flex items-center justify-center gap-2"
>
<LogOut class="w-4 h-4" />
<SignOut class="w-4 h-4" />
Abmelden
</button>
</section>
@ -140,7 +148,7 @@
{#if loading}
<div class="flex items-center justify-center py-8">
<Loader2 class="w-6 h-6 animate-spin text-[var(--color-text-muted)]" />
<CircleNotch class="w-6 h-6 animate-spin text-[var(--color-text-muted)]" />
</div>
{:else}
<div class="space-y-4">
@ -238,7 +246,7 @@
<div
class="bg-red-500/10 border border-red-500/20 rounded-lg p-3 flex items-center gap-2 text-red-400 text-sm"
>
<AlertCircle class="w-4 h-4 flex-shrink-0" />
<WarningCircle class="w-4 h-4 flex-shrink-0" />
<span>{error}</span>
</div>
{/if}
@ -257,10 +265,10 @@
class="w-full py-3 bg-[var(--color-primary)] hover:bg-[var(--color-primary-hover)] text-white font-medium rounded-lg transition-colors disabled:opacity-50 flex items-center justify-center gap-2"
>
{#if saving}
<Loader2 class="w-5 h-5 animate-spin" />
<CircleNotch class="w-5 h-5 animate-spin" />
Speichern...
{:else}
<Save class="w-5 h-5" />
<FloppyDisk class="w-5 h-5" />
Ziele speichern
{/if}
</button>

View file

@ -43,7 +43,6 @@
"@manacore/shared-theme": "workspace:*",
"@manacore/shared-theme-ui": "workspace:*",
"@manacore/shared-ui": "workspace:*",
"lucide-svelte": "^0.460.0",
"svelte-i18n": "^4.0.1"
},
"type": "module"

View file

@ -3,7 +3,14 @@
import { goto } from '$app/navigation';
import { decksStore } from '$lib/stores/decks.svelte';
import { PageHeader } from '@manacore/shared-ui';
import { Plus, Presentation, Trash2, MoreVertical, Clock, Layers } from 'lucide-svelte';
import {
Plus,
Presentation,
Trash,
DotsThreeVertical,
Clock,
Stack,
} from '@manacore/shared-icons';
let showCreateModal = $state(false);
let showDeleteModal = $state(false);
@ -132,7 +139,7 @@
class="p-2 text-slate-400 hover:text-red-600 hover:bg-red-50 dark:hover:bg-red-900/30 rounded-lg transition-colors opacity-0 group-hover:opacity-100"
aria-label="Delete deck"
>
<Trash2 class="w-4 h-4" />
<Trash class="w-4 h-4" />
</button>
</div>
</div>

View file

@ -11,22 +11,22 @@
ArrowLeft,
Play,
Plus,
Trash2,
GripVertical,
ChevronUp,
ChevronDown,
Trash,
DotsSixVertical,
CaretUp,
CaretDown,
Image,
Type,
TextT,
List,
Edit3,
PencilSimple,
X,
Save,
Share2,
FloppyDisk,
ShareNetwork,
Link,
Copy,
Check,
ExternalLink,
} from 'lucide-svelte';
ArrowSquareOut,
} from '@manacore/shared-icons';
let showSlideModal = $state(false);
let editingSlide = $state<Slide | null>(null);
@ -250,7 +250,7 @@
onclick={openShareModal}
class="flex items-center gap-2 px-4 py-2 bg-slate-100 dark:bg-slate-700 hover:bg-slate-200 dark:hover:bg-slate-600 text-slate-700 dark:text-slate-200 font-medium rounded-lg transition-colors"
>
<Share2 class="w-5 h-5" />
<ShareNetwork class="w-5 h-5" />
Share
</button>
{#if decksStore.currentSlides.length > 0}
@ -271,7 +271,7 @@
<div
class="mx-auto w-16 h-16 bg-slate-100 dark:bg-slate-800 rounded-full flex items-center justify-center mb-4"
>
<Type class="w-8 h-8 text-slate-400" />
<TextT class="w-8 h-8 text-slate-400" />
</div>
<h2 class="text-lg font-medium text-slate-900 dark:text-white mb-2">No slides yet</h2>
<p class="text-slate-600 dark:text-slate-400 mb-4">Add your first slide to get started</p>
@ -339,7 +339,7 @@
class="p-1.5 hover:bg-slate-100 dark:hover:bg-slate-700 rounded disabled:opacity-30"
aria-label="Move up"
>
<ChevronUp class="w-4 h-4 text-slate-600 dark:text-slate-400" />
<CaretUp class="w-4 h-4 text-slate-600 dark:text-slate-400" />
</button>
<button
onclick={() => moveSlide(slide, 'down')}
@ -347,21 +347,21 @@
class="p-1.5 hover:bg-slate-100 dark:hover:bg-slate-700 rounded disabled:opacity-30"
aria-label="Move down"
>
<ChevronDown class="w-4 h-4 text-slate-600 dark:text-slate-400" />
<CaretDown class="w-4 h-4 text-slate-600 dark:text-slate-400" />
</button>
<button
onclick={() => openEditSlide(slide)}
class="p-1.5 hover:bg-slate-100 dark:hover:bg-slate-700 rounded"
aria-label="Edit"
>
<Edit3 class="w-4 h-4 text-slate-600 dark:text-slate-400" />
<PencilSimple class="w-4 h-4 text-slate-600 dark:text-slate-400" />
</button>
<button
onclick={() => confirmDeleteSlide(slide)}
class="p-1.5 hover:bg-red-50 dark:hover:bg-red-900/30 rounded"
aria-label="Delete"
>
<Trash2 class="w-4 h-4 text-red-500" />
<Trash class="w-4 h-4 text-red-500" />
</button>
</div>
</div>
@ -517,7 +517,7 @@
disabled={isSaving}
class="flex items-center gap-2 px-4 py-2 bg-primary-600 hover:bg-primary-700 text-white font-medium rounded-lg transition-colors disabled:opacity-50"
>
<Save class="w-4 h-4" />
<FloppyDisk class="w-4 h-4" />
{isSaving ? 'Saving...' : 'Save'}
</button>
</div>
@ -564,7 +564,7 @@
>
<div class="flex items-center gap-3">
<div class="p-2 bg-primary-100 dark:bg-primary-900/30 rounded-lg">
<Share2 class="w-5 h-5 text-primary-600 dark:text-primary-400" />
<ShareNetwork class="w-5 h-5 text-primary-600 dark:text-primary-400" />
</div>
<h2 class="text-xl font-semibold text-slate-900 dark:text-white">Share Presentation</h2>
</div>
@ -624,7 +624,7 @@
class="p-2 hover:bg-slate-200 dark:hover:bg-slate-600 rounded-lg transition-colors"
title="Open in new tab"
>
<ExternalLink class="w-4 h-4 text-slate-600 dark:text-slate-400" />
<ArrowSquareOut class="w-4 h-4 text-slate-600 dark:text-slate-400" />
</a>
<button
onclick={() => copyShareLink(share)}
@ -642,7 +642,7 @@
class="p-2 hover:bg-red-50 dark:hover:bg-red-900/30 rounded-lg transition-colors"
title="Delete link"
>
<Trash2 class="w-4 h-4 text-red-500" />
<Trash class="w-4 h-4 text-red-500" />
</button>
</div>
</div>

View file

@ -6,16 +6,16 @@
import type { Slide } from '@presi/shared';
import {
X,
ChevronLeft,
ChevronRight,
CaretLeft,
CaretRight,
Play,
Pause,
Eye,
EyeOff,
Maximize,
Minimize,
EyeSlash,
ArrowsOut,
ArrowsIn,
Clock,
} from 'lucide-svelte';
} from '@manacore/shared-icons';
let currentSlideIndex = $state(0);
let isFullscreen = $state(false);
@ -248,7 +248,7 @@
class="p-3 hover:bg-white/10 rounded-lg transition-colors disabled:opacity-30"
aria-label="Previous slide"
>
<ChevronLeft class="w-6 h-6" />
<CaretLeft class="w-6 h-6" />
</button>
<!-- Slide Dots -->
@ -271,7 +271,7 @@
class="p-3 hover:bg-white/10 rounded-lg transition-colors disabled:opacity-30"
aria-label="Next slide"
>
<ChevronRight class="w-6 h-6" />
<CaretRight class="w-6 h-6" />
</button>
</div>
@ -283,7 +283,7 @@
aria-label={showNotes ? 'Hide notes' : 'Show notes'}
>
{#if showNotes}
<EyeOff class="w-5 h-5" />
<EyeSlash class="w-5 h-5" />
{:else}
<Eye class="w-5 h-5" />
{/if}
@ -294,9 +294,9 @@
aria-label={isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen'}
>
{#if isFullscreen}
<Minimize class="w-5 h-5" />
<ArrowsIn class="w-5 h-5" />
{:else}
<Maximize class="w-5 h-5" />
<ArrowsOut class="w-5 h-5" />
{/if}
</button>
</div>

View file

@ -5,7 +5,7 @@
import { auth } from '$lib/stores/auth.svelte';
import { decksStore } from '$lib/stores/decks.svelte';
import { goto } from '$app/navigation';
import { FolderOpen, Layers, Calendar } from 'lucide-svelte';
import { FolderOpen, Stack, Calendar } from '@manacore/shared-icons';
let isLoading = $state(true);
@ -87,7 +87,7 @@
</div>
<div class="text-center p-4 bg-black/5 dark:bg-white/5 rounded-xl">
<div class="flex justify-center mb-2">
<Layers class="w-6 h-6 text-primary" />
<Stack class="w-6 h-6 text-primary" />
</div>
<div class="text-2xl font-bold text-foreground">-</div>
<div class="text-sm text-muted-foreground">Folien</div>

View file

@ -4,16 +4,16 @@
import { shareApi } from '$lib/api/client';
import type { Slide } from '@presi/shared';
import {
ChevronLeft,
ChevronRight,
CaretLeft,
CaretRight,
Play,
Pause,
Maximize,
Minimize,
ArrowsOut,
ArrowsIn,
Clock,
Presentation,
AlertCircle,
} from 'lucide-svelte';
WarningCircle,
} from '@manacore/shared-icons';
let deck = $state<any>(null);
let slides = $state<Slide[]>([]);
@ -151,7 +151,7 @@
{:else if error}
<div class="flex-1 flex flex-col items-center justify-center px-4">
<div class="p-4 bg-red-900/30 rounded-full mb-4">
<AlertCircle class="w-12 h-12 text-red-400" />
<WarningCircle class="w-12 h-12 text-red-400" />
</div>
<h1 class="text-2xl font-bold mb-2">Unable to load presentation</h1>
<p class="text-slate-400 text-center max-w-md mb-6">{error}</p>
@ -257,7 +257,7 @@
class="p-3 hover:bg-white/10 rounded-lg transition-colors disabled:opacity-30"
aria-label="Previous slide"
>
<ChevronLeft class="w-6 h-6" />
<CaretLeft class="w-6 h-6" />
</button>
<!-- Slide Dots -->
@ -280,7 +280,7 @@
class="p-3 hover:bg-white/10 rounded-lg transition-colors disabled:opacity-30"
aria-label="Next slide"
>
<ChevronRight class="w-6 h-6" />
<CaretRight class="w-6 h-6" />
</button>
</div>
@ -292,9 +292,9 @@
aria-label={isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen'}
>
{#if isFullscreen}
<Minimize class="w-5 h-5" />
<ArrowsIn class="w-5 h-5" />
{:else}
<Maximize class="w-5 h-5" />
<ArrowsOut class="w-5 h-5" />
{/if}
</button>
</div>

View file

@ -41,7 +41,6 @@
"@manacore/shared-theme-ui": "workspace:*",
"@manacore/shared-ui": "workspace:*",
"date-fns": "^4.1.0",
"lucide-svelte": "^0.556.0",
"svelte-i18n": "^4.0.1"
},
"type": "module"

View file

@ -1,5 +1,5 @@
<script lang="ts">
import { X } from 'lucide-svelte';
import { X } from '@manacore/shared-icons';
import { collectionsStore } from '$lib/stores';
import type { Collection, CreateCollectionDto, UpdateCollectionDto } from '$lib/types';

View file

@ -1,5 +1,5 @@
<script lang="ts">
import { AlertCircle, X, RefreshCw } from 'lucide-svelte';
import { WarningCircle, X, ArrowsClockwise } from '@manacore/shared-icons';
interface Props {
message: string;
@ -14,7 +14,7 @@
class="flex items-start gap-3 rounded-lg border border-destructive/20 bg-destructive/10 p-4"
role="alert"
>
<AlertCircle class="mt-0.5 h-5 w-5 flex-shrink-0 text-destructive" />
<WarningCircle class="mt-0.5 h-5 w-5 flex-shrink-0 text-destructive" />
<div class="flex-1">
<p class="text-sm font-medium text-destructive">Error</p>
@ -25,7 +25,7 @@
onclick={onRetry}
class="mt-2 inline-flex items-center gap-1 text-sm font-medium text-primary hover:underline"
>
<RefreshCw class="h-4 w-4" />
<ArrowsClockwise class="h-4 w-4" />
Try again
</button>
{/if}

View file

@ -4,16 +4,16 @@
import { authStore, collectionsStore, questionsStore } from '$lib/stores';
import { apiClient } from '$lib/api/client';
import {
Search,
MagnifyingGlass,
Plus,
FolderOpen,
Settings,
LogOut,
Gear,
SignOut,
Moon,
Sun,
HelpCircle,
ChevronRight,
} from 'lucide-svelte';
Question,
CaretRight,
} from '@manacore/shared-icons';
import { theme } from '$lib/stores/theme';
let { children } = $props();
@ -65,7 +65,7 @@
onclick={() => (sidebarOpen = !sidebarOpen)}
class="rounded-lg p-2 text-muted-foreground hover:bg-secondary"
>
<ChevronRight class="h-5 w-5 transition-transform" class:rotate-180={sidebarOpen} />
<CaretRight class="h-5 w-5 transition-transform" class:rotate-180={sidebarOpen} />
</button>
</div>
@ -89,7 +89,7 @@
class="collection-item flex w-full items-center gap-3 rounded-lg px-3 py-2 text-foreground"
class:active={!collectionsStore.selectedId}
>
<HelpCircle class="h-5 w-5" />
<Question class="h-5 w-5" />
{#if sidebarOpen}
<span>All Questions</span>
<span class="ml-auto text-xs text-muted-foreground">{questionsStore.total}</span>
@ -111,7 +111,8 @@
<FolderOpen class="h-5 w-5" style="color: {collection.color}" />
{#if sidebarOpen}
<span class="truncate">{collection.name}</span>
<span class="ml-auto text-xs text-muted-foreground">{collection.questionCount || 0}</span
<span class="ml-auto text-xs text-muted-foreground"
>{collection.questionCount || 0}</span
>
{/if}
</button>
@ -148,7 +149,7 @@
href="/settings"
class="flex items-center gap-3 rounded-lg px-3 py-2 text-muted-foreground hover:bg-secondary hover:text-foreground"
>
<Settings class="h-5 w-5" />
<Gear class="h-5 w-5" />
{#if sidebarOpen}
<span>Settings</span>
{/if}
@ -158,7 +159,7 @@
onclick={handleSignOut}
class="flex w-full items-center gap-3 rounded-lg px-3 py-2 text-muted-foreground hover:bg-secondary hover:text-foreground"
>
<LogOut class="h-5 w-5" />
<SignOut class="h-5 w-5" />
{#if sidebarOpen}
<span>Sign Out</span>
{/if}

View file

@ -1,7 +1,14 @@
<script lang="ts">
import { questionsStore, collectionsStore } from '$lib/stores';
import { QuestionSkeleton, ErrorAlert } from '$lib/components';
import { Search, Filter, Clock, CheckCircle, Loader2, Archive } from 'lucide-svelte';
import {
MagnifyingGlass,
Funnel,
Clock,
CheckCircle,
CircleNotch,
Archive,
} from '@manacore/shared-icons';
import type { QuestionStatus, ResearchDepth } from '$lib/types';
let searchQuery = $state('');
@ -9,7 +16,7 @@
const statusIcons = {
open: { icon: Clock, color: 'text-gray-500' },
researching: { icon: Loader2, color: 'text-blue-500' },
researching: { icon: CircleNotch, color: 'text-blue-500' },
answered: { icon: CheckCircle, color: 'text-green-500' },
archived: { icon: Archive, color: 'text-gray-400' },
};
@ -60,7 +67,9 @@
<!-- Search and Filters -->
<div class="mb-6 flex gap-4">
<div class="relative flex-1">
<Search class="absolute left-3 top-1/2 h-5 w-5 -translate-y-1/2 text-muted-foreground" />
<MagnifyingGlass
class="absolute left-3 top-1/2 h-5 w-5 -translate-y-1/2 text-muted-foreground"
/>
<input
type="text"
bind:value={searchQuery}
@ -86,7 +95,7 @@
onclick={handleSearch}
class="flex items-center gap-2 rounded-lg bg-secondary px-4 py-2 text-foreground hover:bg-secondary-hover"
>
<Filter class="h-5 w-5" />
<Funnel class="h-5 w-5" />
<span>Filter</span>
</button>
</div>

View file

@ -1,7 +1,14 @@
<script lang="ts">
import { collectionsStore } from '$lib/stores';
import CollectionModal from '$lib/components/CollectionModal.svelte';
import { ArrowLeft, Plus, Edit2, Trash2, FolderOpen, GripVertical } from 'lucide-svelte';
import {
ArrowLeft,
Plus,
PencilSimple,
Trash,
FolderOpen,
DotsSixVertical,
} from '@manacore/shared-icons';
import type { Collection } from '$lib/types';
let showModal = $state(false);
@ -47,9 +54,7 @@
Back to questions
</a>
<h1 class="text-2xl font-bold text-foreground">Collections</h1>
<p class="mt-1 text-muted-foreground">
Organize your questions into collections
</p>
<p class="mt-1 text-muted-foreground">Organize your questions into collections</p>
</div>
<button
onclick={openCreateModal}
@ -84,7 +89,7 @@
>
<!-- Drag Handle -->
<div class="cursor-grab text-muted-foreground">
<GripVertical class="h-5 w-5" />
<DotsSixVertical class="h-5 w-5" />
</div>
<!-- Icon & Color -->
@ -122,7 +127,7 @@
class="rounded-lg p-2 text-muted-foreground hover:bg-secondary hover:text-foreground"
title="Edit"
>
<Edit2 class="h-4 w-4" />
<PencilSimple class="h-4 w-4" />
</button>
{#if deleteConfirm === collection.id}
@ -146,7 +151,7 @@
class="rounded-lg p-2 text-muted-foreground hover:bg-destructive/10 hover:text-destructive"
title="Delete"
>
<Trash2 class="h-4 w-4" />
<Trash class="h-4 w-4" />
</button>
{/if}
</div>

View file

@ -2,7 +2,7 @@
import { goto } from '$app/navigation';
import { questionsStore, collectionsStore } from '$lib/stores';
import { researchApi } from '$lib/api/research';
import { ArrowLeft, Zap, Clock, Sparkles } from 'lucide-svelte';
import { ArrowLeft, Lightning, Clock, Sparkle } from '@manacore/shared-icons';
import type { ResearchDepth, QuestionPriority } from '$lib/types';
let title = $state('');
@ -17,10 +17,15 @@
let loading = $state(false);
let error = $state<string | null>(null);
const depthOptions: { value: ResearchDepth; label: string; description: string; icon: typeof Zap }[] = [
{ value: 'quick', label: 'Quick', description: '5 sources, fast results', icon: Zap },
const depthOptions: {
value: ResearchDepth;
label: string;
description: string;
icon: typeof Lightning;
}[] = [
{ value: 'quick', label: 'Quick', description: '5 sources, fast results', icon: Lightning },
{ value: 'standard', label: 'Standard', description: '15 sources, balanced', icon: Clock },
{ value: 'deep', label: 'Deep', description: '30+ sources, comprehensive', icon: Sparkles },
{ value: 'deep', label: 'Deep', description: '30+ sources, comprehensive', icon: Sparkle },
];
function addTag() {
@ -79,9 +84,7 @@
Back to questions
</a>
<h1 class="text-2xl font-bold text-foreground">Ask a Question</h1>
<p class="mt-1 text-muted-foreground">
Enter your question and let AI research it for you
</p>
<p class="mt-1 text-muted-foreground">Enter your question and let AI research it for you</p>
</div>
<form onsubmit={handleSubmit} class="space-y-6">

View file

@ -8,14 +8,14 @@
import {
ArrowLeft,
Clock,
Loader2,
CircleNotch,
CheckCircle,
Archive,
Play,
ExternalLink,
ChevronDown,
ChevronUp,
} from 'lucide-svelte';
ArrowSquareOut,
CaretDown,
CaretUp,
} from '@manacore/shared-icons';
import type { Question, ResearchResult, Source } from '$lib/types';
let question = $state<Question | null>(null);
@ -103,7 +103,7 @@
<ErrorAlert message={error} onRetry={loadQuestion} />
</div>
{:else if question}
<div class="p-6">
<div class="p-6">
<!-- Header -->
<div class="mb-6">
<a
@ -160,7 +160,7 @@
class="flex items-center gap-2 rounded-lg bg-primary px-4 py-2 font-medium text-primary-foreground hover:bg-primary-hover disabled:opacity-50"
>
{#if researchLoading}
<Loader2 class="h-5 w-5 animate-spin" />
<CircleNotch class="h-5 w-5 animate-spin" />
Researching...
{:else}
<Play class="h-5 w-5" />
@ -252,7 +252,7 @@
>
{source.title}
</a>
<ExternalLink class="h-4 w-4 text-muted-foreground" />
<ArrowSquareOut class="h-4 w-4 text-muted-foreground" />
</div>
<p class="mt-1 text-sm text-muted-foreground">{source.domain}</p>
@ -299,9 +299,9 @@
class="rounded-lg p-2 text-muted-foreground hover:bg-secondary hover:text-foreground"
>
{#if expandedSources.has(source.id)}
<ChevronUp class="h-5 w-5" />
<CaretUp class="h-5 w-5" />
{:else}
<ChevronDown class="h-5 w-5" />
<CaretDown class="h-5 w-5" />
{/if}
</button>
{/if}
@ -311,5 +311,5 @@
</div>
</div>
{/if}
</div>
</div>
{/if}

View file

@ -1,7 +1,7 @@
<script lang="ts">
import { authStore } from '$lib/stores/auth.svelte';
import { theme } from '$lib/stores/theme';
import { ArrowLeft, User, Moon, Sun, Monitor, Bell, Shield, Trash2 } from 'lucide-svelte';
import { ArrowLeft, User, Moon, Sun, Desktop, Bell, Shield, Trash } from '@manacore/shared-icons';
let currentTheme = $state(theme.current);
let deleteConfirm = $state(false);
@ -14,7 +14,7 @@
const themeOptions = [
{ value: 'light', label: 'Light', icon: Sun },
{ value: 'dark', label: 'Dark', icon: Moon },
{ value: 'system', label: 'System', icon: Monitor },
{ value: 'system', label: 'System', icon: Desktop },
] as const;
</script>
@ -156,7 +156,7 @@
onclick={() => (deleteConfirm = true)}
class="flex items-center gap-2 rounded-lg border border-destructive px-4 py-2 text-sm font-medium text-destructive hover:bg-destructive/10"
>
<Trash2 class="h-4 w-4" />
<Trash class="h-4 w-4" />
Delete Account
</button>
{/if}

View file

@ -1,6 +1,6 @@
<script lang="ts">
import { authStore } from '$lib/stores/auth.svelte';
import { ArrowLeft } from 'lucide-svelte';
import { ArrowLeft } from '@manacore/shared-icons';
let email = $state('');
let error = $state<string | null>(null);

View file

@ -32,11 +32,11 @@
},
"dependencies": {
"@manacore/shared-auth": "workspace:*",
"@manacore/shared-icons": "workspace:*",
"@manacore/shared-tailwind": "workspace:*",
"@manacore/shared-theme": "workspace:*",
"@manacore/shared-utils": "workspace:*",
"idb": "^8.0.0",
"lucide-svelte": "^0.556.0",
"uuid": "^11.0.0"
},
"type": "module"

View file

@ -1,7 +1,7 @@
<script lang="ts">
import type { Skill, SkillBranch } from '$lib/types';
import { BRANCH_INFO } from '$lib/types';
import { X } from 'lucide-svelte';
import { X } from '@manacore/shared-icons';
interface Props {
onClose: () => void;
@ -59,9 +59,7 @@
<form onsubmit={handleSubmit} class="space-y-4">
<!-- Name -->
<div>
<label for="name" class="mb-1 block text-sm font-medium text-gray-300">
Name *
</label>
<label for="name" class="mb-1 block text-sm font-medium text-gray-300"> Name * </label>
<input
id="name"
type="text"
@ -88,22 +86,18 @@
<!-- Branch -->
<div>
<label for="branch" class="mb-2 block text-sm font-medium text-gray-300">
Kategorie
</label>
<label for="branch" class="mb-2 block text-sm font-medium text-gray-300"> Kategorie </label>
<div class="grid grid-cols-2 gap-2">
{#each Object.entries(BRANCH_INFO) as [key, info]}
<button
type="button"
onclick={() => (branch = key as SkillBranch)}
class="flex items-center gap-2 rounded-lg border px-3 py-2 text-left text-sm transition-colors {branch === key
class="flex items-center gap-2 rounded-lg border px-3 py-2 text-left text-sm transition-colors {branch ===
key
? 'border-emerald-500 bg-emerald-500/20 text-white'
: 'border-gray-600 bg-gray-700/50 text-gray-300 hover:border-gray-500'}"
>
<span
class="h-3 w-3 rounded-full"
style="background-color: {info.color}"
></span>
<span class="h-3 w-3 rounded-full" style="background-color: {info.color}"></span>
{info.name}
</button>
{/each}

View file

@ -1,7 +1,7 @@
<script lang="ts">
import type { Skill } from '$lib/types';
import { LEVEL_NAMES } from '$lib/types';
import { X, Zap, Clock, Star } from 'lucide-svelte';
import { X, Lightning, Clock, Star } from '@manacore/shared-icons';
interface Props {
skill: Skill;
@ -75,15 +75,14 @@
<form onsubmit={handleSubmit} class="space-y-4">
<!-- Quick XP Presets -->
<div>
<label class="mb-2 block text-sm font-medium text-gray-300">
Schnellauswahl
</label>
<label class="mb-2 block text-sm font-medium text-gray-300"> Schnellauswahl </label>
<div class="flex flex-wrap gap-2">
{#each xpPresets as preset}
<button
type="button"
onclick={() => selectPreset(preset)}
class="rounded-lg border px-3 py-1.5 text-sm font-medium transition-colors {xp === preset.value
class="rounded-lg border px-3 py-1.5 text-sm font-medium transition-colors {xp ===
preset.value
? 'border-emerald-500 bg-emerald-500/20 text-emerald-400'
: 'border-gray-600 bg-gray-700/50 text-gray-300 hover:border-gray-500'}"
>
@ -96,7 +95,7 @@
<!-- Custom XP -->
<div>
<label for="xp" class="mb-1 block text-sm font-medium text-gray-300">
<Zap class="mr-1 inline h-4 w-4 text-yellow-500" />
<Lightning class="mr-1 inline h-4 w-4 text-yellow-500" />
XP Menge
</label>
<input

View file

@ -1,7 +1,7 @@
<script lang="ts">
import type { Skill, SkillBranch } from '$lib/types';
import { BRANCH_INFO } from '$lib/types';
import { X, Trash2 } from 'lucide-svelte';
import { X, Trash } from '@manacore/shared-icons';
interface Props {
skill: Skill;
@ -68,8 +68,10 @@
{#if showDeleteConfirm}
<!-- Delete Confirmation -->
<div class="text-center">
<div class="mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-red-500/20">
<Trash2 class="h-8 w-8 text-red-500" />
<div
class="mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-red-500/20"
>
<Trash class="h-8 w-8 text-red-500" />
</div>
<h3 class="mb-2 text-lg font-semibold text-white">Skill löschen?</h3>
<p class="mb-6 text-gray-400">
@ -94,9 +96,7 @@
<form onsubmit={handleSubmit} class="space-y-4">
<!-- Name -->
<div>
<label for="name" class="mb-1 block text-sm font-medium text-gray-300">
Name *
</label>
<label for="name" class="mb-1 block text-sm font-medium text-gray-300"> Name * </label>
<input
id="name"
type="text"
@ -123,22 +123,18 @@
<!-- Branch -->
<div>
<label class="mb-2 block text-sm font-medium text-gray-300">
Kategorie
</label>
<label class="mb-2 block text-sm font-medium text-gray-300"> Kategorie </label>
<div class="grid grid-cols-2 gap-2">
{#each Object.entries(BRANCH_INFO) as [key, info]}
<button
type="button"
onclick={() => (branch = key as SkillBranch)}
class="flex items-center gap-2 rounded-lg border px-3 py-2 text-left text-sm transition-colors {branch === key
class="flex items-center gap-2 rounded-lg border px-3 py-2 text-left text-sm transition-colors {branch ===
key
? 'border-emerald-500 bg-emerald-500/20 text-white'
: 'border-gray-600 bg-gray-700/50 text-gray-300 hover:border-gray-500'}"
>
<span
class="h-3 w-3 rounded-full"
style="background-color: {info.color}"
></span>
<span class="h-3 w-3 rounded-full" style="background-color: {info.color}"></span>
{info.name}
</button>
{/each}
@ -173,7 +169,7 @@
class="rounded-lg bg-red-600/20 p-2 text-red-400 transition-colors hover:bg-red-600/30"
title="Löschen"
>
<Trash2 class="h-5 w-5" />
<Trash class="h-5 w-5" />
</button>
<button
type="button"

View file

@ -1,6 +1,6 @@
<script lang="ts">
import { LEVEL_NAMES } from '$lib/types';
import { Star, Trophy, Sparkles } from 'lucide-svelte';
import { Star, Trophy, Sparkle } from '@manacore/shared-icons';
import { onMount } from 'svelte';
interface Props {
@ -42,11 +42,8 @@
<!-- Sparkle effects -->
<div class="sparkles">
{#each Array(12) as _, i}
<div
class="sparkle"
style="--delay: {i * 0.1}s; --angle: {i * 30}deg"
>
<Sparkles class="h-6 w-6 text-yellow-400" />
<div class="sparkle" style="--delay: {i * 0.1}s; --angle: {i * 30}deg">
<Sparkle class="h-6 w-6 text-yellow-400" />
</div>
{/each}
</div>
@ -54,20 +51,26 @@
<!-- Main content -->
<div class="relative z-10">
<!-- Trophy icon -->
<div class="mx-auto mb-4 flex h-24 w-24 items-center justify-center rounded-full bg-gradient-to-br {getLevelColor(newLevel)} level-up-bounce shadow-lg shadow-yellow-500/30">
<div
class="mx-auto mb-4 flex h-24 w-24 items-center justify-center rounded-full bg-gradient-to-br {getLevelColor(
newLevel
)} level-up-bounce shadow-lg shadow-yellow-500/30"
>
<Trophy class="h-12 w-12 text-white" />
</div>
<!-- Level up text -->
<h2 class="mb-2 text-3xl font-bold text-white level-up-text">
LEVEL UP!
</h2>
<h2 class="mb-2 text-3xl font-bold text-white level-up-text">LEVEL UP!</h2>
<!-- Skill name -->
<p class="mb-4 text-xl text-gray-300">{skillName}</p>
<!-- New level badge -->
<div class="inline-flex items-center gap-2 rounded-full bg-gradient-to-r {getLevelColor(newLevel)} px-6 py-3 text-lg font-bold text-white shadow-lg">
<div
class="inline-flex items-center gap-2 rounded-full bg-gradient-to-r {getLevelColor(
newLevel
)} px-6 py-3 text-lg font-bold text-white shadow-lg"
>
<Star class="h-5 w-5 fill-current" />
Level {newLevel} - {levelName}
<Star class="h-5 w-5 fill-current" />
@ -149,7 +152,9 @@
text-shadow: 0 0 10px rgba(251, 191, 36, 0.5);
}
to {
text-shadow: 0 0 30px rgba(251, 191, 36, 0.8), 0 0 60px rgba(251, 191, 36, 0.4);
text-shadow:
0 0 30px rgba(251, 191, 36, 0.8),
0 0 60px rgba(251, 191, 36, 0.4);
}
}

View file

@ -1,7 +1,7 @@
<script lang="ts">
import type { Skill } from '$lib/types';
import { BRANCH_INFO, LEVEL_NAMES, xpProgress, xpForNextLevel } from '$lib/types';
import { Plus, Trash2, Edit, Star } from 'lucide-svelte';
import { Plus, Trash, PencilSimple, Star } from '@manacore/shared-icons';
interface Props {
skill: Skill;
@ -31,7 +31,9 @@
}
</script>
<div class="skill-card group relative overflow-hidden rounded-xl border border-gray-700 bg-gray-800/50 p-4">
<div
class="skill-card group relative overflow-hidden rounded-xl border border-gray-700 bg-gray-800/50 p-4"
>
<!-- Branch Indicator -->
<div
class="branch-indicator absolute left-0 top-0 h-full"
@ -56,7 +58,11 @@
<!-- Level Badge -->
<div class="mb-3 pl-3">
<span class="inline-flex items-center gap-1 rounded-full bg-gray-700/50 px-3 py-1 text-sm {getLevelColor(skill.level)}">
<span
class="inline-flex items-center gap-1 rounded-full bg-gray-700/50 px-3 py-1 text-sm {getLevelColor(
skill.level
)}"
>
Lvl {skill.level} - {levelName}
</span>
</div>
@ -96,14 +102,14 @@
class="rounded-lg bg-gray-600/20 p-2 text-gray-400 opacity-0 transition-all hover:bg-gray-600/30 hover:text-white group-hover:opacity-100"
title="Bearbeiten"
>
<Edit class="h-4 w-4" />
<PencilSimple class="h-4 w-4" />
</button>
<button
onclick={onDelete}
class="rounded-lg bg-red-600/20 p-2 text-red-400 opacity-0 transition-all hover:bg-red-600/30 group-hover:opacity-100"
title="Löschen"
>
<Trash2 class="h-4 w-4" />
<Trash class="h-4 w-4" />
</button>
</div>
</div>

View file

@ -1,7 +1,7 @@
<script lang="ts">
import type { Skill, SkillBranch } from '$lib/types';
import { BRANCH_INFO } from '$lib/types';
import { X, Plus, Sparkles } from 'lucide-svelte';
import { X, Plus, Sparkle } from '@manacore/shared-icons';
interface Props {
onClose: () => void;
@ -41,14 +41,14 @@
{ name: 'Schreiben', description: 'Kreatives Schreiben', branch: 'creativity' },
{ name: 'Design', description: 'Visuelles Design', branch: 'creativity' },
],
'Sprachen': [
Sprachen: [
{ name: 'Englisch', description: 'Die Weltsprache', branch: 'intellect' },
{ name: 'Spanisch', description: 'Spanisch sprechen', branch: 'intellect' },
{ name: 'Französisch', description: 'La langue française', branch: 'intellect' },
{ name: 'Japanisch', description: '日本語', branch: 'intellect' },
{ name: 'Deutsch', description: 'Deutsche Sprache', branch: 'intellect' },
],
'Produktivität': [
Produktivität: [
{ name: 'Zeitmanagement', description: 'Zeit effektiv nutzen', branch: 'mindset' },
{ name: 'Fokus', description: 'Konzentration verbessern', branch: 'mindset' },
{ name: 'Organisation', description: 'Ordnung und Struktur', branch: 'practical' },
@ -114,7 +114,7 @@
<!-- Header -->
<div class="mb-6 flex items-center justify-between">
<div class="flex items-center gap-2">
<Sparkles class="h-6 w-6 text-yellow-500" />
<Sparkle class="h-6 w-6 text-yellow-500" />
<h2 class="text-xl font-bold text-white">Skill-Vorlagen</h2>
</div>
<button
@ -126,7 +126,8 @@
</div>
<p class="mb-6 text-gray-400">
Starte schnell mit vorgefertigten Skill-Sets. Wähle eine Vorlage und füge einzelne Skills oder alle auf einmal hinzu.
Starte schnell mit vorgefertigten Skill-Sets. Wähle eine Vorlage und füge einzelne Skills oder
alle auf einmal hinzu.
</p>
<!-- Template List -->
@ -184,7 +185,12 @@
>
{#if isAdded}
<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="M5 13l4 4L19 7" />
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M5 13l4 4L19 7"
/>
</svg>
{:else}
<Plus class="h-4 w-4" />

View file

@ -1,6 +1,6 @@
<script lang="ts">
import { skillStore } from '$lib/stores/skills.svelte';
import { Trophy, Zap, Target, Flame } from 'lucide-svelte';
import { Trophy, Lightning, Target, Fire } from '@manacore/shared-icons';
</script>
<div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
@ -8,7 +8,7 @@
<div class="rounded-xl border border-gray-700 bg-gray-800/50 p-4">
<div class="flex items-center gap-3">
<div class="flex h-12 w-12 items-center justify-center rounded-full bg-yellow-500/20">
<Zap class="h-6 w-6 text-yellow-500" />
<Lightning class="h-6 w-6 text-yellow-500" />
</div>
<div>
<p class="text-sm text-gray-400">Gesamt-XP</p>
@ -53,7 +53,7 @@
<div class="rounded-xl border border-gray-700 bg-gray-800/50 p-4">
<div class="flex items-center gap-3">
<div class="flex h-12 w-12 items-center justify-center rounded-full bg-orange-500/20">
<Flame class="h-6 w-6 text-orange-500" />
<Fire class="h-6 w-6 text-orange-500" />
</div>
<div>
<p class="text-sm text-gray-400">Streak</p>

View file

@ -11,13 +11,13 @@
import SkillTemplates from '$lib/components/SkillTemplates.svelte';
import {
Plus,
TreeDeciduous,
Zap,
Download,
Upload,
Sparkles,
Network,
} from 'lucide-svelte';
Tree,
Lightning,
DownloadSimple,
UploadSimple,
Sparkle,
Graph,
} from '@manacore/shared-icons';
// Modal states
let showAddSkillModal = $state(false);
@ -114,7 +114,7 @@
<div class="mx-auto max-w-7xl px-4 py-4">
<div class="flex items-center justify-between">
<div class="flex items-center gap-3">
<TreeDeciduous class="h-8 w-8 text-emerald-500" />
<Tree class="h-8 w-8 text-emerald-500" />
<h1 class="text-2xl font-bold text-white">SkillTree</h1>
</div>
<div class="flex items-center gap-2">
@ -124,7 +124,7 @@
class="rounded-lg p-2 text-gray-400 transition-colors hover:bg-gray-800 hover:text-emerald-400"
title="Skill-Tree Ansicht"
>
<Network class="h-5 w-5" />
<Graph class="h-5 w-5" />
</a>
<!-- Templates -->
<button
@ -132,7 +132,7 @@
class="rounded-lg p-2 text-gray-400 transition-colors hover:bg-gray-800 hover:text-yellow-500"
title="Skill-Vorlagen"
>
<Sparkles class="h-5 w-5" />
<Sparkle class="h-5 w-5" />
</button>
<!-- Export/Import -->
<button
@ -140,14 +140,14 @@
class="rounded-lg p-2 text-gray-400 transition-colors hover:bg-gray-800 hover:text-white"
title="Daten exportieren"
>
<Download class="h-5 w-5" />
<DownloadSimple class="h-5 w-5" />
</button>
<button
onclick={handleImport}
class="rounded-lg p-2 text-gray-400 transition-colors hover:bg-gray-800 hover:text-white"
title="Daten importieren"
>
<Upload class="h-5 w-5" />
<UploadSimple class="h-5 w-5" />
</button>
<!-- Add Skill -->
<button
@ -171,7 +171,8 @@
<div class="flex flex-wrap gap-2">
<button
onclick={() => (selectedBranch = 'all')}
class="rounded-full px-4 py-2 text-sm font-medium transition-colors {selectedBranch === 'all'
class="rounded-full px-4 py-2 text-sm font-medium transition-colors {selectedBranch ===
'all'
? 'bg-emerald-600 text-white'
: 'bg-gray-800 text-gray-300 hover:bg-gray-700'}"
>
@ -182,7 +183,8 @@
{#if count > 0 || branch !== 'custom'}
<button
onclick={() => (selectedBranch = branch as SkillBranch)}
class="rounded-full px-4 py-2 text-sm font-medium transition-colors {selectedBranch === branch
class="rounded-full px-4 py-2 text-sm font-medium transition-colors {selectedBranch ===
branch
? 'bg-emerald-600 text-white'
: 'bg-gray-800 text-gray-300 hover:bg-gray-700'}"
>
@ -196,13 +198,13 @@
<!-- Skills Grid -->
{#if filteredSkills().length === 0}
<div class="mt-16 text-center">
<div class="mx-auto mb-6 flex h-24 w-24 items-center justify-center rounded-full bg-gray-800">
<TreeDeciduous class="h-12 w-12 text-gray-600" />
<div
class="mx-auto mb-6 flex h-24 w-24 items-center justify-center rounded-full bg-gray-800"
>
<Tree class="h-12 w-12 text-gray-600" />
</div>
<h2 class="mb-2 text-xl font-semibold text-gray-300">Noch keine Skills</h2>
<p class="mb-6 text-gray-500">
Füge deinen ersten Skill hinzu und beginne dein Abenteuer!
</p>
<p class="mb-6 text-gray-500">Füge deinen ersten Skill hinzu und beginne dein Abenteuer!</p>
<button
onclick={() => (showAddSkillModal = true)}
class="inline-flex items-center gap-2 rounded-lg bg-emerald-600 px-6 py-3 font-medium text-white transition-colors hover:bg-emerald-500"
@ -228,7 +230,7 @@
{#if skillStore.recentActivities().length > 0}
<div class="mt-12">
<h2 class="mb-4 flex items-center gap-2 text-lg font-semibold text-white">
<Zap class="h-5 w-5 text-yellow-500" />
<Lightning class="h-5 w-5 text-yellow-500" />
Letzte Aktivitäten
</h2>
<div class="space-y-2">
@ -237,7 +239,9 @@
{#if skill}
<div class="flex items-center justify-between rounded-lg bg-gray-800/50 px-4 py-3">
<div class="flex items-center gap-3">
<div class="flex h-8 w-8 items-center justify-center rounded-full bg-emerald-900/50 text-sm font-medium text-emerald-400">
<div
class="flex h-8 w-8 items-center justify-center rounded-full bg-emerald-900/50 text-sm font-medium text-emerald-400"
>
+{activity.xpEarned}
</div>
<div>
@ -269,11 +273,7 @@
{/if}
{#if showAddXpModal && selectedSkill}
<AddXpModal
skill={selectedSkill}
onClose={closeModals}
onSave={handleAddXp}
/>
<AddXpModal skill={selectedSkill} onClose={closeModals} onSave={handleAddXp} />
{/if}
{#if showEditSkillModal && selectedSkill}

View file

@ -2,7 +2,7 @@
import { skillStore } from '$lib/stores/skills.svelte';
import { BRANCH_INFO, LEVEL_NAMES } from '$lib/types';
import type { SkillBranch } from '$lib/types';
import { ArrowLeft, Star } from 'lucide-svelte';
import { ArrowLeft, Star } from '@manacore/shared-icons';
// Group skills by branch for radial layout
const branches = Object.keys(BRANCH_INFO) as SkillBranch[];
@ -31,7 +31,9 @@
const radiusStep = 60;
// Spread skills in a small arc
const skillAngle = branchAngle + (skillIndex - (skillCount - 1) / 2) * (spreadAngle / Math.max(skillCount - 1, 1));
const skillAngle =
branchAngle +
(skillIndex - (skillCount - 1) / 2) * (spreadAngle / Math.max(skillCount - 1, 1));
const radius = baseRadius + skillIndex * radiusStep * 0.3;
return {
@ -104,9 +106,33 @@
style="min-width: 600px; height: auto; max-height: 80vh;"
>
<!-- Background circles -->
<circle cx="400" cy="400" r="120" fill="none" stroke="#374151" stroke-width="1" stroke-dasharray="4" />
<circle cx="400" cy="400" r="200" fill="none" stroke="#374151" stroke-width="1" stroke-dasharray="4" />
<circle cx="400" cy="400" r="280" fill="none" stroke="#374151" stroke-width="1" stroke-dasharray="4" />
<circle
cx="400"
cy="400"
r="120"
fill="none"
stroke="#374151"
stroke-width="1"
stroke-dasharray="4"
/>
<circle
cx="400"
cy="400"
r="200"
fill="none"
stroke="#374151"
stroke-width="1"
stroke-dasharray="4"
/>
<circle
cx="400"
cy="400"
r="280"
fill="none"
stroke="#374151"
stroke-width="1"
stroke-dasharray="4"
/>
<!-- Center node -->
<circle cx="400" cy="400" r="50" fill="#10b981" opacity="0.2" />
@ -162,7 +188,10 @@
/>
<!-- Skill node -->
<g class="tree-node cursor-pointer" transform="translate({skillPos.x}, {skillPos.y})">
<g
class="tree-node cursor-pointer"
transform="translate({skillPos.x}, {skillPos.y})"
>
<!-- Glow effect for high level -->
{#if skill.level >= 4}
<circle

View file

@ -40,8 +40,7 @@
"@manacore/shared-theme": "workspace:*",
"@manacore/shared-theme-ui": "workspace:*",
"@manacore/shared-ui": "workspace:*",
"svelte-i18n": "^4.0.1",
"lucide-svelte": "^0.469.0"
"svelte-i18n": "^4.0.1"
},
"type": "module"
}

View file

@ -1,5 +1,5 @@
<script lang="ts">
import { ChevronRight, Home } from 'lucide-svelte';
import { CaretRight, House } from '@manacore/shared-icons';
interface BreadcrumbItem {
id: string | null;
@ -18,13 +18,13 @@
<ol class="breadcrumb-list">
<li class="breadcrumb-item">
<button onclick={() => onNavigate(null)} class="breadcrumb-link" aria-label="Home">
<Home size={16} />
<House size={16} />
<span>Meine Dateien</span>
</button>
</li>
{#each items as item, index (item.id)}
<li class="breadcrumb-item">
<ChevronRight size={16} class="separator" />
<CaretRight size={16} class="separator" />
{#if index === items.length - 1}
<span class="breadcrumb-current">{item.name}</span>
{:else}

View file

@ -6,10 +6,10 @@
FileText,
FileVideo,
FileAudio,
FileArchive,
FileZip,
Heart,
MoreVertical,
} from 'lucide-svelte';
DotsThreeVertical,
} from '@manacore/shared-icons';
interface Props {
file: StorageFile;
@ -26,7 +26,7 @@
if (mimeType.startsWith('video/')) return FileVideo;
if (mimeType.startsWith('audio/')) return FileAudio;
if (mimeType.startsWith('text/')) return FileText;
if (mimeType.includes('zip') || mimeType.includes('archive')) return FileArchive;
if (mimeType.includes('zip') || mimeType.includes('archive')) return FileZip;
return File;
}
@ -65,7 +65,7 @@
<span class="file-size">{formatFileSize(file.size)}</span>
</div>
<button class="menu-button" onclick={handleMenuClick} type="button">
<MoreVertical size={16} />
<DotsThreeVertical size={16} />
</button>
{#if showMenu}

View file

@ -6,10 +6,10 @@
FileText,
FileVideo,
FileAudio,
FileArchive,
FileZip,
Heart,
MoreVertical,
} from 'lucide-svelte';
DotsThreeVertical,
} from '@manacore/shared-icons';
interface Props {
file: StorageFile;
@ -28,7 +28,7 @@
if (mimeType.startsWith('video/')) return FileVideo;
if (mimeType.startsWith('audio/')) return FileAudio;
if (mimeType.startsWith('text/')) return FileText;
if (mimeType.includes('zip') || mimeType.includes('archive')) return FileArchive;
if (mimeType.includes('zip') || mimeType.includes('archive')) return FileZip;
return File;
}
@ -59,7 +59,7 @@
<span class="col-date">{formatDate(file.updatedAt)}</span>
<span class="col-actions">
<button class="menu-button" onclick={handleMenuClick} type="button">
<MoreVertical size={16} />
<DotsThreeVertical size={16} />
</button>
{#if showMenu}
<div class="menu-dropdown">

View file

@ -1,6 +1,6 @@
<script lang="ts">
import type { StorageFolder } from '$lib/api/client';
import { Folder, Heart, MoreVertical } from 'lucide-svelte';
import { Folder, Heart, DotsThreeVertical } from '@manacore/shared-icons';
interface Props {
folder: StorageFolder;
@ -50,7 +50,7 @@
<span class="folder-name" title={folder.name}>{folder.name}</span>
</div>
<button class="menu-button" onclick={handleMenuClick} type="button">
<MoreVertical size={16} />
<DotsThreeVertical size={16} />
</button>
{#if showMenu}

View file

@ -1,6 +1,6 @@
<script lang="ts">
import type { StorageFolder } from '$lib/api/client';
import { Folder, Heart, MoreVertical } from 'lucide-svelte';
import { Folder, Heart, DotsThreeVertical } from '@manacore/shared-icons';
interface Props {
folder: StorageFolder;
@ -52,7 +52,7 @@
<span class="col-date">{formatDate(folder.updatedAt)}</span>
<span class="col-actions">
<button class="menu-button" onclick={handleMenuClick} type="button">
<MoreVertical size={16} />
<DotsThreeVertical size={16} />
</button>
{#if showMenu}
<div class="menu-dropdown">

View file

@ -1,5 +1,5 @@
<script lang="ts">
import { X } from 'lucide-svelte';
import { X } from '@manacore/shared-icons';
interface Props {
open: boolean;

View file

@ -1,5 +1,5 @@
<script lang="ts">
import { Upload, X } from 'lucide-svelte';
import { UploadSimple } from '@manacore/shared-icons';
interface Props {
onUpload: (files: FileList) => void;
@ -74,7 +74,7 @@
</div>
{:else}
<div class="upload-content">
<Upload size={32} />
<UploadSimple size={32} />
<span class="upload-text">
Dateien hierher ziehen oder <strong>klicken</strong> zum Auswählen
</span>

View file

@ -1,7 +1,7 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { onMount } from 'svelte';
import { Heart, Grid, List } from 'lucide-svelte';
import { Heart, GridFour, List } from '@manacore/shared-icons';
import { searchApi } from '$lib/api/client';
import type { StorageFile, StorageFolder } from '$lib/api/client';
import { filesStore } from '$lib/stores/files.svelte';
@ -81,7 +81,7 @@
onclick={() => filesStore.setViewMode('grid')}
aria-label="Rasteransicht"
>
<Grid size={18} />
<GridFour size={18} />
</button>
<button
class="view-btn"

View file

@ -1,5 +1,5 @@
<script lang="ts">
import { MessageSquare, Send } from 'lucide-svelte';
import { ChatCircle, PaperPlaneTilt } from '@manacore/shared-icons';
import { toast } from '$lib/stores/toast';
let type = $state<'bug' | 'feature' | 'other'>('feature');
@ -28,7 +28,7 @@
<div class="feedback-page">
<div class="page-header">
<h1>
<MessageSquare size={24} />
<ChatCircle size={24} />
Feedback
</h1>
</div>
@ -86,7 +86,7 @@
</div>
<button type="submit" class="submit-btn" disabled={!message.trim() || sending}>
<Send size={18} />
<PaperPlaneTilt size={18} />
{sending ? 'Wird gesendet...' : 'Feedback senden'}
</button>
</form>

View file

@ -1,7 +1,7 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { onMount } from 'svelte';
import { Grid, List, Plus, FolderPlus, Upload } from 'lucide-svelte';
import { GridFour, List, Plus, FolderPlus, UploadSimple } from '@manacore/shared-icons';
import { filesStore } from '$lib/stores/files.svelte';
import { toast } from '$lib/stores/toast';
import type { StorageFile, StorageFolder } from '$lib/api/client';
@ -178,7 +178,7 @@
onclick={() => filesStore.setViewMode('grid')}
aria-label="Rasteransicht"
>
<Grid size={18} />
<GridFour size={18} />
</button>
<button
class="view-btn"
@ -196,7 +196,7 @@
</button>
<button class="action-btn primary" onclick={() => (showUploadZone = !showUploadZone)}>
<Upload size={18} />
<UploadSimple size={18} />
<span>Hochladen</span>
</button>
</div>
@ -218,7 +218,7 @@
</div>
{:else if filesStore.files.length === 0 && filesStore.folders.length === 0}
<div class="empty-state">
<Upload size={48} />
<UploadSimple size={48} />
<h2>Noch keine Dateien</h2>
<p>Lade deine ersten Dateien hoch oder erstelle einen Ordner.</p>
<div class="empty-actions">
@ -227,7 +227,7 @@
<span>Neuer Ordner</span>
</button>
<button class="action-btn primary" onclick={() => (showUploadZone = true)}>
<Upload size={18} />
<UploadSimple size={18} />
<span>Hochladen</span>
</button>
</div>

View file

@ -2,7 +2,7 @@
import { goto } from '$app/navigation';
import { page } from '$app/stores';
import { onMount } from 'svelte';
import { Grid, List, FolderPlus, Upload, ArrowLeft } from 'lucide-svelte';
import { GridFour, List, FolderPlus, UploadSimple, ArrowLeft } from '@manacore/shared-icons';
import { filesStore } from '$lib/stores/files.svelte';
import { toast } from '$lib/stores/toast';
import type { StorageFile, StorageFolder } from '$lib/api/client';
@ -197,7 +197,7 @@
onclick={() => filesStore.setViewMode('grid')}
aria-label="Rasteransicht"
>
<Grid size={18} />
<GridFour size={18} />
</button>
<button
class="view-btn"
@ -215,7 +215,7 @@
</button>
<button class="action-btn primary" onclick={() => (showUploadZone = !showUploadZone)}>
<Upload size={18} />
<UploadSimple size={18} />
<span>Hochladen</span>
</button>
</div>
@ -237,7 +237,7 @@
</div>
{:else if filesStore.files.length === 0 && filesStore.folders.length === 0}
<div class="empty-state">
<Upload size={48} />
<UploadSimple size={48} />
<h2>Leerer Ordner</h2>
<p>Dieser Ordner ist leer. Lade Dateien hoch oder erstelle Unterordner.</p>
<div class="empty-actions">
@ -246,7 +246,7 @@
<span>Neuer Ordner</span>
</button>
<button class="action-btn primary" onclick={() => (showUploadZone = true)}>
<Upload size={18} />
<UploadSimple size={18} />
<span>Hochladen</span>
</button>
</div>

View file

@ -1,5 +1,5 @@
<script lang="ts">
import { User } from 'lucide-svelte';
import { User } from '@manacore/shared-icons';
import { authStore } from '$lib/stores/auth.svelte';
</script>

View file

@ -2,7 +2,7 @@
import { goto } from '$app/navigation';
import { page } from '$app/stores';
import { onMount } from 'svelte';
import { Search, Grid, List } from 'lucide-svelte';
import { MagnifyingGlass, GridFour, List } from '@manacore/shared-icons';
import { searchApi } from '$lib/api/client';
import type { StorageFile, StorageFolder } from '$lib/api/client';
import { filesStore } from '$lib/stores/files.svelte';
@ -68,7 +68,7 @@
<div class="search-page">
<div class="page-header">
<h1>
<Search size={24} />
<MagnifyingGlass size={24} />
Suche
</h1>
@ -79,7 +79,7 @@
onclick={() => filesStore.setViewMode('grid')}
aria-label="Rasteransicht"
>
<Grid size={18} />
<GridFour size={18} />
</button>
<button
class="view-btn"
@ -93,7 +93,7 @@
</div>
<div class="search-bar">
<Search size={20} />
<MagnifyingGlass size={20} />
<input
type="text"
bind:value={query}
@ -113,7 +113,7 @@
</div>
{:else if searched && files.length === 0 && folders.length === 0}
<div class="empty-state">
<Search size={48} />
<MagnifyingGlass size={48} />
<h2>Keine Ergebnisse</h2>
<p>Keine Dateien oder Ordner für "{query}" gefunden.</p>
</div>
@ -129,7 +129,7 @@
{/if}
{:else}
<div class="empty-state">
<Search size={48} />
<MagnifyingGlass size={48} />
<h2>Dateien durchsuchen</h2>
<p>Gib einen Suchbegriff ein, um Dateien und Ordner zu finden.</p>
</div>

View file

@ -1,6 +1,6 @@
<script lang="ts">
import { onMount } from 'svelte';
import { Share2, Link, Copy, Trash2 } from 'lucide-svelte';
import { ShareNetwork, Link, Copy, Trash } from '@manacore/shared-icons';
import { sharesApi } from '$lib/api/client';
import type { Share } from '$lib/api/client';
import { toast } from '$lib/stores/toast';
@ -75,7 +75,7 @@
<div class="shared-page">
<div class="page-header">
<h1>
<Share2 size={24} />
<ShareNetwork size={24} />
Geteilte Links
</h1>
</div>
@ -92,7 +92,7 @@
</div>
{:else if shares.length === 0}
<div class="empty-state">
<Share2 size={48} />
<ShareNetwork size={48} />
<h2>Keine geteilten Links</h2>
<p>Teile Dateien oder Ordner, um Links hier zu verwalten.</p>
</div>
@ -128,7 +128,7 @@
Link kopieren
</button>
<button class="delete-btn" onclick={() => deleteShare(share.id)}>
<Trash2 size={16} />
<Trash size={16} />
</button>
</div>
</div>

View file

@ -1,5 +1,5 @@
<script lang="ts">
import { Palette, Check } from 'lucide-svelte';
import { Palette, Check } from '@manacore/shared-icons';
import { theme } from '$lib/stores/theme.svelte';
import { THEME_DEFINITIONS, THEME_VARIANTS } from '@manacore/shared-theme';
import type { ThemeVariant } from '@manacore/shared-theme';

View file

@ -1,6 +1,6 @@
<script lang="ts">
import { onMount } from 'svelte';
import { Trash2, RotateCcw, AlertTriangle } from 'lucide-svelte';
import { Trash, ArrowCounterClockwise, Warning } from '@manacore/shared-icons';
import { trashApi } from '$lib/api/client';
import type { StorageFile, StorageFolder } from '$lib/api/client';
import { toast } from '$lib/stores/toast';
@ -89,13 +89,13 @@
<div class="trash-page">
<div class="page-header">
<h1>
<Trash2 size={24} />
<Trash size={24} />
Papierkorb
</h1>
{#if files.length > 0 || folders.length > 0}
<button class="empty-btn" onclick={handleEmptyTrash}>
<AlertTriangle size={16} />
<Warning size={16} />
Papierkorb leeren
</button>
{/if}
@ -113,7 +113,7 @@
</div>
{:else if files.length === 0 && folders.length === 0}
<div class="empty-state">
<Trash2 size={48} />
<Trash size={48} />
<h2>Papierkorb ist leer</h2>
<p>Gelöschte Dateien und Ordner erscheinen hier.</p>
</div>
@ -130,7 +130,7 @@
</div>
<div class="item-actions">
<button class="restore-btn" onclick={() => handleRestore(folder.id, 'folder')}>
<RotateCcw size={16} />
<ArrowCounterClockwise size={16} />
Wiederherstellen
</button>
<button class="delete-btn" onclick={() => handlePermanentDelete(folder.id, 'folder')}>
@ -150,7 +150,7 @@
</div>
<div class="item-actions">
<button class="restore-btn" onclick={() => handleRestore(file.id, 'file')}>
<RotateCcw size={16} />
<ArrowCounterClockwise size={16} />
Wiederherstellen
</button>
<button class="delete-btn" onclick={() => handlePermanentDelete(file.id, 'file')}>

View file

@ -50,7 +50,6 @@
"@todo/shared": "workspace:*",
"d3-force": "^3.0.0",
"date-fns": "^4.1.0",
"lucide-svelte": "^0.556.0",
"svelte-dnd-action": "^0.9.68",
"svelte-i18n": "^4.0.1"
},

1728
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff