Spaces:
Running
Running
| import React, { useState, useEffect } from 'react'; | |
| import { createPortal } from 'react-dom'; | |
| import { motion, AnimatePresence } from 'framer-motion'; | |
| import { Sparkles, ArrowRight, X } from 'lucide-react'; | |
| interface OnboardingWelcomeModalProps { | |
| onComplete: () => void; | |
| } | |
| export const OnboardingWelcomeModal: React.FC<OnboardingWelcomeModalProps> = ({ onComplete }) => { | |
| const [isOpen, setIsOpen] = useState(false); | |
| useEffect(() => { | |
| const hasSeenWelcome = localStorage.getItem('has_seen_welcome'); | |
| if (!hasSeenWelcome) { | |
| setIsOpen(true); | |
| } | |
| }, []); | |
| const handleClose = () => { | |
| localStorage.setItem('has_seen_welcome', 'true'); | |
| setIsOpen(false); | |
| onComplete(); | |
| }; | |
| if (!isOpen) return null; | |
| return createPortal( | |
| <AnimatePresence> | |
| {isOpen && ( | |
| <div style={{ | |
| position: 'fixed', | |
| top: 0, left: 0, right: 0, bottom: 0, | |
| background: 'rgba(0,0,0,0.8)', | |
| backdropFilter: 'blur(10px)', | |
| display: 'flex', | |
| alignItems: 'center', | |
| justifyContent: 'center', | |
| zIndex: 99999 | |
| }}> | |
| <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="glass-card" | |
| style={{ position: 'relative', width: '100%', maxWidth: '600px', margin: '1rem', padding: '3rem', textAlign: 'center' }} | |
| > | |
| <button | |
| onClick={handleClose} | |
| style={{ position: 'absolute', top: '1.5rem', right: '1.5rem', background: 'transparent', border: 'none', color: 'var(--text-muted)', cursor: 'pointer' }} | |
| className="hover-lift" | |
| > | |
| <X size={24} /> | |
| </button> | |
| <div style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', width: '64px', height: '64px', borderRadius: '50%', background: 'linear-gradient(135deg, var(--accent-blue), var(--accent-purple))', marginBottom: '2rem' }}> | |
| <Sparkles size={32} color="#fff" /> | |
| </div> | |
| <h2 style={{ fontSize: '2.5rem', fontWeight: 800, marginBottom: '1rem', color: 'var(--text-primary)' }}>Witaj w GrantForge Enterprise 2.0</h2> | |
| <p style={{ fontSize: '1.1rem', color: 'var(--text-secondary)', lineHeight: '1.6', marginBottom: '2.5rem' }}> | |
| Jesteś zaledwie o krok od automatyzacji procesu pisania wniosków unijnych. Nasz system potrafi przygotować kompletną strukturę pod programy takie jak <strong>Ścieżka SMART</strong> w kilka minut. | |
| </p> | |
| <div style={{ display: 'flex', gap: '1rem', justifyContent: 'center' }}> | |
| <button | |
| onClick={() => { | |
| localStorage.setItem('has_seen_tour_dashboard', 'true'); | |
| localStorage.setItem('has_seen_tour_workspace', 'true'); | |
| handleClose(); | |
| }} | |
| className="btn hover-lift" | |
| style={{ | |
| padding: '1rem 2rem', | |
| fontSize: '1rem', | |
| fontWeight: 600, | |
| borderRadius: '12px', | |
| background: 'transparent', | |
| color: 'var(--text-secondary)', | |
| border: '1px solid var(--border)', | |
| cursor: 'pointer' | |
| }} | |
| > | |
| Pomiń onboarding | |
| </button> | |
| <button | |
| onClick={handleClose} | |
| className="btn hover-lift" | |
| style={{ | |
| padding: '1rem 3rem', | |
| fontSize: '1.1rem', | |
| fontWeight: 800, | |
| borderRadius: '12px', | |
| background: 'var(--accent-green)', | |
| color: '#000', | |
| border: 'none', | |
| display: 'inline-flex', | |
| alignItems: 'center', | |
| gap: '0.6rem', | |
| cursor: 'pointer' | |
| }} | |
| > | |
| Zaczynajmy <ArrowRight size={20} /> | |
| </button> | |
| </div> | |
| </motion.div> | |
| </div> | |
| )} | |
| </AnimatePresence>, | |
| document.body | |
| ); | |
| }; | |