feat: add wishlist
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
<script setup lang="ts">
|
||||
import type { FormSubmitEvent } from '@nuxt/ui'
|
||||
|
||||
const emit = defineEmits<{ saved: [] }>()
|
||||
|
||||
const { data: books, status } = useFetch<DiaryBook[]>('/api/diary/books', { key: 'diary-books', default: () => [], lazy: true })
|
||||
|
||||
// Recently read books first, then the rest by title
|
||||
const bookItems = computed(() => books.value
|
||||
.toSorted((a, b) => (b.readDate ?? '').localeCompare(a.readDate ?? '') || a.title.localeCompare(b.title, 'de'))
|
||||
.map(book => ({
|
||||
label: book.title,
|
||||
description: book.authors.join('; '),
|
||||
originalTitle: book.originalTitle,
|
||||
value: book.id
|
||||
})))
|
||||
|
||||
const state = reactive({ bookId: undefined as number | undefined, date: todayIso(), text: '' })
|
||||
const { saving, save } = useSaveEntry({
|
||||
url: '/api/diary/reviews',
|
||||
dataKey: ['diary-reviews', 'diary-books'],
|
||||
noun: 'review',
|
||||
onSaved: () => emit('saved')
|
||||
})
|
||||
|
||||
watch(() => state.bookId, (id) => {
|
||||
state.date = books.value.find(book => book.id === id)?.readDate ?? todayIso()
|
||||
})
|
||||
|
||||
function onSubmit(event: FormSubmitEvent<NewReviewInput>) {
|
||||
return save(event.data)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UForm :schema="newReviewSchema" :state="state" class="space-y-5" @submit="onSubmit">
|
||||
<UFormField label="Book" 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"
|
||||
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>
|
||||
<UInput v-model="state.date" type="date" />
|
||||
</UFormField>
|
||||
|
||||
<UFormField label="Review" 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" />
|
||||
</UForm>
|
||||
</template>
|
||||
Reference in New Issue
Block a user