feat: Add error display for sheet generation failures, improve SVG content detection, and validate generated data on the server.
This commit is contained in:
parent
5b0b37df3e
commit
9f5a0e155a
@ -111,6 +111,10 @@ CRITICAL: content_svg MUST be a string with single quotes in SVG attributes. Pat
|
|||||||
const jsonStr = text.replace(/```json/g, '').replace(/```/g, '').trim();
|
const jsonStr = text.replace(/```json/g, '').replace(/```/g, '').trim();
|
||||||
const data = JSON.parse(jsonStr);
|
const data = JSON.parse(jsonStr);
|
||||||
|
|
||||||
|
if (!data.title || !data.sections || !Array.isArray(data.sections)) {
|
||||||
|
throw new Error('Invalid generation format');
|
||||||
|
}
|
||||||
|
|
||||||
res.json(data);
|
res.json(data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Generation error:', error);
|
console.error('Generation error:', error);
|
||||||
|
|||||||
@ -11,9 +11,11 @@ function App() {
|
|||||||
const [isGenerating, setIsGenerating] = React.useState(false);
|
const [isGenerating, setIsGenerating] = React.useState(false);
|
||||||
|
|
||||||
const [history, setHistory] = React.useState([]);
|
const [history, setHistory] = React.useState([]);
|
||||||
|
const [error, setError] = React.useState(null);
|
||||||
|
|
||||||
const handleGenerate = async (data) => {
|
const handleGenerate = async (data) => {
|
||||||
setIsGenerating(true);
|
setIsGenerating(true);
|
||||||
|
setError(null);
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/generate', {
|
const response = await fetch('/api/generate', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -40,7 +42,7 @@ function App() {
|
|||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error generating sheet:", error);
|
console.error("Error generating sheet:", error);
|
||||||
// Optional: Show error state
|
setError(error.message || "Failed to generate sheet. Please try again.");
|
||||||
} finally {
|
} finally {
|
||||||
setIsGenerating(false);
|
setIsGenerating(false);
|
||||||
}
|
}
|
||||||
@ -75,6 +77,11 @@ function App() {
|
|||||||
|
|
||||||
{/* Main Content */}
|
{/* Main Content */}
|
||||||
<main className="max-w-7xl mx-auto px-4">
|
<main className="max-w-7xl mx-auto px-4">
|
||||||
|
{error && (
|
||||||
|
<div className="bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded-xl mb-6 flex items-center gap-2">
|
||||||
|
<span className="font-bold">Error:</span> {error}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<Hero onGenerate={handleGenerate} generatedSheet={generatedSheet} isGenerating={isGenerating} />
|
<Hero onGenerate={handleGenerate} generatedSheet={generatedSheet} isGenerating={isGenerating} />
|
||||||
<Gallery items={galleryItems} title={galleryTitle} onRestore={handleRestore} />
|
<Gallery items={galleryItems} title={galleryTitle} onRestore={handleRestore} />
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@ -68,7 +68,7 @@ export const Hero = ({ onGenerate, generatedSheet, isGenerating }) => {
|
|||||||
// since we don't have a separate loading state, we can reuse isGenerating logic or add one.
|
// since we don't have a separate loading state, we can reuse isGenerating logic or add one.
|
||||||
// For now, we'll just set the values when they arrive.
|
// For now, we'll just set the values when they arrive.
|
||||||
|
|
||||||
const res = await fetch('http://localhost:3001/api/surprise', { method: 'POST' });
|
const res = await fetch('/api/surprise', { method: 'POST' });
|
||||||
if (!res.ok) throw new Error('Surprise failed');
|
if (!res.ok) throw new Error('Surprise failed');
|
||||||
|
|
||||||
const idea = await res.json();
|
const idea = await res.json();
|
||||||
@ -310,7 +310,7 @@ export const Hero = ({ onGenerate, generatedSheet, isGenerating }) => {
|
|||||||
>
|
>
|
||||||
<div className="text-[10px] font-bold text-slate-400 uppercase mb-1 w-full text-left">{sec.type}</div>
|
<div className="text-[10px] font-bold text-slate-400 uppercase mb-1 w-full text-left">{sec.type}</div>
|
||||||
{/* Handle both new content_svg and legacy content fields */}
|
{/* Handle both new content_svg and legacy content fields */}
|
||||||
{(sec.content_svg || sec.content || '').trim().startsWith('<svg') ? (
|
{(sec.content_svg || sec.content || '').toLowerCase().includes('<svg') ? (
|
||||||
<div
|
<div
|
||||||
className={`w-full flex-1 flex items-center justify-center ${generatedSheet.sections.length === 1 ? 'max-h-full' : ''}`}
|
className={`w-full flex-1 flex items-center justify-center ${generatedSheet.sections.length === 1 ? 'max-h-full' : ''}`}
|
||||||
dangerouslySetInnerHTML={{ __html: sec.content_svg || sec.content }}
|
dangerouslySetInnerHTML={{ __html: sec.content_svg || sec.content }}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user