diff --git a/src/samples/FleetManagement.Library/FleetManagementComponent.razor b/src/samples/FleetManagement.Library/FleetManagementComponent.razor index a84e7c1..36ecc22 100644 --- a/src/samples/FleetManagement.Library/FleetManagementComponent.razor +++ b/src/samples/FleetManagement.Library/FleetManagementComponent.razor @@ -22,25 +22,118 @@ } else { - - - - - - - - - - - - +
+

Fleet Management

+

Master-Detail Grid for managing vehicle acquisition, operations, and maintenance records

+ + +
+
+
+
+
Total Vehicles
+

@FleetService.Data.Count

+
+
+
+
+
+
+
Active
+

@FleetService.Data.Count(v => v.Status == "Active")

+
+
+
+
+
+
+
In Maintenance
+

@FleetService.Data.Count(v => v.Status == "Maintenance")

+
+
+
+
+
+
+
Avg Fuel Level
+

@(FleetService.Data.Any() ? FleetService.Data.Average(v => v.FuelLevel).ToString("N1") : "0")%

+
+
+
+
+
+ + +
+
+
Vehicle Fleet
+
+
+ + + + + + + + + + + +
+
+ + + @if (selectedVehicle != null) + { +
+
+
Maintenance History - @selectedVehicle.VehicleId (@selectedVehicle.Make @selectedVehicle.Model)
+
+
+ @{ + var maintenanceRecords = FleetService.GetMaintenanceForVehicle(selectedVehicle.VehicleId); + } + @if (maintenanceRecords.Any()) + { + + + + + + + + + + } + else + { +
+

No maintenance records found for this vehicle.

+
+ } +
+
+ } + else + { + + } +
- Data updates every 3 seconds to simulate live fleet tracking + Data updates every 3 seconds to simulate live fleet tracking. Click on a row to view maintenance history.
} @@ -50,6 +143,8 @@ private bool isLoading = true; private System.Timers.Timer? updateTimer; private IgbGrid? grid; + private IgbGrid? maintenanceGrid; + private FleetData? selectedVehicle = null; protected override async Task OnInitializedAsync() { @@ -64,6 +159,12 @@ FleetService.UpdateAllData(); }; updateTimer.Start(); + + // Select first vehicle by default + if (FleetService.Data.Any()) + { + selectedVehicle = FleetService.Data.First(); + } } private void OnDataChanged() @@ -75,9 +176,32 @@ { grid.MarkForCheck(); } + if (maintenanceGrid != null) + { + maintenanceGrid.MarkForCheck(); + } }); } + private void OnCellClick(object args) + { + // Extract the row data from the click event + dynamic eventArgs = args; + try + { + var clickedVehicle = eventArgs.Cell.Row.Data as FleetData; + if (clickedVehicle != null) + { + selectedVehicle = clickedVehicle; + StateHasChanged(); + } + } + catch + { + // Fallback: ignore if event structure is different + } + } + public void Dispose() { updateTimer?.Stop(); diff --git a/src/samples/FleetManagement.Library/Models/FleetData.cs b/src/samples/FleetManagement.Library/Models/FleetData.cs index cfb0d27..8529e50 100644 --- a/src/samples/FleetManagement.Library/Models/FleetData.cs +++ b/src/samples/FleetManagement.Library/Models/FleetData.cs @@ -39,4 +39,7 @@ public class FleetData [JsonPropertyName("nextService")] public DateTime NextService { get; set; } + + // Property for child grid data (not serialized from JSON) + public List MaintenanceRecords { get; set; } = new(); } diff --git a/src/samples/FleetManagement.Library/Models/MaintenanceData.cs b/src/samples/FleetManagement.Library/Models/MaintenanceData.cs new file mode 100644 index 0000000..d16cf5f --- /dev/null +++ b/src/samples/FleetManagement.Library/Models/MaintenanceData.cs @@ -0,0 +1,33 @@ +using System.Text.Json.Serialization; + +namespace FleetManagement.Library.Models; + +public class MaintenanceData +{ + [JsonPropertyName("id")] + public string? Id { get; set; } + + [JsonPropertyName("vehicleId")] + public string? VehicleId { get; set; } + + [JsonPropertyName("date")] + public DateTime Date { get; set; } + + [JsonPropertyName("type")] + public string? Type { get; set; } + + [JsonPropertyName("description")] + public string? Description { get; set; } + + [JsonPropertyName("cost")] + public double Cost { get; set; } + + [JsonPropertyName("technician")] + public string? Technician { get; set; } + + [JsonPropertyName("status")] + public string? Status { get; set; } + + [JsonPropertyName("mileage")] + public double Mileage { get; set; } +} diff --git a/src/samples/FleetManagement.Library/Services/FleetService.cs b/src/samples/FleetManagement.Library/Services/FleetService.cs index e870d01..43bcff7 100644 --- a/src/samples/FleetManagement.Library/Services/FleetService.cs +++ b/src/samples/FleetManagement.Library/Services/FleetService.cs @@ -19,6 +19,7 @@ public class FleetService }; public List Data { get; private set; } = new(); + public Dictionary> MaintenanceData { get; private set; } = new(); public event Action? OnDataChanged; public FleetService(HttpClient httpClient) @@ -30,8 +31,25 @@ public async Task LoadDataAsync() { try { - var jsonText = await _httpClient.GetStringAsync(VehicleDataUrl); - Data = JsonSerializer.Deserialize>(jsonText, options) ?? new(); + // Load vehicles data + var vehicleJsonText = await _httpClient.GetStringAsync(VehicleDataUrl); + Data = JsonSerializer.Deserialize>(vehicleJsonText, options) ?? new(); + + // Load maintenance data + try + { + var maintenanceJsonText = await _httpClient.GetStringAsync(MaintanenceDataUrl); + var maintenanceList = JsonSerializer.Deserialize>(maintenanceJsonText, options) ?? new(); + + // Group maintenance records by vehicleId + MaintenanceData = maintenanceList + .GroupBy(m => m.VehicleId ?? string.Empty) + .ToDictionary(g => g.Key, g => g.ToList()); + } + catch + { + // Maintenance data is optional - continue if it fails + } OnDataChanged?.Invoke(); } @@ -56,4 +74,13 @@ public void UpdateAllData() OnDataChanged?.Invoke(); } + + public List GetMaintenanceForVehicle(string? vehicleId) + { + if (string.IsNullOrEmpty(vehicleId) || !MaintenanceData.ContainsKey(vehicleId)) + { + return new List(); + } + return MaintenanceData[vehicleId]; + } } diff --git a/src/samples/FleetManagement/Components/App.razor b/src/samples/FleetManagement/Components/App.razor index c28db40..42263e2 100644 --- a/src/samples/FleetManagement/Components/App.razor +++ b/src/samples/FleetManagement/Components/App.razor @@ -9,7 +9,7 @@ - +