bookclub-manager/nuxt/stores/book-recommendations.ts

147 lines
4.2 KiB
TypeScript

import { defineStore } from 'pinia'
export enum BookRecommendationStatusEnum {
PENDING = 'PENDING',
REJECTED = 'REJECTED',
ACTIVE = 'ACTIVE',
COMPLETED = 'COMPLETED',
}
export interface BookRecommendation {
id: number
book_name: string
author: string
description: string
isbn: string
pages: number
recommended_by?: number
recommender?: {
ulid: number
name: string
email: string
avatar: string
}
votes?: Vote[]
status: BookRecommendationStatusEnum
cover_image?: string
published_at?: string
}
export interface Vote {
book_recommendation_id: number
id: number
user_id: number
created_at: string
updated_at: string
}
export const useBookRecommendationStore = defineStore('bookRecommendations', () => {
const recommendations = ref<BookRecommendation[]>([])
const statusOptions = [
{
name: 'Ausstehend',
value: BookRecommendationStatusEnum.PENDING,
color: 'orange',
},
{
name: 'Abgelehnt',
value: BookRecommendationStatusEnum.REJECTED,
color: 'red',
},
{
name: 'Aktiv',
value: BookRecommendationStatusEnum.ACTIVE,
color: 'green',
},
{
name: 'Abgeschlossen',
value: BookRecommendationStatusEnum.COMPLETED,
color: 'primary',
},
]
// Fetch all book recommendations
const { refresh: fetchRecommendations, status: fetchRecommendationsStatus } = useFetch<BookRecommendation[]>('book-recommendations?with=recommender,votes', {
immediate: false,
onResponse({ response }) {
if (response.status === 200) {
recommendations.value = response._data
}
},
})
const { refresh: fetchActiveRecommendations, status: fetchActiveRecommendationsStatus } = useFetch<BookRecommendation[]>('book-recommendations?with=recommender,votes&status=ACTIVE', {
immediate: false,
onResponse({ response }) {
if (response.status === 200) {
recommendations.value = response._data
}
},
})
const updateRecommendationWS = async (data: Partial<BookRecommendation>) => {
// This data can be Partial, the id should always be present. We need to only update the properties that are present in the data object.
// We also have a special case for activeRecommendations, in this case we could have a new recommendation that needs to be added to the list. This should only happen if the status is ACTIVE.
// If the Status is not ACTIVE, we need to remove the recommendation from the list.
const index = recommendations.value.findIndex(r => r.id === data.id)
if (index !== -1) {
recommendations.value[index] = { ...recommendations.value[index], ...data }
}
switch (data.status) {
case BookRecommendationStatusEnum.ACTIVE:
const activeIndex = recommendations.value.findIndex(r => r.id === data.id)
if (activeIndex === -1) {
await createRecommendationWS(data)
}
break
default:
const inactiveIndex = recommendations.value.findIndex(r => r.id === data.id)
if (inactiveIndex !== -1) {
recommendations.value.splice(inactiveIndex, 1)
}
break
}
}
const deleteRecommendationWS = async (data: Partial<BookRecommendation>) => {
const index = recommendations.value.findIndex(r => r.id === data.id)
if (index !== -1) {
recommendations.value.splice(index, 1)
}
}
const createRecommendationWS = async (data: Partial<BookRecommendation>) => {
// Here we need to get the missing with data from the server
await useFetch<BookRecommendation>(`book-recommendations/${data.id}?with=recommender,votes`, {
onResponse({ response }) {
if (response.status === 200) {
recommendations.value.push(response._data)
}
},
})
}
function resetRecommendations() {
recommendations.value = []
}
return {
recommendations,
resetRecommendations,
updateRecommendationWS,
deleteRecommendationWS,
createRecommendationWS,
statusOptions,
fetchRecommendations,
fetchRecommendationsStatus,
fetchActiveRecommendations,
fetchActiveRecommendationsStatus,
}
})
if (import.meta.hot) {
import.meta.hot.accept(acceptHMRUpdate(useBookRecommendationStore, import.meta.hot))
}