Spaces:
Running
Running
| import React, { useState, useEffect } from 'react'; | |
| import ProgressStepper from '../components/dashboard/ProgressStepper'; | |
| import DashboardHome from '../components/dashboard/DashboardHome'; | |
| import EmptyProjectsState from '../components/dashboard/EmptyProjectsState'; | |
| import WizardModal from '../components/dashboard/WizardModal'; | |
| import { useQuery } from '@tanstack/react-query'; | |
| import { getSubscriptionStatus, createWelcomeSeed } from '../api/client'; | |
| import { useProjectStore } from '../store/useProjectStore'; | |
| import { WifiOff } from 'lucide-react'; | |
| import { motion, AnimatePresence } from 'framer-motion'; | |
| import { OnboardingTour } from '../components/onboarding/OnboardingTour'; | |
| const Dashboard: React.FC = () => { | |
| const [runTour, setRunTour] = useState(false); | |
| const [showWizard, setShowWizard] = useState(false); | |
| const { projects, fetchProjects } = useProjectStore(); | |
| useEffect(() => { | |
| let timeoutId: ReturnType<typeof setTimeout>; | |
| const initDashboard = async () => { | |
| await fetchProjects(); | |
| const hasSeenTour = localStorage.getItem('has_seen_tour_dashboard'); | |
| if (!hasSeenTour) { | |
| // Gdy brak projektów (Empty State) i start, tworzymy seed onboardingowy | |
| try { | |
| const seedData = await createWelcomeSeed(); | |
| if (seedData) { | |
| await fetchProjects(); // Odśwież listę, aby pokazać powitalny projekt | |
| } | |
| } catch (e) { | |
| console.error("Błąd podczas ładowania seeda", e); | |
| } | |
| timeoutId = setTimeout(() => setRunTour(true), 1500); | |
| } | |
| }; | |
| initDashboard(); | |
| return () => { | |
| if (timeoutId) clearTimeout(timeoutId); | |
| }; | |
| }, []); | |
| // Używamy domyślnych, globalnych kroków zdefiniowanych w OnboardingTour | |
| const { isError } = useQuery({ | |
| queryKey: ['subscription'], | |
| queryFn: getSubscriptionStatus, | |
| retry: false | |
| }); | |
| return ( | |
| <div style={{ display: 'flex', flexDirection: 'column', height: '100%', position: 'relative' }}> | |
| <AnimatePresence> | |
| {isError && ( | |
| <motion.div | |
| initial={{ opacity: 0, scale: 0.9 }} | |
| animate={{ opacity: 1, scale: 1 }} | |
| exit={{ opacity: 0, scale: 0.9 }} | |
| style={{ | |
| position: 'absolute', | |
| top: '1rem', | |
| right: '1rem', | |
| background: 'rgba(245, 158, 11, 0.1)', | |
| border: '1px solid var(--accent-orange)', | |
| color: 'var(--accent-orange)', | |
| padding: '0.4rem 0.8rem', | |
| borderRadius: '20px', | |
| display: 'flex', | |
| alignItems: 'center', | |
| gap: '0.5rem', | |
| fontSize: '0.75rem', | |
| fontWeight: 'bold', | |
| zIndex: 100, | |
| backdropFilter: 'blur(10px)' | |
| }} | |
| > | |
| <WifiOff size={14} /> Tryb Offline (Mock) | |
| </motion.div> | |
| )} | |
| </AnimatePresence> | |
| <div style={{ flex: 1, overflowY: 'auto' }}> | |
| {projects.length === 0 ? ( | |
| <div style={{ padding: '3rem', maxWidth: '1200px', margin: '0 auto', height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center' }}> | |
| <EmptyProjectsState onCreateClick={() => setShowWizard(true)} /> | |
| </div> | |
| ) : ( | |
| <> | |
| <header className="main-header" style={{ alignItems: 'flex-start' }}> | |
| <div> | |
| <div style={{ fontSize: '0.75rem', color: 'var(--accent-blue)', letterSpacing: '1px', textTransform: 'uppercase', marginBottom: '0.4rem', fontWeight: 600 }}>Projekt Dotacyjny • {projects[0].status === 'completed' ? 'Zakończony' : 'W Trakcie'}</div> | |
| <h1 className="main-title" style={{ fontSize: '1.4rem', margin: 0, fontWeight: 700 }}>Przegląd Dotacji</h1> | |
| </div> | |
| <ProgressStepper activeStep={ | |
| projects[0].status === 'completed' ? 5 : | |
| (projects[0].sections && projects[0].sections.length > 0) ? (projects[0].sections.every(s => s.is_approved) ? 5 : 4) : | |
| projects[0].program_name ? 3 : | |
| projects[0].description ? 2 : 1 | |
| } /> | |
| </header> | |
| <div className="main-content-scroll" style={{ paddingTop: '1rem' }}> | |
| <DashboardHome /> | |
| </div> | |
| </> | |
| )} | |
| </div> | |
| {runTour && ( | |
| <OnboardingTour | |
| run={runTour} | |
| onFinish={() => { | |
| setRunTour(false); | |
| localStorage.setItem('has_seen_tour_dashboard', 'true'); | |
| }} | |
| /> | |
| )} | |
| {showWizard && <WizardModal onClose={() => setShowWizard(false)} />} | |
| </div> | |
| ); | |
| }; | |
| export default Dashboard; | |