feat(decks): Deck-Kategorien über den ganzen Stack
Some checks are pending
CI / validate (push) Waiting to run

- cards-domain: DECK_CATEGORY_IDS, Labels, DeckCategorySchema,
  category-Feld im DeckSchema
- DB-Schema (decks + marketplace/decks): category-Spalte
- API-Routen: category in create/update/list/explore
- Web: DeckCategoryIcon-Komponente, Kategorie-Picker auf Deck-Detail,
  Kategorie-Icon in DeckListGrid (Marketplace)
- Layout: Bottom-Padding für floating Nav-Bar

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-05-09 20:24:47 +02:00
parent 5876f95d85
commit 7bf61315b5
13 changed files with 251 additions and 11 deletions

View file

@ -4,6 +4,37 @@ import { FsrsSettingsSchema } from './fsrs-settings.ts';
const VisibilitySchema = z.enum(['private', 'space', 'public']);
export const DECK_CATEGORY_IDS = [
'language',
'medicine',
'science',
'math',
'history',
'law',
'technology',
'arts',
'music',
'sport',
'other',
] as const;
export type DeckCategoryId = (typeof DECK_CATEGORY_IDS)[number];
export const DeckCategorySchema = z.enum(DECK_CATEGORY_IDS);
export const DECK_CATEGORY_LABELS: Record<DeckCategoryId, string> = {
language: 'Sprache',
medicine: 'Medizin',
science: 'Wissenschaft',
math: 'Mathematik',
history: 'Geschichte',
law: 'Recht',
technology: 'Technik',
arts: 'Kunst',
music: 'Musik',
sport: 'Sport',
other: 'Sonstiges',
};
export const DeckSchema = z
.object({
id: z.string().min(1),
@ -15,6 +46,7 @@ export const DeckSchema = z
.regex(/^#[0-9a-fA-F]{6}$/)
.optional()
.nullable(),
category: DeckCategorySchema.optional().nullable(),
visibility: VisibilitySchema.default('private'),
fsrs_settings: FsrsSettingsSchema.default({}),
content_hash: z.string().optional().nullable(),
@ -32,6 +64,7 @@ export const DeckCreateSchema = z
.string()
.regex(/^#[0-9a-fA-F]{6}$/)
.optional(),
category: DeckCategorySchema.optional(),
visibility: VisibilitySchema.optional(),
fsrs_settings: FsrsSettingsSchema.optional(),
})