From 12dc38a4528ac89535f62ab71a3abb5fbe20dc13 Mon Sep 17 00:00:00 2001 From: Ajay Kumar Goel Date: Sat, 7 Feb 2026 18:44:59 +0000 Subject: [PATCH] Add truck booking SPA flow --- .../DemoCargoClix/Content/app.css | 14 ++- .../Controllers/TruckBookingsController.cs | 107 +++++++++++++++++ .../DemoCargoClix/DemoCargoClix.csproj | 4 +- .../DemoCargoClix/Scripts/app/app.js | 6 +- .../DemoCargoClix/Scripts/app/controllers.js | 72 +++++++++++- .../DemoCargoClix/Views/TruckBookings.cshtml | 111 ++++++++++++++++++ .../domain/DTO/Truck.cs | 13 ++ .../domain/DTO/TruckBooking.cs | 16 +++ .../domain/DTO/TruckBookingRequest.cs | 14 +++ .../domain/domain.csproj | 5 +- 10 files changed, 357 insertions(+), 5 deletions(-) create mode 100644 WebApi Angular Spa Mvc5 UnitOfWork/DemoCargoClix/Controllers/TruckBookingsController.cs create mode 100644 WebApi Angular Spa Mvc5 UnitOfWork/DemoCargoClix/Views/TruckBookings.cshtml create mode 100644 WebApi Angular Spa Mvc5 UnitOfWork/domain/DTO/Truck.cs create mode 100644 WebApi Angular Spa Mvc5 UnitOfWork/domain/DTO/TruckBooking.cs create mode 100644 WebApi Angular Spa Mvc5 UnitOfWork/domain/DTO/TruckBookingRequest.cs diff --git a/WebApi Angular Spa Mvc5 UnitOfWork/DemoCargoClix/Content/app.css b/WebApi Angular Spa Mvc5 UnitOfWork/DemoCargoClix/Content/app.css index 2a49f04..414870d 100644 --- a/WebApi Angular Spa Mvc5 UnitOfWork/DemoCargoClix/Content/app.css +++ b/WebApi Angular Spa Mvc5 UnitOfWork/DemoCargoClix/Content/app.css @@ -6016,4 +6016,16 @@ td.visible-print { -moz-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3); -webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3); box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3); -} \ No newline at end of file +} +.truck-booking .page-header { + margin-top: 20px; + border-bottom: 1px solid #e5e5e5; +} + +.truck-booking .panel-title { + font-weight: 600; +} + +.truck-booking .table > tbody > tr > td { + vertical-align: middle; +} diff --git a/WebApi Angular Spa Mvc5 UnitOfWork/DemoCargoClix/Controllers/TruckBookingsController.cs b/WebApi Angular Spa Mvc5 UnitOfWork/DemoCargoClix/Controllers/TruckBookingsController.cs new file mode 100644 index 0000000..bb1a178 --- /dev/null +++ b/WebApi Angular Spa Mvc5 UnitOfWork/DemoCargoClix/Controllers/TruckBookingsController.cs @@ -0,0 +1,107 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web.Http; +using App.DemoCargoClix.common; +using domain.Model; + +namespace App.DemoCargoClix.Controllers +{ + public class TruckBookingsController : BaseApiController + { + private static readonly List Trucks = new List + { + new Truck + { + Id = 1, + PlateNumber = "TX-1042", + Model = "Volvo FH16", + CapacityTons = 18.5m, + Status = "Available" + }, + new Truck + { + Id = 2, + PlateNumber = "CA-8831", + Model = "Freightliner Cascadia", + CapacityTons = 16.0m, + Status = "Booked" + }, + new Truck + { + Id = 3, + PlateNumber = "NV-5519", + Model = "Kenworth T680", + CapacityTons = 20.0m, + Status = "Available" + } + }; + + private static readonly List Bookings = new List + { + new TruckBooking + { + Id = 1001, + TruckId = 2, + CustomerName = "Northern Retail Group", + PickupLocation = "Phoenix, AZ", + DropoffLocation = "Las Vegas, NV", + PickupDate = DateTime.Today.AddDays(1), + Notes = "Palletized goods, dock 7", + Status = "Confirmed" + } + }; + + private static int _nextBookingId = 1002; + + [HttpGet] + public IEnumerable GetTrucks() + { + return Trucks; + } + + [HttpGet] + public IEnumerable GetBookings() + { + return Bookings.OrderByDescending(booking => booking.PickupDate).ToList(); + } + + [HttpGet] + public TruckBooking GetBooking(int id) + { + return Bookings.FirstOrDefault(booking => booking.Id == id); + } + + [HttpPost] + public TruckBooking CreateBooking(TruckBookingRequest request) + { + if (request == null) + { + return null; + } + + var truck = Trucks.FirstOrDefault(candidate => candidate.Id == request.TruckId); + if (truck == null || string.Equals(truck.Status, "Booked", StringComparison.OrdinalIgnoreCase)) + { + return null; + } + + var booking = new TruckBooking + { + Id = _nextBookingId++, + TruckId = request.TruckId, + CustomerName = request.CustomerName, + PickupLocation = request.PickupLocation, + DropoffLocation = request.DropoffLocation, + PickupDate = request.PickupDate, + Notes = request.Notes, + Status = "Confirmed" + }; + + Bookings.Add(booking); + truck.Status = "Booked"; + + return booking; + } + } +} diff --git a/WebApi Angular Spa Mvc5 UnitOfWork/DemoCargoClix/DemoCargoClix.csproj b/WebApi Angular Spa Mvc5 UnitOfWork/DemoCargoClix/DemoCargoClix.csproj index 03fdc09..438de60 100644 --- a/WebApi Angular Spa Mvc5 UnitOfWork/DemoCargoClix/DemoCargoClix.csproj +++ b/WebApi Angular Spa Mvc5 UnitOfWork/DemoCargoClix/DemoCargoClix.csproj @@ -1066,6 +1066,7 @@ + @@ -1086,6 +1087,7 @@ + Global.asax @@ -1143,4 +1145,4 @@ --> - \ No newline at end of file + diff --git a/WebApi Angular Spa Mvc5 UnitOfWork/DemoCargoClix/Scripts/app/app.js b/WebApi Angular Spa Mvc5 UnitOfWork/DemoCargoClix/Scripts/app/app.js index 1bc8f61..7678fad 100644 --- a/WebApi Angular Spa Mvc5 UnitOfWork/DemoCargoClix/Scripts/app/app.js +++ b/WebApi Angular Spa Mvc5 UnitOfWork/DemoCargoClix/Scripts/app/app.js @@ -31,7 +31,11 @@ cargoclixApp.config(['$routeProvider', templateUrl: '/views/EnterMessage.cshtml', controller: 'BookingDetailsSendMessageCtrl' }). + when('/truck-bookings', { + templateUrl: '/views/TruckBookings.cshtml', + controller: 'TruckBookingsCtrl' + }). otherwise({ templateUrl: '/views/404.cshtml', }); - }]); \ No newline at end of file + }]); diff --git a/WebApi Angular Spa Mvc5 UnitOfWork/DemoCargoClix/Scripts/app/controllers.js b/WebApi Angular Spa Mvc5 UnitOfWork/DemoCargoClix/Scripts/app/controllers.js index e569502..e36d7d3 100644 --- a/WebApi Angular Spa Mvc5 UnitOfWork/DemoCargoClix/Scripts/app/controllers.js +++ b/WebApi Angular Spa Mvc5 UnitOfWork/DemoCargoClix/Scripts/app/controllers.js @@ -111,6 +111,76 @@ cargoclixAppControllers.controller('BookingDetailsSendMessageCtrl', [ } ]); +// Path: /truck-bookings +cargoclixAppControllers.controller('TruckBookingsCtrl', [ + '$scope', '$http', function ($scope, $http) { + $scope.$root.title = 'Truck Booking System'; + $scope.trucks = []; + $scope.bookings = []; + $scope.booking = { + TruckId: '', + CustomerName: '', + PickupLocation: '', + DropoffLocation: '', + PickupDate: '', + Notes: '' + }; + + $scope.loadData = function () { + $http.get('/api/TruckBookings/GetTrucks'). + success(function (data) { + $scope.trucks = data || []; + }). + error(function () { + toastr.error("Unable to load trucks"); + }); + + $http.get('/api/TruckBookings/GetBookings'). + success(function (data) { + $scope.bookings = data || []; + }). + error(function () { + toastr.error("Unable to load bookings"); + }); + }; + + $scope.truckLabel = function (truckId) { + var match = null; + angular.forEach($scope.trucks, function (truck) { + if (truck.Id === truckId) { + match = truck; + } + }); + + return match ? match.Model + ' (' + match.PlateNumber + ')' : 'Truck #' + truckId; + }; + + $scope.createBooking = function () { + $http.post('/api/TruckBookings/CreateBooking', $scope.booking). + success(function (data) { + if (data) { + toastr.success("Truck booking confirmed"); + $scope.booking = { + TruckId: '', + CustomerName: '', + PickupLocation: '', + DropoffLocation: '', + PickupDate: '', + Notes: '' + }; + $scope.loadData(); + } else { + toastr.error("Unable to create booking"); + } + }). + error(function () { + toastr.error("Unable to create booking"); + }); + }; + + $scope.loadData(); + } +]); // Path: /login cargoclixAppControllers.controller('LoginCtrl', [ @@ -147,4 +217,4 @@ cargoclixAppControllers.controller('LoginCtrl', [ cargoclixAppControllers.controller('Error404Ctrl', ['$scope', '$location', function ($scope, $location) { $scope.$root.title = 'Error 404: Page Not Found'; -}]); \ No newline at end of file +}]); diff --git a/WebApi Angular Spa Mvc5 UnitOfWork/DemoCargoClix/Views/TruckBookings.cshtml b/WebApi Angular Spa Mvc5 UnitOfWork/DemoCargoClix/Views/TruckBookings.cshtml new file mode 100644 index 0000000..27aff5c --- /dev/null +++ b/WebApi Angular Spa Mvc5 UnitOfWork/DemoCargoClix/Views/TruckBookings.cshtml @@ -0,0 +1,111 @@ +
+ + +
+
+
+
+

Available Trucks

+
+
+ + + + + + + + + + + + + + + + + +
TruckPlateCapacity (tons)Status
{{truck.Model}}{{truck.PlateNumber}}{{truck.CapacityTons | number:1}} + + {{truck.Status}} + +
+
+
+
+ +
+
+
+

Create a Booking

+
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+
+
+
+
+ +
+
+

Recent Bookings

+
+
+ + + + + + + + + + + + + + + + + + + + + +
Booking #TruckCustomerRoutePickupStatus
{{booking.Id}}{{truckLabel(booking.TruckId)}}{{booking.CustomerName}}{{booking.PickupLocation}} → {{booking.DropoffLocation}}{{booking.PickupDate | date:'mediumDate'}}{{booking.Status}}
+
+
+
diff --git a/WebApi Angular Spa Mvc5 UnitOfWork/domain/DTO/Truck.cs b/WebApi Angular Spa Mvc5 UnitOfWork/domain/DTO/Truck.cs new file mode 100644 index 0000000..47b2e02 --- /dev/null +++ b/WebApi Angular Spa Mvc5 UnitOfWork/domain/DTO/Truck.cs @@ -0,0 +1,13 @@ +using System; + +namespace domain.Model +{ + public class Truck + { + public int Id { get; set; } + public string PlateNumber { get; set; } + public string Model { get; set; } + public decimal CapacityTons { get; set; } + public string Status { get; set; } + } +} diff --git a/WebApi Angular Spa Mvc5 UnitOfWork/domain/DTO/TruckBooking.cs b/WebApi Angular Spa Mvc5 UnitOfWork/domain/DTO/TruckBooking.cs new file mode 100644 index 0000000..d1c8924 --- /dev/null +++ b/WebApi Angular Spa Mvc5 UnitOfWork/domain/DTO/TruckBooking.cs @@ -0,0 +1,16 @@ +using System; + +namespace domain.Model +{ + public class TruckBooking + { + public int Id { get; set; } + public int TruckId { get; set; } + public string CustomerName { get; set; } + public string PickupLocation { get; set; } + public string DropoffLocation { get; set; } + public DateTime PickupDate { get; set; } + public string Notes { get; set; } + public string Status { get; set; } + } +} diff --git a/WebApi Angular Spa Mvc5 UnitOfWork/domain/DTO/TruckBookingRequest.cs b/WebApi Angular Spa Mvc5 UnitOfWork/domain/DTO/TruckBookingRequest.cs new file mode 100644 index 0000000..82c3ef0 --- /dev/null +++ b/WebApi Angular Spa Mvc5 UnitOfWork/domain/DTO/TruckBookingRequest.cs @@ -0,0 +1,14 @@ +using System; + +namespace domain.Model +{ + public class TruckBookingRequest + { + public int TruckId { get; set; } + public string CustomerName { get; set; } + public string PickupLocation { get; set; } + public string DropoffLocation { get; set; } + public DateTime PickupDate { get; set; } + public string Notes { get; set; } + } +} diff --git a/WebApi Angular Spa Mvc5 UnitOfWork/domain/domain.csproj b/WebApi Angular Spa Mvc5 UnitOfWork/domain/domain.csproj index 4215d39..283ded3 100644 --- a/WebApi Angular Spa Mvc5 UnitOfWork/domain/domain.csproj +++ b/WebApi Angular Spa Mvc5 UnitOfWork/domain/domain.csproj @@ -45,6 +45,9 @@ + + + @@ -56,4 +59,4 @@ --> - \ No newline at end of file +