102 lines
3.9 KiB
JavaScript
102 lines
3.9 KiB
JavaScript
import React from 'react';
|
|
import { Hero } from './components/Hero';
|
|
import { Gallery } from './components/Gallery';
|
|
import { Button } from './components/ui/Button';
|
|
import { popularSheets } from './data/mockData';
|
|
|
|
import { HowItWorks } from './components/HowItWorks';
|
|
|
|
function App() {
|
|
const [generatedSheet, setGeneratedSheet] = React.useState(null);
|
|
const [isGenerating, setIsGenerating] = React.useState(false);
|
|
|
|
const [history, setHistory] = React.useState([]);
|
|
const [error, setError] = React.useState(null);
|
|
|
|
const handleGenerate = async (data) => {
|
|
setIsGenerating(true);
|
|
setError(null);
|
|
try {
|
|
const response = await fetch('/api/generate', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify(data),
|
|
});
|
|
|
|
if (!response.ok) throw new Error('Generation failed');
|
|
|
|
const result = await response.json();
|
|
setGeneratedSheet(result);
|
|
|
|
// Add to history
|
|
const newHistoryItem = {
|
|
...result, // Store full result (sections, etc)
|
|
id: Date.now(),
|
|
age: data.age,
|
|
downloads: 0,
|
|
bgColor: 'bg-primary-50',
|
|
};
|
|
setHistory(prev => [newHistoryItem, ...prev]);
|
|
|
|
} catch (error) {
|
|
console.error("Error generating sheet:", error);
|
|
setError(error.message || "Failed to generate sheet. Please try again.");
|
|
} finally {
|
|
setIsGenerating(false);
|
|
}
|
|
};
|
|
|
|
const handleRestore = (item) => {
|
|
setGeneratedSheet(item);
|
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
|
};
|
|
|
|
const galleryItems = history.length > 0 ? history.slice(0, 3) : popularSheets.slice(0, 3);
|
|
const galleryTitle = history.length > 0 ? "Your Recent Creations" : "Most Popular Printables";
|
|
|
|
return (
|
|
<div className="min-h-screen bg-slate-50/50">
|
|
{/* Navbar */}
|
|
<nav className="border-b border-slate-200 bg-white/80 backdrop-blur-md sticky top-0 z-50">
|
|
<div className="max-w-7xl mx-auto px-4 h-16 flex items-center justify-between">
|
|
<div className="flex items-center gap-2">
|
|
<span className="text-2xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-violet-600 to-indigo-600">
|
|
WonderSheets
|
|
</span>
|
|
<span className="text-yellow-400 text-xl">✨</span>
|
|
</div>
|
|
|
|
<div className="hidden md:flex items-center gap-8 text-sm font-medium text-slate-600">
|
|
<a href="#" className="hover:text-primary-600">Gallery</a>
|
|
<a href="#how-it-works" className="hover:text-primary-600">How it Works</a>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
{/* Main Content */}
|
|
<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} />
|
|
<Gallery items={galleryItems} title={galleryTitle} onRestore={handleRestore} />
|
|
</main>
|
|
|
|
<HowItWorks />
|
|
|
|
{/* Footer */}
|
|
<footer className="bg-white border-t border-slate-200 mt-20 py-12">
|
|
<div className="max-w-7xl mx-auto px-4 text-center text-slate-500 text-sm">
|
|
<p>© 2024 WonderSheets. All rights reserved.</p>
|
|
</div>
|
|
</footer>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default App;
|