diff --git a/apps/web/src/lib/components/DeckGrid.svelte b/apps/web/src/lib/components/DeckGrid.svelte index d4b7a14..f360afc 100644 --- a/apps/web/src/lib/components/DeckGrid.svelte +++ b/apps/web/src/lib/components/DeckGrid.svelte @@ -1,6 +1,7 @@
- {#if hasContent} {#each layers as layer, i (i)}
+ + {#if category} + + {/if} + +

{deck.name}

{#if deck.description}

{deck.description}

{/if}
+ +
{tn('decks.card_count', cardCount)} {#if dueCount > 0} @@ -76,7 +87,6 @@ aspect-ratio: 5 / 7; } - /* Hintergrund-Layers — versteckte Karten unter dem Deckblatt */ .layer { position: absolute; inset: 0; @@ -86,52 +96,62 @@ box-shadow: 0 1px 3px hsl(var(--color-foreground) / 0.06); } - /* Inneres Layout des Deckblatt-Inhalts */ .cover-inner { position: absolute; inset: 0; display: flex; flex-direction: column; - justify-content: space-between; - gap: 0.75rem; - padding: 1.25rem 1.125rem 1.25rem 1.5rem; + padding: 1rem 1rem 1.125rem 1.375rem; overflow: hidden; } + /* Icon-Ecke oben rechts */ + .cover-corner { + position: absolute; + top: 0.875rem; + right: 0.875rem; + display: flex; + align-items: center; + justify-content: center; + opacity: 0.85; + } + .cover-body { flex: 1; + display: flex; + flex-direction: column; + align-items: flex-start; + justify-content: flex-start; + gap: 0.875rem; + padding: 2.5rem 0.5rem 0 0; min-height: 0; } .cover-title { margin: 0; - font-size: 1.125rem; + font-size: 1.0625rem; font-weight: 600; line-height: 1.3; display: -webkit-box; - -webkit-line-clamp: 2; - line-clamp: 2; - -webkit-box-orient: vertical; - overflow: hidden; - } - - .cover-desc { - margin: 0.5rem 0 0; - font-size: 0.8125rem; - color: hsl(var(--color-muted-foreground)); - line-height: 1.4; - display: -webkit-box; -webkit-line-clamp: 3; line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; } + .cover-desc { + margin: 0; + font-size: 0.75rem; + color: hsl(var(--color-muted-foreground)); + line-height: 1.4; + } + .cover-meta { + flex: 0 0 auto; display: flex; flex-wrap: wrap; - gap: 0.375rem 0.75rem; - font-size: 0.8125rem; + gap: 0.25rem 0.5rem; + font-size: 0.75rem; color: hsl(var(--color-muted-foreground)); font-variant-numeric: tabular-nums; } @@ -146,7 +166,6 @@ font-weight: 500; } - /* Empty-State: kein Stapel-Hint, dashed Border über CardSurface-Wrapper */ .stack-wrap.empty :global(.cover.empty) { border-style: dashed; background: transparent; diff --git a/apps/web/src/lib/components/Header.svelte b/apps/web/src/lib/components/Header.svelte index 8055d43..8277622 100644 --- a/apps/web/src/lib/components/Header.svelte +++ b/apps/web/src/lib/components/Header.svelte @@ -12,7 +12,6 @@ const navOptions = $derived([ { id: 'decks', label: t('nav.decks') }, - { id: 'study', label: t('nav.study') }, { id: 'explore', label: t('nav.explore') }, { id: 'import', label: t('nav.import') }, { id: 'stats', label: t('nav.stats') }, @@ -20,73 +19,136 @@ const activeNav = $derived.by(() => { const path = page.url.pathname; - if (path.startsWith('/decks')) return 'decks'; - if (path.startsWith('/study')) return 'study'; - // /explore zeigt aktiv für Marketplace-Surfaces: - // /explore selbst, /d/, /u/, /me/{published,subscribed,forks}. + if (path.startsWith('/decks') || path.startsWith('/study')) return 'decks'; if ( path.startsWith('/explore') || path.startsWith('/d/') || path.startsWith('/u/') || path.startsWith('/me/') - ) { - return 'explore'; - } + ) return 'explore'; if (path.startsWith('/import')) return 'import'; if (path.startsWith('/stats')) return 'stats'; return ''; }); + const userInitial = $derived( + devUser.user?.name?.charAt(0).toUpperCase() ?? + devUser.user?.email?.charAt(0).toUpperCase() ?? + '?' + ); + function navTo(id: string) { goto('/' + id); } -
-
- - - {t('app.name')} + - + diff --git a/apps/web/src/lib/components/NewDeckCard.svelte b/apps/web/src/lib/components/NewDeckCard.svelte new file mode 100644 index 0000000..3c5f0af --- /dev/null +++ b/apps/web/src/lib/components/NewDeckCard.svelte @@ -0,0 +1,398 @@ + + +
+ {#if !open} + (open = true)} ariaLabel={t('deck_new.title')} class="new-card"> +
+ + {t('deck_new.title')} +
+
+ {:else} + +
+ + + + + + +
+ Fach + + {#if catOpen} +
+ {#each DECK_CATEGORY_IDS as id} + + {/each} +
+ {/if} +
+ + + + + + + + {#if aiError} + + {/if} + {#if generating} +

Generiere… ca. 10–60 s

+ {/if} + +
+ + + +
+ +
+
+ {/if} +
+ + diff --git a/apps/web/src/routes/decks/+page.svelte b/apps/web/src/routes/decks/+page.svelte index 0962bb9..5a765b5 100644 --- a/apps/web/src/routes/decks/+page.svelte +++ b/apps/web/src/routes/decks/+page.svelte @@ -56,25 +56,14 @@ } function handleSelect(deckId: string) { - // Stufe 1: andere Decks weichen, selected hebt sich. selectedId = deckId; - // URL wechselt nach kurzer Verzögerung. Klick auf einen Stapel - // landet direkt im Lern-Modus — die Detail-View (/decks/) - // bleibt über den "Karten verwalten"-Link im Study-Header - // erreichbar. setTimeout(() => { goto(`/study/${deckId}`); }, 220); } -
-

{t('decks.title')}

- -
+

{t('decks.title')}

@@ -84,61 +73,17 @@

{t('decks.loading')}

{:else if error}

{t('decks.error', { msg: error })}

-{:else if decks.length === 0} -
-

{t('decks.empty')}

- {t('decks.empty_cta')} → -
{:else} {/if} diff --git a/apps/web/src/routes/decks/new-ai/+page.svelte b/apps/web/src/routes/decks/new-ai/+page.svelte index 914a850..75a52b8 100644 --- a/apps/web/src/routes/decks/new-ai/+page.svelte +++ b/apps/web/src/routes/decks/new-ai/+page.svelte @@ -1,146 +1,4 @@ - - - KI-Deck · Cards - - -
- - ← {t('nav.decks')} - -

✨ Deck mit KI erstellen

-

- Beschreibe ein Thema, und mana-llm baut ein Deck mit Karteikarten daraus. Du kannst die Karten - danach jederzeit editieren oder ergänzen. -

- -
- - -
- - - -
- - {#if error} - - {/if} - -
- - {t('deck_new.cancel')} -
- - {#if busy} -

- mana-llm denkt nach. Bei {count} Karten typischerweise 10–60 Sekunden. -

- {/if} -
- - -
diff --git a/apps/web/src/routes/decks/new/+page.svelte b/apps/web/src/routes/decks/new/+page.svelte index b899bfc..9590117 100644 --- a/apps/web/src/routes/decks/new/+page.svelte +++ b/apps/web/src/routes/decks/new/+page.svelte @@ -1,15 +1,32 @@
@@ -34,13 +66,14 @@ >

{t('deck_new.title')}

-
+ @@ -55,26 +88,134 @@ > - +
+ Fach +
+ {#each DECK_CATEGORY_IDS as id} + + {/each} +
+
-
+
+ + + +
+ + {#if aiError} + + {/if} + + {#if generating} +

+ mana-llm generiert… Bei {count} Karten typischerweise 10–60 Sekunden. +

+ {/if} + +
- {t('deck_new.cancel')} + {generating ? '✨ Generiere…' : '✨ Mit KI generieren'} + + {t('deck_new.cancel')}
+ + diff --git a/apps/web/src/routes/study/+page.svelte b/apps/web/src/routes/study/+page.svelte index 51a5234..af960ee 100644 --- a/apps/web/src/routes/study/+page.svelte +++ b/apps/web/src/routes/study/+page.svelte @@ -1,80 +1,4 @@ - -

{t('study.title')}

- -
- -
- -{#if loading} -

{t('study_session.loading')}

-{:else} -
    - {#each items as it (it.deck.id)} -
  • -
    - {#if it.deck.color} - - {/if} - {it.deck.name} - - {t('study.due_count', { n: it.due })} - -
    - {#if it.due > 0} - - {t('study.study_now')} - - {:else} - - {/if} -
  • - {/each} -
-{/if}