Skip to content

Commit 503368f

Browse files
fixed the graph
1 parent 8ff5b6c commit 503368f

10 files changed

Lines changed: 257 additions & 128 deletions

File tree

ECommerce.AdminUI/Pages/Index.cshtml

Lines changed: 51 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@
143143
<h2 class="accordion-header" id="headingOrders">
144144
<button class="accordion-button" type="button" data-bs-toggle="collapse"
145145
data-bs-target="#collapseOrders" aria-expanded="true" aria-controls="collapseOrders">
146-
<i class="bi bi-graph-up me-2"></i> Orders Over Time
146+
<i class="bi bi-graph-up me-2"></i> Sales Over Time
147147
</button>
148148
</h2>
149149
<div id="collapseOrders" class="accordion-collapse collapse show" aria-labelledby="headingOrders"
@@ -259,94 +259,88 @@
259259
// Order statistics data from the model
260260
const orderStats = @Html.Raw(Json.Serialize(Model.Stats.OrderStatistics));
261261
262-
// Format dates for display
262+
console.log("Chart data:", orderStats); // Log data for debugging
263+
264+
// Format dates for display - improved to handle timezone issues
263265
const labels = orderStats.map(stat => {
264-
const date = new Date(stat.date);
266+
// Parse the date with explicit handling of UTC dates
267+
const dateParts = stat.date.split('T')[0].split('-');
268+
const year = parseInt(dateParts[0]);
269+
const month = parseInt(dateParts[1]) - 1; // JavaScript months are 0-indexed
270+
const day = parseInt(dateParts[2]);
271+
272+
// Create date object using UTC to avoid timezone shifts
273+
const date = new Date(Date.UTC(year, month, day));
265274
return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
266275
});
267276
268-
// Order counts for the chart
269-
const orderCounts = orderStats.map(stat => stat.orderCount);
270-
271277
// Total sales for the chart
272278
const totalSales = orderStats.map(stat => stat.totalSales);
273279
280+
console.log("Chart labels:", labels); // Log formatted labels for debugging
281+
console.log("Chart values:", totalSales); // Log values for debugging
282+
274283
// Create the chart
275284
const ctx = document.getElementById('ordersChart');
276-
const ordersChart = new Chart(ctx, {
277-
type: 'line',
285+
const salesChart = new Chart(ctx, {
286+
type: 'bar',
278287
data: {
279288
labels: labels,
280289
datasets: [
281290
{
282-
label: 'Orders',
283-
data: orderCounts,
284-
backgroundColor: 'rgba(54, 162, 235, 0.2)',
285-
borderColor: 'rgba(54, 162, 235, 1)',
286-
borderWidth: 2,
287-
tension: 0.2,
288-
yAxisID: 'y'
289-
},
290-
{
291-
label: 'Sales ($)',
291+
label: 'Daily Sales ($)',
292292
data: totalSales,
293-
backgroundColor: 'rgba(75, 192, 192, 0.2)',
294-
borderColor: 'rgba(75, 192, 192, 1)',
295-
borderWidth: 2,
296-
tension: 0.2,
297-
yAxisID: 'y1'
293+
backgroundColor: 'rgba(46, 204, 113, 0.6)',
294+
borderColor: 'rgba(39, 174, 96, 1)',
295+
borderWidth: 1
298296
}
299297
]
300298
},
301299
options: {
302300
responsive: true,
303-
interaction: {
304-
mode: 'index',
305-
intersect: false,
306-
},
307-
scales: {
308-
y: {
309-
type: 'linear',
310-
display: true,
311-
position: 'left',
312-
title: {
313-
display: true,
314-
text: 'Orders'
315-
}
301+
plugins: {
302+
legend: {
303+
position: 'top',
316304
},
317-
y1: {
318-
type: 'linear',
305+
title: {
319306
display: true,
320-
position: 'right',
321-
title: {
322-
display: true,
323-
text: 'Sales ($)'
324-
},
325-
grid: {
326-
drawOnChartArea: false, // only want the grid lines for one axis to show up
327-
},
328-
}
329-
},
330-
plugins: {
307+
text: 'Total Sales for the Last 7 Days'
308+
},
331309
tooltip: {
332310
callbacks: {
333311
label: function(context) {
334312
let label = context.dataset.label || '';
335313
if (label) {
336314
label += ': ';
337315
}
338-
if (context.dataset.label === 'Sales ($)') {
339-
label += new Intl.NumberFormat('en-US', {
340-
style: 'currency',
341-
currency: 'USD'
342-
}).format(context.raw);
343-
} else {
344-
label += context.raw;
345-
}
316+
label += new Intl.NumberFormat('en-US', {
317+
style: 'currency',
318+
currency: 'USD'
319+
}).format(context.raw);
346320
return label;
347321
}
348322
}
349323
}
324+
},
325+
scales: {
326+
y: {
327+
beginAtZero: true,
328+
title: {
329+
display: true,
330+
text: 'Sales Amount ($)'
331+
},
332+
ticks: {
333+
callback: function(value) {
334+
return '$' + value.toLocaleString();
335+
}
336+
}
337+
},
338+
x: {
339+
title: {
340+
display: true,
341+
text: 'Date'
342+
}
343+
}
350344
}
351345
}
352346
});

ECommerce.AdminUI/Services/ApiOrderDto.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ public class ApiOrderDto
99
{
1010
public Guid Id { get; set; }
1111
public Guid CustomerId { get; set; }
12+
public DateTime CreatedAt { get; set; }
1213
public List<ApiOrderItemDto> Items { get; set; } = new List<ApiOrderItemDto>();
1314
}
1415

ECommerce.AdminUI/Services/DashboardService.cs

Lines changed: 57 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,19 @@
11
using System.Net.Http.Json;
2+
using System.Text.Json;
23

34
namespace ECommerce.AdminUI.Services;
45

5-
public class DashboardService
6+
public class DashboardService(
7+
IHttpClientFactory httpClientFactory,
8+
ILogger<DashboardService> logger,
9+
IHttpContextAccessor httpContextAccessor,
10+
OrderService orderService)
611
{
7-
private readonly HttpClient _httpClient;
8-
private readonly ILogger<DashboardService> _logger;
9-
private readonly IHttpContextAccessor _httpContextAccessor;
10-
private readonly OrderService _orderService;
11-
12-
public DashboardService(
13-
IHttpClientFactory httpClientFactory,
14-
ILogger<DashboardService> logger,
15-
IHttpContextAccessor httpContextAccessor,
16-
OrderService orderService)
17-
{
18-
_httpClient = httpClientFactory.CreateClient("ModularMonolith");
19-
_logger = logger;
20-
_httpContextAccessor = httpContextAccessor;
21-
_orderService = orderService;
22-
}
12+
private readonly HttpClient _httpClient = httpClientFactory.CreateClient("ModularMonolith");
2313

2414
private void AddAuthorizationHeader()
2515
{
26-
var token = _httpContextAccessor.HttpContext?.Session.GetString("AuthToken");
16+
var token = httpContextAccessor.HttpContext?.Session.GetString("AuthToken");
2717
if (!string.IsNullOrEmpty(token))
2818
{
2919
_httpClient.DefaultRequestHeaders.Remove("Authorization");
@@ -56,10 +46,20 @@ public async Task<DashboardStats> GetDashboardStatsAsync()
5646
}
5747

5848
// Get orders
59-
var orders = await _orderService.GetAllOrdersAsync();
49+
var orders = await orderService.GetAllOrdersAsync();
6050
stats.OrderCount = orders.Count;
6151
stats.TotalSales = orders.Sum(o => o.TotalPrice);
6252

53+
logger.LogInformation("Retrieved {OrderCount} orders with total sales: ${TotalSales}",
54+
orders.Count, stats.TotalSales);
55+
56+
// Log order dates to diagnose the issue
57+
foreach (var order in orders)
58+
{
59+
logger.LogInformation("Order ID: {OrderId}, CreatedAt: {CreatedAt}, Price: ${Price}",
60+
order.Id, order.CreatedAt, order.TotalPrice);
61+
}
62+
6363
// Get business events
6464
var eventsResponse = await _httpClient.GetAsync("events");
6565
if (eventsResponse.IsSuccessStatusCode)
@@ -70,10 +70,22 @@ public async Task<DashboardStats> GetDashboardStatsAsync()
7070

7171
// Generate order statistics for chart
7272
stats.OrderStatistics = GenerateOrderStatistics(orders);
73+
74+
// Log the generated statistics
75+
logger.LogInformation("Generated {StatCount} order statistics entries:", stats.OrderStatistics.Count);
76+
foreach (var stat in stats.OrderStatistics)
77+
{
78+
logger.LogInformation("Date: {Date}, OrderCount: {Count}, TotalSales: ${Sales}",
79+
stat.Date.ToString("yyyy-MM-dd"), stat.OrderCount, stat.TotalSales);
80+
}
81+
82+
// Log the JSON that will be sent to the chart
83+
logger.LogInformation("Order statistics JSON: {OrderStatsJson}",
84+
JsonSerializer.Serialize(stats.OrderStatistics));
7385
}
7486
catch (Exception ex)
7587
{
76-
_logger.LogError(ex, "Error retrieving dashboard statistics");
88+
logger.LogError(ex, "Error retrieving dashboard statistics");
7789
}
7890

7991
return stats;
@@ -84,34 +96,50 @@ private List<OrderStatistic> GenerateOrderStatistics(List<OrderDto> orders)
8496
// For demo/initial implementation purpose, if no orders exist, create some sample data
8597
if (orders == null || !orders.Any())
8698
{
99+
logger.LogInformation("No orders found, generating sample statistics");
87100
return GenerateSampleOrderStatistics();
88101
}
89102

90-
// Group orders by day for the last 7 days (week) instead of 30 days
91-
var startDate = DateTime.UtcNow.AddDays(-7);
103+
// Calculate a date range for the past 7 days
104+
var endDate = DateTime.UtcNow.Date;
105+
var startDate = endDate.AddDays(-6); // This gives us 7 days total (today + 6 previous days)
106+
107+
logger.LogInformation("Generating statistics from {StartDate} to {EndDate}",
108+
startDate.ToString("yyyy-MM-dd"), endDate.ToString("yyyy-MM-dd"));
109+
110+
// Log the orders being considered for the chart
111+
logger.LogInformation("Orders in date range: {Count}",
112+
orders.Count(o => o.CreatedAt.Date >= startDate && o.CreatedAt.Date <= endDate));
113+
114+
// Group orders by day for the last 7 days
92115
var ordersByDay = orders
93-
.Where(o => o.CreatedAt >= startDate)
116+
.Where(o => o.CreatedAt.Date >= startDate && o.CreatedAt.Date <= endDate)
94117
.GroupBy(o => o.CreatedAt.Date)
95118
.Select(g => new OrderStatistic
96119
{
97120
Date = g.Key,
98121
OrderCount = g.Count(),
99122
TotalSales = g.Sum(o => o.TotalPrice)
100123
})
101-
.OrderBy(x => x.Date)
102-
.ToList();
124+
.ToDictionary(x => x.Date, x => x); // Convert to dictionary for easier lookup
125+
126+
// Log the unique dates found in orders
127+
logger.LogInformation("Found orders on these dates: {Dates}",
128+
string.Join(", ", ordersByDay.Keys.Select(d => d.ToString("yyyy-MM-dd"))));
103129

104-
// Fill in missing dates
130+
// Fill in missing dates with zero values
105131
var result = new List<OrderStatistic>();
106-
for (var day = startDate.Date; day <= DateTime.UtcNow.Date; day = day.AddDays(1))
132+
for (var day = startDate; day <= endDate; day = day.AddDays(1))
107133
{
108-
var existingStat = ordersByDay.FirstOrDefault(s => s.Date == day);
109-
if (existingStat != null)
134+
if (ordersByDay.TryGetValue(day, out var existingStat))
110135
{
136+
logger.LogInformation("Adding existing stat for {Date}: {Count} orders, ${Sales}",
137+
day.ToString("yyyy-MM-dd"), existingStat.OrderCount, existingStat.TotalSales);
111138
result.Add(existingStat);
112139
}
113140
else
114141
{
142+
logger.LogInformation("Adding zero stat for {Date} (no orders)", day.ToString("yyyy-MM-dd"));
115143
result.Add(new OrderStatistic { Date = day, OrderCount = 0, TotalSales = 0 });
116144
}
117145
}

0 commit comments

Comments
 (0)