63 lines
2.0 KiB
Vue
63 lines
2.0 KiB
Vue
<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>
|