Compare commits

...

2 Commits

4 changed files with 83 additions and 17 deletions

View File

@ -30,14 +30,11 @@ function App() {
// Add to history
const newHistoryItem = {
...result, // Store full result (sections, etc)
id: Date.now(),
title: result.title,
subtitle: result.subtitle,
age: data.age,
downloads: 0,
bgColor: 'bg-primary-50', // Default color
// We'll need to figure out how to preview it in the gallery.
// For now, Gallery expects 'bgColor'.
bgColor: 'bg-primary-50',
};
setHistory(prev => [newHistoryItem, ...prev]);
@ -49,6 +46,11 @@ function App() {
}
};
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";
@ -74,7 +76,7 @@ function App() {
{/* Main Content */}
<main className="max-w-7xl mx-auto px-4">
<Hero onGenerate={handleGenerate} generatedSheet={generatedSheet} isGenerating={isGenerating} />
<Gallery items={galleryItems} title={galleryTitle} />
<Gallery items={galleryItems} title={galleryTitle} onRestore={handleRestore} />
</main>
<HowItWorks />

View File

@ -3,7 +3,7 @@ import { motion } from 'framer-motion';
import { Wand2, Download, Star } from 'lucide-react';
import { Button } from './ui/Button';
export const Gallery = ({ items, title = "Most Popular Printables" }) => {
export const Gallery = ({ items, title = "Most Popular Printables", onRestore }) => {
return (
<section className="py-12">
<div className="flex items-center gap-2 mb-8">
@ -21,17 +21,36 @@ export const Gallery = ({ items, title = "Most Popular Printables" }) => {
className="group bg-white rounded-3xl border-2 border-slate-100 overflow-hidden hover:border-primary-200 hover:shadow-xl hover:shadow-primary-100/50 transition-all duration-300"
>
<div className={`aspect-[3/4] p-6 flex flex-col items-center justify-center relative ${item.bgColor}`}>
{/* This would ideally be the actual sheet preview */}
<div className="w-full h-full bg-white rounded-xl shadow-sm border border-black/5 flex flex-col items-center justify-center p-4 text-center">
<h3 className="font-bold text-lg mb-2">{item.title}</h3>
<p className="text-sm text-slate-500 mb-4">{item.subtitle}</p>
<div className="text-4xl font-mono opacity-20">123</div>
</div>
{item.sections && item.sections.length > 0 && item.sections[0].content_svg ? (
<div className="w-full h-full bg-white rounded-xl shadow-sm border border-black/5 overflow-hidden relative">
<div
className="w-full h-full transform scale-90 origin-center"
dangerouslySetInnerHTML={{ __html: item.sections[0].content_svg }}
/>
{/* Overlay to prevent interaction with SVG parts */}
<div className="absolute inset-0 z-10"></div>
</div>
) : (
<div className="w-full h-full bg-white rounded-xl shadow-sm border border-black/5 flex flex-col items-center justify-center p-4 text-center">
{item.image ? (
<img src={item.image} alt={item.title} className="w-full h-full object-cover rounded-lg" />
) : (
<>
<h3 className="font-bold text-lg mb-2">{item.title}</h3>
<p className="text-sm text-slate-500 mb-4">{item.subtitle}</p>
<div className="text-4xl font-mono opacity-20">123</div>
</>
)}
</div>
)}
<div className="absolute inset-0 bg-black/0 group-hover:bg-black/5 transition-colors flex items-center justify-center opacity-0 group-hover:opacity-100">
<Button className="shadow-xl">
<Download className="mr-2" size={18} />
Download PDF
<div className="absolute inset-0 bg-black/0 group-hover:bg-black/5 transition-colors flex items-center justify-center opacity-0 group-hover:opacity-100 z-20">
<Button
className="shadow-xl"
onClick={() => onRestore && onRestore(item)}
>
<Wand2 className="mr-2" size={18} />
{onRestore ? "Open in Editor" : "View Sheet"}
</Button>
</div>
</div>

View File

@ -12,6 +12,48 @@ export const Hero = ({ onGenerate, generatedSheet, isGenerating }) => {
const [age, setAge] = useState(5);
const [selectedSection, setSelectedSection] = useState('coloring');
// Sync state when a sheet is restored
React.useEffect(() => {
if (generatedSheet) {
setTheme(generatedSheet.title || '');
if (generatedSheet.age) setAge(generatedSheet.age);
// If sections exist, restore the first one's type as selected
if (generatedSheet.sections && generatedSheet.sections.length > 0) {
// Map section type back to ID if possible, or fallback
const secType = generatedSheet.sections[0].type; // e.g. "coloring"
// Our IDs match the types mostly, but let's be safe
// IDs: coloring, numbers, writing, find-the-way, counting
// Types from prompt: coloring|numbers|writing|find-the-way|counting
// So direct mapping should work.
// But wait, finding the ID that matches the type/id from result
// In App.jsx we assume result has sections.
// The prompt returns 'type' and we use that? No, prompt returns 'id' and 'type'.
// Let's use the first section's ID if valid.
const secId = generatedSheet.sections[0].id; // e.g. "coloring-123"
// This ID from AI might be "coloring-main". We need to map it to our internal IDs: 'coloring', 'writing', 'numbers', etc.
// Internal IDs in Hero are: 'coloring', 'numbers', 'writing', 'find-way' (wait, it's 'find-way' not 'find-the-way'!), 'counting'.
// Let's check mockData for IDs.
// sections: [{id: 'find-way', label: 'Find the Way', ...}]
// AI prompt was: "find-the-way" for type.
// We need to map "find-the-way" -> "find-way".
const typeToId = {
'coloring': 'coloring',
'numbers': 'numbers',
'writing': 'writing',
'find-the-way': 'find-way',
'counting': 'counting'
};
if (typeToId[secType]) {
setSelectedSection(typeToId[secType]);
}
}
}
}, [generatedSheet]);
const handleSectionChange = (id) => {
if (!isGenerating) {
setSelectedSection(id);

View File

@ -8,6 +8,7 @@ export const popularSheets = [
type: "Math",
bgColor: "bg-green-50",
image: "https://images.unsplash.com/photo-1559810686-353c7a974b7c?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.0.3",
sections: [{ type: "Math", content: "Dinosaur Math Content (Placeholder)" }]
},
{
id: 2,
@ -18,6 +19,7 @@ export const popularSheets = [
type: "Maze",
bgColor: "bg-pink-50",
image: "https://images.unsplash.com/photo-1555557760-b610c1f207d5?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.0.3",
sections: [{ type: "Maze", content: "Princess Maze Content (Placeholder)" }]
},
{
id: 3,
@ -28,6 +30,7 @@ export const popularSheets = [
type: "Writing",
bgColor: "bg-slate-50",
image: "https://images.unsplash.com/photo-1451187580459-43490279c0fa?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.0.3",
sections: [{ type: "Writing", content: "Space Writing Content (Placeholder)" }]
}
];