admin dashboard
This commit is contained in:
parent
c913b09edf
commit
58244d6afa
1 changed files with 90 additions and 54 deletions
|
|
@ -22,21 +22,17 @@ import {
|
||||||
AttachMoney as MoneyIcon,
|
AttachMoney as MoneyIcon,
|
||||||
Class as CategoryIcon
|
Class as CategoryIcon
|
||||||
} from '@mui/icons-material';
|
} from '@mui/icons-material';
|
||||||
import { Link as RouterLink } from 'react-router-dom';
|
import { Link as RouterLink, useNavigate } from 'react-router-dom';
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import apiClient from '../../services/api';
|
import apiClient from '../../services/api';
|
||||||
import { useAdminCategories } from '../../hooks/categoryAdminHooks';
|
import { useAdminCategories } from '../../hooks/categoryAdminHooks';
|
||||||
|
import { useAdminOrders, useAdminUsers } from '../../hooks/adminHooks';
|
||||||
|
import { format } from 'date-fns';
|
||||||
|
|
||||||
const AdminDashboardPage = () => {
|
const AdminDashboardPage = () => {
|
||||||
const [stats, setStats] = useState({
|
const navigate = useNavigate();
|
||||||
totalProducts: 0,
|
|
||||||
totalUsers: 0,
|
|
||||||
totalOrders: 0,
|
|
||||||
revenue: 0,
|
|
||||||
totalCategories: 0
|
|
||||||
});
|
|
||||||
|
|
||||||
// Fetch products for the stats
|
// Fetch data with React Query
|
||||||
const { data: products, isLoading: productsLoading, error: productsError } = useQuery({
|
const { data: products, isLoading: productsLoading, error: productsError } = useQuery({
|
||||||
queryKey: ['admin-products'],
|
queryKey: ['admin-products'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
|
|
@ -49,38 +45,68 @@ const AdminDashboardPage = () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Fetch categories
|
|
||||||
const { data: categories, isLoading: categoriesLoading } = useAdminCategories();
|
const { data: categories, isLoading: categoriesLoading } = useAdminCategories();
|
||||||
|
const { data: orders, isLoading: ordersLoading } = useAdminOrders();
|
||||||
|
const { data: users, isLoading: usersLoading } = useAdminUsers();
|
||||||
|
|
||||||
const recentOrders = [
|
// Calculate total revenue from orders
|
||||||
{ id: '4532', customer: 'John Doe', date: '2023-04-22', total: 49.99, status: 'Delivered' },
|
const calculateTotalRevenue = () => {
|
||||||
{ id: '4531', customer: 'Jane Smith', date: '2023-04-21', total: 89.95, status: 'Processing' },
|
if (!orders || orders.length === 0) return 0;
|
||||||
{ id: '4530', customer: 'Bob Johnson', date: '2023-04-20', total: 24.99, status: 'Shipped' },
|
return orders.reduce((sum, order) => {
|
||||||
{ id: '4529', customer: 'Alice Brown', date: '2023-04-19', total: 129.99, status: 'Delivered' }
|
// Only count orders that are completed/paid
|
||||||
];
|
if (order.payment_completed) {
|
||||||
|
return sum + parseFloat(order.total_amount || 0);
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}, 0);
|
||||||
|
};
|
||||||
|
|
||||||
// Update stats when products and categories are loaded
|
// Get recent orders (last 4)
|
||||||
|
const getRecentOrders = () => {
|
||||||
|
if (!orders || orders.length === 0) return [];
|
||||||
|
|
||||||
|
// Sort orders by created_at date (newest first) and take the first 4
|
||||||
|
return orders
|
||||||
|
.sort((a, b) => new Date(b.created_at) - new Date(a.created_at))
|
||||||
|
.slice(0, 4);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Format date
|
||||||
|
const formatDate = (dateString) => {
|
||||||
|
if (!dateString) return '';
|
||||||
|
try {
|
||||||
|
return format(new Date(dateString), 'yyyy-MM-dd');
|
||||||
|
} catch (error) {
|
||||||
|
return dateString;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Stats state
|
||||||
|
const [stats, setStats] = useState({
|
||||||
|
totalProducts: 0,
|
||||||
|
totalUsers: 0,
|
||||||
|
totalOrders: 0,
|
||||||
|
revenue: 0,
|
||||||
|
totalCategories: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update stats when data is loaded
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (products) {
|
const newStats = {
|
||||||
setStats(prev => ({
|
totalProducts: products?.length || 0,
|
||||||
...prev,
|
totalUsers: users?.length || 0,
|
||||||
totalProducts: products.length,
|
totalOrders: orders?.length || 0,
|
||||||
totalUsers: 15,
|
revenue: calculateTotalRevenue(),
|
||||||
totalOrders: 42,
|
totalCategories: categories?.length || 0
|
||||||
revenue: 2459.99
|
};
|
||||||
}));
|
setStats(newStats);
|
||||||
}
|
}, [products, categories, orders, users]);
|
||||||
|
|
||||||
if (categories) {
|
// Recent orders
|
||||||
setStats(prev => ({
|
const recentOrders = getRecentOrders();
|
||||||
...prev,
|
|
||||||
totalCategories: categories.length
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}, [products, categories]);
|
|
||||||
|
|
||||||
// Placeholder for when we add actual API calls
|
// Placeholder for when we add actual API calls
|
||||||
const isLoading = productsLoading || categoriesLoading;
|
const isLoading = productsLoading || categoriesLoading || ordersLoading || usersLoading;
|
||||||
const error = productsError;
|
const error = productsError;
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
|
|
@ -200,17 +226,23 @@ const AdminDashboardPage = () => {
|
||||||
/>
|
/>
|
||||||
<CardContent sx={{ pt: 0 }}>
|
<CardContent sx={{ pt: 0 }}>
|
||||||
<List>
|
<List>
|
||||||
{recentOrders.map((order, index) => (
|
{recentOrders.length > 0 ? (
|
||||||
<React.Fragment key={order.id}>
|
recentOrders.map((order, index) => (
|
||||||
<ListItem>
|
<React.Fragment key={order.id}>
|
||||||
<ListItemText
|
<ListItem>
|
||||||
primary={`Order #${order.id} - ${order.customer}`}
|
<ListItemText
|
||||||
secondary={`Date: ${order.date} | Total: $${order.total} | Status: ${order.status}`}
|
primary={`Order #${order.id.substring(0, 8)} - ${order.first_name} ${order.last_name}`}
|
||||||
/>
|
secondary={`Date: ${formatDate(order.created_at)} | Total: $${parseFloat(order.total_amount).toFixed(2)} | Status: ${order.status}`}
|
||||||
</ListItem>
|
/>
|
||||||
{index < recentOrders.length - 1 && <Divider />}
|
</ListItem>
|
||||||
</React.Fragment>
|
{index < recentOrders.length - 1 && <Divider />}
|
||||||
))}
|
</React.Fragment>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<ListItem>
|
||||||
|
<ListItemText primary="No orders found" />
|
||||||
|
</ListItem>
|
||||||
|
)}
|
||||||
</List>
|
</List>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
@ -279,7 +311,11 @@ const AdminDashboardPage = () => {
|
||||||
>
|
>
|
||||||
Manage Products
|
Manage Products
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="outlined">
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
component={RouterLink}
|
||||||
|
to="/admin/orders"
|
||||||
|
>
|
||||||
View Orders
|
View Orders
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue