Spaces:
Build error
Build error
| import React, { useState, useEffect, useContext } from 'react'; | |
| import Head from 'next/head'; | |
| import { | |
| LayoutDashboard, | |
| FolderKanban, | |
| CheckSquare, | |
| Users, | |
| Settings, | |
| Bell, | |
| Search, | |
| Menu, | |
| Moon, | |
| Sun, | |
| Plus, | |
| TrendingUp, | |
| TrendingDown, | |
| DollarSign, | |
| Activity, | |
| Calendar, | |
| MoreHorizontal, | |
| ChevronRight, | |
| Filter, | |
| Download, | |
| RefreshCw | |
| } from 'lucide-react'; | |
| import { ThemeContext } from './_app'; | |
| import Sidebar from '@/components/Sidebar'; | |
| import Header from '@/components/Header'; | |
| import StatCard from '@/components/StatCard'; | |
| import RevenueChart from '@/components/RevenueChart'; | |
| import ProjectTable from '@/components/ProjectTable'; | |
| import TaskBoard from '@/components/TaskBoard'; | |
| import TeamPerformance from '@/components/TeamPerformance'; | |
| import RecentActivity from '@/components/RecentActivity'; | |
| export default function Home() { | |
| const { darkMode, toggleTheme } = useContext(ThemeContext); | |
| const [sidebarOpen, setSidebarOpen] = useState(false); | |
| const [loading, setLoading] = useState(true); | |
| const [stats, setStats] = useState(null); | |
| const [projects, setProjects] = useState([]); | |
| useEffect(() => { | |
| const fetchData = async () => { | |
| try { | |
| await new Promise(resolve => setTimeout(resolve, 1000)); | |
| const statsRes = await fetch('/api/stats'); | |
| const statsData = await statsRes.json(); | |
| setStats(statsData); | |
| const projectsRes = await fetch('/api/projects'); | |
| const projectsData = await projectsRes.json(); | |
| setProjects(projectsData); | |
| } catch (error) { | |
| console.error('Error fetching data:', error); | |
| } finally { | |
| setLoading(false); | |
| } | |
| }; | |
| fetchData(); | |
| }, []); | |
| return ( | |
| <div className={`min-h-screen flex ${darkMode ? 'dark' : ''}`}> | |
| {sidebarOpen && ( | |
| <div | |
| className="fixed inset-0 z-40 bg-gray-600 bg-opacity-75 lg:hidden" | |
| onClick={() => setSidebarOpen(false)} | |
| ></div> | |
| )} | |
| <Sidebar | |
| isOpen={sidebarOpen} | |
| onClose={() => setSidebarOpen(false)} | |
| /> | |
| <div className="flex-1 flex flex-col lg:pl-64 transition-all duration-300"> | |
| <Header | |
| onMenuClick={() => setSidebarOpen(true)} | |
| onThemeToggle={toggleTheme} | |
| isDark={darkMode} | |
| /> | |
| <main className="flex-1 p-4 lg:p-8 overflow-y-auto bg-gray-50 dark:bg-dark-bg"> | |
| <div className="max-w-7xl mx-auto space-y-8 animate-fade-in"> | |
| <div className="flex flex-col md:flex-row md:items-center md:justify-between animate-slide-up"> | |
| <div> | |
| <h1 className="text-3xl font-bold text-gray-900 dark:text-white"> | |
| Dashboard Overview | |
| </h1> | |
| <p className="mt-1 text-sm text-gray-500 dark:text-gray-400"> | |
| Welcome back, here's what's happening today. | |
| </p> | |
| </div> | |
| <div className="mt-4 md:mt-0 flex space-x-3"> | |
| <button className="btn btn-secondary flex items-center"> | |
| <RefreshCw className="w-4 h-4 mr-2" /> | |
| Refresh | |
| </button> | |
| <button className="btn btn-primary flex items-center"> | |
| <Plus className="w-4 h-4 mr-2" /> | |
| New Project | |
| </button> | |
| </div> | |
| </div> | |
| {loading ? ( | |
| <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6"> | |
| {[1, 2, 3, 4].map((i) => ( | |
| <div key={i} className="h-32 bg-gray-200 dark:bg-gray-700 rounded-lg animate-pulse"></div> | |
| ))} | |
| </div> | |
| ) : ( | |
| <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 animate-slide-up" style={{animationDelay: '0.1s'}}> | |
| <StatCard | |
| title="Total Revenue" | |
| value={stats?.revenue} | |
| change="+12.5%" | |
| positive={true} | |
| icon={<DollarSign className="w-6 h-6 text-primary-600" />} | |
| /> | |
| <StatCard | |
| title="Active Projects" | |
| value={stats?.projects} | |
| change="+2.4%" | |
| positive={true} | |
| icon={<FolderKanban className="w-6 h-6 text-green-600" />} | |
| /> | |
| <StatCard | |
| title="Tasks Completed" | |
| value={stats?.tasks} | |
| change="-0.8%" | |
| positive={false} | |
| icon={<CheckSquare className="w-6 h-6 text-blue-600" />} | |
| /> | |
| <StatCard | |
| title="Team Velocity" | |
| value={stats?.velocity} | |
| change="+5.2%" | |
| positive={true} | |
| icon={<Activity className="w-6 h-6 text-purple-600" />} | |
| /> | |
| </div> | |
| )} | |
| <div className="grid grid-cols-1 lg:grid-cols-3 gap-8 animate-slide-up" style={{animationDelay: '0.2s'}}> | |
| <div className="lg:col-span-2 card"> | |
| <div className="flex items-center justify-between mb-6"> | |
| <h3 className="text-lg font-semibold text-gray-900 dark:text-white"> | |
| Revenue Analytics | |
| </h3> | |
| <select className="input-field w-auto py-1 pl-3 pr-8 text-sm"> | |
| <option>Last 7 Days</option> | |
| <option>Last 30 Days</option> | |
| <option>This Year</option> | |
| </select> | |
| </div> | |
| <div className="h-80"> | |
| <RevenueChart /> | |
| </div> | |
| </div> | |
| <div className="card"> | |
| <h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-6"> | |
| Team Performance | |
| </h3> | |
| <div className="space-y-6"> | |
| <TeamPerformance /> | |
| </div> | |
| </div> | |
| </div> | |
| <div className="grid grid-cols-1 lg:grid-cols-3 gap-8 animate-slide-up" style={{animationDelay: '0.3s'}}> | |
| <div className="lg:col-span-2 card"> | |
| <div className="flex items-center justify-between mb-6"> | |
| <h3 className="text-lg font-semibold text-gray-900 dark:text-white"> | |
| Current Projects | |
| </h3> | |
| <button className="text-sm text-primary-600 hover:text-primary-700 font-medium flex items-center"> | |
| View All <ChevronRight className="w-4 h-4 ml-1" /> | |
| </button> | |
| </div> | |
| <ProjectTable projects={projects} loading={loading} /> | |
| </div> | |
| <div className="card"> | |
| <h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-6"> | |
| Recent Activity | |
| </h3> | |
| <RecentActivity /> | |
| </div> | |
| </div> | |
| <div className="card animate-slide-up" style={{animationDelay: '0.4s'}}> | |
| <div className="flex items-center justify-between mb-6"> | |
| <h3 className="text-lg font-semibold text-gray-900 dark:text-white"> | |
| Sprint Task Board | |
| </h3> | |
| <div className="flex space-x-2"> | |
| <button className="p-2 text-gray-400 hover:text-gray-500 dark:hover:text-gray-300"> | |
| <Filter className="w-5 h-5" /> | |
| </button> | |
| <button className="p-2 text-gray-400 hover:text-gray-500 dark:hover:text-gray-300"> | |
| <Download className="w-5 h-5" /> | |
| </button> | |
| </div> | |
| </div> | |
| <TaskBoard /> | |
| </div> | |
| </div> | |
| </main> | |
| </div> | |
| </div> | |
| ); | |
| } |