diff --git a/src/lib/components/Lightbox.svelte b/src/lib/components/Lightbox.svelte
index 5aa30e2..3564561 100644
--- a/src/lib/components/Lightbox.svelte
+++ b/src/lib/components/Lightbox.svelte
@@ -131,7 +131,7 @@
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.9);
- z-index: 1000;
+ z-index: 1400;
display: flex;
align-items: center;
justify-content: center;
diff --git a/src/lib/components/PhotoLightbox.svelte b/src/lib/components/PhotoLightbox.svelte
index a7550f8..2614f43 100644
--- a/src/lib/components/PhotoLightbox.svelte
+++ b/src/lib/components/PhotoLightbox.svelte
@@ -173,7 +173,7 @@
display: flex;
align-items: center;
justify-content: center;
- z-index: 1000;
+ z-index: 1400;
padding: $unit-2x;
@include breakpoint('phone') {
diff --git a/src/lib/components/admin/AdminSegmentedController.svelte b/src/lib/components/admin/AdminSegmentedController.svelte
index 3cd680b..1eb962b 100644
--- a/src/lib/components/admin/AdminSegmentedController.svelte
+++ b/src/lib/components/admin/AdminSegmentedController.svelte
@@ -237,7 +237,7 @@
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
min-width: 150px;
- z-index: 1000;
+ z-index: 1050;
overflow: hidden;
animation: slideDown 0.2s ease;
}
diff --git a/src/lib/components/admin/AlbumListItem.svelte b/src/lib/components/admin/AlbumListItem.svelte
index 23afafd..09f8e9a 100644
--- a/src/lib/components/admin/AlbumListItem.svelte
+++ b/src/lib/components/admin/AlbumListItem.svelte
@@ -272,7 +272,7 @@
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
overflow: hidden;
min-width: 180px;
- z-index: 10;
+ z-index: 1050;
}
.dropdown-item {
diff --git a/src/lib/components/admin/DropdownMenu.svelte b/src/lib/components/admin/DropdownMenu.svelte
index 55c6a51..833612d 100644
--- a/src/lib/components/admin/DropdownMenu.svelte
+++ b/src/lib/components/admin/DropdownMenu.svelte
@@ -97,7 +97,7 @@
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
overflow: hidden;
min-width: 180px;
- z-index: 1000;
+ z-index: 1050;
}
.dropdown-item {
diff --git a/src/lib/components/admin/DropdownMenuContainer.svelte b/src/lib/components/admin/DropdownMenuContainer.svelte
index 91559cc..ff63d57 100644
--- a/src/lib/components/admin/DropdownMenuContainer.svelte
+++ b/src/lib/components/admin/DropdownMenuContainer.svelte
@@ -23,6 +23,6 @@
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
overflow: hidden;
min-width: 180px;
- z-index: 10;
+ z-index: 1050;
}
diff --git a/src/lib/components/admin/GenericMetadataPopover.svelte b/src/lib/components/admin/GenericMetadataPopover.svelte
index 224eb68..f6bd96e 100644
--- a/src/lib/components/admin/GenericMetadataPopover.svelte
+++ b/src/lib/components/admin/GenericMetadataPopover.svelte
@@ -106,7 +106,7 @@
popoverElement.style.position = 'fixed'
popoverElement.style.top = `${top}px`
popoverElement.style.left = `${left}px`
- popoverElement.style.zIndex = '1000'
+ popoverElement.style.zIndex = '1200'
}
function handleFieldUpdate(key: string, value: any) {
diff --git a/src/lib/components/admin/MetadataPopover.svelte b/src/lib/components/admin/MetadataPopover.svelte
index fe4970a..d5da20b 100644
--- a/src/lib/components/admin/MetadataPopover.svelte
+++ b/src/lib/components/admin/MetadataPopover.svelte
@@ -90,7 +90,7 @@
popoverElement.style.position = 'fixed'
popoverElement.style.top = `${top}px`
popoverElement.style.left = `${left}px`
- popoverElement.style.zIndex = '1000'
+ popoverElement.style.zIndex = '1200'
}
onMount(() => {
diff --git a/src/lib/components/admin/Modal.svelte b/src/lib/components/admin/Modal.svelte
index e0f9fd7..23bfeee 100644
--- a/src/lib/components/admin/Modal.svelte
+++ b/src/lib/components/admin/Modal.svelte
@@ -89,7 +89,7 @@
display: flex;
justify-content: center;
align-items: center;
- z-index: 1000;
+ z-index: 1400;
padding: $unit-2x;
}
diff --git a/src/lib/components/admin/PostDropdown.svelte b/src/lib/components/admin/PostDropdown.svelte
index e801de3..f10ab6f 100644
--- a/src/lib/components/admin/PostDropdown.svelte
+++ b/src/lib/components/admin/PostDropdown.svelte
@@ -146,7 +146,7 @@
border-radius: $unit-2x;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
min-width: 140px;
- z-index: 100;
+ z-index: 1050;
overflow: hidden;
margin: 0;
padding: 0;
diff --git a/src/lib/components/admin/ProjectForm.svelte b/src/lib/components/admin/ProjectForm.svelte
index 4fa1bd5..b9c14ce 100644
--- a/src/lib/components/admin/ProjectForm.svelte
+++ b/src/lib/components/admin/ProjectForm.svelte
@@ -220,28 +220,26 @@
diff --git a/src/lib/server/cloudinary.ts b/src/lib/server/cloudinary.ts
index 0e90a2e..53c24d9 100644
--- a/src/lib/server/cloudinary.ts
+++ b/src/lib/server/cloudinary.ts
@@ -77,8 +77,11 @@ export async function uploadFile(
customOptions?: any
): Promise {
try {
+ // TEMPORARY: Force Cloudinary usage for testing
+ const FORCE_CLOUDINARY_IN_DEV = true; // Toggle this to test
+
// Use local storage in development or when Cloudinary is not configured
- if (dev || !isCloudinaryConfigured()) {
+ if ((dev && !FORCE_CLOUDINARY_IN_DEV) || !isCloudinaryConfigured()) {
logger.info('Using local storage for file upload')
const localResult = await uploadFileLocally(file, type)
@@ -123,14 +126,13 @@ export async function uploadFile(
}
// Log upload attempt for debugging
- if (isSvg) {
- logger.info('Attempting SVG upload with options:', {
- filename: file.name,
- mimeType: file.type,
- size: file.size,
- uploadOptions
- })
- }
+ logger.info('Attempting file upload:', {
+ filename: file.name,
+ mimeType: file.type,
+ size: file.size,
+ isSvg,
+ uploadOptions
+ })
// Upload to Cloudinary
const result = await new Promise((resolve, reject) => {
@@ -168,6 +170,17 @@ export async function uploadFile(
} catch (error) {
logger.error('Cloudinary upload failed', error as Error)
logger.mediaUpload(file.name, file.size, file.type, false)
+
+ // Enhanced error logging
+ if (error instanceof Error) {
+ logger.error('Upload error details:', {
+ filename: file.name,
+ mimeType: file.type,
+ size: file.size,
+ errorMessage: error.message,
+ errorStack: error.stack
+ })
+ }
return {
success: false,
diff --git a/src/routes/admin/albums/[id]/edit/+page.svelte b/src/routes/admin/albums/[id]/edit/+page.svelte
index dd78a55..e63b98e 100644
--- a/src/routes/admin/albums/[id]/edit/+page.svelte
+++ b/src/routes/admin/albums/[id]/edit/+page.svelte
@@ -10,7 +10,7 @@
import MediaLibraryModal from '$lib/components/admin/MediaLibraryModal.svelte'
import MediaDetailsModal from '$lib/components/admin/MediaDetailsModal.svelte'
import GalleryUploader from '$lib/components/admin/GalleryUploader.svelte'
- import SaveActionsGroup from '$lib/components/admin/SaveActionsGroup.svelte'
+ import StatusDropdown from '$lib/components/admin/StatusDropdown.svelte'
import AlbumMetadataPopover from '$lib/components/admin/AlbumMetadataPopover.svelte'
// Form state
@@ -93,7 +93,7 @@
}
}
- async function handleSave(publishStatus?: 'draft' | 'published') {
+ async function handleSave(newStatus?: string) {
if (!title.trim()) {
error = 'Title is required'
return
@@ -122,7 +122,7 @@
location: location.trim() || null,
isPhotography,
showInUniverse,
- status: publishStatus || status
+ status: newStatus || status
}
const response = await fetch(`/api/albums/${album.id}`, {
@@ -142,8 +142,8 @@
const updatedAlbum = await response.json()
album = updatedAlbum
- if (publishStatus) {
- status = publishStatus
+ if (newStatus) {
+ status = newStatus
}
} catch (err) {
error = err instanceof Error ? err.message : 'Failed to update album'
@@ -591,12 +591,19 @@
/>
{/if}
-
{/if}
diff --git a/src/routes/admin/posts/[id]/edit/+page.svelte b/src/routes/admin/posts/[id]/edit/+page.svelte
index efdd953..7432f6c 100644
--- a/src/routes/admin/posts/[id]/edit/+page.svelte
+++ b/src/routes/admin/posts/[id]/edit/+page.svelte
@@ -8,7 +8,7 @@
import PostMetadataPopover from '$lib/components/admin/PostMetadataPopover.svelte'
import DeleteConfirmationModal from '$lib/components/admin/DeleteConfirmationModal.svelte'
import Button from '$lib/components/admin/Button.svelte'
- import SaveActionsGroup from '$lib/components/admin/SaveActionsGroup.svelte'
+ import StatusDropdown from '$lib/components/admin/StatusDropdown.svelte'
import type { JSONContent } from '@tiptap/core'
let post = $state(null)
@@ -48,49 +48,55 @@
type: 'paragraph',
content: block.content ? [{ type: 'text', text: block.content }] : []
}
-
+
case 'heading':
return {
type: 'heading',
attrs: { level: block.level || 1 },
content: block.content ? [{ type: 'text', text: block.content }] : []
}
-
+
case 'bulletList':
case 'ul':
return {
type: 'bulletList',
content: (block.content || []).map((item: any) => ({
type: 'listItem',
- content: [{
- type: 'paragraph',
- content: [{ type: 'text', text: item.content || item }]
- }]
+ content: [
+ {
+ type: 'paragraph',
+ content: [{ type: 'text', text: item.content || item }]
+ }
+ ]
}))
}
-
+
case 'orderedList':
case 'ol':
return {
type: 'orderedList',
content: (block.content || []).map((item: any) => ({
type: 'listItem',
- content: [{
- type: 'paragraph',
- content: [{ type: 'text', text: item.content || item }]
- }]
+ content: [
+ {
+ type: 'paragraph',
+ content: [{ type: 'text', text: item.content || item }]
+ }
+ ]
}))
}
-
+
case 'blockquote':
return {
type: 'blockquote',
- content: [{
- type: 'paragraph',
- content: [{ type: 'text', text: block.content || '' }]
- }]
+ content: [
+ {
+ type: 'paragraph',
+ content: [{ type: 'text', text: block.content || '' }]
+ }
+ ]
}
-
+
case 'codeBlock':
case 'code':
return {
@@ -98,7 +104,7 @@
attrs: { language: block.language || '' },
content: [{ type: 'text', text: block.content || '' }]
}
-
+
case 'image':
return {
type: 'image',
@@ -108,11 +114,11 @@
title: block.caption || ''
}
}
-
+
case 'hr':
case 'horizontalRule':
return { type: 'horizontalRule' }
-
+
default:
// Default to paragraph for unknown types
return {
@@ -134,66 +140,74 @@
return { blocks: [] }
}
- const blocks = tiptapContent.content.map((node: any) => {
- switch (node.type) {
- case 'paragraph':
- const text = extractTextFromNode(node)
- return text ? { type: 'paragraph', content: text } : null
-
- case 'heading':
- return {
- type: 'heading',
- level: node.attrs?.level || 1,
- content: extractTextFromNode(node)
- }
-
- case 'bulletList':
- return {
- type: 'bulletList',
- content: node.content?.map((item: any) => {
- const itemText = extractTextFromNode(item.content?.[0])
- return itemText
- }).filter(Boolean) || []
- }
-
- case 'orderedList':
- return {
- type: 'orderedList',
- content: node.content?.map((item: any) => {
- const itemText = extractTextFromNode(item.content?.[0])
- return itemText
- }).filter(Boolean) || []
- }
-
- case 'blockquote':
- return {
- type: 'blockquote',
- content: extractTextFromNode(node.content?.[0])
- }
-
- case 'codeBlock':
- return {
- type: 'codeBlock',
- language: node.attrs?.language || '',
- content: node.content?.[0]?.text || ''
- }
-
- case 'image':
- return {
- type: 'image',
- src: node.attrs?.src || '',
- alt: node.attrs?.alt || '',
- caption: node.attrs?.title || ''
- }
-
- case 'horizontalRule':
- return { type: 'hr' }
-
- default:
- // Skip unknown types
- return null
- }
- }).filter(Boolean)
+ const blocks = tiptapContent.content
+ .map((node: any) => {
+ switch (node.type) {
+ case 'paragraph':
+ const text = extractTextFromNode(node)
+ return text ? { type: 'paragraph', content: text } : null
+
+ case 'heading':
+ return {
+ type: 'heading',
+ level: node.attrs?.level || 1,
+ content: extractTextFromNode(node)
+ }
+
+ case 'bulletList':
+ return {
+ type: 'bulletList',
+ content:
+ node.content
+ ?.map((item: any) => {
+ const itemText = extractTextFromNode(item.content?.[0])
+ return itemText
+ })
+ .filter(Boolean) || []
+ }
+
+ case 'orderedList':
+ return {
+ type: 'orderedList',
+ content:
+ node.content
+ ?.map((item: any) => {
+ const itemText = extractTextFromNode(item.content?.[0])
+ return itemText
+ })
+ .filter(Boolean) || []
+ }
+
+ case 'blockquote':
+ return {
+ type: 'blockquote',
+ content: extractTextFromNode(node.content?.[0])
+ }
+
+ case 'codeBlock':
+ return {
+ type: 'codeBlock',
+ language: node.attrs?.language || '',
+ content: node.content?.[0]?.text || ''
+ }
+
+ case 'image':
+ return {
+ type: 'image',
+ src: node.attrs?.src || '',
+ alt: node.attrs?.alt || '',
+ caption: node.attrs?.title || ''
+ }
+
+ case 'horizontalRule':
+ return { type: 'hr' }
+
+ default:
+ // Skip unknown types
+ return null
+ }
+ })
+ .filter(Boolean)
return { blocks }
}
@@ -244,7 +258,7 @@
status = post.status || 'draft'
slug = post.slug || ''
excerpt = post.excerpt || ''
-
+
// Convert blocks format to Tiptap format if needed
if (post.content && post.content.blocks) {
content = convertBlocksToTiptap(post.content)
@@ -253,7 +267,7 @@
} else {
content = { type: 'doc', content: [] }
}
-
+
tags = post.tags || []
} else {
if (response.status === 404) {
@@ -283,7 +297,7 @@
tags = tags.filter((t) => t !== tag)
}
- async function handleSave(publishStatus?: 'draft' | 'published') {
+ async function handleSave(newStatus?: string) {
const auth = localStorage.getItem('admin_auth')
if (!auth) {
goto('/admin/login')
@@ -291,18 +305,18 @@
}
saving = true
-
+
// Convert content to blocks format if it's in Tiptap format
let saveContent = content
if (config?.showContent && content && content.type === 'doc') {
saveContent = convertTiptapToBlocks(content)
}
-
+
const postData = {
title: config?.showTitle ? title : null,
slug,
type: postType,
- status: publishStatus || status,
+ status: newStatus || status,
content: config?.showContent ? saveContent : null,
excerpt: postType === 'essay' ? excerpt : undefined,
link_url: undefined,
@@ -322,8 +336,8 @@
if (response.ok) {
post = await response.json()
- if (publishStatus) {
- status = publishStatus
+ if (newStatus) {
+ status = newStatus
}
}
} catch (error) {
@@ -431,12 +445,15 @@
/>
{/if}
-
{/if}
@@ -591,7 +608,7 @@
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
min-width: 150px;
- z-index: 100;
+ z-index: 1050;
overflow: hidden;
}
diff --git a/src/routes/admin/posts/new/+page.svelte b/src/routes/admin/posts/new/+page.svelte
index 0819280..a20f5b6 100644
--- a/src/routes/admin/posts/new/+page.svelte
+++ b/src/routes/admin/posts/new/+page.svelte
@@ -276,7 +276,7 @@
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
min-width: 150px;
- z-index: 100;
+ z-index: 1050;
overflow: hidden;
}