diff --git a/src/components/RecentActivity.tsx b/src/components/RecentActivity.tsx new file mode 100644 index 0000000..ff519fc --- /dev/null +++ b/src/components/RecentActivity.tsx @@ -0,0 +1,79 @@ +import React from 'react'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { ScrollArea } from '@/components/ui/scroll-area'; +import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'; + +interface ActivityItem { + id: string; + type: 'order' | 'stock-in' | 'stock-out'; + description: string; + timestamp: string; + user?: { + name: string; + avatarUrl?: string; + }; +} + +const mockActivity: ActivityItem[] = [ + { + id: '1', + type: 'order', + description: 'New order #1001 placed by John Doe.', + timestamp: '2 hours ago', + user: { name: 'John Doe', avatarUrl: 'https://api.dicebear.com/7.x/initials/svg?seed=JD' }, + }, + { + id: '2', + type: 'stock-in', + description: '50 units of "Wireless Mouse" added to stock.', + timestamp: '5 hours ago', + }, + { + id: '3', + type: 'stock-out', + description: '10 units of "Mechanical Keyboard" booked out for delivery.', + timestamp: '1 day ago', + }, + { + id: '4', + type: 'order', + description: 'Order #1000 updated by Jane Smith.', + timestamp: '2 days ago', + user: { name: 'Jane Smith', avatarUrl: 'https://api.dicebear.com/7.x/initials/svg?seed=JS' }, + }, + { + id: '5', + type: 'stock-in', + description: '100 units of "USB-C Cable" received from supplier.', + timestamp: '3 days ago', + }, +]; + +export const RecentActivity = () => { + return ( + + + Recent Activity + Recent actions in your stock management system. + + + +
+ {mockActivity.map((activity) => ( +
+ + + {activity.user ? activity.user.name.substring(0, 2) : 'NA'} + +
+

{activity.description}

+

{activity.timestamp}

+
+
+ ))} +
+
+
+
+ ); +}; \ No newline at end of file diff --git a/src/components/StatCard.tsx b/src/components/StatCard.tsx index be0687f..1c60ce6 100644 --- a/src/components/StatCard.tsx +++ b/src/components/StatCard.tsx @@ -1,23 +1,24 @@ -import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; +import { cn } from '@/lib/utils'; -interface StatCardProps { +interface StatCardProps extends React.HTMLAttributes { title: string; value: string; description: string; icon: React.ReactNode; } -export default function StatCard({ title, value, description, icon }: StatCardProps) { +export const StatCard = ({ title, value, description, icon, className, ...props }: StatCardProps) => { return ( - - - {title} + + {/* Changed bg-primary-dark to bg-primary and text-white to text-primary-foreground */} + {title} {/* Changed text-white to text-primary-foreground */} {icon} - +
{value}

{description}

); -} \ No newline at end of file +}; \ No newline at end of file diff --git a/src/lib/api.ts b/src/lib/api.ts new file mode 100644 index 0000000..cd60f9e --- /dev/null +++ b/src/lib/api.ts @@ -0,0 +1,21 @@ +// Define the interface for the dashboard data +export interface DashboardData { + totalStockValue: number; + totalItems: number; + totalOrders: number; + totalCustomers: number; +} + +// Mock API function to fetch dashboard data +export const fetchDashboardData = async (): Promise => { + // Simulate a network delay + await new Promise((resolve) => setTimeout(resolve, 500)); + + // Return mock data + return { + totalStockValue: 125000, + totalItems: 750, + totalOrders: 120, + totalCustomers: 85, + }; +}; \ No newline at end of file diff --git a/src/pages/Index.tsx b/src/pages/Index.tsx index 76c2a0d..fb3ac2d 100644 --- a/src/pages/Index.tsx +++ b/src/pages/Index.tsx @@ -1,92 +1,84 @@ -import StatCard from '@/components/StatCard'; +import { StatCard } from '@/components/StatCard'; import { StockChart } from '@/components/StockChart'; -import StockActivityChart from '@/components/StockActivityChart'; -import { useDashboardData } from '@/hooks/useDashboardData'; +import { RecentActivity } from '@/components/RecentActivity'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; -import { DollarSign, Package, TrendingDown, AlertTriangle } from 'lucide-react'; +import { DollarSign, Package, ShoppingCart, Users } from 'lucide-react'; +import { useQuery } from '@tanstack/react-query'; +import { fetchDashboardData, DashboardData } from '@/lib/api'; // Import DashboardData interface -export default function Index() { - const { stats, loading, error } = useDashboardData(); +const Index = () => { + const { data, isLoading, error } = useQuery({ // Use DashboardData for typing + queryKey: ['dashboardData'], + queryFn: fetchDashboardData, + }); - if (loading) { - return ( -
-

Dashboard

-
- {[...Array(4)].map((_, i) => ( - - - Loading... - - - -
...
-

...

-
-
- ))} -
-
- - - Loading chart data... - - -
-
- ); + if (isLoading) { + return
Loading dashboard data...
; } if (error) { - return ( -
-

Dashboard

-
- - - Error loading dashboard data: {error} - - -
-
- ); + return
Error loading dashboard data: {error.message}
; } - return ( -
-

Dashboard

+ // Provide default values if data is undefined (though useQuery's type should handle this better now) + const { totalStockValue, totalItems, totalOrders, totalCustomers } = data || { + totalStockValue: 0, + totalItems: 0, + totalOrders: 0, + totalCustomers: 0, + }; + return ( +
+
+

Dashboard

+
} + value={`$${totalStockValue.toLocaleString()}`} + description="The total value of all items in stock." + icon={} /> } + title="Total Items" + value={totalItems.toLocaleString()} + description="The total number of unique items in stock." + icon={} /> } + title="Total Orders" + value={totalOrders.toLocaleString()} + description="Total orders processed this month." + icon={} /> } + title="Total Customers" + value={totalCustomers.toLocaleString()} + description="Total active customers." + icon={} />
- -
- - {/* */} +
+ + + Stock Overview + + + + + + + + Recent Activity + + + + +
); -} \ No newline at end of file +}; + +export default Index; \ No newline at end of file