refactor(admin): use shared api client across projects list, posts list, new post, project edit load, and media modal

This commit is contained in:
Justin Edmund 2025-08-31 11:03:27 -07:00
parent f5a440a2ca
commit 9bc942211a
5 changed files with 26 additions and 152 deletions

View file

@ -225,8 +225,6 @@
// Short delay to prevent flicker
await new Promise((resolve) => setTimeout(resolve, 500))
const auth = localStorage.getItem('admin_auth')
if (!auth) return
let url = `/api/media?page=${page}&limit=24`
@ -248,15 +246,7 @@
url += `&albumId=${albumId}`
}
const response = await fetch(url, {
headers: { Authorization: `Basic ${auth}` }
})
if (!response.ok) {
throw new Error('Failed to load media')
}
const data = await response.json()
const data = await (await import('$lib/admin/api')).api.get(url)
if (page === 1) {
// Only clear media after we have new data to prevent flash

View file

@ -1,6 +1,7 @@
<script lang="ts">
import { onMount } from 'svelte'
import { goto } from '$app/navigation'
import { goto } from '$app/navigation'
import { api } from '$lib/admin/api'
import AdminPage from '$lib/components/admin/AdminPage.svelte'
import AdminHeader from '$lib/components/admin/AdminHeader.svelte'
import AdminFilters from '$lib/components/admin/AdminFilters.svelte'
@ -85,25 +86,7 @@
async function loadPosts() {
try {
const auth = localStorage.getItem('admin_auth')
if (!auth) {
goto('/admin/login')
return
}
const response = await fetch('/api/posts', {
headers: { Authorization: `Basic ${auth}` }
})
if (!response.ok) {
if (response.status === 401) {
goto('/admin/login')
return
}
throw new Error('Failed to load posts')
}
const data = await response.json()
const data = await api.get('/api/posts')
posts = data.posts || []
total = data.pagination?.total || posts.length
@ -209,28 +192,11 @@
async function handleTogglePublish(event: CustomEvent<{ post: Post }>) {
const { post } = event.detail
const auth = localStorage.getItem('admin_auth')
if (!auth) {
goto('/admin/login')
return
}
const newStatus = post.status === 'published' ? 'draft' : 'published'
try {
const response = await fetch(`/api/posts/${post.id}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
Authorization: `Basic ${auth}`
},
body: JSON.stringify({ status: newStatus })
})
if (response.ok) {
// Reload posts to refresh the list
await loadPosts()
}
await api.patch(`/api/posts/${post.id}`, { status: newStatus, updatedAt: post.updatedAt })
await loadPosts()
} catch (error) {
console.error('Failed to toggle publish status:', error)
}
@ -244,24 +210,11 @@
async function confirmDelete() {
if (!postToDelete) return
const auth = localStorage.getItem('admin_auth')
if (!auth) {
goto('/admin/login')
return
}
try {
const response = await fetch(`/api/posts/${postToDelete.id}`, {
method: 'DELETE',
headers: { Authorization: `Basic ${auth}` }
})
if (response.ok) {
showDeleteConfirmation = false
postToDelete = null
// Reload posts to refresh the list
await loadPosts()
}
await api.delete(`/api/posts/${postToDelete.id}`)
showDeleteConfirmation = false
postToDelete = null
await loadPosts()
} catch (error) {
console.error('Failed to delete post:', error)
}

View file

@ -1,6 +1,7 @@
<script lang="ts">
import { page } from '$app/stores'
import { goto } from '$app/navigation'
import { goto } from '$app/navigation'
import { api } from '$lib/admin/api'
import { onMount } from 'svelte'
import AdminPage from '$lib/components/admin/AdminPage.svelte'
import Composer from '$lib/components/admin/composer'
@ -73,12 +74,6 @@
}
async function handleSave(publishStatus?: 'draft' | 'published') {
const auth = localStorage.getItem('admin_auth')
if (!auth) {
goto('/admin/login')
return
}
saving = true
const postData = {
title: config?.showTitle ? title : null,
@ -91,22 +86,8 @@
}
try {
const response = await fetch('/api/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Basic ${auth}`
},
body: JSON.stringify(postData)
})
if (response.ok) {
const newPost = await response.json()
// Redirect to edit page after creation
goto(`/admin/posts/${newPost.id}/edit`)
} else {
console.error('Failed to create post:', response.statusText)
}
const newPost = await api.post('/api/posts', postData)
goto(`/admin/posts/${newPost.id}/edit`)
} catch (error) {
console.error('Failed to create post:', error)
} finally {

View file

@ -1,6 +1,7 @@
<script lang="ts">
import { onMount } from 'svelte'
import { goto } from '$app/navigation'
import { goto } from '$app/navigation'
import { api } from '$lib/admin/api'
import AdminPage from '$lib/components/admin/AdminPage.svelte'
import AdminHeader from '$lib/components/admin/AdminHeader.svelte'
import AdminFilters from '$lib/components/admin/AdminFilters.svelte'
@ -79,25 +80,7 @@
async function loadProjects() {
try {
const auth = localStorage.getItem('admin_auth')
if (!auth) {
goto('/admin/login')
return
}
const response = await fetch('/api/projects', {
headers: { Authorization: `Basic ${auth}` }
})
if (!response.ok) {
if (response.status === 401) {
goto('/admin/login')
return
}
throw new Error('Failed to load projects')
}
const data = await response.json()
const data = await api.get('/api/projects')
projects = data.projects
// Calculate status counts
@ -126,21 +109,9 @@
const project = event.detail.project
try {
const auth = localStorage.getItem('admin_auth')
const newStatus = project.status === 'published' ? 'draft' : 'published'
const response = await fetch(`/api/projects/${project.id}`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
Authorization: `Basic ${auth}`
},
body: JSON.stringify({ status: newStatus })
})
if (response.ok) {
await loadProjects()
}
await api.patch(`/api/projects/${project.id}`, { status: newStatus, updatedAt: project.updatedAt })
await loadProjects()
} catch (err) {
console.error('Failed to update project status:', err)
}
@ -155,16 +126,8 @@
if (!projectToDelete) return
try {
const auth = localStorage.getItem('admin_auth')
const response = await fetch(`/api/projects/${projectToDelete.id}`, {
method: 'DELETE',
headers: { Authorization: `Basic ${auth}` }
})
if (response.ok) {
await loadProjects()
}
await api.delete(`/api/projects/${projectToDelete.id}`)
await loadProjects()
} catch (err) {
console.error('Failed to delete project:', err)
} finally {

View file

@ -1,9 +1,10 @@
<script lang="ts">
import { onMount } from 'svelte'
import { goto } from '$app/navigation'
import { page } from '$app/stores'
import ProjectForm from '$lib/components/admin/ProjectForm.svelte'
import type { Project } from '$lib/types/project'
import { page } from '$app/stores'
import ProjectForm from '$lib/components/admin/ProjectForm.svelte'
import type { Project } from '$lib/types/project'
import { api } from '$lib/admin/api'
let project = $state<Project | null>(null)
let isLoading = $state(true)
@ -17,21 +18,7 @@
async function loadProject() {
try {
const auth = localStorage.getItem('admin_auth')
if (!auth) {
goto('/admin/login')
return
}
const response = await fetch(`/api/projects/${projectId}`, {
headers: { Authorization: `Basic ${auth}` }
})
if (!response.ok) {
throw new Error('Failed to load project')
}
const data = await response.json()
const data = await api.get(`/api/projects/${projectId}`)
project = data
} catch (err) {
error = 'Failed to load project'