Spaces:
Running
Running
Download client/src/components/UserGuideModal.tsx from VSRAJHAVEL/Neural-Ai: direct link, hf CLI and curl.
- Browser
- Download file 4.41 kB
-
https://huggingface.co/spaces/VSRAJHAVEL/Neural-Ai/resolve/main/client/src/components/UserGuideModal.tsx
- Command line
-
hf download hf://spaces/VSRAJHAVEL/Neural-Ai/client/src/components/UserGuideModal.tsx
-
curl -L -o UserGuideModal.tsx https://huggingface.co/spaces/VSRAJHAVEL/Neural-Ai/resolve/main/client/src/components/UserGuideModal.tsx
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> | |
| ); | |
| } | |