♻️ 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

@ -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')}>