file uploaded path correction

This commit is contained in:
sandhiya-hepl
2026-07-23 12:32:42 +05:30
parent b5f7a38c2a
commit 1b40a451b1
10 changed files with 247 additions and 75 deletions
+35 -18
View File
@@ -1,4 +1,6 @@
import { API_BASE } from '../lib/apiBase';
import { uploadLocal } from '../lib/localFileStore';
import { notifyContentUpdated } from '../context/ContentContext';
/** Frontend-only fallback when the Node API is not reachable on the host. */
const STATIC_USER = 'admin';
@@ -45,7 +47,9 @@ async function apiFetch(path, options = {}) {
: res.status === 502
? 'API server unreachable. Start Node on the host (port 3001).'
: 'Request failed';
throw new Error(data.error || fallback);
const err = new Error(data.error || fallback);
err.status = res.status;
throw err;
}
return data;
}
@@ -65,7 +69,17 @@ export const adminApi = {
me: async () => {
if (isStaticSession()) {
return { username: STATIC_USER, mode: 'static' };
// If server is now running, clear the stale static token so real login is used
try {
await apiFetch('/api/auth/me');
// Server responded — clear static token so user re-authenticates properly
clearToken();
throw new Error('Session expired, please log in again');
} catch (err) {
if (err.status) throw err; // server is up but rejected — force re-login
// Server unreachable — static session is fine
return { username: STATIC_USER, mode: 'static' };
}
}
return apiFetch('/api/auth/me');
},
@@ -82,14 +96,28 @@ export const adminApi = {
},
updateSection: async (section, data) => {
try {
return await apiFetch(`/api/content/${section}`, { method: 'PUT', body: JSON.stringify(data) });
} catch {
// Skip API entirely for static sessions
if (isStaticSession()) {
const saved = localStorage.getItem('static_content');
const { default: seed } = await import('../../server/seed/default-content.json');
const current = saved ? JSON.parse(saved) : seed;
const updated = { ...current, [section]: data, _updatedAt: new Date().toISOString() };
localStorage.setItem('static_content', JSON.stringify(updated));
notifyContentUpdated();
return { message: `${section} updated (local)`, updatedAt: updated._updatedAt };
}
try {
const result = await apiFetch(`/api/content/${section}`, { method: 'PUT', body: JSON.stringify(data) });
notifyContentUpdated();
return result;
} catch (err) {
if (err.status === 401) clearToken();
const saved = localStorage.getItem('static_content');
const { default: seed } = await import('../../server/seed/default-content.json');
const current = saved ? JSON.parse(saved) : seed;
const updated = { ...current, [section]: data, _updatedAt: new Date().toISOString() };
localStorage.setItem('static_content', JSON.stringify(updated));
notifyContentUpdated();
return { message: `${section} updated (local)`, updatedAt: updated._updatedAt };
}
},
@@ -103,18 +131,7 @@ export const adminApi = {
},
upload: async (file) => {
// Try Node API first; fall back to local data URL when server is unavailable.
try {
const form = new FormData();
form.append('file', file);
return await apiFetch('/api/upload', { method: 'POST', body: form });
} catch {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve({ url: reader.result, filename: file.name });
reader.onerror = () => reject(new Error('Failed to read file'));
reader.readAsDataURL(file);
});
}
// Store file locally in IndexedDB — no server needed
return uploadLocal(file);
},
};
+1 -1
View File
@@ -14,7 +14,7 @@ export function ImageUpload({ value, onChange, label = 'Image' }) {
const { url } = await adminApi.upload(file);
onChange(url);
} catch (err) {
alert(err.message);
alert('Upload failed: ' + err.message);
} finally {
setUploading(false);
}
+9 -5
View File
@@ -2,9 +2,13 @@ import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import './admin.css';
import App from './App.jsx';
import { restoreAllBlobUrls } from '../lib/localFileStore';
createRoot(document.getElementById('root')).render(
<StrictMode>
<App />
</StrictMode>
);
// Restore IndexedDB-stored file blob URLs before rendering
restoreAllBlobUrls().then(() => {
createRoot(document.getElementById('root')).render(
<StrictMode>
<App />
</StrictMode>
);
});