Neural-Ai / client /src /components /UserGuideModal.tsx
Rajhavelvssince's picture
deploy: initial sync to hugging face
3487904
Raw History Blame Contribute Delete
4.41 kB
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>
);
}