feat: BR Overview + Modal for New Recommendations

This commit is contained in:
2024-03-20 18:10:02 +01:00
parent 923e41b396
commit fffe1b4717
3 changed files with 139 additions and 58 deletions

View File

@@ -2,50 +2,95 @@
import { useBookRecommendationStore } from '~/stores/book-recommendations'
const isOpen = ref(false)
const loading = ref(false)
const dayjs = useDayjs()
const form = ref()
const state = reactive({
book_name: null,
author: null,
description: null,
isbn: null,
pages: null,
cover_image: null,
status: null,
interface State {
book_name: string
author: string
description: string
isbn: string
pages: number
cover_image?: File | string
status: string
published_at: string
// Index signature
[key: string]: string | number | File | undefined
}
const state: State = reactive({
book_name: '',
author: '',
description: '',
isbn: '',
pages: 0,
cover_image: '',
status: 'PENDING',
published_at: dayjs().format('YYYY-MM-DD'),
})
const bookRecommendationStore = useBookRecommendationStore()
const { refresh: onSubmit, status } = useFetch<any>(`book-recommendations`, {
method: 'POST',
body: state,
immediate: false,
watch: false,
async onResponse({ response }) {
if (response?.status === 422) {
form.value.setErrors(response._data?.errors)
}
else if (response.ok) {
useToast().add({
icon: 'i-heroicons-check-circle-20-solid',
title: 'Buchempfehlung wurde erfolgreich aktualisiert.',
color: 'emerald',
})
await bookRecommendationStore.fetchRecommendations()
function handleCoverImageInput(event: Event) {
const file = (event.target as HTMLInputElement).files?.[0]
if (file) {
// Update the state with the selected file
state.cover_image = file
}
}
state.book_name = null
state.author = null
state.description = null
state.isbn = null
state.pages = null
state.cover_image = null
state.status = null
isOpen.value = false
async function onSubmit() {
loading.value = true
const formData = new FormData()
for (const key in state) {
const item = state[key]
if (item === undefined) {
continue
}
},
})
if (key === 'cover_image' && state[key] instanceof File) {
formData.append(key, item as Blob, (state[key] as File).name)
}
else {
if (key === 'cover_image') {
continue
}
const value = typeof item === 'string' ? item : String(item)
formData.append(key, value)
}
}
await $fetch<any>(`book-recommendations`, {
method: 'POST',
body: formData,
async onResponse({ response }) {
loading.value = false
if (response?.status === 422) {
form.value.setErrors(response._data?.errors)
}
else if (response.ok) {
useToast().add({
icon: 'i-heroicons-check-circle-20-solid',
title: 'Buchempfehlung wurde erfolgreich angelegt.',
color: 'emerald',
})
await bookRecommendationStore.fetchRecommendations()
state.book_name = ''
state.author = ''
state.description = ''
state.isbn = ''
state.pages = 0
state.cover_image = ''
state.status = 'PENDING'
state.published_at = dayjs().format('YYYY-MM-DD')
isOpen.value = false
}
},
})
}
</script>
<template>
@@ -72,9 +117,15 @@ const { refresh: onSubmit, status } = useFetch<any>(`book-recommendations`, {
<UFormGroup label="Autor" name="author">
<UInput v-model="state.author" />
</UFormGroup>
<UFormGroup label="Erstveröffentlichung">
<UInput v-model="state.published_at" type="date" />
</UFormGroup>
<UFormGroup label="Beschreibung" name="description">
<UTextarea v-model="state.description" />
</UFormGroup>
<UFormGroup label="Cover" name="cover_image">
<UInput type="file" @change="handleCoverImageInput" />
</UFormGroup>
<UFormGroup label="ISBN" name="isbn">
<UInput v-model="state.isbn" />
</UFormGroup>