feat: add hub
This commit is contained in:
@@ -16,7 +16,7 @@ const background = computed(() => {
|
||||
class="relative size-full overflow-hidden text-white [container-type:inline-size]"
|
||||
:style="{ background }"
|
||||
role="img"
|
||||
:aria-label="`Cover of ${title}`"
|
||||
:aria-label="`Cover von ${title}`"
|
||||
>
|
||||
<span class="absolute inset-y-0 left-[7cqw] w-px bg-white/25" aria-hidden="true" />
|
||||
<div class="flex size-full flex-col justify-between gap-1 p-[8cqw] pl-[12cqw]">
|
||||
|
||||
@@ -47,7 +47,7 @@ const parts = computed(() => highlight(props.entry.text, props.search))
|
||||
color="neutral"
|
||||
variant="link"
|
||||
class="mt-1 px-0"
|
||||
:label="expanded ? 'Show less' : `Read more (${wordCount} words)`"
|
||||
:label="expanded ? 'Weniger anzeigen' : `Weiterlesen (${wordCount} Wörter)`"
|
||||
@click="expanded = !expanded"
|
||||
/>
|
||||
</article>
|
||||
|
||||
@@ -7,10 +7,11 @@ const log = useLog()
|
||||
<template>
|
||||
<div class="mx-auto max-w-3xl">
|
||||
<div class="mb-8 flex flex-wrap items-center justify-between gap-3">
|
||||
<h1 class="text-2xl font-semibold text-highlighted">Diary</h1>
|
||||
<h1 class="text-2xl font-semibold text-highlighted">Tagebuch</h1>
|
||||
<div class="flex w-full items-center gap-2 sm:w-auto">
|
||||
<UInput v-model="search" icon="i-lucide-search" placeholder="Search the diary" class="flex-1 sm:w-64 sm:flex-none" />
|
||||
<UButton icon="i-lucide-plus" label="Log" @click="log.show()" />
|
||||
<UInput v-model="search" icon="i-lucide-search" placeholder="Tagebuch durchsuchen" class="flex-1 sm:w-64 sm:flex-none" />
|
||||
<UButton icon="i-lucide-plus" label="Eintragen" @click="log.show()" />
|
||||
<AppHeaderActions />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -20,7 +21,7 @@ const log = useLog()
|
||||
color="error"
|
||||
variant="subtle"
|
||||
icon="i-lucide-triangle-alert"
|
||||
:title="`Couldn't load your ${what}`"
|
||||
:title="`${what} konnten nicht geladen werden`"
|
||||
:description="errorMessage(error)"
|
||||
class="mb-6"
|
||||
/>
|
||||
@@ -38,7 +39,7 @@ const log = useLog()
|
||||
</section>
|
||||
|
||||
<p v-if="!years.length && !errors.length" class="py-16 text-center text-muted">
|
||||
{{ search ? 'Nothing in the diary matches your search.' : 'Nothing logged yet.' }}
|
||||
{{ search ? 'Nichts im Tagebuch passt zur Suche.' : 'Noch nichts eingetragen.' }}
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
const { open, close } = useLog()
|
||||
|
||||
const tabs = [
|
||||
{ label: 'Note', value: 'note', icon: NOTE_ICON, slot: 'note' as const },
|
||||
{ label: 'Review', value: 'review', icon: REVIEW_ICON, slot: 'review' as const }
|
||||
{ label: 'Notiz', value: 'note', icon: NOTE_ICON, slot: 'note' as const },
|
||||
{ label: 'Rezension', value: 'review', icon: REVIEW_ICON, slot: 'review' as const }
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UModal v-model:open="open" title="Log">
|
||||
<UModal v-model:open="open" title="Eintragen">
|
||||
<template #body>
|
||||
<UTabs :items="tabs" default-value="note" class="w-full" :ui="{ content: 'pt-4' }">
|
||||
<template #note>
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { FormSubmitEvent } from '@nuxt/ui'
|
||||
const emit = defineEmits<{ saved: [] }>()
|
||||
|
||||
const state = reactive({ date: todayIso(), text: '' })
|
||||
const { saving, save } = useSaveEntry({ url: '/api/diary/notes', dataKey: 'diary-notes', noun: 'note', onSaved: () => emit('saved') })
|
||||
const { saving, save } = useSaveEntry({ url: '/api/diary/notes', dataKey: 'diary-notes', saved: 'Notiz gespeichert', failed: 'Notiz konnte nicht gespeichert werden', onSaved: () => emit('saved') })
|
||||
|
||||
function onSubmit(event: FormSubmitEvent<NewNoteInput>) {
|
||||
return save(event.data)
|
||||
@@ -13,14 +13,14 @@ function onSubmit(event: FormSubmitEvent<NewNoteInput>) {
|
||||
|
||||
<template>
|
||||
<UForm :schema="newNoteSchema" :state="state" class="space-y-5" @submit="onSubmit">
|
||||
<UFormField label="Date" name="date" required>
|
||||
<UFormField label="Datum" name="date" required>
|
||||
<UInput v-model="state.date" type="date" />
|
||||
</UFormField>
|
||||
|
||||
<UFormField label="Note" name="text" required>
|
||||
<UFormField label="Notiz" name="text" required>
|
||||
<UTextarea v-model="state.text" :rows="8" autoresize :maxrows="18" class="w-full" autofocus />
|
||||
</UFormField>
|
||||
|
||||
<UButton type="submit" label="Save note" :icon="NOTE_ICON" :loading="saving" />
|
||||
<UButton type="submit" label="Notiz speichern" :icon="NOTE_ICON" :loading="saving" />
|
||||
</UForm>
|
||||
</template>
|
||||
|
||||
@@ -19,7 +19,8 @@ const state = reactive({ bookId: undefined as number | undefined, date: todayIso
|
||||
const { saving, save } = useSaveEntry({
|
||||
url: '/api/diary/reviews',
|
||||
dataKey: ['diary-reviews', 'diary-books'],
|
||||
noun: 'review',
|
||||
saved: 'Rezension gespeichert',
|
||||
failed: 'Rezension konnte nicht gespeichert werden',
|
||||
onSaved: () => emit('saved')
|
||||
})
|
||||
|
||||
@@ -34,29 +35,29 @@ function onSubmit(event: FormSubmitEvent<NewReviewInput>) {
|
||||
|
||||
<template>
|
||||
<UForm :schema="newReviewSchema" :state="state" class="space-y-5" @submit="onSubmit">
|
||||
<UFormField label="Book" name="bookId" required>
|
||||
<UFormField label="Buch" name="bookId" required>
|
||||
<USelectMenu
|
||||
v-model="state.bookId"
|
||||
:items="bookItems"
|
||||
value-key="value"
|
||||
:filter-fields="['label', 'description', 'originalTitle']"
|
||||
:loading="status === 'pending'"
|
||||
:search-input="{ placeholder: 'Title or author' }"
|
||||
placeholder="Pick a book"
|
||||
:search-input="{ placeholder: 'Titel oder Autor' }"
|
||||
placeholder="Buch auswählen"
|
||||
icon="i-lucide-book-open"
|
||||
virtualize
|
||||
class="w-full"
|
||||
/>
|
||||
</UFormField>
|
||||
|
||||
<UFormField label="Read on" name="date" help="Saved as the book's read date" required>
|
||||
<UFormField label="Gelesen am" name="date" help="Wird als Lesedatum des Buchs gespeichert" required>
|
||||
<UInput v-model="state.date" type="date" />
|
||||
</UFormField>
|
||||
|
||||
<UFormField label="Review" name="text" required>
|
||||
<UFormField label="Rezension" name="text" required>
|
||||
<UTextarea v-model="state.text" :rows="8" autoresize :maxrows="18" class="w-full" />
|
||||
</UFormField>
|
||||
|
||||
<UButton type="submit" label="Save review" :icon="REVIEW_ICON" :loading="saving" />
|
||||
<UButton type="submit" label="Rezension speichern" :icon="REVIEW_ICON" :loading="saving" />
|
||||
</UForm>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user