60 lines
1.5 KiB
TypeScript
60 lines
1.5 KiB
TypeScript
import { ref } from 'vue'
|
|
import { defineStore } from 'pinia'
|
|
|
|
export interface ChildElement {
|
|
id: number
|
|
title: string
|
|
description: string
|
|
}
|
|
|
|
export interface Element extends ChildElement {
|
|
richText: string
|
|
}
|
|
|
|
interface ElementResponse {
|
|
element: Element
|
|
childElements: ChildElement[]
|
|
}
|
|
|
|
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL as string
|
|
|
|
export const useElementsStore = defineStore('elements', () => {
|
|
const element = ref<Element | null>(null)
|
|
const childElements = ref<ChildElement[]>([])
|
|
const isLoading = ref(false)
|
|
const error = ref<string | null>(null)
|
|
|
|
async function fetchElement(elementId: string): Promise<void> {
|
|
element.value = null
|
|
childElements.value = []
|
|
error.value = null
|
|
isLoading.value = true
|
|
|
|
try {
|
|
const encodedElementId = encodeURIComponent(elementId)
|
|
const elementUrl = `${API_BASE_URL}/api/elements/${encodedElementId}`
|
|
const response = await fetch(elementUrl)
|
|
|
|
if (response.status === 404) {
|
|
error.value = 'Element not found'
|
|
return
|
|
}
|
|
|
|
if (!response.ok) {
|
|
error.value = 'Could not load element'
|
|
return
|
|
}
|
|
|
|
const data: ElementResponse = await response.json()
|
|
element.value = data.element
|
|
childElements.value = data.childElements
|
|
} catch {
|
|
childElements.value = []
|
|
error.value = 'Network error - could not load element'
|
|
} finally {
|
|
isLoading.value = false
|
|
}
|
|
}
|
|
|
|
return { element, childElements, isLoading, error, fetchElement }
|
|
})
|