Overview
The DADDO analytics dashboard provides real-time insights into your business performance with KPI metrics, interactive charts powered by Recharts, top product analysis, and sales breakdowns by day and user.
Dashboard Data Fetching
Get Dashboard Action
The fetchDashboardData action (src/Redux/actions/Dash/getDash.js) retrieves all dashboard metrics:
export const fetchDashboardData =
( startDate = null , endDate = null ) =>
async ( dispatch ) => {
dispatch ({ type: "DASHBOARD_REQUEST" });
try {
const noCacheHeaders = { "Cache-Control" : "no-cache" };
const query =
startDate && endDate
? `?startDate= ${ encodeURIComponent ( startDate ) } &endDate= ${ encodeURIComponent ( endDate ) } `
: "" ;
const [ salesByDayRes , salesByMonthRes , topProductsRes , salesByUserRes ] =
await Promise . all ([
api . get ( "/dash/sales/day" , { headers: noCacheHeaders }),
api . get ( "/dash/sales/month" , { headers: noCacheHeaders }),
api . get ( `/dash/top-products ${ query } ` , { headers: noCacheHeaders }),
api . get ( "/dash/sales/user" , { headers: noCacheHeaders }),
api . get ( "/dash/sales/week" , { headers: noCacheHeaders }),
api . get ( "/dash/product-profit" , { headers: noCacheHeaders }),
]);
dispatch ({
type: "DASHBOARD_SUCCESS" ,
payload: {
salesByDay: salesByDayRes . data || [],
salesByMonth: salesByMonthRes . data || [],
topProducts: topProductsRes . data || [],
salesByUser: salesByUserRes . data || [],
},
});
} catch ( error ) {
dispatch ({
type: "DASHBOARD_FAILURE" ,
payload: error . response ?. data ?. error || error . message ,
});
}
};
All dashboard requests use no-cache headers to ensure real-time data accuracy.
Dashboard Component
The main dashboard (src/Views/DashBoard.jsx) organizes all metrics into a comprehensive view:
const DashboardSPA = () => {
const dispatch = useDispatch ();
const navigate = useNavigate ();
const {
salesByDay ,
topProducts ,
salesByUser : userSales ,
loading ,
} = useSelector ( state => state . dashboard );
useEffect (() => {
dispatch ( fetchDashboardData ());
}, [ dispatch ]);
if ( loading )
return (
< p className = "text-white text-center mt-10" >
Cargando dashboard...
</ p >
);
// Calculate KPIs...
};
KPI Metrics
KPI Calculations
The dashboard calculates key performance indicators from the sales data:
const totalRevenue = userSales . reduce (
( acc , s ) => acc + Number ( s . totalAmount || 0 ),
0
);
const totalProductsSold = userSales . reduce (
( acc , s ) => acc + Number ( s . numberOfProducts || 0 ),
0
);
KPI Display
< div className = "grid grid-cols-2 md:grid-cols-4 gap-4" >
< KpiCard title = "Ingresos totales" value = { `$ ${ totalRevenue } ` } />
< KpiCard title = "Ventas realizadas" value = { userSales . length } />
< KpiCard title = "Productos vendidos" value = { totalProductsSold } />
</ div >
KpiCard Component
The KpiCard component (src/components/dash/kpiCard.jsx) displays individual metrics:
const KpiCard = ({ title , value }) => (
< div className = "bg-gray-900 rounded-xl p-4 shadow-lg" >
< h3 className = "text-gray-400 text-sm mb-2" > { title } </ h3 >
< p className = "text-white text-2xl font-bold" > { value } </ p >
</ div >
);
Total Revenue Sum of all confirmed sales amounts
Sales Count Total number of sales transactions
Products Sold Total quantity of all products sold
Active Products Number of products in inventory
Sales by Day Chart
Recharts Integration
The SalesByDayChart component (src/components/dash/salesDayChart.jsx) uses Recharts for visualization:
import {
LineChart ,
Line ,
CartesianGrid ,
XAxis ,
YAxis ,
Tooltip ,
ResponsiveContainer ,
} from "recharts" ;
const SalesByDayChart = ({ data }) => (
< div className = "bg-gray-900 rounded-2xl p-4 h-80" >
< h2 className = "text-white text-lg font-semibold mb-3" >
Ventas por día
</ h2 >
< ResponsiveContainer width = "100%" height = "100%" >
< LineChart data = { data } >
< CartesianGrid strokeDasharray = "3 3" />
< XAxis dataKey = "date" />
< YAxis />
< Tooltip />
< Line
type = "monotone"
dataKey = "totalSales"
stroke = "#8884d8"
strokeWidth = { 2 }
/>
</ LineChart >
</ ResponsiveContainer >
</ div >
);
Chart Usage
< SalesByDayChart data = { salesByDay } />
Data Format:
[
{ date: "2024-01-15" , totalSales: 1250.00 },
{ date: "2024-01-16" , totalSales: 980.50 },
{ date: "2024-01-17" , totalSales: 1450.75 }
]
The line chart automatically scales to fit all data points and provides hover tooltips for detailed information.
Top Products Grid
TopProductsGrid Component
The TopProductsGrid component (src/components/dash/topProducts.jsx) displays best-selling products:
const TopProductsGrid = ({ products }) => (
< div className = "bg-gray-900 rounded-2xl p-4" >
< h2 className = "text-white text-lg font-semibold mb-4" >
Productos más vendidos
</ h2 >
< div className = "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4" >
{ products . map (( product ) => (
< div key = { product . id } className = "bg-gray-800 rounded-lg p-4" >
< img
src = { product . images ?.[ 0 ]?. url || '/placeholder.png' }
alt = { product . name }
className = "w-full h-32 object-cover rounded-lg mb-3"
/>
< h3 className = "text-white font-semibold" > { product . name } </ h3 >
< p className = "text-gray-400 text-sm" > Vendidos: { product . totalSold } </ p >
< p className = "text-purple-400 font-bold" > $ { product . totalRevenue } </ p >
</ div >
)) }
</ div >
</ div >
);
Usage
< TopProductsGrid products = { topProducts } />
Product Name : Display name of the product
Total Sold : Quantity sold in the selected period
Total Revenue : Revenue generated by this product
Product Image : First image from the product gallery
Sales by User Table
SalesByUserTable Component
The SalesByUserTable component (src/components/dash/salesUserChart.jsx) shows sales performance per user:
const SalesByUserTable = ({ sales }) => (
< div className = "bg-gray-900 rounded-2xl p-4" >
< h2 className = "text-white text-lg font-semibold mb-4" >
Ventas por usuario
</ h2 >
< div className = "overflow-x-auto" >
< table className = "w-full text-left" >
< thead >
< tr className = "text-gray-400 text-sm border-b border-gray-700" >
< th className = "pb-3" > Usuario </ th >
< th className = "pb-3" > Ventas </ th >
< th className = "pb-3" > Productos </ th >
< th className = "pb-3" > Total </ th >
</ tr >
</ thead >
< tbody >
{ sales . map (( sale , idx ) => (
< tr key = { idx } className = "text-white border-b border-gray-800" >
< td className = "py-3" > { sale . userName } </ td >
< td className = "py-3" > { sale . salesCount } </ td >
< td className = "py-3" > { sale . numberOfProducts } </ td >
< td className = "py-3 text-purple-400 font-bold" >
$ { sale . totalAmount }
</ td >
</ tr >
)) }
</ tbody >
</ table >
</ div >
</ div >
);
Usage
< SalesByUserTable sales = { userSales } />
User Name Display name of the sales representative
Sales Count Number of transactions completed
Products Sold Total quantity of products sold
Total Amount Total revenue generated by this user
Profitable Products
ProfitableProducts Component
The ProfitableProducts component (src/components/dash/profitableProducts.jsx) calculates profit margins:
const ProfitableProducts = ({ sales }) => {
const calculateProfit = ( product ) => {
const revenue = product . totalSales * product . price ;
const cost = product . totalSales * product . buyPrice ;
return revenue - cost ;
};
const sortedProducts = [ ... sales ]. sort (( a , b ) =>
calculateProfit ( b ) - calculateProfit ( a )
);
return (
< div className = "bg-gray-900 rounded-2xl p-4" >
< h2 className = "text-white text-lg font-semibold mb-4" >
Productos más rentables
</ h2 >
< div className = "space-y-3" >
{ sortedProducts . slice ( 0 , 5 ). map (( product ) => (
< div key = { product . id } className = "flex justify-between items-center" >
< div >
< p className = "text-white font-medium" > { product . name } </ p >
< p className = "text-gray-400 text-sm" >
Vendidos: { product . totalSales }
</ p >
</ div >
< p className = "text-green-400 font-bold" >
+$ { calculateProfit ( product ). toFixed ( 2 ) }
</ p >
</ div >
)) }
</ div >
</ div >
);
};
Usage
< ProfitableProducts sales = { userSales } />
Profit calculation uses the difference between sale price and purchase price (buyPrice) multiplied by quantity sold.
Dashboard Layout
Grid Organization
The dashboard uses a responsive grid layout:
< div className = "min-h-screen bg-black bg-opacity-75 p-5 space-y-10" >
{ /* Header */ }
< div className = "flex items-center justify-between" >
< button onClick = { () => navigate ( "/" ) } >
← Inicio
</ button >
< h1 className = "text-xl font-semibold text-white" >
Dashboard
</ h1 >
</ div >
{ /* KPIs */ }
< div className = "grid grid-cols-2 md:grid-cols-4 gap-4" >
< KpiCard title = "Ingresos totales" value = { `$ ${ totalRevenue } ` } />
< KpiCard title = "Ventas realizadas" value = { userSales . length } />
< KpiCard title = "Productos vendidos" value = { totalProductsSold } />
</ div >
{ /* Sales Chart */ }
< SalesByDayChart data = { salesByDay } />
{ /* Top Products */ }
< TopProductsGrid products = { topProducts } />
{ /* User Sales & Profitability */ }
< div className = "grid md:grid-cols-2 gap-6" >
< SalesByUserTable sales = { userSales } />
< ProfitableProducts sales = { userSales } />
</ div >
</ div >
Date Range Filtering
The dashboard supports custom date ranges:
const [ startDate , setStartDate ] = useState ( null );
const [ endDate , setEndDate ] = useState ( null );
const handleDateFilter = () => {
dispatch ( fetchDashboardData ( startDate , endDate ));
};
Filter top products by date range
Compare performance across time periods
Export filtered data
Reset to default (all time) view
API Endpoints
The dashboard fetches data from multiple endpoints:
/dash/sales/day Daily sales aggregated by date
/dash/sales/month Monthly sales totals
/dash/top-products Best-selling products with optional date filters
/dash/sales/user Sales broken down by user/employee
/dash/sales/week Weekly sales trends
/dash/product-profit Profit margins by product
Loading States
The dashboard handles loading gracefully:
if ( loading )
return (
< p className = "text-white text-center mt-10" >
Cargando dashboard...
</ p >
);
Error Handling
Dashboard errors are caught and displayed to users:
dispatch ({
type: "DASHBOARD_FAILURE" ,
payload: error . response ?. data ?. error || error . message ,
});
Responsive Design
KPI cards stack vertically on mobile
Charts use ResponsiveContainer for auto-sizing
Tables scroll horizontally when needed
Grid layouts adapt to screen size
Touch-friendly interactive elements
Multi-column layouts for efficiency
Larger charts for better data visualization
Side-by-side comparisons
Expanded data tables
Interactive hover states
Best Practices
Review dashboard daily for business insights
Monitor KPI trends over time
Identify top-performing products
Track user sales performance
Use date filters for period comparisons
Compare current period to previous periods
Look for seasonal trends in sales
Identify underperforming products
Monitor profit margins closely
Track inventory turnover rates