Spaces:
Running
Running
File size: 4,409 Bytes
3487904 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | import React, { useState, useEffect } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { X, Hand, Move, Palette, Sparkles, CheckCircle2 } from 'lucide-react';
export function UserGuideModal() {
const [isOpen, setIsOpen] = useState(false);
const [step, setStep] = useState(0);
useEffect(() => {
const hasSeenGuide = localStorage.getItem('neural_ai_has_seen_guide');
if (!hasSeenGuide) {
// Delay showing it slightly so the page loads first
const timer = setTimeout(() => setIsOpen(true), 1000);
return () => clearTimeout(timer);
}
}, []);
const handleClose = () => {
setIsOpen(false);
localStorage.setItem('neural_ai_has_seen_guide', 'true');
};
const nextStep = () => {
if (step < steps.length - 1) {
setStep(step + 1);
} else {
handleClose();
}
};
const steps = [
{
title: "Welcome to Neural AI! π",
description: "Let's take a quick tour of how to build your perfect website in minutes.",
icon: <Sparkles className="w-12 h-12 text-yellow-500 mx-auto mb-4" />
},
{
title: "Adding Components π§±",
description: "Open the Components tab to add sections, containers, text, and buttons directly to your canvas.",
icon: <Hand className="w-12 h-12 text-yellow-500 mx-auto mb-4" />
},
{
title: "Moving Things Around βοΈ",
description: "Tap any component on your canvas to open its action menu. Use the Up and Down arrows to instantly reposition it without dragging!",
icon: <Move className="w-12 h-12 text-yellow-500 mx-auto mb-4" />
},
{
title: "Customizing Properties π¨",
description: "With a component selected, open the Properties panel to change its colors, spacing, borders, and text content.",
icon: <Palette className="w-12 h-12 text-yellow-500 mx-auto mb-4" />
},
{
title: "You're all set! π",
description: "Tap the AI Optimize button at the top if you ever need AI to polish your layout automatically.",
icon: <CheckCircle2 className="w-12 h-12 text-green-500 mx-auto mb-4" />
}
];
return (
<AnimatePresence>
{isOpen && (
<>
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="fixed inset-0 bg-black/80 backdrop-blur-sm z-[999]"
onClick={handleClose}
/>
<motion.div
initial={{ opacity: 0, scale: 0.9, y: 20 }}
animate={{ opacity: 1, scale: 1, y: 0 }}
exit={{ opacity: 0, scale: 0.9, y: 20 }}
className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[90%] max-w-sm bg-zinc-950 border border-yellow-500/20 rounded-2xl shadow-2xl p-6 z-[1000] flex flex-col items-center text-center"
>
<button
onClick={handleClose}
className="absolute top-4 right-4 text-white/40 hover:text-white"
>
<X size={20} />
</button>
<AnimatePresence mode="wait">
<motion.div
key={step}
initial={{ opacity: 0, x: 20 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: -20 }}
className="w-full py-4"
>
{steps[step].icon}
<h3 className="text-xl font-bold text-white mb-2">{steps[step].title}</h3>
<p className="text-white/60 text-sm leading-relaxed">
{steps[step].description}
</p>
</motion.div>
</AnimatePresence>
{/* Dots */}
<div className="flex gap-2 mb-6">
{steps.map((_, i) => (
<div
key={i}
className={`w-2 h-2 rounded-full transition-colors ${
i === step ? 'bg-yellow-500' : 'bg-white/20'
}`}
/>
))}
</div>
<button
onClick={nextStep}
className="w-full bg-yellow-500 text-black font-bold py-3 rounded-xl hover:bg-yellow-400 transition-colors"
>
{step === steps.length - 1 ? 'Get Started' : 'Next'}
</button>
</motion.div>
</>
)}
</AnimatePresence>
);
}
|