diff --git a/client/src/pages/Analytics.tsx b/client/src/pages/Analytics.tsx
index 3c7401d..bbf2843 100644
--- a/client/src/pages/Analytics.tsx
+++ b/client/src/pages/Analytics.tsx
@@ -11,7 +11,7 @@ const Analytics = () => {
const { customers } = useSelector((state: RootState) => state.customers);
const { expenses } = useSelector((state: RootState) => state.expenses);
- const [dateRange, setDateRange] = useState('month');
+ const [dateRange, setDateRange] = useState('2026');
// Helper function to get updated printing cost using current product costs
const getUpdatedPrintingCost = (order: any) => {
@@ -19,111 +19,104 @@ const Analytics = () => {
return calculateOrderPrintingCost(updatedItems);
};
- // Helper function to filter data by date range
- const getDateRangeFilter = (range: string) => {
- const now = new Date();
- const cutoffDate = new Date();
-
- switch (range) {
- case 'week':
- cutoffDate.setDate(now.getDate() - 7);
- break;
- case 'month':
- // Get the first day of last month
- cutoffDate.setMonth(now.getMonth() - 1);
- cutoffDate.setDate(1);
- cutoffDate.setHours(0, 0, 0, 0);
- break;
- case 'quarter':
- cutoffDate.setMonth(now.getMonth() - 3);
- break;
- case 'year':
- cutoffDate.setFullYear(now.getFullYear() - 1);
- break;
- default:
- // Default to first day of last month
- cutoffDate.setMonth(now.getMonth() - 1);
- cutoffDate.setDate(1);
- cutoffDate.setHours(0, 0, 0, 0);
- }
-
- return cutoffDate;
- };
-
- // Filter orders and expenses by selected date range
+ // Filter orders and expenses by selected date range using consistent logic
const filteredOrders = useMemo(() => {
- if (!orders) return [];
-
- // Handle specific month selections (e.g., "2026-03" for March 2026)
- if (dateRange.match(/^\d{4}-\d{2}$/)) {
- const [year, month] = dateRange.split('-').map(Number);
- const startOfMonth = new Date(year, month - 1, 1);
- const endOfMonth = new Date(year, month, 0, 23, 59, 59);
-
- return orders.filter(order => {
- if (!order.dateOrdered) return false;
- const orderDate = new Date(order.dateOrdered);
- return orderDate >= startOfMonth && orderDate <= endOfMonth;
- });
- }
-
- const cutoffDate = getDateRangeFilter(dateRange);
-
- if (dateRange === 'month') {
- // For month view, show only the previous complete month
- const now = new Date();
- const startOfLastMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1);
- const endOfLastMonth = new Date(now.getFullYear(), now.getMonth(), 0, 23, 59, 59);
-
- return orders.filter(order => {
- if (!order.dateOrdered) return false;
- const orderDate = new Date(order.dateOrdered);
- return orderDate >= startOfLastMonth && orderDate <= endOfLastMonth;
- });
- }
+ if (!orders || dateRange === 'all') return orders || [];
+ const now = new Date();
return orders.filter(order => {
if (!order.dateOrdered) return false;
const orderDate = new Date(order.dateOrdered);
- return orderDate >= cutoffDate;
+
+ // Handle specific month format (e.g., "2026-03" for March 2026)
+ if (dateRange.match(/^\d{4}-\d{2}$/)) {
+ const [year, month] = dateRange.split('-');
+ return orderDate.getFullYear() === parseInt(year) &&
+ orderDate.getMonth() === parseInt(month) - 1;
+ }
+
+ // Handle quarter format (e.g., "2026-Q1")
+ if (dateRange.match(/^\d{4}-Q[1-4]$/)) {
+ const [year, quarter] = dateRange.split('-Q');
+ const targetYear = parseInt(year);
+ const targetQuarter = parseInt(quarter);
+ const orderYear = orderDate.getFullYear();
+ const orderQuarter = Math.floor(orderDate.getMonth() / 3) + 1;
+ return orderYear === targetYear && orderQuarter === targetQuarter;
+ }
+
+ // Handle year format (e.g., "2026") - calendar year, not rolling 365 days
+ if (dateRange.match(/^\d{4}$/)) {
+ return orderDate.getFullYear() === parseInt(dateRange);
+ }
+
+ // Handle legacy preset ranges (rolling periods from today)
+ const timeDiff = now.getTime() - orderDate.getTime();
+ const daysDiff = timeDiff / (24 * 60 * 60 * 1000);
+
+ switch (dateRange) {
+ case 'week':
+ return daysDiff >= 0 && daysDiff <= 7;
+ case 'month':
+ return daysDiff >= 0 && daysDiff <= 30;
+ case 'quarter':
+ return daysDiff >= 0 && daysDiff <= 90;
+ case 'year':
+ // For "This Year" option, show current calendar year
+ return orderDate.getFullYear() === now.getFullYear();
+ default:
+ return true;
+ }
});
}, [orders, dateRange]);
const filteredExpenses = useMemo(() => {
- if (!expenses) return [];
-
- // Handle specific month selections (e.g., "2026-03" for March 2026)
- if (dateRange.match(/^\d{4}-\d{2}$/)) {
- const [year, month] = dateRange.split('-').map(Number);
- const startOfMonth = new Date(year, month - 1, 1);
- const endOfMonth = new Date(year, month, 0, 23, 59, 59);
-
- return expenses.filter(expense => {
- if (!expense.date) return false;
- const expenseDate = new Date(expense.date);
- return expenseDate >= startOfMonth && expenseDate <= endOfMonth;
- });
- }
-
- const cutoffDate = getDateRangeFilter(dateRange);
-
- if (dateRange === 'month') {
- // For month view, show only the previous complete month
- const now = new Date();
- const startOfLastMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1);
- const endOfLastMonth = new Date(now.getFullYear(), now.getMonth(), 0, 23, 59, 59);
-
- return expenses.filter(expense => {
- if (!expense.date) return false;
- const expenseDate = new Date(expense.date);
- return expenseDate >= startOfLastMonth && expenseDate <= endOfLastMonth;
- });
- }
+ if (!expenses || dateRange === 'all') return expenses || [];
+ const now = new Date();
return expenses.filter(expense => {
if (!expense.date) return false;
const expenseDate = new Date(expense.date);
- return expenseDate >= cutoffDate;
+
+ // Handle specific month format (e.g., "2026-03" for March 2026)
+ if (dateRange.match(/^\d{4}-\d{2}$/)) {
+ const [year, month] = dateRange.split('-');
+ return expenseDate.getFullYear() === parseInt(year) &&
+ expenseDate.getMonth() === parseInt(month) - 1;
+ }
+
+ // Handle quarter format (e.g., "2026-Q1")
+ if (dateRange.match(/^\d{4}-Q[1-4]$/)) {
+ const [year, quarter] = dateRange.split('-Q');
+ const targetYear = parseInt(year);
+ const targetQuarter = parseInt(quarter);
+ const expenseYear = expenseDate.getFullYear();
+ const expenseQuarter = Math.floor(expenseDate.getMonth() / 3) + 1;
+ return expenseYear === targetYear && expenseQuarter === targetQuarter;
+ }
+
+ // Handle year format (e.g., "2026") - calendar year, not rolling 365 days
+ if (dateRange.match(/^\d{4}$/)) {
+ return expenseDate.getFullYear() === parseInt(dateRange);
+ }
+
+ // Handle legacy preset ranges (rolling periods from today)
+ const timeDiff = now.getTime() - expenseDate.getTime();
+ const daysDiff = timeDiff / (24 * 60 * 60 * 1000);
+
+ switch (dateRange) {
+ case 'week':
+ return daysDiff >= 0 && daysDiff <= 7;
+ case 'month':
+ return daysDiff >= 0 && daysDiff <= 30;
+ case 'quarter':
+ return daysDiff >= 0 && daysDiff <= 90;
+ case 'year':
+ // For "This Year" option, show current calendar year
+ return expenseDate.getFullYear() === now.getFullYear();
+ default:
+ return true;
+ }
});
}, [expenses, dateRange]);
@@ -314,8 +307,11 @@ const Analytics = () => {
-
+
+
+