add element upload UI
This commit is contained in:
parent
4292494345
commit
a2c3ffad8b
3 changed files with 384 additions and 67 deletions
|
|
@ -22,9 +22,7 @@ interface ElementResponse {
|
|||
export interface UpdateElementInput {
|
||||
title: string
|
||||
description: string
|
||||
iconImageUrl: string
|
||||
richText: string
|
||||
pdfPath: string
|
||||
youtubeUrl: string
|
||||
}
|
||||
|
||||
|
|
@ -32,6 +30,15 @@ interface UpdateElementResponse {
|
|||
element: Element
|
||||
}
|
||||
|
||||
interface ElementPatchInput {
|
||||
title?: string
|
||||
description?: string
|
||||
iconImageUrl?: string
|
||||
richText?: string
|
||||
pdfPath?: string
|
||||
youtubeUrl?: string
|
||||
}
|
||||
|
||||
interface ErrorResponse {
|
||||
error?: string
|
||||
}
|
||||
|
|
@ -44,6 +51,8 @@ export const useElementsStore = defineStore('elements', () => {
|
|||
const isLoading = ref(false)
|
||||
const error = ref<string | null>(null)
|
||||
const isSaving = ref(false)
|
||||
const isUploadingIconImage = ref(false)
|
||||
const isUploadingPdf = ref(false)
|
||||
const saveError = ref<string | null>(null)
|
||||
|
||||
async function fetchElement(elementId: string): Promise<void> {
|
||||
|
|
@ -80,6 +89,22 @@ export const useElementsStore = defineStore('elements', () => {
|
|||
}
|
||||
|
||||
async function updateElement(elementId: string, input: UpdateElementInput): Promise<boolean> {
|
||||
return await saveElementPatch(elementId, input, 'Could not save element')
|
||||
}
|
||||
|
||||
async function clearElementIconImage(elementId: string): Promise<boolean> {
|
||||
return await saveElementPatch(elementId, { iconImageUrl: '' }, 'Could not remove icon image')
|
||||
}
|
||||
|
||||
async function clearElementPdf(elementId: string): Promise<boolean> {
|
||||
return await saveElementPatch(elementId, { pdfPath: '' }, 'Could not remove PDF')
|
||||
}
|
||||
|
||||
async function saveElementPatch(
|
||||
elementId: string,
|
||||
input: ElementPatchInput,
|
||||
failureMessage: string,
|
||||
): Promise<boolean> {
|
||||
saveError.value = null
|
||||
isSaving.value = true
|
||||
|
||||
|
|
@ -93,46 +118,117 @@ export const useElementsStore = defineStore('elements', () => {
|
|||
body: JSON.stringify(input),
|
||||
})
|
||||
|
||||
if (response.status === 401) {
|
||||
saveError.value = 'Please log in again'
|
||||
return false
|
||||
}
|
||||
|
||||
if (response.status === 404) {
|
||||
saveError.value = 'Element not found'
|
||||
return false
|
||||
}
|
||||
|
||||
if (response.status === 400) {
|
||||
const data: ErrorResponse = await response.json()
|
||||
saveError.value = data.error ?? 'Could not save element'
|
||||
return false
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
saveError.value = 'Could not save element'
|
||||
return false
|
||||
}
|
||||
|
||||
const data: UpdateElementResponse = await response.json()
|
||||
element.value = data.element
|
||||
return true
|
||||
return await handleElementResponse(response, failureMessage)
|
||||
} catch {
|
||||
saveError.value = 'Network error - could not save element'
|
||||
saveError.value = `Network error - ${failureMessage.toLowerCase()}`
|
||||
return false
|
||||
} finally {
|
||||
isSaving.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function uploadElementIconImage(elementId: string, file: File): Promise<boolean> {
|
||||
saveError.value = null
|
||||
isUploadingIconImage.value = true
|
||||
|
||||
try {
|
||||
const encodedElementId = encodeURIComponent(elementId)
|
||||
const elementUrl = `${API_BASE_URL}/api/elements/${encodedElementId}`
|
||||
const formData = new FormData()
|
||||
formData.append('iconImage', file)
|
||||
const response = await fetch(`${elementUrl}/icon-image`, {
|
||||
method: 'POST',
|
||||
headers: { Accept: 'application/json' },
|
||||
credentials: 'include',
|
||||
body: formData,
|
||||
})
|
||||
|
||||
return await handleElementResponse(response, 'Could not upload icon image')
|
||||
} catch {
|
||||
saveError.value = 'Network error - could not upload icon image'
|
||||
return false
|
||||
} finally {
|
||||
isUploadingIconImage.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function uploadElementPdf(elementId: string, file: File): Promise<boolean> {
|
||||
saveError.value = null
|
||||
isUploadingPdf.value = true
|
||||
|
||||
try {
|
||||
const encodedElementId = encodeURIComponent(elementId)
|
||||
const elementUrl = `${API_BASE_URL}/api/elements/${encodedElementId}`
|
||||
const formData = new FormData()
|
||||
formData.append('pdf', file)
|
||||
const response = await fetch(`${elementUrl}/pdf`, {
|
||||
method: 'POST',
|
||||
headers: { Accept: 'application/json' },
|
||||
credentials: 'include',
|
||||
body: formData,
|
||||
})
|
||||
|
||||
return await handleElementResponse(response, 'Could not upload PDF')
|
||||
} catch {
|
||||
saveError.value = 'Network error - could not upload PDF'
|
||||
return false
|
||||
} finally {
|
||||
isUploadingPdf.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function handleElementResponse(
|
||||
response: Response,
|
||||
failureMessage: string,
|
||||
): Promise<boolean> {
|
||||
if (response.status === 401) {
|
||||
saveError.value = 'Please log in again'
|
||||
return false
|
||||
}
|
||||
|
||||
if (response.status === 404) {
|
||||
saveError.value = 'Element not found'
|
||||
return false
|
||||
}
|
||||
|
||||
if (response.status === 400) {
|
||||
saveError.value = await errorMessage(response, failureMessage)
|
||||
return false
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
saveError.value = failureMessage
|
||||
return false
|
||||
}
|
||||
|
||||
const data: UpdateElementResponse = await response.json()
|
||||
element.value = data.element
|
||||
return true
|
||||
}
|
||||
|
||||
async function errorMessage(response: Response, fallbackMessage: string): Promise<string> {
|
||||
try {
|
||||
const data: ErrorResponse = await response.json()
|
||||
return data.error ?? fallbackMessage
|
||||
} catch {
|
||||
return fallbackMessage
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
element,
|
||||
childElements,
|
||||
isLoading,
|
||||
error,
|
||||
isSaving,
|
||||
isUploadingIconImage,
|
||||
isUploadingPdf,
|
||||
saveError,
|
||||
fetchElement,
|
||||
updateElement,
|
||||
uploadElementIconImage,
|
||||
uploadElementPdf,
|
||||
clearElementIconImage,
|
||||
clearElementPdf,
|
||||
}
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue