diff --git a/.github/workflows/integration_checkdriver.yml b/.github/workflows/integration_checkdriver.yml new file mode 100644 index 00000000..3167fcd1 --- /dev/null +++ b/.github/workflows/integration_checkdriver.yml @@ -0,0 +1,66 @@ +# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy +# More GitHub Actions for Azure: https://github.com/Azure/actions + +name: Build and deploy ASP.Net Core app to Azure Web App - CheckDriver + +on: + push: + branches: + - integration + workflow_dispatch: + +jobs: + build: + runs-on: windows-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up .NET Core + uses: actions/setup-dotnet@v1 + with: + dotnet-version: '8.x' + include-prerelease: true + + - name: Build with dotnet + run: dotnet build --configuration Release + + - name: dotnet publish + run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/myapp + + - name: Upload artifact for deployment job + uses: actions/upload-artifact@v3 + with: + name: .net-app + path: ${{env.DOTNET_ROOT}}/myapp + + deploy: + runs-on: windows-latest + needs: build + environment: + name: 'Production' + url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} + permissions: + id-token: write #This is required for requesting the JWT + + steps: + - name: Download artifact from build job + uses: actions/download-artifact@v3 + with: + name: .net-app + + - name: Login to Azure + uses: azure/login@v1 + with: + client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_E9AF348E5C5C43AA8D4DC6D5D7832550 }} + tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_C81C36AF407F47E0841F8C513B2E4689 }} + subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_548C4B80BB1545B19DFB28DE2B816ED6 }} + + - name: Deploy to Azure Web App + id: deploy-to-webapp + uses: azure/webapps-deploy@v2 + with: + app-name: 'CheckDriver' + slot-name: 'Production' + package: . + \ No newline at end of file diff --git a/CheckDrive.Web/CheckDrive.Web.sln b/CheckDrive.Web/CheckDrive.Web.sln index ee6386de..663482f1 100644 --- a/CheckDrive.Web/CheckDrive.Web.sln +++ b/CheckDrive.Web/CheckDrive.Web.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.9.34728.123 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CheckDrive.Web", "CheckDrive.Web\CheckDrive.Web.csproj", "{7F91792F-530C-4443-AC8D-04D956B346F4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CheckDrive.Web", "CheckDrive.Web\CheckDrive.Web.csproj", "{7F91792F-530C-4443-AC8D-04D956B346F4}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/CheckDrive.Web/CheckDrive.Web/CheckDrive.Web.csproj b/CheckDrive.Web/CheckDrive.Web/CheckDrive.Web.csproj index 1b28a01c..6261dcf0 100644 --- a/CheckDrive.Web/CheckDrive.Web/CheckDrive.Web.csproj +++ b/CheckDrive.Web/CheckDrive.Web/CheckDrive.Web.csproj @@ -1,4 +1,4 @@ - + net8.0 @@ -6,4 +6,35 @@ enable + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CheckDrive.Web/CheckDrive.Web/Constants/Configurations.cs b/CheckDrive.Web/CheckDrive.Web/Constants/Configurations.cs new file mode 100644 index 00000000..33235529 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Constants/Configurations.cs @@ -0,0 +1,8 @@ +namespace CheckDrive.Web.Constants +{ + public static class Configurations + { + public const string JwtToken = "JwtToken"; + public const string SynfusionLicenseKey = "Mgo+DSMBMAY9C3t2UFhhQlJBfVldWnxLflFyVWRTelx6cF1WESFaRnZdRl1mSH1TfkBgWXhXeXdV"; + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Controllers/AccountsController.cs b/CheckDrive.Web/CheckDrive.Web/Controllers/AccountsController.cs new file mode 100644 index 00000000..2c7deb01 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Controllers/AccountsController.cs @@ -0,0 +1,133 @@ +using CheckDrive.ApiContracts.Account; +using CheckDrive.ApiContracts.Role; +using CheckDrive.Web.Stores.Accounts; +using CheckDrive.Web.Stores.Roles; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Rendering; + +namespace CheckDrive.Web.Controllers +{ + public class AccountsController : Controller + { + private readonly IAccountDataStore _accountDataStore; + private readonly IRoleDataStore _roleStore; + public AccountsController(IAccountDataStore accountDataStore, IRoleDataStore roleDataStore) + { + _roleStore = roleDataStore; + _accountDataStore = accountDataStore; + } + + public async Task Index(string? searchString, int? roleId, DateTime? birthDate, int? pageNumber) + { + var accounts = await _accountDataStore.GetAccountsAsync(searchString, roleId, birthDate, pageNumber); + + var roles = await GETRoles(); + + roles.Insert(0, new RoleDto + { + Id = 0, + Name = "Barcha ishchilar", + }); + var selectedRole = roles[0]; + + if (roleId.HasValue && roleId != 0) + { + selectedRole = roles.FirstOrDefault(x => x.Id == roleId); + } + + ViewBag.Accounts = accounts.Data; + ViewBag.Roles = roles; + + ViewBag.PageSize = accounts.PageSize; + ViewBag.PageCount = accounts.TotalPages; + ViewBag.TotalCount = accounts.TotalCount; + ViewBag.CurrentPage = accounts.PageNumber; + ViewBag.HasPreviousPage = accounts.HasPreviousPage; + ViewBag.HasNextPage = accounts.HasNextPage; + + ViewBag.SearchString = searchString; + ViewBag.CurrentRoleId = roleId; + ViewBag.SelectedRole = selectedRole; + + return View(); + } + public async Task Details(int id) + { + var account = await _accountDataStore.GetAccountAsync(id); + if (account == null) + { + return NotFound(); + } + return View(account); + } + public async Task Create() + { + var roles = await GETRoles(); + ViewBag.Roles = new SelectList(roles, "Id", "Name"); + return View(); + } + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Create([Bind("Login,Password,PhoneNumber,FirstName,LastName,Bithdate,RoleId")] + AccountForCreateDto account) + { + if (ModelState.IsValid) + { + await _accountDataStore.CreateAccountAsync(account); + return RedirectToAction(nameof(Index)); + } + var roles = await GETRoles(); + ViewBag.Roles = new SelectList(roles, "Id", "Name"); + return View(account); + } + + public async Task Edit(int id) + { + var account = await _accountDataStore.GetAccountAsync(id); + if (account == null) + { + return NotFound(); + } + + return View(account); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Edit(int id, [Bind("Id,Login,Password,PhoneNumber,FirstName,LastName,Bithdate,RoleId")] + AccountForUpdateDto account) + { + if (ModelState.IsValid) + { + await _accountDataStore.UpdateAccountAsync(id, account); + return RedirectToAction(nameof(Index)); + } + return View(account); + } + + public async Task Delete(int id) + { + var account = await _accountDataStore.GetAccountAsync(id); + if (account == null) + { + return NotFound(); + } + return View(account); + } + + [HttpPost, ActionName("Delete")] + [ValidateAntiForgeryToken] + public async Task DeleteConfirmed(int id) + { + await _accountDataStore.DeleteAccountAsync(id); + return RedirectToAction(nameof(Index)); + } + + private async Task> GETRoles() + { + var roleResponse = await _roleStore.GetRoles(); + var roles = roleResponse.Data.ToList(); + return roles; + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Controllers/AuthController.cs b/CheckDrive.Web/CheckDrive.Web/Controllers/AuthController.cs new file mode 100644 index 00000000..9505373f --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Controllers/AuthController.cs @@ -0,0 +1,116 @@ +using CheckDrive.ApiContracts.Account; +using CheckDrive.Web.Stores.User; +using CheckDrive.Web.ViewModels; +using Microsoft.AspNetCore.Mvc; +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; + +namespace CheckDrive.Web.Controllers +{ + public class AuthController : Controller + { + private readonly IUserDataStore _userDataStore; + public AuthController(IUserDataStore userDataStore) + { + _userDataStore = userDataStore; + } + + public IActionResult Login() + { + HttpContext.Response.Cookies.Delete("tasty-cookies"); + return RedirectToAction("Index", "Auth"); + } + + public IActionResult Index() + { + if (HttpContext.Request.Cookies.TryGetValue("tasty-cookies", out _)) + { + string token = HttpContext.Request.Cookies["tasty-cookies"]; + var tokenHandler = new JwtSecurityTokenHandler(); + var jwtToken = tokenHandler.ReadToken(token) as JwtSecurityToken; + if (jwtToken == null) + { + return RedirectToAction("Login", "Account"); + } + var roleId = jwtToken.Claims.First(claim => claim.Type == ClaimTypes.Role).Value; + + switch (roleId) + { + case "1": + return RedirectToAction("Index", "Dashboard"); + case "3": + return RedirectToAction("PersonalIndex", "DoctorReviews"); + case "4": + return RedirectToAction("PersonalIndex", "OperatorReviews"); + case "5": + return RedirectToAction("PersonalIndex", "DispatcherReviews"); + case "6": + return RedirectToAction("PersonalIndex", "MechanicHandovers"); + } + return RedirectToAction("Index", "Auth"); + } + return View("Index"); + } + + [HttpPost] + public async Task Index(AccountForLoginDto loginViewModel) + { + if (!ModelState.IsValid) + { + return View(loginViewModel); + } + + var user = new AccountForLoginDto + { + Login = loginViewModel.Login, + Password = loginViewModel.Password, + }; + + var (success, token) = await _userDataStore.AuthenticateLoginAsync(user); + + if (success) + { + HttpContext.Response.Cookies.Append("tasty-cookies", token, new CookieOptions + { + Secure = true, + SameSite = SameSiteMode.Strict, + HttpOnly = true, + IsEssential = true + }); + + var tokenHandler = new JwtSecurityTokenHandler(); + var jwtToken = tokenHandler.ReadToken(token) as JwtSecurityToken; + if (jwtToken == null) + { + return RedirectToAction("Login", "Account"); + } + var roleId = jwtToken.Claims.First(claim => claim.Type == ClaimTypes.Role).Value; + var accountId = jwtToken.Claims.First(claim => claim.Type == ClaimTypes.NameIdentifier).Value; + + switch (roleId) + { + case "1": + return RedirectToAction("Index", "Dashboard"); + case "3": + TempData["AccountId"] = accountId; + return RedirectToAction("PersonalIndex", "DoctorReviews"); + case "4": + TempData["AccountId"] = accountId; + return RedirectToAction("PersonalIndex", "OperatorReviews"); + case "5": + TempData["AccountId"] = accountId; + return RedirectToAction("PersonalIndex", "DispatcherReviews"); + case "6": + TempData["AccountId"] = accountId; + return RedirectToAction("PersonalIndex", "MechanicHandovers"); + default: + return RedirectToAction("Index", "Auth"); + } + } + + ModelState.AddModelError(string.Empty, "Invalid login attempt."); + ModelState.AddModelError("Password", "Incorrect password or login"); + return View(loginViewModel); + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Controllers/CarsController.cs b/CheckDrive.Web/CheckDrive.Web/Controllers/CarsController.cs new file mode 100644 index 00000000..1dc80e4b --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Controllers/CarsController.cs @@ -0,0 +1,120 @@ +using CheckDrive.ApiContracts.Car; +using CheckDrive.Web.Models; +using CheckDrive.Web.Stores.Cars; +using Microsoft.AspNetCore.Mvc; + +namespace CheckDrive.Web.Controllers +{ + public class CarsController : Controller + { + private readonly ICarDataStore _carDataStore; + + public CarsController(ICarDataStore carDataStore) + { + _carDataStore = carDataStore; + } + + public async Task Index(string? searchString,int? pageNumber) + { + var cars = await _carDataStore.GetCarsAsync(searchString,pageNumber); + + ViewBag.SearchString = searchString; + ViewBag.Cars = cars.Data; + + ViewBag.PageSize = cars.PageSize; + ViewBag.PageCount = cars.TotalPages; + ViewBag.TotalCount = cars.TotalCount; + ViewBag.CurrentPage = cars.PageNumber; + ViewBag.HasPreviousPage = cars.HasPreviousPage; + ViewBag.HasNextPage = cars.HasNextPage; + return View(); + } + + public async Task Details(int id) + { + var car = await _carDataStore.GetCarAsync(id); + if (car == null) + { + return NotFound(); + } + return View(car); + } + + public async Task DetailsForMechanicAcceptance(int id) + { + var car = await _carDataStore.GetCarAsync(id); + if (car == null) + { + return NotFound(); + } + return PartialView("_CarDetailsForMechanicAcceptance", car); + } + + public async Task DetailsForMechanicHandover(int id) + { + var car = await _carDataStore.GetCarAsync(id); + if (car == null) + { + return NotFound(); + } + return PartialView("_CarDetailsForMechanicHandover", car); + } + + public IActionResult Create() + { + return View(); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Create([Bind("Model,Color,Number,RemainingFuel,MeduimFuelConsumption,FuelTankCapacity,ManufacturedYear")] CarForCreateDto car) + { + if (ModelState.IsValid) + { + await _carDataStore.CreateCarAsync(car); + return RedirectToAction(nameof(Index)); + } + return View(car); + } + + public async Task Edit(int id) + { + var car = await _carDataStore.GetCarAsync(id); + if (car == null) + { + return NotFound(); + } + return View(car); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Edit(int id, [Bind("Id,Model,Color,Number,RemainingFuel,MeduimFuelConsumption,FuelTankCapacity,ManufacturedYear")] CarForUpdateDto car) + { + if (ModelState.IsValid) + { + await _carDataStore.UpdateCarAsync(id, car); + return RedirectToAction(nameof(Index)); + } + return View(car); + } + + public async Task Delete(int id) + { + var car = await _carDataStore.GetCarAsync(id); + if (car == null) + { + return NotFound(); + } + return View(car); + } + + [HttpPost, ActionName("Delete")] + [ValidateAntiForgeryToken] + public async Task DeleteConfirmed(int id) + { + await _carDataStore.DeleteCarAsync(id); + return RedirectToAction(nameof(Index)); + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Controllers/DashboardController.cs b/CheckDrive.Web/CheckDrive.Web/Controllers/DashboardController.cs new file mode 100644 index 00000000..fa91009e --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Controllers/DashboardController.cs @@ -0,0 +1,41 @@ +using CheckDrive.Web.Stores.Cars; +using CheckDrive.Web.Stores.Dashbord; +using CheckDrive.Web.ViewModels; +using Microsoft.AspNetCore.Mvc; + +namespace CheckDrive.Web.Controllers +{ + public class DashboardController : Controller + { + private readonly IDashboardStore _store; + public DashboardController(IDashboardStore store) + { + _store = store; + } + + public async Task Index() + { + var dashboard = await _store.GetDashboard(); + + if (dashboard is null) + { + return BadRequest(); + } + SetViewBagProperties(dashboard); + + return View(); + } + private void SetViewBagProperties(DashboardViewModel dashboard) + { + var summary = dashboard.Summary; + + ViewBag.MonthlyFuelConsumption = summary.MonthlyFuelConsumption.ToString("0.00"); + ViewBag.CarsCount = summary.CarsCount; + ViewBag.DriversCount = summary.DriversCount; + + ViewBag.EmployeesCountByRole = dashboard.EmployeesCountByRoles; + + ViewBag.SplineChartData = dashboard.SplineCharts; + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Controllers/DispatcherReviewsController.cs b/CheckDrive.Web/CheckDrive.Web/Controllers/DispatcherReviewsController.cs new file mode 100644 index 00000000..eca351cf --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Controllers/DispatcherReviewsController.cs @@ -0,0 +1,217 @@ +using CheckDrive.ApiContracts.Car; +using CheckDrive.ApiContracts.Dispatcher; +using CheckDrive.ApiContracts.DispatcherReview; +using CheckDrive.Web.Models; +using CheckDrive.Web.Stores.Cars; +using CheckDrive.Web.Stores.DispatcherReviews; +using CheckDrive.Web.Stores.Dispatchers; +using CheckDrive.Web.Stores.MechanicAcceptances; +using CheckDrive.Web.Stores.MechanicHandovers; +using CheckDrive.Web.Stores.OperatorReviews; +using Microsoft.AspNetCore.Mvc; + +namespace CheckDrive.Web.Controllers +{ + public class DispatcherReviewsController : Controller + { + private readonly IDispatcherReviewDataStore _dispatcherReviewDataStore; + private readonly IMechanicAcceptanceDataStore _mechanicAcceptanceDataStore; + private readonly IMechanicHandoverDataStore _mechanicHandoverDataStore; + private readonly IOperatorReviewDataStore _operatorDataStore; + private readonly IDispatcherDataStore _dispatcherDataStore; + private readonly ICarDataStore _carDataStore; + + public DispatcherReviewsController( + IDispatcherReviewDataStore dispatcherReviewDataStore, + IMechanicAcceptanceDataStore mechanicAcceptanceDataStore, + IOperatorReviewDataStore operatorDataStore, + IMechanicHandoverDataStore mechanicHandoverDataStore, + IDispatcherDataStore dispatcherDataStore, + ICarDataStore carDataStore) + { + _dispatcherReviewDataStore = dispatcherReviewDataStore; + _mechanicAcceptanceDataStore = mechanicAcceptanceDataStore; + _operatorDataStore = operatorDataStore; + _mechanicHandoverDataStore = mechanicHandoverDataStore; + _carDataStore = carDataStore; + _dispatcherDataStore = dispatcherDataStore; + } + + public async Task Index(int? pagenumber, string? searchString, DateTime? date) + { + var response = await _dispatcherReviewDataStore.GetDispatcherReviews(pagenumber, searchString, date, 1); + + + if (response is null) + { + return BadRequest(); + } + ViewBag.PageSize = response.PageSize; + ViewBag.PageCount = response.TotalPages; + ViewBag.TotalCount = response.TotalCount; + ViewBag.CurrentPage = response.PageNumber; + ViewBag.HasPreviousPage = response.HasPreviousPage; + ViewBag.HasNextPage = response.HasNextPage; + + var dispatcherReviewResponse = response.Data.Select(r => new + { + r.Id, + FuelSpended = r.FuelSpended.ToString("0.00").PadLeft(4, '0'), + r.DistanceCovered, + r.Date, + r.CarMeduimFuelConsumption, + r.CarName, + r.DispatcherName, + r.MechanicName, + r.OperatorName, + r.DriverName + }).ToList(); + + ViewBag.DispatcherReviews = dispatcherReviewResponse; + return View(); + } + + public async Task PersonalIndex(int? pagenumber) + { + var reviewsResponse = await _dispatcherReviewDataStore.GetDispatcherReviews(pagenumber, null, null, 5); + + ViewBag.PageSize = reviewsResponse.PageSize; + ViewBag.PageCount = reviewsResponse.TotalPages; + ViewBag.TotalCount = reviewsResponse.TotalCount; + ViewBag.CurrentPage = reviewsResponse.PageNumber; + ViewBag.HasPreviousPage = reviewsResponse.HasPreviousPage; + ViewBag.HasNextPage = reviewsResponse.HasNextPage; + + return View(reviewsResponse.Data); + } + + public async Task Details(int id) + { + var review = await _dispatcherReviewDataStore.GetDispatcherReview(id); + if (review == null) + { + return NotFound(); + } + return View(review); + } + + public async Task Create(double? distanceCovered, double? fuelSpended, int operatorId, int mechanicId, int driverId, int mechanicHandoverId, int mechanicAcceptanceId, int carId, int operatorReviewId) + { + var accountIdStr = TempData["AccountId"] as string; + TempData.Keep("AccountId"); + var dispatcher = new DispatcherDto(); + if (int.TryParse(accountIdStr, out int accountId)) + { + var dispatcherResponse = await _dispatcherDataStore.GetDispatchers(accountId); + dispatcher = dispatcherResponse.Data.First(); + } + var model = new DispatcherReviewForCreateDto + { + DistanceCovered = distanceCovered ?? 0, + FuelSpended = fuelSpended ?? 0, + Date = DateTime.Now, + DispatcherId = dispatcher.Id, + OperatorId = operatorId, + MechanicId = mechanicId, + DriverId = driverId, + CarId = carId, + MechanicAcceptanceId = mechanicAcceptanceId, + MechanicHandoverId = mechanicHandoverId, + OperatorReviewId = operatorReviewId + }; + + return View(model); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Create([Bind("FuelSpended,DistanceCovered,Date,DispatcherId,OperatorId,MechanicId,DriverId,MechanicHandoverId,MechanicAcceptanceId,CarId, OperatorReviewId")] DispatcherReviewForCreateDto dispatcherReview) + { + dispatcherReview.Date = DateTime.Now; + var car = _carDataStore.GetCarAsync(dispatcherReview.CarId); + var carr = new CarForUpdateDto + { + Id = dispatcherReview.CarId, + Color = car.Result.Color, + FuelTankCapacity = car.Result.FuelTankCapacity, + ManufacturedYear = car.Result.ManufacturedYear, + MeduimFuelConsumption = car.Result.MeduimFuelConsumption, + Model = car.Result.Model, + Number = car.Result.Number, + RemainingFuel = car.Result.RemainingFuel - dispatcherReview.FuelSpended, + }; + if (ModelState.IsValid) + { + await _carDataStore.UpdateCarAsync(dispatcherReview.CarId, carr); + await _dispatcherReviewDataStore.CreateDispatcherReview(dispatcherReview); + return RedirectToAction(nameof(Index)); + } + return View(dispatcherReview); + } + + public async Task Edit(int id) + { + var review = await _dispatcherReviewDataStore.GetDispatcherReview(id); + if (review == null) + { + return NotFound(); + } + return View(review); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Edit(int id, [Bind("Id,FuelSpended,DistanceCovered,Date,DispatcherId,OperatorId,MechanicId,DriverId")] DispatcherReviewForUpdateDto dispatcherReview) + { + if (id != dispatcherReview.Id) + { + return NotFound(); + } + + if (ModelState.IsValid) + { + try + { + await _dispatcherReviewDataStore.UpdateDispatcherReview(id, dispatcherReview); + } + catch (Exception) + { + if (!await DispatcherReviewExists(id)) + { + return NotFound(); + } + else + { + throw; + } + } + return RedirectToAction(nameof(Index)); + } + return View(dispatcherReview); + } + + public async Task Delete(int id) + { + var review = await _dispatcherReviewDataStore.GetDispatcherReview(id); + if (review == null) + { + return NotFound(); + } + return View(review); + } + + [HttpPost, ActionName("Delete")] + [ValidateAntiForgeryToken] + public async Task DeleteConfirmed(int id) + { + await _dispatcherReviewDataStore.DeleteDispatcherReview(id); + return RedirectToAction(nameof(Index)); + } + + private async Task DispatcherReviewExists(int id) + { + var review = await _dispatcherReviewDataStore.GetDispatcherReview(id); + return review != null; + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Controllers/DoctorReviewsController.cs b/CheckDrive.Web/CheckDrive.Web/Controllers/DoctorReviewsController.cs new file mode 100644 index 00000000..a28bc4b5 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Controllers/DoctorReviewsController.cs @@ -0,0 +1,238 @@ +using CheckDrive.ApiContracts.DoctorReview; +using CheckDrive.Web.Stores.Accounts; +using CheckDrive.Web.Stores.DoctorReviews; +using CheckDrive.Web.Stores.Doctors; +using CheckDrive.Web.Stores.Drivers; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Rendering; + +namespace CheckDrive.Web.Controllers +{ + public class DoctorReviewsController : Controller + { + private readonly IDoctorReviewDataStore _doctorReviewDataStore; + private readonly IDoctorDataStore _doctorDataStore; + private readonly IDriverDataStore _driverDataStore; + private readonly IAccountDataStore _accountDataStore; + + public DoctorReviewsController(IDoctorReviewDataStore doctorReviewDataStore, IDoctorDataStore doctorDataStore, IDriverDataStore driverDataStore, IAccountDataStore accountDataStore) + { + _doctorReviewDataStore = doctorReviewDataStore; + _doctorDataStore = doctorDataStore; + _driverDataStore = driverDataStore; + _accountDataStore = accountDataStore; + } + + public async Task Index(int? pageNumber, string? searchString, DateTime? date) + { + var response = await _doctorReviewDataStore.GetDoctorReviewsAsync(pageNumber, searchString, date, 1); + + ViewBag.PageSize = response.PageSize; + ViewBag.PageCount = response.TotalPages; + ViewBag.TotalCount = response.TotalCount; + ViewBag.CurrentPage = response.PageNumber; + ViewBag.HasPreviousPage = response.HasPreviousPage; + ViewBag.HasNextPage = response.HasNextPage; + + var doctorReviews = response.Data.Select(r => new + { + r.Id, + r.DriverName, + r.DoctorName, + r.Date, + IsHealthy = (bool)r.IsHealthy ? "Sog`lom" : "Kasal", + r.Comments + }).ToList(); + + ViewBag.DoctorsReview = doctorReviews; + + return View(); + } + + public async Task PersonalIndex(int? pageNumber, string? searchString) + { + var reviewsResponse = await _doctorReviewDataStore.GetDoctorReviewsAsync(pageNumber, searchString, null, 3); + + ViewBag.PageSize = reviewsResponse.PageSize; + ViewBag.PageCount = reviewsResponse.TotalPages; + ViewBag.TotalCount = reviewsResponse.TotalCount; + ViewBag.CurrentPage = reviewsResponse.PageNumber; + ViewBag.HasPreviousPage = reviewsResponse.HasPreviousPage; + ViewBag.HasNextPage = reviewsResponse.HasNextPage; + + return View(reviewsResponse.Data); + } + + public async Task Details(int id) + { + var review = await _doctorReviewDataStore.GetDoctorReviewAsync(id); + if (review == null) + { + return NotFound(); + } + return View(review); + } + + public async Task Create(int driverId, string driverName) + { + var accountIdStr = TempData["AccountId"] as string; + TempData.Keep("AccountId"); + + if (int.TryParse(accountIdStr, out int accountId)) + { + var doctorResponse = await _doctorDataStore.GetDoctors(accountId); + var doctor = doctorResponse.Data.FirstOrDefault(); + if (doctor != null) + { + var doctors = new List + { + new SelectListItem { Value = doctor.Id.ToString(), Text = $"{doctor.FirstName} {doctor.LastName}" } + }; + + var driversNotUsedToday = await GetDriversNotUsedToday(); + + ViewBag.Doctors = new SelectList(doctors, "Value", "Text"); + ViewBag.SelectedDriverName = driverName; + ViewBag.SelectedDriverId = driverId; + ViewBag.DoctorId = doctor.Id; + ViewBag.Drivers = new SelectList(driversNotUsedToday, "Value", "Text"); + + return View(new DoctorReviewForCreateDto { DriverId = driverId, Date = DateTime.Now, DoctorId = doctor.Id }); + } + } + + return NotFound("Bu akkauntdagi shifokor topilmadi"); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Create([Bind("IsHealthy,Comments,DriverId,DoctorId")] DoctorReviewForCreateDto doctorReview) + { + if (ModelState.IsValid) + { + doctorReview.Date = DateTime.Now; + await _doctorReviewDataStore.CreateDoctorReviewAsync(doctorReview); + return RedirectToAction(nameof(PersonalIndex)); + } + + var driver = await _driverDataStore.GetDriverAsync(doctorReview.DriverId); + ViewBag.SelectedDriverName = $"{driver.FirstName} {driver.LastName}"; + ViewBag.SelectedDriverId = doctorReview.DriverId; + + var accountIdStr = TempData["AccountId"] as string; + TempData.Keep("AccountId"); + + if (int.TryParse(accountIdStr, out int accountId)) + { + var doctorResponse = await _doctorDataStore.GetDoctors(accountId); + var doctor = doctorResponse.Data.FirstOrDefault(); + if (doctor != null) + { + var doctors = new List + { + new SelectListItem { Value = doctor.Id.ToString(), Text = $"{doctor.FirstName} {doctor.LastName}" } + }; + + ViewBag.Doctors = new SelectList(doctors, "Value", "Text"); + ViewBag.DoctorId = doctor.Id; + } + } + + return View(doctorReview); + } + + public async Task Edit(int id) + { + var review = await _doctorReviewDataStore.GetDoctorReviewAsync(id); + if (review == null) + { + return NotFound(); + } + return View(review); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Edit(int id, [Bind("Id,IsHealthy,Comments,Date,DriverId,DoctorId")] DoctorReviewForUpdateDto doctorReview) + { + if (id != doctorReview.Id) + { + return NotFound(); + } + + if (ModelState.IsValid) + { + try + { + await _doctorReviewDataStore.UpdateDoctorReviewAsync(id, doctorReview); + } + catch (Exception) + { + if (!await DoctorReviewExists(id)) + { + return NotFound(); + } + else + { + throw; + } + } + return RedirectToAction(nameof(Index)); + } + return View(doctorReview); + } + + public async Task Delete(int id) + { + var review = await _doctorReviewDataStore.GetDoctorReviewAsync(id); + if (review == null) + { + return NotFound(); + } + return View(review); + } + + [HttpPost, ActionName("Delete")] + [ValidateAntiForgeryToken] + public async Task DeleteConfirmed(int id) + { + await _doctorReviewDataStore.DeleteDoctorReviewAsync(id); + return RedirectToAction(nameof(Index)); + } + + private async Task DoctorReviewExists(int id) + { + var review = await _doctorReviewDataStore.GetDoctorReviewAsync(id); + return review != null; + } + + private async Task> GetDriversNotUsedToday() + { + var doctorReviews = await _doctorReviewDataStore.GetDoctorReviewsAsync(null, null, null, 1); + var today = DateTime.Today; + var usedDriverIds = doctorReviews.Data + .Where(dr => dr.Date.Date == today) + .Select(dr => dr.DriverId) + .ToList(); + + var drivers = await GETDrivers(); + var driversNotUsedToday = drivers + .Where(d => !usedDriverIds.Contains(int.Parse(d.Value))) + .ToList(); + + return driversNotUsedToday; + } + private async Task> GETDrivers() + { + var driverResponse = await _driverDataStore.GetDriversAsync(null, null); + var drivers = driverResponse.Data + .Select(d => new SelectListItem + { + Value = d.Id.ToString(), + Text = $"{d.FirstName} {d.LastName}" + }) + .ToList(); + return drivers; + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Controllers/DoctorsController.cs b/CheckDrive.Web/CheckDrive.Web/Controllers/DoctorsController.cs new file mode 100644 index 00000000..9607f3ec --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Controllers/DoctorsController.cs @@ -0,0 +1,115 @@ +using CheckDrive.ApiContracts.Account; +using CheckDrive.ApiContracts.Doctor; +using CheckDrive.Web.Stores.Doctors; +using Microsoft.AspNetCore.Mvc; + +namespace CheckDrive.Web.Controllers +{ + public class DoctorsController : Controller + { + private readonly IDoctorDataStore _doctorDataStore; + + public DoctorsController(IDoctorDataStore doctorDataStore) + { + _doctorDataStore = doctorDataStore; + } + + public async Task Index() + { + var doctors = await _doctorDataStore.GetDoctors(); + return View(doctors); + } + + public async Task Details(int id) + { + var doctor = await _doctorDataStore.GetDoctor(id); + if (doctor == null) + { + return NotFound(); + } + return View(doctor); + } + + public IActionResult Create() + { + return View(); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Create([Bind("AccountId")] DoctorForCreateDto doctor) + { + if (ModelState.IsValid) + { + await _doctorDataStore.CreateDoctor(doctor); + return RedirectToAction(nameof(Index)); + } + return View(doctor); + } + + public async Task Edit(int id) + { + var doctor = await _doctorDataStore.GetDoctor(id); + if (doctor == null) + { + return NotFound(); + } + return View(doctor); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Edit(int id, [Bind("Id,AccountId")] AccountForUpdateDto doctor) + { + if (id != doctor.Id) + { + return NotFound(); + } + + if (ModelState.IsValid) + { + try + { + await _doctorDataStore.UpdateDoctor(id, doctor); + } + catch (Exception) + { + if (!await DoctorExists(id)) + { + return NotFound(); + } + else + { + throw; + } + } + return RedirectToAction(nameof(Index)); + } + return View(doctor); + } + + public async Task Delete(int id) + { + var doctor = await _doctorDataStore.GetDoctor(id); + if (doctor == null) + { + return NotFound(); + } + return View(doctor); + } + + [HttpPost, ActionName("Delete")] + [ValidateAntiForgeryToken] + public async Task DeleteConfirmed(int id) + { + await _doctorDataStore.DeleteDoctor(id); + return RedirectToAction(nameof(Index)); + } + + private async Task DoctorExists(int id) + { + var doctor = await _doctorDataStore.GetDoctor(id); + return doctor != null; + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Controllers/DriversController.cs b/CheckDrive.Web/CheckDrive.Web/Controllers/DriversController.cs new file mode 100644 index 00000000..f1018a34 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Controllers/DriversController.cs @@ -0,0 +1,112 @@ +using CheckDrive.ApiContracts.Account; +using CheckDrive.ApiContracts.Driver; +using CheckDrive.Web.Stores.Drivers; +using Microsoft.AspNetCore.Mvc; + +namespace CheckDrive.Web.Controllers +{ + public class DriversController(IDriverDataStore driverDataStore) : Controller + { + private readonly IDriverDataStore _driverDataStore = driverDataStore; + + public async Task Index() + { + var drivers = await _driverDataStore.GetDriversAsync(null, null); + + ViewBag.Drivers = drivers; + return View(); + } + + public async Task Details(int id) + { + var driver = await _driverDataStore.GetDriverAsync(id); + if (driver == null) + { + return NotFound(); + } + return View(driver); + } + + public IActionResult Create() + { + return View(); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Create([Bind("AccountId")] DriverForCreateDto driver) + { + if (ModelState.IsValid) + { + await _driverDataStore.CreateDriverAsync(driver); + return RedirectToAction(nameof(Index)); + } + return View(driver); + } + + public async Task Edit(int id) + { + var driver = await _driverDataStore.GetDriverAsync(id); + if (driver == null) + { + return NotFound(); + } + return View(driver); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Edit(int id, [Bind("Id,AccountId")] AccountForUpdateDto driver) + { + if (id != driver.Id) + { + return NotFound(); + } + + if (ModelState.IsValid) + { + try + { + await _driverDataStore.UpdateDriverAsync(id, driver); + } + catch (Exception) + { + if (!await DriverExists(id)) + { + return NotFound(); + } + else + { + throw; + } + } + return RedirectToAction(nameof(Index)); + } + return View(driver); + } + + public async Task Delete(int id) + { + var driver = await _driverDataStore.GetDriverAsync(id); + if (driver == null) + { + return NotFound(); + } + return View(driver); + } + + [HttpPost, ActionName("Delete")] + [ValidateAntiForgeryToken] + public async Task DeleteConfirmed(int id) + { + await _driverDataStore.DeleteDriverAsync(id); + return RedirectToAction(nameof(Index)); + } + + private async Task DriverExists(int id) + { + var driver = await _driverDataStore.GetDriverAsync(id); + return driver != null; + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Controllers/HomeController.cs b/CheckDrive.Web/CheckDrive.Web/Controllers/HomeController.cs deleted file mode 100644 index 2fafb34e..00000000 --- a/CheckDrive.Web/CheckDrive.Web/Controllers/HomeController.cs +++ /dev/null @@ -1,30 +0,0 @@ -using CheckDrive.Web.Models; -using Microsoft.AspNetCore.Mvc; -using System.Diagnostics; - -namespace CheckDrive.Web.Controllers; -public class HomeController : Controller -{ - private readonly ILogger _logger; - - public HomeController(ILogger logger) - { - _logger = logger; - } - - public IActionResult Index() - { - return View(); - } - - public IActionResult Privacy() - { - return View(); - } - - [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] - public IActionResult Error() - { - return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); - } -} diff --git a/CheckDrive.Web/CheckDrive.Web/Controllers/MechanicAcceptancesController.cs b/CheckDrive.Web/CheckDrive.Web/Controllers/MechanicAcceptancesController.cs new file mode 100644 index 00000000..9033c743 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Controllers/MechanicAcceptancesController.cs @@ -0,0 +1,304 @@ +using CheckDrive.ApiContracts; +using CheckDrive.ApiContracts.MechanicAcceptance; +using CheckDrive.Web.Stores.Cars; +using CheckDrive.Web.Stores.Drivers; +using CheckDrive.Web.Stores.MechanicAcceptances; +using CheckDrive.Web.Stores.MechanicHandovers; +using CheckDrive.Web.Stores.Mechanics; +using CheckDrive.Web.Stores.OperatorReviews; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Rendering; + +namespace CheckDrive.Web.Controllers +{ + public class MechanicAcceptancesController : Controller + { + private readonly IMechanicAcceptanceDataStore _mechanicAcceptanceDataStore; + private readonly IDriverDataStore _driverDataStore; + private readonly ICarDataStore _carDataStore; + private readonly IMechanicDataStore _mechanicDataStore; + private readonly IOperatorReviewDataStore _operatorReviewDataStore; + private readonly IMechanicHandoverDataStore _mechanicHandoverDataStore; + + public MechanicAcceptancesController(IMechanicAcceptanceDataStore mechanicAcceptanceDataStore, IDriverDataStore driverDataStore, ICarDataStore carDataStore, IMechanicDataStore mechanicDataStore, IOperatorReviewDataStore operatorReviewDataStore, IMechanicHandoverDataStore mechanicHandoverDataStore) + { + _mechanicAcceptanceDataStore = mechanicAcceptanceDataStore; + _driverDataStore = driverDataStore; + _carDataStore = carDataStore; + _mechanicDataStore = mechanicDataStore; + _operatorReviewDataStore = operatorReviewDataStore; + _mechanicHandoverDataStore = mechanicHandoverDataStore; + } + + public async Task Index(int? pageNumber, string? searchString, DateTime? date) + { + + var response = await _mechanicAcceptanceDataStore.GetMechanicAcceptancesAsync(pageNumber, searchString, date, 1); + + ViewBag.PageSize = response.PageSize; + ViewBag.PageCount = response.TotalPages; + ViewBag.TotalCount = response.TotalCount; + ViewBag.CurrentPage = response.PageNumber; + ViewBag.HasPreviousPage = response.HasPreviousPage; + ViewBag.HasNextPage = response.HasNextPage; + + var mechanicAcceptances = response.Data.Select(r => new + { + r.Id, + IsAccepted = (bool)r.IsAccepted ? "Qabul qilindi" : "Rad etildi", + r.Comments, + Status = ((StatusForDto)r.Status) switch + { + StatusForDto.Pending => "Pending", + StatusForDto.Completed => "Completed", + StatusForDto.Rejected => "Rejected", + StatusForDto.Unassigned => "Unassigned", + _ => "Unknown Status" + }, + r.Date, + r.Distance, + r.DriverName, + r.MechanicName, + r.CarName, + r.CarId + }).ToList(); + + ViewBag.MechanicAcceptances = mechanicAcceptances; + + return View(); + } + + + public async Task PersonalIndex(string? searchString, int? pageNumber) + { + var response = await _mechanicAcceptanceDataStore.GetMechanicAcceptancesAsync(pageNumber, searchString, null, 6); + + ViewBag.PageSize = response.PageSize; + ViewBag.PageCount = response.TotalPages; + ViewBag.TotalCount = response.TotalCount; + ViewBag.CurrentPage = response.PageNumber; + ViewBag.HasPreviousPage = response.HasPreviousPage; + ViewBag.HasNextPage = response.HasNextPage; + + return View(response.Data); + } + public async Task Create(int? driverId, int? carId) + { + var mechanics = await GETMechanics(); + var drivers = await GETDrivers(); + var cars = await GETCars(); + + var operatorReviews = await _operatorReviewDataStore.GetOperatorReviews(null, null, null, 1); + var mechanicAcceptances = await _mechanicAcceptanceDataStore.GetMechanicAcceptancesAsync(); + + var accountIdStr = TempData["AccountId"] as string; + TempData.Keep("AccountId"); + + if (int.TryParse(accountIdStr, out int accountId)) + { + var mechanicResponse = await _mechanicDataStore.GetMechanics(accountId); + var mechanic = mechanicResponse.Data.FirstOrDefault(); + + if (mechanic != null) + { + var healthyDrivers = operatorReviews.Data + .Where(dr => dr.IsGiven.HasValue && dr.IsGiven.Value && dr.Date.HasValue && dr.Date.Value.Date == DateTime.Today) + .Select(dr => dr.DriverId) + .ToList(); + + var acceptedDrivers = mechanicAcceptances.Data + .Where(ma => ma.Date.HasValue && ma.Date.Value.Date == DateTime.Today) + .Select(ma => ma.DriverId) + .ToList(); + + var filteredDrivers = drivers + .Where(d => healthyDrivers.Contains(int.Parse(d.Value)) && !acceptedDrivers.Contains(int.Parse(d.Value))) + .ToList(); + + if (driverId == null && filteredDrivers.Any()) + { + driverId = int.Parse(filteredDrivers.First().Value); + } + + filteredDrivers = filteredDrivers.Where(d => d.Value != driverId.ToString()).ToList(); + + if (carId == null && cars.Any()) + { + carId = int.Parse(cars.First().Value); + } + + ViewBag.Mechanics = new SelectList(mechanics, "Value", "Text"); + ViewBag.Drivers = new SelectList(filteredDrivers, "Value", "Text", driverId); + ViewBag.Cars = new SelectList(cars, "Value", "Text", carId); + + var selectedDriverName = drivers.FirstOrDefault(d => d.Value == driverId.ToString())?.Text; + ViewBag.SelectedDriverName = selectedDriverName ?? string.Empty; + ViewBag.SelectedDriverId = driverId; + + var selectedCar = cars.FirstOrDefault(c => c.Value == carId.ToString())?.Text; + ViewBag.SelectedCar = selectedCar ?? string.Empty; + ViewBag.SelectedCarId = carId; + + var model = new MechanicAcceptanceForCreateDto + { + DriverId = driverId ?? 0, + MechanicId = mechanic.Id, + CarId = carId ?? 0 + }; + + return View(model); + } + } + + return NotFound("Mechanic not found for the specified account."); + } + + + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Create([Bind("IsAccepted,Comments,MechanicId,Distance,CarId,DriverId")] MechanicAcceptanceForCreateDto mechanicAcceptanceForCreateDto) + { + if (ModelState.IsValid) + { + if (mechanicAcceptanceForCreateDto.IsAccepted == null) + { + mechanicAcceptanceForCreateDto.IsAccepted = false; + } + + mechanicAcceptanceForCreateDto.Date = DateTime.Now; + + await _mechanicAcceptanceDataStore.CreateMechanicAcceptanceAsync(mechanicAcceptanceForCreateDto); + return RedirectToAction(nameof(PersonalIndex)); + } + + var mechanics = await GETMechanics(); + var drivers = await GETDrivers(); + var cars = await GETCars(); + + ViewBag.Mechanics = new SelectList(mechanics, "Value", "Text"); + ViewBag.Drivers = new SelectList(drivers, "Value", "Text", mechanicAcceptanceForCreateDto.DriverId); + ViewBag.Cars = new SelectList(cars, "Value", "Text", mechanicAcceptanceForCreateDto.CarId); + + var selectedDriverName = drivers.FirstOrDefault(d => d.Value == mechanicAcceptanceForCreateDto.DriverId.ToString())?.Text; + ViewBag.SelectedDriverName = selectedDriverName ?? string.Empty; + ViewBag.SelectedDriverId = mechanicAcceptanceForCreateDto.DriverId; + + var selectedCar = cars.FirstOrDefault(c => c.Value == mechanicAcceptanceForCreateDto.CarId.ToString())?.Text; + ViewBag.SelectedCar = selectedCar ?? string.Empty; + ViewBag.SelectedCarId = mechanicAcceptanceForCreateDto.CarId; + + return View(mechanicAcceptanceForCreateDto); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Edit(int id, MechanicAcceptanceForUpdateDto mechanicAcceptance) + { + if (id != mechanicAcceptance.Id) + { + return NotFound(); + } + + if (ModelState.IsValid) + { + try + { + await _mechanicAcceptanceDataStore.UpdateMechanicAcceptanceAsync(id, mechanicAcceptance); + } + catch (Exception) + { + if (!await MechanicAcceptanceExists(id)) + { + return NotFound(); + } + else + { + throw; + } + } + return RedirectToAction(nameof(Index)); + } + + ViewBag.Drivers = new SelectList(await GETDrivers(), "Value", "Text"); + ViewBag.Cars = new SelectList(await GETCars(), "Value", "Text"); + + return View(mechanicAcceptance); + } + + public async Task Delete(int id) + { + var mechanicAcceptance = await _mechanicAcceptanceDataStore.GetMechanicAcceptanceAsync(id); + if (mechanicAcceptance == null) + { + return NotFound(); + } + return View(mechanicAcceptance); + } + + [HttpPost, ActionName("Delete")] + [ValidateAntiForgeryToken] + public async Task DeleteConfirmed(int id) + { + await _mechanicAcceptanceDataStore.DeleteMechanicAcceptanceAsync(id); + return RedirectToAction(nameof(Index)); + } + + private async Task MechanicAcceptanceExists(int id) + { + var mechanicAcceptance = await _mechanicAcceptanceDataStore.GetMechanicAcceptanceAsync(id); + return mechanicAcceptance != null; + } + + private async Task> GETMechanics() + { + var mechanicResponse = await _mechanicDataStore.GetMechanicsAsync(); + var mechanics = mechanicResponse.Data + .Select(d => new SelectListItem + { + Value = d.Id.ToString(), + Text = $"{d.FirstName} {d.LastName}" + }) + .ToList(); + return mechanics; + } + private async Task> GETCars() + { + var carResponse = await _carDataStore.GetCarsAsync(null, null); + var cars = carResponse.Data + .Select(c => new SelectListItem + { + Value = c.Id.ToString(), + Text = $"{c.Model} ({c.Number})" + }) + .ToList(); + return cars; + } + + private async Task> GETDrivers() + { + var driverResponse = await _driverDataStore.GetDriversAsync(null, null); + var drivers = driverResponse.Data + .Select(d => new SelectListItem + { + Value = d.Id.ToString(), + Text = $"{d.FirstName} {d.LastName}" + }) + .ToList(); + return drivers; + } + + public async Task GetCarByDriverId(int driverId) + { + var operatorReviews = await _operatorReviewDataStore.GetOperatorReviews(null,null, null, null); + var operatorr = operatorReviews.Data.FirstOrDefault(m => m.DriverId == driverId && m.Date.Value.Date == DateTime.Today); + + if (operatorr != null) + { + var car = await _carDataStore.GetCarAsync(operatorr.CarId); + return Json(new { success = true, car }); + } + return Json(new { success = false }); + } + } +} \ No newline at end of file diff --git a/CheckDrive.Web/CheckDrive.Web/Controllers/MechanicHandoversController.cs b/CheckDrive.Web/CheckDrive.Web/Controllers/MechanicHandoversController.cs new file mode 100644 index 00000000..15159f67 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Controllers/MechanicHandoversController.cs @@ -0,0 +1,267 @@ +using CheckDrive.ApiContracts; +using CheckDrive.ApiContracts.MechanicHandover; +using CheckDrive.Web.Stores.Cars; +using CheckDrive.Web.Stores.DoctorReviews; +using CheckDrive.Web.Stores.Drivers; +using CheckDrive.Web.Stores.MechanicHandovers; +using CheckDrive.Web.Stores.Mechanics; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Rendering; + +namespace CheckDrive.Web.Controllers +{ + public class MechanicHandoversController : Controller + { + private readonly IMechanicHandoverDataStore _mechanicHandoverDataStore; + private readonly IDriverDataStore _driverDataStore; + private readonly ICarDataStore _carDataStore; + private readonly IMechanicDataStore _mechanicDataStore; + private readonly IDoctorReviewDataStore _doctorReviewDataStore; + + public MechanicHandoversController(IMechanicHandoverDataStore mechanicHandoverDataStore, IDriverDataStore driverDataStore, ICarDataStore carDataStore, IMechanicDataStore mechanicDataStore, IDoctorReviewDataStore doctorReviewDataStore) + { + _mechanicHandoverDataStore = mechanicHandoverDataStore; + _driverDataStore = driverDataStore; + _carDataStore = carDataStore; + _mechanicDataStore = mechanicDataStore; + _doctorReviewDataStore = doctorReviewDataStore; + } + + public async Task Index(int? pageNumber, string? searchString, DateTime? date) + { + var response = await _mechanicHandoverDataStore.GetMechanicHandoversAsync(pageNumber, searchString, date, 1); + + ViewBag.PageSize = response.PageSize; + ViewBag.PageCount = response.TotalPages; + ViewBag.TotalCount = response.TotalCount; + ViewBag.CurrentPage = response.PageNumber; + ViewBag.HasPreviousPage = response.HasPreviousPage; + ViewBag.HasNextPage = response.HasNextPage; + + var mechanicHandovers = response.Data.Select(r => new + { + r.Id, + IsHanded = (bool)r.IsHanded ? "Topshirildi" : "Topshirilmadi", + r.Comments, + Status = ((StatusForDto)r.Status) switch + { + StatusForDto.Pending => "Pending", + StatusForDto.Completed => "Completed", + StatusForDto.Rejected => "Rejected", + StatusForDto.Unassigned => "Unassigned", + _ => "Unknown Status" + }, + r.Date, + r.Distance, + r.DriverName, + r.MechanicName, + r.CarName, + r.CarId + }).ToList(); + + ViewBag.MechanicHandovers = mechanicHandovers; + + return View(); + } + + public async Task PersonalIndex(string? searchString, int? pageNumber) + { + var response = await _mechanicHandoverDataStore.GetMechanicHandoversAsync(pageNumber, searchString, null, 6); + + ViewBag.PageSize = response.PageSize; + ViewBag.PageCount = response.TotalPages; + ViewBag.TotalCount = response.TotalCount; + ViewBag.CurrentPage = response.PageNumber; + ViewBag.HasPreviousPage = response.HasPreviousPage; + ViewBag.HasNextPage = response.HasNextPage; + + return View(response.Data); + } + + public async Task Create(int? driverId) + { + var mechanics = await GETMechanics(); + var drivers = await GETDrivers(); + var cars = await GETCars(); + + var doctorReviews = await _doctorReviewDataStore.GetDoctorReviewsAsync(null, null, null, 1); + var mechanicHandovers = await _mechanicHandoverDataStore.GetMechanicHandoversAsync(); + + var accountIdStr = TempData["AccountId"] as string; + TempData.Keep("AccountId"); + + if (int.TryParse(accountIdStr, out int accountId)) + { + var mechanicResponse = await _mechanicDataStore.GetMechanics(accountId); + var mechanic = mechanicResponse.Data.First(); + if (mechanic != null) + { + var healthyDrivers = doctorReviews.Data + .Where(dr => dr.IsHealthy.HasValue && dr.IsHealthy.Value && dr.Date.Date == DateTime.Today) + .Select(dr => dr.DriverId) + .ToList(); + + var handedDrivers = mechanicHandovers.Data + .Where(ma => ma.Date.Date == DateTime.Today) + .Select(ma => ma.DriverId) + .ToList(); + + var filteredDrivers = drivers + .Where(d => healthyDrivers.Contains(int.Parse(d.Value)) && !handedDrivers.Contains(int.Parse(d.Value))) + .ToList(); + + var usedCarIds = mechanicHandovers.Data + .Where(mh => mh.Date.Date == DateTime.Today && mh.IsHanded == true) + .Select(mh => mh.CarId) + .ToList(); + + var filteredCars = cars + .Where(c => !usedCarIds.Contains(int.Parse(c.Value))) + .ToList(); + + ViewBag.Mechanics = new SelectList(mechanics, "Value", "Text"); + ViewBag.Drivers = new SelectList(filteredDrivers, "Value", "Text", driverId); + ViewBag.Cars = new SelectList(filteredCars, "Value", "Text"); + + var selectedDriverName = filteredDrivers.FirstOrDefault(d => d.Value == driverId.ToString())?.Text; + ViewBag.SelectedDriverName = selectedDriverName ?? string.Empty; + ViewBag.SelectedDriverId = driverId; + + return View(new MechanicHandoverForCreateDto { DriverId = driverId ?? 0, MechanicId = mechanic.Id }); + } + } + + return NotFound("Механик не найден для указанного аккаунта."); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Create([Bind("IsHanded,Comments,MechanicId,Distance,CarId,DriverId")] MechanicHandoverForCreateDto mechanicHandoverForCreateDto) + { + if (ModelState.IsValid) + { + if (mechanicHandoverForCreateDto.IsHanded == false) + { + mechanicHandoverForCreateDto.Status = StatusForDto.Rejected; + } + + mechanicHandoverForCreateDto.Date = DateTime.Now; + await _mechanicHandoverDataStore.CreateMechanicHandoverAsync(mechanicHandoverForCreateDto); + return RedirectToAction(nameof(PersonalIndex)); + } + + var mechanics = await GETMechanics(); + var drivers = await GETDrivers(); + var cars = await GETCars(); + ViewBag.Mechanics = new SelectList(mechanics, "Value", "Text"); + ViewBag.Drivers = new SelectList(drivers, "Value", "Text", mechanicHandoverForCreateDto.DriverId); + ViewBag.Cars = new SelectList(cars, "Value", "Text"); + + var selectedDriverName = drivers.FirstOrDefault(d => d.Value == mechanicHandoverForCreateDto.DriverId.ToString())?.Text; + ViewBag.SelectedDriverName = selectedDriverName ?? string.Empty; + ViewBag.SelectedDriverId = mechanicHandoverForCreateDto.DriverId; + + return View(mechanicHandoverForCreateDto); + } + + + + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Edit(int id, MechanicHandoverForUpdateDto mechanicHandover) + { + if (id != mechanicHandover.Id) + { + return NotFound(); + } + + if (ModelState.IsValid) + { + try + { + await _mechanicHandoverDataStore.UpdateMechanicHandoverAsync(id, mechanicHandover); + } + catch (Exception) + { + if (!await MechanicHandoverExists(id)) + { + return NotFound(); + } + else + { + throw; + } + } + return RedirectToAction(nameof(Index)); + } + + ViewBag.Drivers = new SelectList(await GETDrivers(), "Value", "Text"); + ViewBag.Cars = new SelectList(await GETCars(), "Value", "Text"); + + return View(mechanicHandover); + } + + public async Task Delete(int id) + { + var mechanicHandover = await _mechanicHandoverDataStore.GetMechanicHandoverAsync(id); + if (mechanicHandover == null) + { + return NotFound(); + } + return View(mechanicHandover); + } + + [HttpPost, ActionName("Delete")] + [ValidateAntiForgeryToken] + public async Task DeleteConfirmed(int id) + { + await _mechanicHandoverDataStore.DeleteMechanicHandoverAsync(id); + return RedirectToAction(nameof(Index)); + } + + private async Task MechanicHandoverExists(int id) + { + var mechanicAcceptance = await _mechanicHandoverDataStore.GetMechanicHandoverAsync(id); + return mechanicAcceptance != null; + } + + private async Task> GETMechanics() + { + var mechanicResponse = await _mechanicDataStore.GetMechanicsAsync(); + var mechanics = mechanicResponse.Data + .Select(d => new SelectListItem + { + Value = d.Id.ToString(), + Text = $"{d.FirstName} {d.LastName}" + }) + .ToList(); + return mechanics; + } + private async Task> GETCars() + { + var carResponse = await _carDataStore.GetCarsAsync(null, null); + var cars = carResponse.Data + .Select(c => new SelectListItem + { + Value = c.Id.ToString(), + Text = $"{c.Model} ({c.Number})" + }) + .ToList(); + return cars; + } + + private async Task> GETDrivers() + { + var driverResponse = await _driverDataStore.GetDriversAsync(null, null); + var drivers = driverResponse.Data + .Select(d => new SelectListItem + { + Value = d.Id.ToString(), + Text = $"{d.FirstName} {d.LastName}" + }) + .ToList(); + return drivers; + } + } +} \ No newline at end of file diff --git a/CheckDrive.Web/CheckDrive.Web/Controllers/MechanicsController.cs b/CheckDrive.Web/CheckDrive.Web/Controllers/MechanicsController.cs new file mode 100644 index 00000000..201d8ab5 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Controllers/MechanicsController.cs @@ -0,0 +1,114 @@ +using CheckDrive.Web.Models; +using CheckDrive.Web.Stores.Mechanics; +using Microsoft.AspNetCore.Mvc; + +namespace CheckDrive.Web.Controllers +{ + public class MechanicsController : Controller + { + private readonly IMechanicDataStore _mechanicDataStore; + + public MechanicsController(IMechanicDataStore mechanicDataStore) + { + _mechanicDataStore = mechanicDataStore; + } + + public async Task Index() + { + var mechanics = await _mechanicDataStore.GetMechanicsAsync(); + return View(mechanics); + } + + public async Task Details(int id) + { + var mechanic = await _mechanicDataStore.GetMechanicAsync(id); + if (mechanic == null) + { + return NotFound(); + } + return View(mechanic); + } + + public IActionResult Create() + { + return View(); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Create([Bind("AccountId")] Mechanic mechanic) + { + if (ModelState.IsValid) + { + await _mechanicDataStore.CreateMechanicAsync(mechanic); + return RedirectToAction(nameof(Index)); + } + return View(mechanic); + } + + public async Task Edit(int id) + { + var mechanic = await _mechanicDataStore.GetMechanicAsync(id); + if (mechanic == null) + { + return NotFound(); + } + return View(mechanic); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Edit(int id, [Bind("Id,AccountId")] Mechanic mechanic) + { + if (id != mechanic.Id) + { + return NotFound(); + } + + if (ModelState.IsValid) + { + try + { + await _mechanicDataStore.UpdateMechanicAsync(id, mechanic); + } + catch (Exception) + { + if (!await MechanicExists(id)) + { + return NotFound(); + } + else + { + throw; + } + } + return RedirectToAction(nameof(Index)); + } + return View(mechanic); + } + + public async Task Delete(int id) + { + var mechanic = await _mechanicDataStore.GetMechanicAsync(id); + if (mechanic == null) + { + return NotFound(); + } + return View(mechanic); + } + + [HttpPost, ActionName("Delete")] + [ValidateAntiForgeryToken] + public async Task DeleteConfirmed(int id) + { + await _mechanicDataStore.DeleteMechanicAsync(id); + return RedirectToAction(nameof(Index)); + } + + private async Task MechanicExists(int id) + { + var mechanic = await _mechanicDataStore.GetMechanicAsync(id); + return mechanic != null; + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Controllers/OperatorReviewsController.cs b/CheckDrive.Web/CheckDrive.Web/Controllers/OperatorReviewsController.cs new file mode 100644 index 00000000..a2b08ff3 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Controllers/OperatorReviewsController.cs @@ -0,0 +1,356 @@ +using CheckDrive.ApiContracts; +using CheckDrive.ApiContracts.Car; +using CheckDrive.ApiContracts.Operator; +using CheckDrive.ApiContracts.OperatorReview; +using CheckDrive.Web.Models; +using CheckDrive.Web.Stores.Cars; +using CheckDrive.Web.Stores.Drivers; +using CheckDrive.Web.Stores.MechanicHandovers; +using CheckDrive.Web.Stores.OperatorReviews; +using CheckDrive.Web.Stores.Operators; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Rendering; + +namespace CheckDrive.Web.Controllers +{ + public class OperatorReviewsController( + IOperatorReviewDataStore operatorReviewDataStore, + IMechanicHandoverDataStore mechanicHandover, + ICarDataStore carDataStore, + IDriverDataStore driverDataStore, + IOperatorDataStore operatorDataStore) : Controller + { + private readonly IOperatorReviewDataStore _operatorReviewDataStore = operatorReviewDataStore; + private readonly IMechanicHandoverDataStore _mechanicHandover = mechanicHandover; + private readonly ICarDataStore _carDataStore = carDataStore; + private readonly IDriverDataStore _driverDataStore = driverDataStore; + private readonly IOperatorDataStore _operatorDataStore = operatorDataStore; + + public async Task Index(int? pageNumber, string? searchString, DateTime? date) + { + + var operatorReviews = await _operatorReviewDataStore.GetOperatorReviews(pageNumber, searchString, date, 1); + + ViewBag.PageSize = operatorReviews.PageSize; + ViewBag.PageCount = operatorReviews.TotalPages; + ViewBag.TotalCount = operatorReviews.TotalCount; + ViewBag.CurrentPage = operatorReviews.PageNumber; + ViewBag.HasPreviousPage = operatorReviews.HasPreviousPage; + ViewBag.HasNextPage = operatorReviews.HasNextPage; + + var operatorReviewss = operatorReviews.Data.Select(r => new + { + r.Id, + r.OperatorName, + r.DriverName, + r.OilAmount, + r.Date, + r.Comments, + Status = ((StatusForDto)r.Status) switch + { + StatusForDto.Pending => "Pending", + StatusForDto.Completed => "Completed", + StatusForDto.Rejected => "Rejected", + StatusForDto.Unassigned => "Unassigned", + _ => "Unknown Status" + } + }).ToList(); + + ViewBag.OperatorsReview = operatorReviewss; + return View(); + + } + + public async Task PersonalIndex(int? pageNumber, string? searchString) + { + var reviewsResponse = await _operatorReviewDataStore.GetOperatorReviews(pageNumber, searchString, null, 4); + + ViewBag.PageSize = reviewsResponse.PageSize; + ViewBag.PageCount = reviewsResponse.TotalPages; + ViewBag.TotalCount = reviewsResponse.TotalCount; + ViewBag.CurrentPage = reviewsResponse.PageNumber; + ViewBag.HasPreviousPage = reviewsResponse.HasPreviousPage; + ViewBag.HasNextPage = reviewsResponse.HasNextPage; + + return View(reviewsResponse.Data); + } + + public async Task Details(int id) + { + var operatorReview = await _operatorReviewDataStore.GetOperatorReview(id); + if (operatorReview == null) + { + return NotFound(); + } + return View(operatorReview); + } + + public async Task Create(int? driverId, string? driverName, int? carId, string? carModel, double? fuelTankCapacity, double? remainingFuel) + { + var drivers = await GETDrivers(); + var cars = await GETCars(); + + var operatorr = new OperatorDto(); + + var accountIdStr = TempData["AccountId"] as string; + TempData.Keep("AccountId"); + if (int.TryParse(accountIdStr, out int accountId)) + { + var operatorResponse = await _operatorDataStore.GetOperators(accountId); + operatorr = operatorResponse.Data.FirstOrDefault(); + } + var operators = new List + { + new SelectListItem { Value = operatorr.Id.ToString(), Text = $"{operatorr.FirstName} {operatorr.LastName}" } + }; + + var response = await _operatorReviewDataStore.GetOperatorReviews(null, null, null, 1); + var oilMarks = GetOilMarks(); + var mechanicHandovers = await _mechanicHandover.GetMechanicHandoversAsync(); + + var healthyDrivers = mechanicHandovers.Data + .Where(dr => dr.IsHanded == true && dr.Date.Date == DateTime.Today) + .Select(dr => dr.DriverId) + .ToList(); + + var givedDrivers = response.Data + .Where(ma => ma.Date.HasValue && ma.Date.Value.Date == DateTime.Today) + .Select(ma => ma.DriverId) + .ToList(); + + var filteredDrivers = drivers + .Where(d => healthyDrivers.Contains(int.Parse(d.Value)) && !givedDrivers.Contains(int.Parse(d.Value))) + .ToList(); + + ViewBag.OilMarks = new SelectList(oilMarks); + ViewBag.Drivers = new SelectList(filteredDrivers, "Value", "Text"); + ViewBag.Operators = operators; + + if (!driverId.HasValue && !carId.HasValue && filteredDrivers.Any()) + { + var firstDriverId = int.Parse(filteredDrivers.First().Value); + var mechanicHandover = mechanicHandovers.Data.FirstOrDefault(m => m.DriverId == firstDriverId && m.Date.Date == DateTime.Today); + + if (mechanicHandover != null) + { + carId = mechanicHandover.CarId; + var car = await _carDataStore.GetCarAsync(mechanicHandover.CarId); + carModel = car?.Model; + fuelTankCapacity = car?.FuelTankCapacity; + remainingFuel = car?.RemainingFuel; + } + + driverId = firstDriverId; + } + + ViewBag.Cars = new SelectList(cars, "Value", "Text", carId); + + var model = new OperatorReviewForCreateDto(); + + if (driverId.HasValue) + { + model.DriverId = driverId.Value; + ViewBag.SelectedDriverName = driverName; + ViewBag.DriverId = driverId.Value; + + if (carId.HasValue) + { + model.CarId = carId.Value; + ViewBag.SelectedCar = $"{carModel} Sig`imi: {fuelTankCapacity?.ToString() ?? "N/A"} litr, Qoldig`i: {remainingFuel?.ToString() ?? "N/A"} litr"; + } + } + + if (fuelTankCapacity.HasValue && remainingFuel.HasValue) + { + ViewBag.FuelTankCapacity = fuelTankCapacity.Value; + ViewBag.RemainingFuel = remainingFuel.Value; + } + + return View(model); + } + + public async Task GetCarByDriverId(int driverId) + { + var mechanicHandovers = await _mechanicHandover.GetMechanicHandoversAsync(); + var handover = mechanicHandovers.Data.FirstOrDefault(m => m.DriverId == driverId && m.Date.Date == DateTime.Today); + + if (handover != null) + { + var car = await _carDataStore.GetCarAsync(handover.CarId); + return Json(new { success = true, car }); + } + return Json(new { success = false }); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Create([Bind("OilAmount,Comments,Status,Date,OperatorId,DriverId,CarId,OilMarks,IsGiven")] OperatorReviewForCreateDto operatorReview) + { + var car = _carDataStore.GetCarAsync(operatorReview.CarId); + var carr = new CarForUpdateDto + { + Id = operatorReview.CarId, + Color = car.Result.Color, + FuelTankCapacity = car.Result.FuelTankCapacity, + ManufacturedYear = car.Result.ManufacturedYear, + MeduimFuelConsumption = car.Result.MeduimFuelConsumption, + Model = car.Result.Model, + Number = car.Result.Number, + RemainingFuel = car.Result.RemainingFuel + operatorReview.OilAmount, + }; + + if (ModelState.IsValid) + { + operatorReview.Date = DateTime.Now; + + await _carDataStore.UpdateCarAsync(operatorReview.CarId, carr); + + double maxOilAmount = await GetMaxOilAmount(operatorReview.CarId); + + if ((operatorReview.OilAmount < 0 && operatorReview.IsGiven == true) || + (operatorReview.OilAmount > 0 && operatorReview.IsGiven == false)) + { + ModelState.AddModelError("IsGiven", "Yoqilg`ini berib bermadim tugmasini bostingiz"); + } + else if (operatorReview.OilAmount < 0 || operatorReview.OilAmount > maxOilAmount) + { + ModelState.AddModelError("OilAmount", $"Oil amount must be between 0 and {maxOilAmount}."); + } + else + { + await _operatorReviewDataStore.CreateOperatorReview(operatorReview); + return RedirectToAction(nameof(PersonalIndex)); + } + } + + var drivers = await GETDrivers(); + var cars = await GETCars(); + var response = await _operatorReviewDataStore.GetOperatorReviews(null, null, null, 1); + var oilMarks = response.Data.Select(r => r.OilMarks).Distinct().ToList(); + + ViewBag.OilMarks = new SelectList(oilMarks); + ViewBag.Drivers = new SelectList(drivers, "Value", "Text"); + ViewBag.Cars = new SelectList(cars, "Value", "Text"); + + return View(operatorReview); + } + + public async Task Edit(int id) + { + var operatorReview = await _operatorReviewDataStore.GetOperatorReview(id); + if (operatorReview == null) + { + return NotFound(); + } + return View(operatorReview); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Edit(int id, [Bind("Id,OilAmount,Comments,Status,Date,OperatorId,DriverId")] OperatorReview operatorReview) + { + if (id != operatorReview.Id) + { + return NotFound(); + } + + if (ModelState.IsValid) + { + try + { + await _operatorReviewDataStore.UpdateOperatorReview(id, operatorReview); + } + catch (Exception) + { + if (!await OperatorReviewExists(id)) + { + return NotFound(); + } + else + { + throw; + } + } + return RedirectToAction(nameof(Index)); + } + return View(operatorReview); + } + + public async Task Delete(int id) + { + var operatorReview = await _operatorReviewDataStore.GetOperatorReview(id); + if (operatorReview == null) + { + return NotFound(); + } + return View(operatorReview); + } + + [HttpPost, ActionName("Delete")] + [ValidateAntiForgeryToken] + public async Task DeleteConfirmed(int id) + { + await _operatorReviewDataStore.DeleteOperatorReview(id); + return RedirectToAction(nameof(Index)); + } + + private async Task OperatorReviewExists(int id) + { + var operatorReview = await _operatorReviewDataStore.GetOperatorReview(id); + return operatorReview != null; + } + + private async Task> GETDrivers() + { + var driverResponse = await _driverDataStore.GetDriversAsync(null, null); + var drivers = driverResponse.Data + .Select(d => new SelectListItem + { + Value = d.Id.ToString(), + Text = $"{d.FirstName} {d.LastName}" + }) + .ToList(); + return drivers; + } + + private async Task> GETOperators() + { + var operatorResponse = await _operatorDataStore.GetOperators(); + var operators = operatorResponse.Data + .Select(d => new SelectListItem + { + Value = d.Id.ToString(), + Text = $"{d.FirstName} {d.LastName}" + }) + .ToList(); + return operators; + } + + private async Task> GETCars() + { + var carResponse = await _carDataStore.GetCarsAsync(null, null); + var cars = carResponse.Data + .Select(d => new SelectListItem + { + Value = d.Id.ToString(), + Text = $"{d.Model} Sig`imi: {d.FuelTankCapacity} litr, Qoldig`i: {d.RemainingFuel} litr" + }) + .ToList(); + return cars; + } + + private async Task GetMaxOilAmount(int carId) + { + var car = await _carDataStore.GetCarAsync(carId); + return car.FuelTankCapacity - car.RemainingFuel; + } + + private List GetOilMarks() + { + return Enum.GetValues(typeof(OilMarksForDto)) + .Cast() + .Select(o => o.ToString()) + .ToList(); + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Controllers/OperatorsController.cs b/CheckDrive.Web/CheckDrive.Web/Controllers/OperatorsController.cs new file mode 100644 index 00000000..19bcfafb --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Controllers/OperatorsController.cs @@ -0,0 +1,119 @@ +using CheckDrive.Web.Models; +using CheckDrive.Web.Stores.Accounts; +using CheckDrive.Web.Stores.Operators; +using CheckDrive.Web.Stores.Roles; +using Microsoft.AspNetCore.Mvc; + +namespace CheckDrive.Web.Controllers +{ + public class OperatorsController : Controller + { + private readonly IOperatorDataStore _operatorDataStore; + private readonly IAccountDataStore _accountDataStore; + private readonly IRoleDataStore _roleDataStore; + + public OperatorsController(IOperatorDataStore operatorDataStore, IAccountDataStore accountDataStore, IRoleDataStore roleDataStore) + { + _operatorDataStore = operatorDataStore; + _accountDataStore = accountDataStore; + _roleDataStore = roleDataStore; + } + + public async Task Index() + { + return View(); + } + + public async Task Details(int id) + { + var @operator = await _operatorDataStore.GetOperator(id); + if (@operator == null) + { + return NotFound(); + } + return View(@operator); + } + + public IActionResult Create() + { + return View(); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Create([Bind("AccountId")] Operator @operator) + { + if (ModelState.IsValid) + { + await _operatorDataStore.CreateOperator(@operator); + return RedirectToAction(nameof(Index)); + } + return View(@operator); + } + + public async Task Edit(int id) + { + var @operator = await _operatorDataStore.GetOperator(id); + if (@operator == null) + { + return NotFound(); + } + return View(@operator); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Edit(int id, [Bind("Id,AccountId")] Operator @operator) + { + if (id != @operator.Id) + { + return NotFound(); + } + + if (ModelState.IsValid) + { + try + { + await _operatorDataStore.UpdateOperator(id, @operator); + } + catch (Exception) + { + if (!await OperatorExists(id)) + { + return NotFound(); + } + else + { + throw; + } + } + return RedirectToAction(nameof(Index)); + } + return View(@operator); + } + + public async Task Delete(int id) + { + var @operator = await _operatorDataStore.GetOperator(id); + if (@operator == null) + { + return NotFound(); + } + return View(@operator); + } + + [HttpPost, ActionName("Delete")] + [ValidateAntiForgeryToken] + public async Task DeleteConfirmed(int id) + { + await _operatorDataStore.DeleteOperator(id); + return RedirectToAction(nameof(Index)); + } + + private async Task OperatorExists(int id) + { + var @operator = await _operatorDataStore.GetOperator(id); + return @operator != null; + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Controllers/PersonalOperatorReviewsController.cs b/CheckDrive.Web/CheckDrive.Web/Controllers/PersonalOperatorReviewsController.cs new file mode 100644 index 00000000..13fe8fc2 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Controllers/PersonalOperatorReviewsController.cs @@ -0,0 +1,387 @@ +using CheckDrive.ApiContracts; +using CheckDrive.ApiContracts.Car; +using CheckDrive.ApiContracts.Operator; +using CheckDrive.ApiContracts.OperatorReview; +using CheckDrive.Web.Models; +using CheckDrive.Web.Stores.Cars; +using CheckDrive.Web.Stores.Drivers; +using CheckDrive.Web.Stores.MechanicHandovers; +using CheckDrive.Web.Stores.OperatorReviews; +using CheckDrive.Web.Stores.Operators; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Rendering; + +namespace CheckDrive.Web.Controllers +{ + public class PersonalOperatorReviewsController( + IOperatorReviewDataStore operatorReviewDataStore, + IMechanicHandoverDataStore mechanicHandover, + ICarDataStore carDataStore, + IDriverDataStore driverDataStore, + IOperatorDataStore operatorDataStore) : Controller + { + private readonly IOperatorReviewDataStore _operatorReviewDataStore = operatorReviewDataStore; + private readonly IMechanicHandoverDataStore _mechanicHandover = mechanicHandover; + private readonly ICarDataStore _carDataStore = carDataStore; + private readonly IDriverDataStore _driverDataStore = driverDataStore; + private readonly IOperatorDataStore _operatorDataStore = operatorDataStore; + + public async Task Index(int? pageNumber, string? searchString) + { + var reviewsResponse = await _operatorReviewDataStore.GetOperatorReviews(null, null, null); + var mechanicHandoverResponse = await _mechanicHandover.GetMechanicHandoversAsync(pageNumber, null, null); + var cars = await _carDataStore.GetCarsAsync(null, null); + + var mechanicHandovers = mechanicHandoverResponse.Data + .Where(m => m.Date.Date == DateTime.Today) + .Where(m => m.IsHanded == true) + .ToList(); + + var operators = new List(); + + foreach (var mechanicHandover in mechanicHandovers) + { + var car = cars.Data.FirstOrDefault(c => c.Id == mechanicHandover.CarId); + var review = reviewsResponse.Data.FirstOrDefault(r => r.DriverId == mechanicHandover.DriverId); + if (review != null) + { + if (review.Date.Value.Date == DateTime.Today) + { + operators.Add(new OperatorReviewDto + { + DriverId = review.DriverId, + DriverName = mechanicHandover.DriverName, + OperatorName = review.OperatorName, + CarId = car?.Id ?? review.CarId, + CarModel = car?.Model ?? review.CarModel, + CarNumber = car?.Number ?? review.CarNumber, + CarOilCapacity = car?.FuelTankCapacity.ToString() ?? review.CarOilCapacity, + CarOilRemainig = car?.RemainingFuel.ToString() ?? review.CarOilRemainig, + OilAmount = review.OilAmount, + OilMarks = review.OilMarks, + IsGiven = review.IsGiven, + Comments = review.Comments, + Date = review.Date, + Status = review.Status + }); + } + else + { + operators.Add(new OperatorReviewDto + { + DriverId = mechanicHandover.DriverId, + DriverName = mechanicHandover.DriverName, + OperatorName = null, + CarId = car?.Id ?? 0, + CarModel = car?.Model ?? string.Empty, + CarNumber = car?.Number ?? string.Empty, + CarOilCapacity = car?.FuelTankCapacity.ToString() ?? string.Empty, + CarOilRemainig = car?.RemainingFuel.ToString() ?? string.Empty, + OilAmount = null, + OilMarks = null, + IsGiven = null, + Comments = null, + Date = null, + Status = StatusForDto.Unassigned + }); + } + } + else + { + operators.Add(new OperatorReviewDto + { + DriverId = mechanicHandover.DriverId, + DriverName = mechanicHandover.DriverName, + OperatorName = null, + CarId = car?.Id ?? 0, + CarModel = car?.Model ?? string.Empty, + CarNumber = car?.Number ?? string.Empty, + CarOilCapacity = car?.FuelTankCapacity.ToString() ?? string.Empty, + CarOilRemainig = car?.RemainingFuel.ToString() ?? string.Empty, + OilAmount = null, + OilMarks = null, + IsGiven = null, + Comments = null, + Date = null, + Status = StatusForDto.Unassigned + }); + } + } + + return View(operators); + } + public async Task Details(int id) + { + var operatorReview = await _operatorReviewDataStore.GetOperatorReview(id); + if (operatorReview == null) + { + return NotFound(); + } + return View(operatorReview); + } + + public async Task Create(int? driverId, string? driverName, int? carId, string? carModel, double? fuelTankCapacity, double? remainingFuel) + { + var drivers = await GETDrivers(); + var cars = await GETCars(); + + var operatorr = new OperatorDto(); + + var accountIdStr = TempData["AccountId"] as string; + TempData.Keep("AccountId"); + if (int.TryParse(accountIdStr, out int accountId)) + { + var operatorResponse = await _operatorDataStore.GetOperators(accountId); + operatorr = operatorResponse.Data.FirstOrDefault(); + } + var operators = new List + { + new SelectListItem { Value = operatorr.Id.ToString(), Text = $"{operatorr.FirstName} {operatorr.LastName}" } + }; + + var response = await _operatorReviewDataStore.GetOperatorReviews(null, null, null); + var oilMarks = response.Data.Select(r => r.OilMarks).Distinct().ToList(); + var mechanicHandovers = await _mechanicHandover.GetMechanicHandoversAsync(); + + var healthyDrivers = mechanicHandovers.Data + .Where(dr => dr.IsHanded == true && dr.Date.Date == DateTime.Today) + .Select(dr => dr.DriverId) + .ToList(); + + var givedDrivers = response.Data + .Where(ma => ma.Date.HasValue && ma.Date.Value.Date == DateTime.Today) + .Select(ma => ma.DriverId) + .ToList(); + + var filteredDrivers = drivers + .Where(d => healthyDrivers.Contains(int.Parse(d.Value)) && !givedDrivers.Contains(int.Parse(d.Value))) + .ToList(); + + ViewBag.OilMarks = new SelectList(oilMarks); + ViewBag.Drivers = new SelectList(filteredDrivers, "Value", "Text"); + ViewBag.Operators = operators; + + if (!driverId.HasValue && !carId.HasValue && filteredDrivers.Any()) + { + var firstDriverId = int.Parse(filteredDrivers.First().Value); + var mechanicHandover = mechanicHandovers.Data.FirstOrDefault(m => m.DriverId == firstDriverId && m.Date.Date == DateTime.Today); + + if (mechanicHandover != null) + { + carId = mechanicHandover.CarId; + var car = await _carDataStore.GetCarAsync(mechanicHandover.CarId); + carModel = car?.Model; + fuelTankCapacity = car?.FuelTankCapacity; + remainingFuel = car?.RemainingFuel; + } + + driverId = firstDriverId; + } + + ViewBag.Cars = new SelectList(cars, "Value", "Text", carId); + + var model = new OperatorReviewForCreateDto(); + + if (driverId.HasValue) + { + model.DriverId = driverId.Value; + ViewBag.SelectedDriverName = driverName; + ViewBag.DriverId = driverId.Value; + + if (carId.HasValue) + { + model.CarId = carId.Value; + ViewBag.SelectedCar = $"{carModel} Sig`imi: {fuelTankCapacity?.ToString() ?? "N/A"} litr, Qoldig`i: {remainingFuel?.ToString() ?? "N/A"} litr"; + } + } + + if (fuelTankCapacity.HasValue && remainingFuel.HasValue) + { + ViewBag.FuelTankCapacity = fuelTankCapacity.Value; + ViewBag.RemainingFuel = remainingFuel.Value; + } + + return View(model); + } + + + + public async Task GetCarByDriverId(int driverId) + { + var mechanicHandovers = await _mechanicHandover.GetMechanicHandoversAsync(); + var handover = mechanicHandovers.Data.FirstOrDefault(m => m.DriverId == driverId && m.Date.Date == DateTime.Today); + + if (handover != null) + { + var car = await _carDataStore.GetCarAsync(handover.CarId); + return Json(new { success = true, car }); + } + return Json(new { success = false }); + } + + + + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Create([Bind("OilAmount,Comments,Status,Date,OperatorId,DriverId,CarId,OilMarks,IsGiven")] OperatorReviewForCreateDto operatorReview) + { + var car = _carDataStore.GetCarAsync(operatorReview.CarId); + var carr = new CarForUpdateDto + { + Id = operatorReview.CarId, + Color = car.Result.Color, + FuelTankCapacity = car.Result.FuelTankCapacity, + ManufacturedYear = car.Result.ManufacturedYear, + MeduimFuelConsumption = car.Result.MeduimFuelConsumption, + Model = car.Result.Model, + Number = car.Result.Number, + RemainingFuel = car.Result.RemainingFuel + operatorReview.OilAmount, + }; + + if (ModelState.IsValid) + { + operatorReview.Date = DateTime.Now; + + await _carDataStore.UpdateCarAsync(operatorReview.CarId, carr); + + double maxOilAmount = await GetMaxOilAmount(operatorReview.CarId); + + if ((operatorReview.OilAmount == 0 && operatorReview.IsGiven == true) || + (operatorReview.OilAmount > 0 && operatorReview.IsGiven == false)) + { + ModelState.AddModelError("IsGiven", "Siz yoqilg`ini 0 litr berib, berdim tugmasini bostingiz yoki\nYoqilg`ini berib bermadim tugmasini bostingiz"); + } + else if (operatorReview.OilAmount < 0 || operatorReview.OilAmount > maxOilAmount) + { + ModelState.AddModelError("OilAmount", $"Oil amount must be between 0 and {maxOilAmount}."); + } + else + { + await _operatorReviewDataStore.CreateOperatorReview(operatorReview); + return RedirectToAction(nameof(Index)); + } + } + + var drivers = await GETDrivers(); + var cars = await GETCars(); + var response = await _operatorReviewDataStore.GetOperatorReviews(null, null, null); + var oilMarks = response.Data.Select(r => r.OilMarks).Distinct().ToList(); + + ViewBag.OilMarks = new SelectList(oilMarks); + ViewBag.Drivers = new SelectList(drivers, "Value", "Text"); + ViewBag.Cars = new SelectList(cars, "Value", "Text"); + + return View(operatorReview); + } + public async Task Edit(int id) + { + var operatorReview = await _operatorReviewDataStore.GetOperatorReview(id); + if (operatorReview == null) + { + return NotFound(); + } + return View(operatorReview); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Edit(int id, [Bind("Id,OilAmount,Comments,Status,Date,OperatorId,DriverId")] OperatorReview operatorReview) + { + if (id != operatorReview.Id) + { + return NotFound(); + } + + if (ModelState.IsValid) + { + try + { + await _operatorReviewDataStore.UpdateOperatorReview(id, operatorReview); + } + catch (Exception) + { + if (!await OperatorReviewExists(id)) + { + return NotFound(); + } + else + { + throw; + } + } + return RedirectToAction(nameof(Index)); + } + return View(operatorReview); + } + + public async Task Delete(int id) + { + var operatorReview = await _operatorReviewDataStore.GetOperatorReview(id); + if (operatorReview == null) + { + return NotFound(); + } + return View(operatorReview); + } + + [HttpPost, ActionName("Delete")] + [ValidateAntiForgeryToken] + public async Task DeleteConfirmed(int id) + { + await _operatorReviewDataStore.DeleteOperatorReview(id); + return RedirectToAction(nameof(Index)); + } + + private async Task OperatorReviewExists(int id) + { + var operatorReview = await _operatorReviewDataStore.GetOperatorReview(id); + return operatorReview != null; + } + + private async Task> GETDrivers() + { + var driverResponse = await _driverDataStore.GetDriversAsync(null, null); + var drivers = driverResponse.Data + .Select(d => new SelectListItem + { + Value = d.Id.ToString(), + Text = $"{d.FirstName} {d.LastName}" + }) + .ToList(); + return drivers; + } + + private async Task> GETOperators() + { + var operatorResponse = await _operatorDataStore.GetOperators(); + var operators = operatorResponse.Data + .Select(d => new SelectListItem + { + Value = d.Id.ToString(), + Text = $"{d.FirstName} {d.LastName}" + }) + .ToList(); + return operators; + } + + private async Task> GETCars() + { + var carResponse = await _carDataStore.GetCarsAsync(null, null); + var cars = carResponse.Data + .Select(d => new SelectListItem + { + Value = d.Id.ToString(), + Text = $"{d.Model} Sig`imi: {d.FuelTankCapacity} litr, Qoldig`i: {d.RemainingFuel} litr" + }) + .ToList(); + return cars; + } + + private async Task GetMaxOilAmount(int carId) + { + var car = await _carDataStore.GetCarAsync(carId); + return car.FuelTankCapacity - car.RemainingFuel; + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Controllers/RolesController.cs b/CheckDrive.Web/CheckDrive.Web/Controllers/RolesController.cs new file mode 100644 index 00000000..cddd2309 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Controllers/RolesController.cs @@ -0,0 +1,112 @@ +using CheckDrive.ApiContracts.Role; +using CheckDrive.DTOs.Role; +using CheckDrive.Web.Models; +using CheckDrive.Web.Stores.Roles; +using Microsoft.AspNetCore.Mvc; + +namespace CheckDrive.Web.Controllers +{ + public class RolesController : Controller + { + private readonly IRoleDataStore _roleDataStore; + + public RolesController(IRoleDataStore roleDataStore) + { + _roleDataStore = roleDataStore; + } + + public async Task Index() + { + var roles = await _roleDataStore.GetRoles(); + return View(roles); + } + + public async Task Details(int id) + { + var role = await _roleDataStore.GetRole(id); + if (role == null) + { + return NotFound(); + } + return View(role); + } + + public IActionResult Create() + { + return View(); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Create([Bind("Name")] ApiContracts.Role.RoleForCreateDto role) + { + if (ModelState.IsValid) + { + await _roleDataStore.CreateRole(role); + return RedirectToAction(nameof(Index)); + } + return View(role); + } + + public async Task Edit(int id) + { + var role = await _roleDataStore.GetRole(id); + if (role == null) + { + return NotFound(); + } + return View(role); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Edit(int id, [Bind("Id,Name")] ApiContracts.Role.RoleForCreateDto role) + { + + if (ModelState.IsValid) + { + try + { + await _roleDataStore.UpdateRole(id, role); + } + catch (Exception) + { + if (!await RoleExists(id)) + { + return NotFound(); + } + else + { + throw; + } + } + return RedirectToAction(nameof(Index)); + } + return View(role); + } + + public async Task Delete(int id) + { + var role = await _roleDataStore.GetRole(id); + if (role == null) + { + return NotFound(); + } + return View(role); + } + + [HttpPost, ActionName("Delete")] + [ValidateAntiForgeryToken] + public async Task DeleteConfirmed(int id) + { + await _roleDataStore.DeleteRole(id); + return RedirectToAction(nameof(Index)); + } + + private async Task RoleExists(int id) + { + var role = await _roleDataStore.GetRole(id); + return role != null; + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Controllers/TechniciansController.cs b/CheckDrive.Web/CheckDrive.Web/Controllers/TechniciansController.cs new file mode 100644 index 00000000..e2d5c0ce --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Controllers/TechniciansController.cs @@ -0,0 +1,92 @@ +using CheckDrive.Web.Models; +using CheckDrive.Web.Stores.Technicians; +using Microsoft.AspNetCore.Mvc; + +namespace CheckDrive.Web.Controllers +{ + public class TechniciansController : Controller + { + private readonly ITechnicianDataStore _technicianDataStore; + + public TechniciansController(ITechnicianDataStore technicianDataStore) + { + _technicianDataStore = technicianDataStore; + } + public async Task Index() + { + var technicians = await _technicianDataStore.GetTechnicians(); + return View(technicians); + } + + public async Task Details(int id) + { + var technician = await _technicianDataStore.GetTechnician(id); + if (technician == null) + { + return NotFound(); + } + return View(technician); + } + + public IActionResult Create() + { + return View(); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Create([Bind("AccountId")] Technician technician) + { + if (ModelState.IsValid) + { + await _technicianDataStore.CreateTechnician(technician); + return RedirectToAction(nameof(Index)); + } + return View(technician); + } + + public async Task Edit(int id) + { + var technician = await _technicianDataStore.GetTechnician(id); + if (technician == null) + { + return NotFound(); + } + return View(technician); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Edit(int id, [Bind("Id, AccountId")] Technician technician) + { + if (id != technician.Id) + { + return NotFound(); + } + + if (ModelState.IsValid) + { + await _technicianDataStore.UpdateTechnician(id, technician); + return RedirectToAction(nameof(Index)); + } + return View(technician); + } + public async Task Delete(int id) + { + var technician = await _technicianDataStore.GetTechnician(id); + if (technician == null) + { + return NotFound(); + } + return View(technician); + } + + [HttpPost, ActionName("Delete")] + [ValidateAntiForgeryToken] + public async Task DeleteConfirmed(int id) + { + await _technicianDataStore.DeleteTechnician(id); + return RedirectToAction(nameof(Index)); + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Exceptions/ApiException.cs b/CheckDrive.Web/CheckDrive.Web/Exceptions/ApiException.cs new file mode 100644 index 00000000..71ce0770 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Exceptions/ApiException.cs @@ -0,0 +1,20 @@ +using System.Net; + +namespace CheckDrive.Web.Exceptions +{ + public class ApiException : Exception + { + public HttpStatusCode StatusCode { get; private set; } + + public ApiException(HttpStatusCode statusCode) : base() + { + StatusCode = statusCode; + } + + public ApiException(HttpStatusCode statusCode, string message) : + base(message) + { + StatusCode = statusCode; + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Extensions/ConfigureServiceExtensions.cs b/CheckDrive.Web/CheckDrive.Web/Extensions/ConfigureServiceExtensions.cs new file mode 100644 index 00000000..b979edef --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Extensions/ConfigureServiceExtensions.cs @@ -0,0 +1,52 @@ +using CheckDrive.Web.Service; +using CheckDrive.Web.Stores.Accounts; +using CheckDrive.Web.Stores.Cars; +using CheckDrive.Web.Stores.Dashbord; +using CheckDrive.Web.Stores.DispatcherReviews; +using CheckDrive.Web.Stores.Dispatchers; +using CheckDrive.Web.Stores.DoctorReviews; +using CheckDrive.Web.Stores.Doctors; +using CheckDrive.Web.Stores.Drivers; +using CheckDrive.Web.Stores.MechanicAcceptances; +using CheckDrive.Web.Stores.MechanicHandovers; +using CheckDrive.Web.Stores.Mechanics; +using CheckDrive.Web.Stores.OperatorReviews; +using CheckDrive.Web.Stores.Operators; +using CheckDrive.Web.Stores.Roles; +using CheckDrive.Web.Stores.Technicians; +using CheckDrive.Web.Stores.User; + +namespace CheckDrive.Web.Extensions +{ + public static class ConfigureServiceExtensions + { + public static IServiceCollection ConfigureDataStores(this IServiceCollection services) + { + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + + return services; + } + + public static IServiceCollection ConfigureServices(this IServiceCollection services) + { + services.AddSingleton(); + + return services; + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Filters/ApiExceptionFilter.cs b/CheckDrive.Web/CheckDrive.Web/Filters/ApiExceptionFilter.cs new file mode 100644 index 00000000..c7eac8a8 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Filters/ApiExceptionFilter.cs @@ -0,0 +1,28 @@ +using CheckDrive.Web.Exceptions; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; + +namespace CheckDrive.Web.Filters +{ + public class ApiExceptionFilter : IExceptionFilter + { + public void OnException(ExceptionContext context) + { + if (context.Exception is ApiException exception) + { + int statusCode = (int)exception.StatusCode; + if (statusCode == 401) + { + context.Result = new RedirectToActionResult("Index", "Auth", new { statusCode }); + } + + context.ExceptionHandled = true; + } + else + { + context.Result = new RedirectToActionResult("Error", "Home", new { statusCode = 500 }); + context.ExceptionHandled = true; + } + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Helpers/PaginatedList.cs b/CheckDrive.Web/CheckDrive.Web/Helpers/PaginatedList.cs new file mode 100644 index 00000000..789b5f63 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Helpers/PaginatedList.cs @@ -0,0 +1,36 @@ +using Microsoft.EntityFrameworkCore; + +namespace CheckDrive.Web.Helpers +{ + public class PaginatedList : List + { + public int PageIndex { get; private set; } + public int TotalPages { get; private set; } + + public PaginatedList(List items, int count, int pageIndex, int pageSize) + { + PageIndex = pageIndex; + TotalPages = (int)Math.Ceiling(count / (double)pageSize); + + AddRange(items); + } + + public bool HasPreviousPage => PageIndex > 1; + + public bool HasNextPage => PageIndex < TotalPages; + + public static async Task> CreateAsync(IQueryable source, int pageIndex, int pageSize) + { + var count = await source.CountAsync(); + var items = await source.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync(); + return new PaginatedList(items, count, pageIndex, pageSize); + } + + public static PaginatedList Create(IQueryable source, int pageIndex, int pageSize) + { + var count = source.Count(); + var items = source.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList(); + return new PaginatedList(items, count, pageIndex, pageSize); + } + } +} \ No newline at end of file diff --git a/CheckDrive.Web/CheckDrive.Web/Models/Account.cs b/CheckDrive.Web/CheckDrive.Web/Models/Account.cs new file mode 100644 index 00000000..acc3f759 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Models/Account.cs @@ -0,0 +1,24 @@ +namespace CheckDrive.Web.Models +{ + public class Account + { + public int Id { get; set; } + public string Login { get; set; } + public string Password { get; set; } + public string PhoneNumber { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public DateTime Bithdate { get; set; } + + public string RoleName { get; set; } + public Role Role { get; set; } + + public virtual ICollection Dispatchers { get; set; } + public virtual ICollection Operators { get; set; } + public virtual ICollection Mechanics { get; set; } + public virtual ICollection Drivers { get; set; } + public virtual ICollection Doctors { get; set; } + public virtual ICollection Technicians { get; set; } + } +} + diff --git a/CheckDrive.Web/CheckDrive.Web/Models/Car.cs b/CheckDrive.Web/CheckDrive.Web/Models/Car.cs new file mode 100644 index 00000000..3e3bc979 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Models/Car.cs @@ -0,0 +1,16 @@ +namespace CheckDrive.Web.Models +{ + public class Car + { + public int Id { get; set; } + public string Model { get; set; } + public string Color { get; set; } + public string Number { get; set; } + public double MeduimFuelConsumption { get; set; } + public double RemainingFuel { get; set; } + public double FuelTankCapacity { get; set; } + public int ManufacturedYear { get; set; } + + public virtual ICollection MechanicHandovers { get; set; } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Models/Dispatcher.cs b/CheckDrive.Web/CheckDrive.Web/Models/Dispatcher.cs new file mode 100644 index 00000000..185908e4 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Models/Dispatcher.cs @@ -0,0 +1,11 @@ +namespace CheckDrive.Web.Models +{ + public class Dispatcher + { + public int Id { get; set; } + public int AccountId { get; set; } + public Account Account { get; set; } + + public virtual ICollection DispetcherReviews { get; set; } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Models/DispatcherReview.cs b/CheckDrive.Web/CheckDrive.Web/Models/DispatcherReview.cs new file mode 100644 index 00000000..e0b60dec --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Models/DispatcherReview.cs @@ -0,0 +1,19 @@ +namespace CheckDrive.Web.Models +{ + public class DispatcherReview + { + public int Id { get; set; } + public double FuelSpended { get; set; } + public double DistanceCovered { get; set; } + public DateTime Date { get; set; } + + public int DispatcherId { get; set; } + public Dispatcher Dispatcher { get; set; } + public int OperatorId { get; set; } + public Operator Operator { get; set; } + public int MechanicId { get; set; } + public Mechanic Mechanic { get; set; } + public int DriverId { get; set; } + public Driver Driver { get; set; } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Models/Doctor.cs b/CheckDrive.Web/CheckDrive.Web/Models/Doctor.cs new file mode 100644 index 00000000..d0de4b93 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Models/Doctor.cs @@ -0,0 +1,11 @@ +namespace CheckDrive.Web.Models +{ + public class Doctor + { + public int Id { get; set; } + public int AccountId { get; set; } + public Account Account { get; set; } + + public virtual ICollection DoctorReviews { get; set; } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Models/DoctorReview.cs b/CheckDrive.Web/CheckDrive.Web/Models/DoctorReview.cs new file mode 100644 index 00000000..a80ef7d7 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Models/DoctorReview.cs @@ -0,0 +1,15 @@ +namespace CheckDrive.Web.Models +{ + public class DoctorReview + { + public int Id { get; set; } + public bool IsHealthy { get; set; } + public string? Comments { get; set; } + public DateTime Date { get; set; } + + public int DriverId { get; set; } + public Driver Driver { get; set; } + public int DoctorId { get; set; } + public Doctor Doctor { get; set; } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Models/Driver.cs b/CheckDrive.Web/CheckDrive.Web/Models/Driver.cs new file mode 100644 index 00000000..a119b9bc --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Models/Driver.cs @@ -0,0 +1,14 @@ +namespace CheckDrive.Web.Models +{ + public class Driver + { + public int Id { get; set; } + public int AccountId { get; set; } + public Account Account { get; set; } + + public virtual ICollection DispetcherReviews { get; set; } + public virtual ICollection DoctorReviews { get; set; } + public virtual ICollection MechanicHandovers { get; set; } + public virtual ICollection OperatorReviews { get; set; } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Models/ErrorViewModel.cs b/CheckDrive.Web/CheckDrive.Web/Models/ErrorViewModel.cs deleted file mode 100644 index 454b90b2..00000000 --- a/CheckDrive.Web/CheckDrive.Web/Models/ErrorViewModel.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace CheckDrive.Web.Models; - -public class ErrorViewModel -{ - public string? RequestId { get; set; } - - public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); -} diff --git a/CheckDrive.Web/CheckDrive.Web/Models/Mechanic.cs b/CheckDrive.Web/CheckDrive.Web/Models/Mechanic.cs new file mode 100644 index 00000000..552b0abb --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Models/Mechanic.cs @@ -0,0 +1,12 @@ +namespace CheckDrive.Web.Models +{ + public class Mechanic + { + public int Id { get; set; } + public int AccountId { get; set; } + public Account Account { get; set; } + + public virtual ICollection DispetcherReviews { get; set; } + public virtual ICollection MechanicHandovers { get; set; } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Models/MechanicAcceptance.cs b/CheckDrive.Web/CheckDrive.Web/Models/MechanicAcceptance.cs new file mode 100644 index 00000000..f65de77e --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Models/MechanicAcceptance.cs @@ -0,0 +1,16 @@ +namespace CheckDrive.Web.Models +{ + public class MechanicAcceptance + { + public int Id { get; set; } + + public bool IsAccepted { get; set; } + public string? Comments { get; set; } + public Status Status { get; set; } + public DateTime Date { get; set; } + public double Distance { get; set; } + + public int MechanicHandoverId { get; set; } + public MechanicHandover MechanicHandover { get; set; } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Models/MechanicHandover.cs b/CheckDrive.Web/CheckDrive.Web/Models/MechanicHandover.cs new file mode 100644 index 00000000..0f8e844a --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Models/MechanicHandover.cs @@ -0,0 +1,20 @@ +namespace CheckDrive.Web.Models +{ + public class MechanicHandover + { + public int Id { get; set; } + public bool IsHanded { get; set; } + public string? Comments { get; set; } + public Status Status { get; set; } + public DateTime Date { get; set; } + + public int MechanicId { get; set; } + public Mechanic Mechanic { get; set; } + public int CarId { get; set; } + public Car Car { get; set; } + public int DriverId { get; set; } + public Driver Driver { get; set; } + + public virtual ICollection MechanicAcceptances { get; set; } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Models/Operator.cs b/CheckDrive.Web/CheckDrive.Web/Models/Operator.cs new file mode 100644 index 00000000..e8461803 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Models/Operator.cs @@ -0,0 +1,12 @@ +namespace CheckDrive.Web.Models +{ + public class Operator + { + public int Id { get; set; } + public int AccountId { get; set; } + public Account Account { get; set; } + + public virtual ICollection DispetcherReviews { get; set; } + public virtual ICollection OperatorReviews { get; set; } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Models/OperatorReview.cs b/CheckDrive.Web/CheckDrive.Web/Models/OperatorReview.cs new file mode 100644 index 00000000..730de0dd --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Models/OperatorReview.cs @@ -0,0 +1,16 @@ +namespace CheckDrive.Web.Models +{ + public class OperatorReview + { + public int Id { get; set; } + public double OilAmount { get; set; } + public string? Comments { get; set; } + public Status Status { get; set; } + public DateTime Date { get; set; } + + public int OperatorId { get; set; } + public Operator Operator { get; set; } + public int DriverId { get; set; } + public Driver Driver { get; set; } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Models/Role.cs b/CheckDrive.Web/CheckDrive.Web/Models/Role.cs new file mode 100644 index 00000000..38d20dee --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Models/Role.cs @@ -0,0 +1,10 @@ +namespace CheckDrive.Web.Models +{ + public class Role + { + public int Id { get; set; } + public string Name { get; set; } + + public virtual ICollection Accounts { get; set; } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Models/Status.cs b/CheckDrive.Web/CheckDrive.Web/Models/Status.cs new file mode 100644 index 00000000..a7174006 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Models/Status.cs @@ -0,0 +1,10 @@ +namespace CheckDrive.Web.Models +{ + public enum Status + { + Pending, + Completed, + Rejected, + Unassigned + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Models/Technician.cs b/CheckDrive.Web/CheckDrive.Web/Models/Technician.cs new file mode 100644 index 00000000..65a4cb45 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Models/Technician.cs @@ -0,0 +1,9 @@ +namespace CheckDrive.Web.Models +{ + public class Technician + { + public int Id { get; set; } + public int AccountId { get; set; } + public Account Account { get; set; } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Program.cs b/CheckDrive.Web/CheckDrive.Web/Program.cs index 07274680..71a3bdde 100644 --- a/CheckDrive.Web/CheckDrive.Web/Program.cs +++ b/CheckDrive.Web/CheckDrive.Web/Program.cs @@ -1,8 +1,19 @@ +using CheckDrive.Web.Constants; +using CheckDrive.Web.Extensions; +using CheckDrive.Web.Filters; + + var builder = WebApplication.CreateBuilder(args); // Add services to the container. -builder.Services.AddControllersWithViews(); - +builder.Services.AddControllersWithViews(options => + options.Filters.Add(new ApiExceptionFilter())); +builder.Services.ConfigureDataStores(); +builder.Services.ConfigureServices(); +builder.Services.AddHttpContextAccessor(); + +Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense(Configurations.SynfusionLicenseKey); +//builder.Services.AddHttpContextAccessor(); var app = builder.Build(); // Configure the HTTP request pipeline. @@ -22,6 +33,5 @@ app.MapControllerRoute( name: "default", - pattern: "{controller=Home}/{action=Index}/{id?}"); - + pattern: "{controller=Auth}/{action=Index}/{id?}"); app.Run(); diff --git a/CheckDrive.Web/CheckDrive.Web/Responses/GetAccountResponse.cs b/CheckDrive.Web/CheckDrive.Web/Responses/GetAccountResponse.cs new file mode 100644 index 00000000..6b71b12c --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Responses/GetAccountResponse.cs @@ -0,0 +1,8 @@ +using CheckDrive.ApiContracts.Account; + +namespace CheckDrive.Web.Responses +{ + public class GetAccountResponse : GetBaseResponse + { + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Responses/GetBaseResponse.cs b/CheckDrive.Web/CheckDrive.Web/Responses/GetBaseResponse.cs new file mode 100644 index 00000000..c6dce540 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Responses/GetBaseResponse.cs @@ -0,0 +1,13 @@ +namespace CheckDrive.Web.Responses +{ + public abstract class GetBaseResponse + { + public IEnumerable? Data { get; set; } + public int PageNumber { get; set; } + public int PageSize { get; set; } + public bool HasNextPage { get; set; } + public bool HasPreviousPage { get; set; } + public int TotalPages { get; set; } + public int TotalCount { get; set; } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Responses/GetCarResponse.cs b/CheckDrive.Web/CheckDrive.Web/Responses/GetCarResponse.cs new file mode 100644 index 00000000..bc34388a --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Responses/GetCarResponse.cs @@ -0,0 +1,8 @@ +using CheckDrive.ApiContracts.Car; + +namespace CheckDrive.Web.Responses +{ + public class GetCarResponse : GetBaseResponse + { + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Responses/GetDispatcherResponse.cs b/CheckDrive.Web/CheckDrive.Web/Responses/GetDispatcherResponse.cs new file mode 100644 index 00000000..adbe187f --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Responses/GetDispatcherResponse.cs @@ -0,0 +1,8 @@ +using CheckDrive.ApiContracts.Dispatcher; + +namespace CheckDrive.Web.Responses +{ + public class GetDispatcherResponse : GetBaseResponse + { + } +} \ No newline at end of file diff --git a/CheckDrive.Web/CheckDrive.Web/Responses/GetDispatcherReviewResponse.cs b/CheckDrive.Web/CheckDrive.Web/Responses/GetDispatcherReviewResponse.cs new file mode 100644 index 00000000..07fffa79 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Responses/GetDispatcherReviewResponse.cs @@ -0,0 +1,8 @@ +using CheckDrive.ApiContracts.DispatcherReview; + +namespace CheckDrive.Web.Responses +{ + public class GetDispatcherReviewResponse : GetBaseResponse + { + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Responses/GetDoctorResponse.cs b/CheckDrive.Web/CheckDrive.Web/Responses/GetDoctorResponse.cs new file mode 100644 index 00000000..d33b8591 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Responses/GetDoctorResponse.cs @@ -0,0 +1,8 @@ +using CheckDrive.ApiContracts.Doctor; + +namespace CheckDrive.Web.Responses +{ + public class GetDoctorResponse : GetBaseResponse + { + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Responses/GetDoctorReviewResponse.cs b/CheckDrive.Web/CheckDrive.Web/Responses/GetDoctorReviewResponse.cs new file mode 100644 index 00000000..df295481 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Responses/GetDoctorReviewResponse.cs @@ -0,0 +1,9 @@ +using CheckDrive.ApiContracts.DoctorReview; +using CheckDrive.Web.Models; + +namespace CheckDrive.Web.Responses +{ + public class GetDoctorReviewResponse : GetBaseResponse + { + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Responses/GetDriverResponse.cs b/CheckDrive.Web/CheckDrive.Web/Responses/GetDriverResponse.cs new file mode 100644 index 00000000..5defe9f3 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Responses/GetDriverResponse.cs @@ -0,0 +1,8 @@ +using CheckDrive.ApiContracts.Driver; + +namespace CheckDrive.Web.Responses +{ + public class GetDriverResponse : GetBaseResponse + { + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Responses/GetMechanicAcceptanceResponse.cs b/CheckDrive.Web/CheckDrive.Web/Responses/GetMechanicAcceptanceResponse.cs new file mode 100644 index 00000000..26b37d3b --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Responses/GetMechanicAcceptanceResponse.cs @@ -0,0 +1,6 @@ +namespace CheckDrive.Web.Responses +{ + public class GetMechanicAcceptanceResponse : GetBaseResponse + { + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Responses/GetMechanicHandoverResponse.cs b/CheckDrive.Web/CheckDrive.Web/Responses/GetMechanicHandoverResponse.cs new file mode 100644 index 00000000..246ad6d0 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Responses/GetMechanicHandoverResponse.cs @@ -0,0 +1,6 @@ +namespace CheckDrive.Web.Responses +{ + public class GetMechanicHandoverResponse : GetBaseResponse + { + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Responses/GetMechanicResponse.cs b/CheckDrive.Web/CheckDrive.Web/Responses/GetMechanicResponse.cs new file mode 100644 index 00000000..d1360c70 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Responses/GetMechanicResponse.cs @@ -0,0 +1,6 @@ +namespace CheckDrive.Web.Responses +{ + public class GetMechanicResponse : GetBaseResponse + { + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Responses/GetOperatorResponse.cs b/CheckDrive.Web/CheckDrive.Web/Responses/GetOperatorResponse.cs new file mode 100644 index 00000000..e9a6ae3a --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Responses/GetOperatorResponse.cs @@ -0,0 +1,9 @@ +using CheckDrive.ApiContracts.Operator; +using CheckDrive.Web.Models; + +namespace CheckDrive.Web.Responses +{ + public class GetOperatorResponse : GetBaseResponse + { + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Responses/GetOperatorReviewResponse.cs b/CheckDrive.Web/CheckDrive.Web/Responses/GetOperatorReviewResponse.cs new file mode 100644 index 00000000..8bb67a89 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Responses/GetOperatorReviewResponse.cs @@ -0,0 +1,8 @@ +using CheckDrive.ApiContracts.OperatorReview; + +namespace CheckDrive.Web.Responses +{ + public class GetOperatorReviewResponse : GetBaseResponse + { + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Responses/GetRoleResponse.cs b/CheckDrive.Web/CheckDrive.Web/Responses/GetRoleResponse.cs new file mode 100644 index 00000000..a8c5d5ec --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Responses/GetRoleResponse.cs @@ -0,0 +1,9 @@ +using CheckDrive.ApiContracts.Role; +using CheckDrive.Web.Models; + +namespace CheckDrive.Web.Responses +{ + public class GetRoleResponse : GetBaseResponse + { + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Responses/GetTechnicianResponse.cs b/CheckDrive.Web/CheckDrive.Web/Responses/GetTechnicianResponse.cs new file mode 100644 index 00000000..15693876 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Responses/GetTechnicianResponse.cs @@ -0,0 +1,8 @@ +using CheckDrive.Web.Models; + +namespace CheckDrive.Web.Responses +{ + public class GetTechnicianResponse : GetBaseResponse + { + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Service/ApiClient.cs b/CheckDrive.Web/CheckDrive.Web/Service/ApiClient.cs new file mode 100644 index 00000000..20263e82 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Service/ApiClient.cs @@ -0,0 +1,93 @@ +using CheckDrive.Web.Exceptions; + +namespace CheckDrive.Web.Service +{ + public class ApiClient + { + private const string baseUrl = "https://localhost:7111/api"; + + private readonly HttpClient _client = new(); + private readonly IHttpContextAccessor _contextAccessor; + + public ApiClient(IHttpContextAccessor contextAccessor) + { + _client.BaseAddress = new Uri(baseUrl); + _client.DefaultRequestHeaders.Add("Accept", "application/json"); + _contextAccessor = contextAccessor ?? throw new ArgumentNullException(nameof(contextAccessor)); + } + + public async Task GetAsync(string url) + { + string token = string.Empty; + var request = new HttpRequestMessage(HttpMethod.Get, _client.BaseAddress?.AbsolutePath + "/" + url); + _contextAccessor.HttpContext?.Request.Cookies.TryGetValue("tasty-cookies", out token); + request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); + + var response = await _client.SendAsync(request); + + if (!response.IsSuccessStatusCode) + { + throw new ApiException(response.StatusCode, $"Error fetching url: {url}"); + } + + return response; + } + + public async Task PostAsync(string url, string data) + { + string token = string.Empty; + var request = new HttpRequestMessage(HttpMethod.Post, _client.BaseAddress?.AbsolutePath + "/" + url) + { + Content = new StringContent(data, System.Text.Encoding.UTF8, "application/json") + }; + _contextAccessor.HttpContext?.Request.Cookies.TryGetValue("tasty-cookies", out token); + request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); + + var response = await _client.SendAsync(request); + + if (!response.IsSuccessStatusCode) + { + throw new ApiException(response.StatusCode, $"Error fetching url: {url}"); + } + + return response; + } + + public async Task PutAsync(string url, string data) + { + string token = string.Empty; + var request = new HttpRequestMessage(HttpMethod.Put, _client.BaseAddress?.AbsolutePath + "/" + url) + { + Content = new StringContent(data, System.Text.Encoding.UTF8, "application/json") + }; + _contextAccessor.HttpContext?.Request.Cookies.TryGetValue("tasty-cookies", out token); + request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); + + var response = await _client.SendAsync(request); + + if (!response.IsSuccessStatusCode) + { + throw new ApiException(response.StatusCode, $"Error fetching url: {url}"); + } + + return response; + } + + public async Task DeleteAsync(string url) + { + string token = string.Empty; + var request = new HttpRequestMessage(HttpMethod.Delete, _client.BaseAddress?.AbsolutePath + "/" + url); + _contextAccessor.HttpContext?.Request.Cookies.TryGetValue("tasty-cookies", out token); + request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); + + var response = await _client.SendAsync(request); + + if (!response.IsSuccessStatusCode) + { + throw new ApiException(response.StatusCode, $"Error fetching url: {url}"); + } + + return response; + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/Accounts/AccountDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/Accounts/AccountDataStore.cs new file mode 100644 index 00000000..4d9d229f --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/Accounts/AccountDataStore.cs @@ -0,0 +1,111 @@ +using CheckDrive.ApiContracts.Account; +using CheckDrive.Web.Responses; +using CheckDrive.Web.Service; +using Newtonsoft.Json; +using System.Text; + +namespace CheckDrive.Web.Stores.Accounts +{ + public class AccountDataStore : IAccountDataStore + { + private readonly ApiClient _api; + + public AccountDataStore(ApiClient apiClient) + { + _api = apiClient; + } + + + public async Task GetAccountsAsync(string? searchString, int? roleId, DateTime? birthDate, int? pageNumber) + { + StringBuilder query = new(""); + + if (birthDate is not null) + { + query.Append($"birthDate={birthDate.Value.ToString("MM/dd/yyyy")}&"); + } + if (!string.IsNullOrWhiteSpace(searchString)) + { + query.Append($"searchString={searchString}&"); + } + if (roleId is not null) + { + query.Append($"roleId={roleId}&"); + } + if (pageNumber != null) + { + query.Append($"pageNumber={pageNumber}"); + } + + var response = await _api.GetAsync("accounts?" + query.ToString()); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Could not fetch accounts."); + } + + + var json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + var result = JsonConvert.DeserializeObject(json); + + return result; + } + + public async Task GetAccountAsync(int id) + + { + var response = await _api.GetAsync($"accounts/{id}"); + + if (!response.IsSuccessStatusCode) + { + throw new Exception($"Could not fetch account with id: {id}."); + } + + var json = await response.Content.ReadAsStringAsync(); + var result = JsonConvert.DeserializeObject(json); + + return result; + } + + public async Task CreateAccountAsync(AccountForCreateDto account) + { + var json = JsonConvert.SerializeObject(account); + var response = await _api.PostAsync("accounts", json); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Error creating account."); + } + + var jsonResponse = await response.Content.ReadAsStringAsync(); + return JsonConvert.DeserializeObject(jsonResponse); + } + + + + public async Task UpdateAccountAsync(int id, AccountForUpdateDto account) + { + var json = JsonConvert.SerializeObject(account); + var response = await _api.PutAsync($"accounts/{account.Id}", json); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Error updating account."); + } + + var jsonResponse = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + + return JsonConvert.DeserializeObject(jsonResponse); + } + + public async Task DeleteAccountAsync(int id) + { + var response = await _api.DeleteAsync($"accounts/{id}"); + + if (!response.IsSuccessStatusCode) + { + throw new Exception($"Could not delete account with id: {id}."); + } + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/Accounts/IAccountDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/Accounts/IAccountDataStore.cs new file mode 100644 index 00000000..23d93843 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/Accounts/IAccountDataStore.cs @@ -0,0 +1,14 @@ +using CheckDrive.ApiContracts.Account; +using CheckDrive.Web.Responses; + +namespace CheckDrive.Web.Stores.Accounts +{ + public interface IAccountDataStore + { + Task GetAccountsAsync(string? searchString, int? roleId, DateTime? birthDate, int? pageNumber); + Task GetAccountAsync(int id); + Task CreateAccountAsync(AccountForCreateDto account); + Task UpdateAccountAsync(int id, AccountForUpdateDto account); + Task DeleteAccountAsync(int id); + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/Cars/CarDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/Cars/CarDataStore.cs new file mode 100644 index 00000000..cbe1e3d7 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/Cars/CarDataStore.cs @@ -0,0 +1,100 @@ +using CheckDrive.ApiContracts.Car; +using CheckDrive.Web.Responses; +using CheckDrive.Web.Service; +using Newtonsoft.Json; +using System.Text; + +namespace CheckDrive.Web.Stores.Cars +{ + public class CarDataStore : ICarDataStore + { + private readonly ApiClient _api; + + public CarDataStore(ApiClient apiClient) + { + _api = apiClient; + } + + public async Task GetCarsAsync(string? searchString,int? pageNumber) + + { + StringBuilder query = new(""); + + if (!string.IsNullOrWhiteSpace(searchString)) + { + query.Append($"searchString={searchString}&"); + } + if (pageNumber != null) + { + query.Append($"pageNumber={pageNumber}"); + } + + var response = await _api.GetAsync("cars?" + query.ToString()); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Could not fetch cars."); + } + + var json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + var result = JsonConvert.DeserializeObject(json); + + return result; + } + + public async Task GetCarAsync(int id) + { + var response = await _api.GetAsync($"cars/{id}"); + + if (!response.IsSuccessStatusCode) + { + throw new Exception($"Could not fetch car with id: {id}."); + } + + var json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + var result = JsonConvert.DeserializeObject(json); + + return result; + } + + public async Task CreateCarAsync(CarForCreateDto carForCreate) + { + var json = JsonConvert.SerializeObject(carForCreate); + var response = await _api.PostAsync("cars", json); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Error creating cars."); + } + + var jsonResponse = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + + return JsonConvert.DeserializeObject(jsonResponse); + } + + public async Task UpdateCarAsync(int id, CarForUpdateDto car) + { + var json = JsonConvert.SerializeObject(car); + var response = await _api.PutAsync($"cars/{car.Id}", json); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Error updating cars."); + } + + var jsonResponse = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + + return JsonConvert.DeserializeObject(jsonResponse); + } + + public async Task DeleteCarAsync(int id) + { + var response = await _api.DeleteAsync($"cars/{id}"); + + if (!response.IsSuccessStatusCode) + { + throw new Exception($"Could not delete car with id: {id}."); + } + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/Cars/ICarDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/Cars/ICarDataStore.cs new file mode 100644 index 00000000..81adc016 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/Cars/ICarDataStore.cs @@ -0,0 +1,14 @@ +using CheckDrive.ApiContracts.Car; +using CheckDrive.Web.Responses; + +namespace CheckDrive.Web.Stores.Cars +{ + public interface ICarDataStore + { + Task GetCarsAsync(string? searchString, int? pageNumber); + Task GetCarAsync(int id); + Task CreateCarAsync(CarForCreateDto carForCreate); + Task UpdateCarAsync(int id, CarForUpdateDto car); + Task DeleteCarAsync(int id); + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/Dashbord/DashboardStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/Dashbord/DashboardStore.cs new file mode 100644 index 00000000..4adbf04b --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/Dashbord/DashboardStore.cs @@ -0,0 +1,27 @@ +using CheckDrive.Web.Service; +using CheckDrive.Web.ViewModels; +using Newtonsoft.Json; + +namespace CheckDrive.Web.Stores.Dashbord +{ + public class DashboardStore : IDashboardStore + { + private readonly ApiClient _client; + public DashboardStore(ApiClient client) + { + _client = client; + } + public async Task GetDashboard() + { + var response = await _client.GetAsync("Dashboard"); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Error occured while fetching dashboard data."); + } + var json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + var result = JsonConvert.DeserializeObject(json); + return result; + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/Dashbord/IDashboardStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/Dashbord/IDashboardStore.cs new file mode 100644 index 00000000..b5f05a7f --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/Dashbord/IDashboardStore.cs @@ -0,0 +1,9 @@ +using CheckDrive.Web.ViewModels; + +namespace CheckDrive.Web.Stores.Dashbord +{ + public interface IDashboardStore + { + public Task GetDashboard(); + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/DispatcherReviews/DispatcherReviewDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/DispatcherReviews/DispatcherReviewDataStore.cs new file mode 100644 index 00000000..3514d692 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/DispatcherReviews/DispatcherReviewDataStore.cs @@ -0,0 +1,83 @@ +using CheckDrive.ApiContracts.DispatcherReview; +using CheckDrive.Web.Models; +using CheckDrive.Web.Responses; +using CheckDrive.Web.Service; +using Newtonsoft.Json; +using System.Text; + +namespace CheckDrive.Web.Stores.DispatcherReviews +{ + public class DispatcherReviewDataStore(ApiClient api) : IDispatcherReviewDataStore + { + private readonly ApiClient _api = api; + public async Task GetDispatcherReviews( + int? pageNumber, + string? searchString, + DateTime? date, + int? roleId) + { + StringBuilder query = new(""); + + if (roleId != 0) + query.Append($"roleId={roleId}&"); + + if (date is not null) + query.Append($"date={date.Value.ToString("MM/dd/yyyy")}&"); + + if (!string.IsNullOrWhiteSpace(searchString)) + query.Append($"searchString={searchString}&"); + + if (pageNumber != null) + query.Append($"pageNumber={pageNumber}"); + + var response = await _api.GetAsync("dispatchers/reviews?OrderBy=datedesc&" + query.ToString()); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Could not fetch drivers."); + } + + var json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + var result = JsonConvert.DeserializeObject(json); + + return result; + } + public async Task GetDispatcherReview(int id) + { + var response = await _api.GetAsync($"dispatchers/review/{id}"); + + if (!response.IsSuccessStatusCode) + { + throw new Exception($"Could not fetch dispatcherReviews with id: {id}."); + } + + var json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + var result = JsonConvert.DeserializeObject(json); + + return result; + } + public async Task CreateDispatcherReview(DispatcherReviewForCreateDto review) + { + var json = JsonConvert.SerializeObject(review); + var response = await _api.PostAsync("dispatchers/review", json); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Error creating dispatcherReviews."); + } + + var jsonResponse = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + + return JsonConvert.DeserializeObject(jsonResponse); + } + public Task UpdateDispatcherReview(int id, DispatcherReviewForUpdateDto review) + { + throw new NotImplementedException(); + } + + public Task DeleteDispatcherReview(int id) + { + throw new NotImplementedException(); + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/DispatcherReviews/IDispatcherReviewDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/DispatcherReviews/IDispatcherReviewDataStore.cs new file mode 100644 index 00000000..3204eef1 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/DispatcherReviews/IDispatcherReviewDataStore.cs @@ -0,0 +1,14 @@ +using CheckDrive.ApiContracts.DispatcherReview; +using CheckDrive.Web.Responses; + +namespace CheckDrive.Web.Stores.DispatcherReviews +{ + public interface IDispatcherReviewDataStore + { + Task GetDispatcherReviews(int? pageNumber, string? searchString, DateTime? date, int? roleId); + Task GetDispatcherReview(int id); + Task CreateDispatcherReview(DispatcherReviewForCreateDto review); + Task UpdateDispatcherReview(int id, DispatcherReviewForUpdateDto review); + Task DeleteDispatcherReview(int id); + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/Dispatchers/DispatcherDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/Dispatchers/DispatcherDataStore.cs new file mode 100644 index 00000000..f33e6219 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/Dispatchers/DispatcherDataStore.cs @@ -0,0 +1,55 @@ +using CheckDrive.Web.Models; +using CheckDrive.Web.Responses; +using CheckDrive.Web.Service; +using Newtonsoft.Json; +using System.Text; + +namespace CheckDrive.Web.Stores.Dispatchers +{ + public class DispatcherDataStore : IDispatcherDataStore + { + private readonly ApiClient _api; + + public DispatcherDataStore(ApiClient apiClient) + { + _api = apiClient; + } + + public async Task GetDispatchers(int accountId) + { + StringBuilder query = new(""); + + if (!accountId.Equals(0)) + { + query.Append($"accountId={accountId}"); + } + + var response = await _api.GetAsync("dispatchers?" + query.ToString()); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Could not fetch dispatchers."); + } + + var json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + var result = JsonConvert.DeserializeObject(json); + + return result; + } + + public async Task GetDispatchers() + { + var response = await _api.GetAsync("dispatchers?"); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Could not fetch dispatchers."); + } + + var json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + var result = JsonConvert.DeserializeObject(json); + + return result; + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/Dispatchers/IDispatcherDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/Dispatchers/IDispatcherDataStore.cs new file mode 100644 index 00000000..6aff9897 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/Dispatchers/IDispatcherDataStore.cs @@ -0,0 +1,11 @@ +using CheckDrive.Web.Models; +using CheckDrive.Web.Responses; + +namespace CheckDrive.Web.Stores.Dispatchers +{ + public interface IDispatcherDataStore + { + Task GetDispatchers(int accountId); + Task GetDispatchers(); + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/DoctorReviews/DoctorReviewDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/DoctorReviews/DoctorReviewDataStore.cs new file mode 100644 index 00000000..d8851086 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/DoctorReviews/DoctorReviewDataStore.cs @@ -0,0 +1,114 @@ +using System.Text; +using CheckDrive.ApiContracts.DoctorReview; +using CheckDrive.Web.Models; +using CheckDrive.Web.Responses; +using CheckDrive.Web.Service; +using Newtonsoft.Json; + +namespace CheckDrive.Web.Stores.DoctorReviews +{ + public class DoctorReviewDataStore(ApiClient api) : IDoctorReviewDataStore + { + private readonly ApiClient _api = api; + + public async Task GetDoctorReviewsAsync(int? pageNumber, string? searchString, DateTime? date, int? roleId) + { + StringBuilder query = new(""); + + if (roleId != 0) + { + query.Append($"roleId={roleId}&"); + } + if (date is not null) + { + query.Append($"date={date.Value.ToString("MM/dd/yyyy")}&"); + } + if (!string.IsNullOrWhiteSpace(searchString)) + { + query.Append($"searchString={searchString}&"); + } + if (pageNumber != null) + { + query.Append($"pageNumber={pageNumber}"); + } + + var response = await _api.GetAsync("doctors/reviews?OrderBy=datedesc&" + query.ToString()); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Could not fetch doctorReviews."); + } + + var json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + var result = JsonConvert.DeserializeObject(json); + + return result; + } + + public async Task>? GetTodayReviewsAsync() + { + + var response = await _api.GetAsync("doctors/reviews/today"); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Could not fetch doctorReviews."); + } + + var json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + var result = JsonConvert.DeserializeObject>(json); + + return result; + } + + public async Task GetDoctorReviewAsync(int id) + { + var response = await _api.GetAsync($"doctors/review/{id}"); + + if (!response.IsSuccessStatusCode) + { + throw new Exception($"Could not fetch doctorReview with id: {id}."); + } + + var json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + var result = JsonConvert.DeserializeObject(json); + + return result; + } + + public async Task CreateDoctorReviewAsync(DoctorReviewForCreateDto review) + { + var json = JsonConvert.SerializeObject(review); + var response = await _api.PostAsync("doctors/review", json); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Error creating doctorReviews."); + } + + var jsonResponse = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + + return JsonConvert.DeserializeObject(jsonResponse); + } + + public async Task UpdateDoctorReviewAsync(int id, DoctorReviewForUpdateDto review) + { + var json = JsonConvert.SerializeObject(review); + var response = await _api.PutAsync($"doctors/review/{review.Id}", json); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Error updating doctorReview."); + } + + var jsonResponse = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + + return JsonConvert.DeserializeObject(jsonResponse); + } + + public async Task DeleteDoctorReviewAsync(int id) + { + throw new NotImplementedException(); + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/DoctorReviews/IDoctorReviewDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/DoctorReviews/IDoctorReviewDataStore.cs new file mode 100644 index 00000000..a208ff7d --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/DoctorReviews/IDoctorReviewDataStore.cs @@ -0,0 +1,15 @@ +using CheckDrive.ApiContracts.DoctorReview; +using CheckDrive.Web.Responses; + +namespace CheckDrive.Web.Stores.DoctorReviews +{ + public interface IDoctorReviewDataStore + { + Task GetDoctorReviewsAsync(int? pageNumber, string? searchString, DateTime? date, int? roleId); + Task>? GetTodayReviewsAsync(); + Task GetDoctorReviewAsync(int id); + Task CreateDoctorReviewAsync(DoctorReviewForCreateDto review); + Task UpdateDoctorReviewAsync(int id, DoctorReviewForUpdateDto review); + Task DeleteDoctorReviewAsync(int id); + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/Doctors/DoctorDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/Doctors/DoctorDataStore.cs new file mode 100644 index 00000000..21f26189 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/Doctors/DoctorDataStore.cs @@ -0,0 +1,111 @@ +using CheckDrive.ApiContracts.Account; +using CheckDrive.ApiContracts.Doctor; +using CheckDrive.Web.Responses; +using CheckDrive.Web.Service; +using Newtonsoft.Json; +using System.Text; + +namespace CheckDrive.Web.Stores.Doctors +{ + public class DoctorDataStore : IDoctorDataStore + { + private readonly ApiClient _api; + + public DoctorDataStore(ApiClient apiClient) + { + _api = apiClient; + } + + public async Task GetDoctors(int accountId) + { + StringBuilder query = new(""); + + if (!accountId.Equals(0)) + { + query.Append($"accountId={accountId}"); + } + + var response = await _api.GetAsync("doctors?" + query.ToString()); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Could not fetch doctors."); + } + + var json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + var result = JsonConvert.DeserializeObject(json); + + return result; + } + + public async Task GetDoctors() + { + var response = await _api.GetAsync("doctors?"); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Could not fetch doctors."); + } + + var json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + var result = JsonConvert.DeserializeObject(json); + + return result; + } + + public async Task GetDoctor(int id) + { + var response = await _api.GetAsync($"doctors/{id}"); + + if (!response.IsSuccessStatusCode) + { + throw new Exception($"Could not fetch doctor with id: {id}."); + } + + var json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + var result = JsonConvert.DeserializeObject(json); + + return result; + } + + public async Task CreateDoctor(DoctorForCreateDto doctorForCreate) + { + var json = JsonConvert.SerializeObject(doctorForCreate); + var response = await _api.PostAsync("doctors", json); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Error creating doctors."); + } + + var jsonResponse = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + + return JsonConvert.DeserializeObject(jsonResponse); + } + + public async Task UpdateDoctor(int id, AccountForUpdateDto doctorForUpdate) + { + var json = JsonConvert.SerializeObject(doctorForUpdate); + var response = await _api.PutAsync($"doctors/{doctorForUpdate.Id}", json); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Error updating doctors."); + } + + var jsonResponse = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + + return JsonConvert.DeserializeObject(jsonResponse); + } + + public async Task DeleteDoctor(int id) + { + var response = await _api.DeleteAsync($"doctors/{id}"); + + if (!response.IsSuccessStatusCode) + { + throw new Exception($"Could not delete doctor with id: {id}."); + } + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/Doctors/IDoctorsDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/Doctors/IDoctorsDataStore.cs new file mode 100644 index 00000000..8cfebae3 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/Doctors/IDoctorsDataStore.cs @@ -0,0 +1,16 @@ +using CheckDrive.ApiContracts.Account; +using CheckDrive.ApiContracts.Doctor; +using CheckDrive.Web.Responses; + +namespace CheckDrive.Web.Stores.Doctors +{ + public interface IDoctorDataStore + { + Task GetDoctors(int accountId); + Task GetDoctors(); + Task GetDoctor(int id); + Task CreateDoctor(DoctorForCreateDto doctorForCreate); + Task UpdateDoctor(int id, AccountForUpdateDto doctorForUpdate); + Task DeleteDoctor(int id); + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/Drivers/DriverDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/Drivers/DriverDataStore.cs new file mode 100644 index 00000000..c31cf152 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/Drivers/DriverDataStore.cs @@ -0,0 +1,99 @@ +using CheckDrive.ApiContracts.Account; +using CheckDrive.ApiContracts.Driver; +using CheckDrive.Web.Responses; +using CheckDrive.Web.Service; +using Newtonsoft.Json; +using System.Text; + +namespace CheckDrive.Web.Stores.Drivers +{ + public class DriverDataStore : IDriverDataStore + { + private readonly ApiClient _api; + + public DriverDataStore(ApiClient apiClient) + { + _api = apiClient; + } + + public async Task GetDriversAsync(string? searchString,int? pageNumber) + { + StringBuilder query = new(""); + + if (!string.IsNullOrWhiteSpace(searchString)) + { + query.Append($"searchString={searchString}&"); + } + if (pageNumber != null) + { + query.Append($"pageNumber={pageNumber}"); + } + + var response = await _api.GetAsync("drivers?" + query.ToString()); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Could not fetch drivers."); + } + + + var json = await response.Content.ReadAsStringAsync(); + var result = JsonConvert.DeserializeObject(json); + + return result; + } + + public async Task GetDriverAsync(int id) + { + var response = await _api.GetAsync($"drivers/{id}"); + + if (!response.IsSuccessStatusCode) + { + throw new Exception($"Could not fetch driver with id: {id}."); + } + + var json = await response.Content.ReadAsStringAsync(); + var result = JsonConvert.DeserializeObject(json); + + return result; + } + + public async Task CreateDriverAsync(DriverForCreateDto driverForCreate) + { + var json = JsonConvert.SerializeObject(driverForCreate); + var response = await _api.PostAsync("drivers", json); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Error creating driver."); + } + + var jsonResponse = await response.Content.ReadAsStringAsync(); + return JsonConvert.DeserializeObject(jsonResponse); + } + + public async Task UpdateDriverAsync(int id, AccountForUpdateDto driverForUpdate) + { + var json = JsonConvert.SerializeObject(driverForUpdate); + var response = await _api.PutAsync($"drivers/{driverForUpdate.Id}", json); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Error updating driver."); + } + + var jsonResponse = await response.Content.ReadAsStringAsync(); + return JsonConvert.DeserializeObject(jsonResponse); + } + + public async Task DeleteDriverAsync(int id) + { + var response = await _api.DeleteAsync($"drivers/{id}"); + + if (!response.IsSuccessStatusCode) + { + throw new Exception($"Could not delete driver with id: {id}."); + } + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/Drivers/IDriverDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/Drivers/IDriverDataStore.cs new file mode 100644 index 00000000..2b579d01 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/Drivers/IDriverDataStore.cs @@ -0,0 +1,15 @@ +using CheckDrive.ApiContracts.Account; +using CheckDrive.ApiContracts.Driver; +using CheckDrive.Web.Responses; + +namespace CheckDrive.Web.Stores.Drivers +{ + public interface IDriverDataStore + { + Task GetDriversAsync(string? searchString,int? pageNumber); + Task GetDriverAsync(int id); + Task CreateDriverAsync(DriverForCreateDto driverForCreate); + Task UpdateDriverAsync(int id, AccountForUpdateDto driverForUpdate); + Task DeleteDriverAsync(int id); + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/MechanicAcceptances/IMechanicAcceptanceDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/MechanicAcceptances/IMechanicAcceptanceDataStore.cs new file mode 100644 index 00000000..ac4851f3 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/MechanicAcceptances/IMechanicAcceptanceDataStore.cs @@ -0,0 +1,15 @@ +using CheckDrive.ApiContracts.MechanicAcceptance; +using CheckDrive.Web.Responses; + +namespace CheckDrive.Web.Stores.MechanicAcceptances +{ + public interface IMechanicAcceptanceDataStore + { + Task GetMechanicAcceptancesAsync(int? pageNumber, string? searchString, DateTime? date, int? roleId); + Task GetMechanicAcceptancesAsync(); + Task GetMechanicAcceptanceAsync(int id); + Task CreateMechanicAcceptanceAsync(MechanicAcceptanceForCreateDto acceptanceForCreateDto); + Task UpdateMechanicAcceptanceAsync(int id, MechanicAcceptanceForUpdateDto mechanicAcceptanceForUpdateDto); + Task DeleteMechanicAcceptanceAsync(int id); + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/MechanicAcceptances/MechanicAcceptanceDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/MechanicAcceptances/MechanicAcceptanceDataStore.cs new file mode 100644 index 00000000..e00b8c25 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/MechanicAcceptances/MechanicAcceptanceDataStore.cs @@ -0,0 +1,99 @@ +using CheckDrive.ApiContracts.MechanicAcceptance; +using CheckDrive.Web.Models; +using CheckDrive.Web.Responses; +using CheckDrive.Web.Service; +using Newtonsoft.Json; +using System.Text; + +namespace CheckDrive.Web.Stores.MechanicAcceptances +{ + public class MechanicAcceptanceDataStore : IMechanicAcceptanceDataStore + { + private readonly ApiClient _api; + + public MechanicAcceptanceDataStore(ApiClient apiClient) + { + _api = apiClient; + } + public async Task GetMechanicAcceptancesAsync( + int? pageNumber, + string? searchString, + DateTime? date, + int? roleId) + { + StringBuilder query = new StringBuilder(); + + if (roleId != 0) + query.Append($"roleId={roleId}&"); + + if (date is not null) + query.Append($"date={date.Value.ToString("MM/dd/yyyy")}&"); + + if (!string.IsNullOrWhiteSpace(searchString)) + query.Append($"searchString={searchString}&"); + + if (pageNumber != null) + query.Append($"pageNumber={pageNumber}"); + + var response = await _api.GetAsync("mechanics/acceptances?OrderBy=datedesc&" + query.ToString()); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Could not fetch mechanic acceptances."); + } + + var json = await response.Content.ReadAsStringAsync(); + var result = JsonConvert.DeserializeObject(json); + + return result; + } + + public async Task GetMechanicAcceptancesAsync() + { + var response = await _api.GetAsync("mechanics/acceptances?OrderBy=datedesc"); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Could not fetch drivers."); + } + + var json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + var result = JsonConvert.DeserializeObject(json); + + return result; + } + public Task DeleteMechanicAcceptanceAsync(int id) + { + throw new NotImplementedException(); + } + + public Task GetMechanicAcceptanceAsync(int id) + { + throw new NotImplementedException(); + } + + public async Task CreateMechanicAcceptanceAsync(MechanicAcceptanceForCreateDto acceptanceForCreateDto) + { + var json = JsonConvert.SerializeObject(acceptanceForCreateDto); + var response = await _api.PostAsync("mechanics/acceptance", json); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Error creating mechanicAcceptance."); + } + + var jsonResponse = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + + return JsonConvert.DeserializeObject(jsonResponse); + } + Task IMechanicAcceptanceDataStore.GetMechanicAcceptanceAsync(int id) + { + throw new NotImplementedException(); + } + + Task IMechanicAcceptanceDataStore.UpdateMechanicAcceptanceAsync(int id, MechanicAcceptanceForUpdateDto mechanicAcceptanceForUpdateDto) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/MechanicHandovers/IMechanicHandoverDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/MechanicHandovers/IMechanicHandoverDataStore.cs new file mode 100644 index 00000000..c4852b4b --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/MechanicHandovers/IMechanicHandoverDataStore.cs @@ -0,0 +1,15 @@ +using CheckDrive.ApiContracts.MechanicHandover; +using CheckDrive.Web.Responses; + +namespace CheckDrive.Web.Stores.MechanicHandovers +{ + public interface IMechanicHandoverDataStore + { + Task GetMechanicHandoversAsync(int? pageNumber, string? searchString, DateTime? date, int? roleId); + Task GetMechanicHandoversAsync(); + Task GetMechanicHandoverAsync(int id); + Task CreateMechanicHandoverAsync(MechanicHandoverForCreateDto mechanicHandoverForCreateDto); + Task UpdateMechanicHandoverAsync(int id, MechanicHandoverForUpdateDto mechanicHandoverForUpdateDto); + Task DeleteMechanicHandoverAsync(int id); + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/MechanicHandovers/MechanicHandoverDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/MechanicHandovers/MechanicHandoverDataStore.cs new file mode 100644 index 00000000..59e17935 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/MechanicHandovers/MechanicHandoverDataStore.cs @@ -0,0 +1,93 @@ +using CheckDrive.ApiContracts.MechanicHandover; +using CheckDrive.Web.Models; +using CheckDrive.Web.Responses; +using CheckDrive.Web.Service; +using Newtonsoft.Json; +using System.Text; + +namespace CheckDrive.Web.Stores.MechanicHandovers +{ + public class MechanicHandoverDataStore : IMechanicHandoverDataStore + { + private readonly ApiClient _api; + + public MechanicHandoverDataStore(ApiClient apiClient) + { + _api = apiClient; + } + public async Task GetMechanicHandoversAsync( + int? pageNumber, + string? searchString, + DateTime? date, + int? roleId) + { + StringBuilder query = new(""); + + if (roleId != 0) + query.Append($"roleId={roleId}&"); + + if (date is not null) + query.Append($"date={date.Value.ToString("MM/dd/yyyy")}&"); + + if (!string.IsNullOrWhiteSpace(searchString)) + query.Append($"searchString={searchString}&"); + + if (pageNumber != null) + query.Append($"pageNumber={pageNumber}"); + + var response = await _api.GetAsync("mechanics/handovers?OrderBy=datedesc&" + query.ToString()); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Could not fetch handovers."); + } + + var json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + var result = JsonConvert.DeserializeObject(json); + + return result; + } + public async Task GetMechanicHandoversAsync() + { + var response = await _api.GetAsync("mechanics/handovers?OrderBy=datedesc"); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Could not fetch handovers."); + } + + var json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + var result = JsonConvert.DeserializeObject(json); + + return result; + } + public async Task CreateMechanicHandoverAsync(MechanicHandoverForCreateDto mechanicHandoverForCreateDto) + { + var json = JsonConvert.SerializeObject(mechanicHandoverForCreateDto); + var response = await _api.PostAsync("mechanics/handover", json); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Error creating mechanicAcceptance."); + } + + var jsonResponse = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + + return JsonConvert.DeserializeObject(jsonResponse); + } + + public Task DeleteMechanicHandoverAsync(int id) + { + throw new NotImplementedException(); + } + + public Task GetMechanicHandoverAsync(int id) + { + throw new NotImplementedException(); + } + public Task UpdateMechanicHandoverAsync(int id, MechanicHandoverForUpdateDto mechanicHandover) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/Mechanics/IMechanicDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/Mechanics/IMechanicDataStore.cs new file mode 100644 index 00000000..553c5f21 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/Mechanics/IMechanicDataStore.cs @@ -0,0 +1,15 @@ +using CheckDrive.Web.Models; +using CheckDrive.Web.Responses; + +namespace CheckDrive.Web.Stores.Mechanics +{ + public interface IMechanicDataStore + { + Task GetMechanics(int accountId); + Task GetMechanicsAsync(); + Task GetMechanicAsync(int id); + Task CreateMechanicAsync(Mechanic mechanic); + Task UpdateMechanicAsync(int id, Mechanic mechanic); + Task DeleteMechanicAsync(int id); + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/Mechanics/MechanicDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/Mechanics/MechanicDataStore.cs new file mode 100644 index 00000000..9512c0b3 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/Mechanics/MechanicDataStore.cs @@ -0,0 +1,73 @@ +using CheckDrive.Web.Models; +using CheckDrive.Web.Responses; +using CheckDrive.Web.Service; +using Newtonsoft.Json; +using System.Text; + +namespace CheckDrive.Web.Stores.Mechanics +{ + public class MechanicDataStore : IMechanicDataStore + { + private readonly ApiClient _api; + + public MechanicDataStore(ApiClient apiClient) + { + _api = apiClient; + } + + public async Task GetMechanics(int accountId) + { + StringBuilder query = new(""); + + if (!accountId.Equals(0)) + { + query.Append($"accountId={accountId}"); + } + + var response = await _api.GetAsync("mechanics?" + query.ToString()); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Could not fetch mechanics."); + } + + var json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + var result = JsonConvert.DeserializeObject(json); + + return result; + } + public async Task GetMechanicsAsync() + { + var response = await _api.GetAsync("mechanics"); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Could not fetch drivers."); + } + + var json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + var result = JsonConvert.DeserializeObject(json); + + return result; + } + public Task CreateMechanicAsync(Mechanic mechanic) + { + throw new NotImplementedException(); + } + + public Task DeleteMechanicAsync(int id) + { + throw new NotImplementedException(); + } + + public Task GetMechanicAsync(int id) + { + throw new NotImplementedException(); + } + + public Task UpdateMechanicAsync(int id, Mechanic mechanic) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/OperatorReviews/IOperatorReviewDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/OperatorReviews/IOperatorReviewDataStore.cs new file mode 100644 index 00000000..3d9ba999 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/OperatorReviews/IOperatorReviewDataStore.cs @@ -0,0 +1,15 @@ +using CheckDrive.ApiContracts.OperatorReview; +using CheckDrive.Web.Models; +using CheckDrive.Web.Responses; + +namespace CheckDrive.Web.Stores.OperatorReviews +{ + public interface IOperatorReviewDataStore + { + Task GetOperatorReviews(int? pageNumber, string? searchString, DateTime? date, int? roleId); + Task GetOperatorReview(int id); + Task CreateOperatorReview(OperatorReviewForCreateDto review); + Task UpdateOperatorReview(int id, OperatorReview operatorReview); + Task DeleteOperatorReview(int id); + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/OperatorReviews/OperatorReviewDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/OperatorReviews/OperatorReviewDataStore.cs new file mode 100644 index 00000000..16b8456b --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/OperatorReviews/OperatorReviewDataStore.cs @@ -0,0 +1,87 @@ +using CheckDrive.ApiContracts.OperatorReview; +using CheckDrive.Web.Models; +using CheckDrive.Web.Responses; +using CheckDrive.Web.Service; +using Newtonsoft.Json; +using System.Text; + +namespace CheckDrive.Web.Stores.OperatorReviews +{ + public class OperatorReviewDataStore(ApiClient api) : IOperatorReviewDataStore + { + private readonly ApiClient _api = api; + + public async Task GetOperatorReviews( + int? pageNumber, + string? searchString, + DateTime? date, + int? roleId) + { + StringBuilder query = new(""); + + if (roleId != 0) + query.Append($"roleId={roleId}&"); + + if (date is not null) + query.Append($"date={date.Value.ToString("MM/dd/yyyy")}&"); + + if (!string.IsNullOrWhiteSpace(searchString)) + query.Append($"searchString={searchString}&"); + + if (pageNumber != null) + query.Append($"pageNumber={pageNumber}"); + + var response = await _api.GetAsync("operators/reviews?OrderBy=datedesc&" + query.ToString()); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Could not fetch operatorReviews."); + } + + var json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + var result = JsonConvert.DeserializeObject(json); + + return result; + } + + public async Task GetOperatorReview(int id) + { + var response = await _api.GetAsync($"operators/review/{id}"); + + if (!response.IsSuccessStatusCode) + { + throw new Exception($"Could not fetch operatorReview with id: {id}."); + } + + var json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + var result = JsonConvert.DeserializeObject(json); + + return result; + } + + public async Task CreateOperatorReview(OperatorReviewForCreateDto review) + { + var json = JsonConvert.SerializeObject(review); + var response = await _api.PostAsync("operators/review", json); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Error creating operatorReviews."); + } + + var jsonResponse = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + + return JsonConvert.DeserializeObject(jsonResponse); + } + + public Task DeleteOperatorReview(int id) + { + throw new NotImplementedException(); + } + + public Task UpdateOperatorReview(int id, OperatorReview operatorReview) + { + throw new NotImplementedException(); + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/Operators/IOperatorDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/Operators/IOperatorDataStore.cs new file mode 100644 index 00000000..f4d0df0c --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/Operators/IOperatorDataStore.cs @@ -0,0 +1,16 @@ +using CheckDrive.Web.Models; +using CheckDrive.Web.Responses; + +namespace CheckDrive.Web.Stores.Operators +{ + public interface IOperatorDataStore + { + Task GetOperators(int accountId); + Task GetOperators(); + Task GetOperator(int id); + Task CreateOperator(Operator @operator); + Task UpdateOperator(int id, Operator @operator); + Task DeleteOperator(int id); + } +} + \ No newline at end of file diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/Operators/OperatorDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/Operators/OperatorDataStore.cs new file mode 100644 index 00000000..a27a30aa --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/Operators/OperatorDataStore.cs @@ -0,0 +1,70 @@ +using CheckDrive.Web.Models; +using CheckDrive.Web.Responses; +using CheckDrive.Web.Service; +using Newtonsoft.Json; +using System.Text; + +namespace CheckDrive.Web.Stores.Operators +{ + public class OperatorDataStore(ApiClient apiClient) : IOperatorDataStore + { + private readonly ApiClient _api = apiClient; + + public async Task GetOperators() + { + var response = await _api.GetAsync("operators?"); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Could not fetch drivers."); + } + + var json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + var result = JsonConvert.DeserializeObject(json); + + return result; + } + + public async Task GetOperators(int accountId) + { + StringBuilder query = new(""); + + if (!accountId.Equals(0)) + { + query.Append($"accountId={accountId}"); + } + + var response = await _api.GetAsync("operators?" + query.ToString()); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Could not fetch operators."); + } + + var json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + var result = JsonConvert.DeserializeObject(json); + + return result; + } + + public Task GetOperator(int id) + { + throw new NotImplementedException(); + } + + public Task CreateOperator(Operator @operator) + { + throw new NotImplementedException(); + } + + public Task DeleteOperator(int id) + { + throw new NotImplementedException(); + } + + public Task UpdateOperator(int id, Operator @operator) + { + throw new NotImplementedException(); + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/Roles/IRoleDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/Roles/IRoleDataStore.cs new file mode 100644 index 00000000..327ddbf2 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/Roles/IRoleDataStore.cs @@ -0,0 +1,16 @@ +using CheckDrive.ApiContracts.Role; +using CheckDrive.Web.Responses; + +namespace CheckDrive.Web.Stores.Roles +{ + public interface IRoleDataStore + { + Task GetRoles(); + Task GetRole(int id); + Task CreateRole(RoleForCreateDto role); + Task UpdateRole(int id, RoleForUpdateDto role); + Task DeleteRole(int id); + Task CreateRole(DTOs.Role.RoleForCreateDto role); + Task UpdateRole(int id, RoleForCreateDto role); + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/Roles/RoleDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/Roles/RoleDataStore.cs new file mode 100644 index 00000000..beb56a2f --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/Roles/RoleDataStore.cs @@ -0,0 +1,104 @@ +using CheckDrive.ApiContracts.Role; +using CheckDrive.Web.Models; +using CheckDrive.Web.Responses; +using CheckDrive.Web.Service; +using Newtonsoft.Json; + +namespace CheckDrive.Web.Stores.Roles +{ + public class RoleDataStore : IRoleDataStore + { + private readonly ApiClient _api; + + public RoleDataStore(ApiClient apiClient) + { + _api = apiClient; + } + + public async Task GetRoles() + { + var response = await _api.GetAsync("roles"); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Could not fetch roles."); + } + + var json = await response.Content.ReadAsStringAsync(); + var result = JsonConvert.DeserializeObject(json); + + return result; + } + + public async Task GetRole(int id) + { + var response = await _api.GetAsync($"roles/{id}"); + + if (!response.IsSuccessStatusCode) + { + throw new Exception($"Could not fetch roles with id: {id}."); + } + + var json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + var result = JsonConvert.DeserializeObject(json); + + return result; + } + + public async Task CreateRole(RoleForCreateDto role) + { + var json = JsonConvert.SerializeObject(role); + var response = await _api.PostAsync("roles", json); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Error creating roles."); + } + + var jsonResponse = await response.Content.ReadAsStringAsync(); + + return JsonConvert.DeserializeObject(jsonResponse); + } + + public async Task UpdateRole(int id, RoleForUpdateDto role) + { + var json = JsonConvert.SerializeObject(role); + var response = await _api.PutAsync($"roles/{role.Id}", json); + + if (!response.IsSuccessStatusCode) + { + throw new Exception("Error updating roles."); + } + + var jsonResponse = await response.Content.ReadAsStringAsync(); + + return JsonConvert.DeserializeObject(jsonResponse); + + } + + public async Task DeleteRole(int id) + { + var response = await _api.DeleteAsync($"roles/{id}"); + + if (!response.IsSuccessStatusCode) + { + throw new Exception($"Could not delete roles with id: {id}."); + } + } + + Task IRoleDataStore.CreateRole(RoleForCreateDto role) + { + throw new NotImplementedException(); + } + + public Task CreateRole(DTOs.Role.RoleForCreateDto role) + { + throw new NotImplementedException(); + } + + public Task UpdateRole(int id, RoleForCreateDto role) + { + throw new NotImplementedException(); + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/Technicians/ITechnicianDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/Technicians/ITechnicianDataStore.cs new file mode 100644 index 00000000..bf9b3c8d --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/Technicians/ITechnicianDataStore.cs @@ -0,0 +1,13 @@ +using CheckDrive.Web.Models; + +namespace CheckDrive.Web.Stores.Technicians +{ + public interface ITechnicianDataStore + { + Task> GetTechnicians(); + Task GetTechnician(int id); + Task CreateTechnician(Technician technician); + Task UpdateTechnician(int id, Technician technician); + Task DeleteTechnician(int id); + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/Technicians/MockTechnicianDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/Technicians/MockTechnicianDataStore.cs new file mode 100644 index 00000000..09add23f --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/Technicians/MockTechnicianDataStore.cs @@ -0,0 +1,60 @@ +using CheckDrive.Web.Models; + +namespace CheckDrive.Web.Stores.Technicians +{ + public class MockTechnicianDataStore : ITechnicianDataStore + { + private readonly List _technician; + + public MockTechnicianDataStore() + { + _technician = new List + { + new Technician{ Id = 1, AccountId = 1 }, + new Technician{ Id = 2, AccountId = 2 }, + }; + } + + public async Task> GetTechnicians() + { + await Task.Delay(100); + return _technician.ToList(); + } + + public async Task GetTechnician(int id) + { + await Task.Delay(100); + return _technician.FirstOrDefault(t => t.Id == id); + } + + public async Task CreateTechnician(Technician technician) + { + await Task.Delay(100); + technician.Id = _technician.Max(t => t.Id) + 1; + _technician.Add(technician); + return technician; + + } + + public async Task UpdateTechnician(int id, Technician technician) + { + await Task.Delay(100); + var exectingTechnician = _technician.FirstOrDefault(t => t.Id == id); + if (exectingTechnician != null) + { + exectingTechnician.AccountId = technician.AccountId; + } + return exectingTechnician; + } + + public async Task DeleteTechnician(int id) + { + await Task.Delay(100); + var exectingTechnician = _technician.FirstOrDefault(t => t.Id == id); + if (exectingTechnician != null) + { + _technician.Remove(exectingTechnician); + } + } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/User/IUserDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/User/IUserDataStore.cs new file mode 100644 index 00000000..b2227664 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/User/IUserDataStore.cs @@ -0,0 +1,10 @@ +using CheckDrive.ApiContracts.Account; +using CheckDrive.Web.ViewModels; + +namespace CheckDrive.Web.Stores.User +{ + public interface IUserDataStore + { + public Task<(bool Success, string Token)> AuthenticateLoginAsync(AccountForLoginDto loginViewModel); + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Stores/User/UserDataStore.cs b/CheckDrive.Web/CheckDrive.Web/Stores/User/UserDataStore.cs new file mode 100644 index 00000000..cbcc9d7f --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Stores/User/UserDataStore.cs @@ -0,0 +1,34 @@ +using CheckDrive.ApiContracts.Account; +using CheckDrive.Web.Service; +using CheckDrive.Web.ViewModels; +using Newtonsoft.Json; +using System.Text; + +namespace CheckDrive.Web.Stores.User; + +public class UserDataStore : IUserDataStore +{ + private readonly ApiClient _apiClient; + public UserDataStore(ApiClient apiClient) + { + _apiClient = apiClient; + } + public async Task<(bool Success, string Token)> AuthenticateLoginAsync(AccountForLoginDto loginViewModel) + { + var json = JsonConvert.SerializeObject(loginViewModel); + var content = new StringContent(json, Encoding.UTF8, "application/json"); + + var response = await _apiClient.PostAsync("login/login", json); + + if (!response.IsSuccessStatusCode) + { + return (false, string.Empty); + } + + var tokenJson = await response.Content.ReadAsStringAsync(); + var token = JsonConvert.DeserializeObject(tokenJson); + + return (true, token); + } +} + diff --git a/CheckDrive.Web/CheckDrive.Web/ViewModels/DashboardViewModel.cs b/CheckDrive.Web/CheckDrive.Web/ViewModels/DashboardViewModel.cs new file mode 100644 index 00000000..5f5e943e --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/ViewModels/DashboardViewModel.cs @@ -0,0 +1,27 @@ +namespace CheckDrive.Web.ViewModels; +public class DashboardViewModel +{ + public SummaryViewModel Summary { get; set; } + public IEnumerable SplineCharts { get; set; } + public IEnumerable EmployeesCountByRoles { get; set; } +} +public class EmployeesCountByRole +{ + public string RoleName { get; set; } + public int CountOfEmployees { get; set; } +} +public class SummaryViewModel +{ + public int CarsCount { get; set; } + public int DriversCount { get; set; } + public double MonthlyFuelConsumption { get; set; } +} +public class SpliteChartData +{ + public string Month { get; set; } + public decimal Ai80 { get; set; } + public decimal Ai91 { get; set; } + public decimal Ai92 { get; set; } + public decimal Ai95 { get; set; } +} + diff --git a/CheckDrive.Web/CheckDrive.Web/ViewModels/LoginViewModel.cs b/CheckDrive.Web/CheckDrive.Web/ViewModels/LoginViewModel.cs new file mode 100644 index 00000000..218df2ed --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/ViewModels/LoginViewModel.cs @@ -0,0 +1,13 @@ +using System.ComponentModel.DataAnnotations; + +namespace CheckDrive.Web.ViewModels +{ + public class LoginViewModel + { + [Required(ErrorMessage = "This field is required")] + public string Login { get; set; } + + [Required(ErrorMessage = "This field is required")] + public string Password { get; set; } + } +} diff --git a/CheckDrive.Web/CheckDrive.Web/Views/Accounts/Create.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/Accounts/Create.cshtml new file mode 100644 index 00000000..91b50648 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/Accounts/Create.cshtml @@ -0,0 +1,60 @@ +@model CheckDrive.ApiContracts.Account.AccountForCreateDto + +@{ + ViewData["Title"] = "Create"; + Layout = "~/Views/Shared/_Layout.cshtml"; +} + +

Ishchi ma`lumotini yaratish

+
+
+
+
+
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + +
+
+ + + Orqaga + + +
+
+
+
+ diff --git a/CheckDrive.Web/CheckDrive.Web/Views/Accounts/Delete.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/Accounts/Delete.cshtml new file mode 100644 index 00000000..cefb394c --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/Accounts/Delete.cshtml @@ -0,0 +1,79 @@ +@model CheckDrive.ApiContracts.Account.AccountDto + +@{ + ViewData["Title"] = "Delete"; + Layout = "~/Views/Shared/_Layout.cshtml"; +} + +

O'chirish

+
+ +

Haqiqatan ham buni oʻchirib tashlamoqchimisiz? + O'chirsangiz bu shaxs ishtirok etgan barcha ma'lumotlar ham o'chiriladi!!! +

+
+
+
+
+ Id: +
+
+ @Html.DisplayFor(model => model.Id) +
+
+ Ism: +
+
+ @Html.DisplayFor(model => model.FirstName) +
+
+ Familiya: +
+
+ @Html.DisplayFor(model => model.LastName) +
+
+ Tug'ilgan kun: +
+
+ @(Model.Bithdate.ToString("yyyy-MM-dd")) +
+
+ Telefon raqam: +
+
+ @Html.DisplayFor(model => model.PhoneNumber) +
+
+ Electron pochta: +
+
+ @Html.DisplayFor(model => model.Login) +
+
+ Parol: +
+
+ @Html.DisplayFor(model => model.Password) +
+
+ Kasb: +
+
+ @Html.DisplayFor(model => model.RoleName) +
+
+ +
+
+ + + Orqaga + + +
+
+
diff --git a/CheckDrive.Web/CheckDrive.Web/Views/Accounts/Details.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/Accounts/Details.cshtml new file mode 100644 index 00000000..37dd079b --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/Accounts/Details.cshtml @@ -0,0 +1,68 @@ +@model CheckDrive.ApiContracts.Account.AccountDto + +@{ + ViewData["Title"] = "Details"; + Layout = "~/Views/Shared/_Layout.cshtml"; +} +
+

Ishchi ma'lumoti

+
+
+
+ Ism: +
+
+ @Html.DisplayFor(model => model.FirstName) +
+
+ Familiya: +
+
+ @Html.DisplayFor(model => model.LastName) +
+
+ Tug'ilgan kun: +
+
+ @(Model.Bithdate.ToString("yyyy-MM-dd")) +
+
+ Telefon raqam: +
+
+ @Html.DisplayFor(model => model.PhoneNumber) +
+
+ Electron pochta: +
+
+ @Html.DisplayFor(model => model.Login) +
+
+ Parol: +
+
+ @Html.DisplayFor(model => model.Password) +
+
+ Kasb: +
+
+ @Html.DisplayFor(model => model.RoleName) +
+
+
+ diff --git a/CheckDrive.Web/CheckDrive.Web/Views/Accounts/Edit.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/Accounts/Edit.cshtml new file mode 100644 index 00000000..a1a14103 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/Accounts/Edit.cshtml @@ -0,0 +1,58 @@ +@model CheckDrive.ApiContracts.Account.AccountDto + +@{ + ViewData["Title"] = "Edit"; + Layout = "~/Views/Shared/_Layout.cshtml"; +} + +

Ishchi ma`lumoti

+
+
+
+
+
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+ +
+ + + Orqaga + + +
+
+
+
+ + diff --git a/CheckDrive.Web/CheckDrive.Web/Views/Accounts/Index.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/Accounts/Index.cshtml new file mode 100644 index 00000000..805c2724 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/Accounts/Index.cshtml @@ -0,0 +1,103 @@ +@model CheckDrive.ApiContracts.Account.AccountDto + +@{ + ViewData["Title"] = "Index"; + Layout = "~/Views/Shared/_Layout.cshtml"; +} +

Ishchilar

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

@ViewBag.PageCount sahifadan @ViewBag.CurrentPage tasi ( umumiy ishchilar soni: @ViewBag.TotalCount)

+
+
+ + \ No newline at end of file diff --git a/CheckDrive.Web/CheckDrive.Web/Views/Auth/Index.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/Auth/Index.cshtml new file mode 100644 index 00000000..89628a03 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/Auth/Index.cshtml @@ -0,0 +1,155 @@ +@model CheckDrive.ApiContracts.Account.AccountForLoginDto + +@{ + ViewData["Title"] = "Index"; + Layout = "~/Views/Shared/_LoginLayout.cshtml"; +} + + + + + + + We are The Lotus Team + + + + + + + + + + + +
+ +

Akkauntingizni kiriting

+
+
+ + @Html.ValidationMessageFor(model => model.Login, "", new { @class = "text-danger" }) +
+
+
+ + + + +
+ +
+ +
+
+ + + + \ No newline at end of file diff --git a/CheckDrive.Web/CheckDrive.Web/Views/Cars/Create.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/Cars/Create.cshtml new file mode 100644 index 00000000..8ef9ec11 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/Cars/Create.cshtml @@ -0,0 +1,61 @@ +@model CheckDrive.ApiContracts.Car.CarForCreateDto + +@{ + ViewData["Title"] = "Create"; + Layout = "~/Views/Shared/_Layout.cshtml"; +} + +

Yangi moshina yaratish oynasi

+
+
+
+
+
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + Back + + +
+
+
+
+ diff --git a/CheckDrive.Web/CheckDrive.Web/Views/Cars/Delete.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/Cars/Delete.cshtml new file mode 100644 index 00000000..77885ba8 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/Cars/Delete.cshtml @@ -0,0 +1,81 @@ +@model CheckDrive.ApiContracts.Car.CarDto + +@{ + ViewData["Title"] = "Delete"; + Layout = "~/Views/Shared/_Layout.cshtml"; +} + +

O'chirish

+
+ +

+ Haqiqatan ham buni oʻchirib tashlamoqchimisiz? + O'chirsangiz bu mashina ishtirok etgan barcha ma'lumotlar ham o'chiriladi!!! +

+
+
+
+
+ ID: +
+
+ @Html.DisplayFor(model => model.Id) +
+
+ Model: +
+
+ @Html.DisplayFor(model => model.Model) +
+
+ Rangi: +
+
+ @Html.DisplayFor(model => model.Color) +
+
+ Davlat raqami: +
+
+ @Html.DisplayFor(model => model.Number) +
+
+ Avtomobildagi yoqilg'i hajmi: +
+
+ @Html.DisplayFor(model => model.RemainingFuel) +
+
+ O'rtacha yoqilg'i sarfi: +
+
+ @Html.DisplayFor(model => model.MeduimFuelConsumption) +
+
+ Yoqilg'i baki sig'imi: +
+
+ @Html.DisplayFor(model => model.FuelTankCapacity) +
+
+ Ishlab chiqarilgan yili: +
+
+ @Html.DisplayFor(model => model.ManufacturedYear) +
+
+ +
+
+ + + Orqaga + + +
+
+
+ diff --git a/CheckDrive.Web/CheckDrive.Web/Views/Cars/Details.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/Cars/Details.cshtml new file mode 100644 index 00000000..a5c84528 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/Cars/Details.cshtml @@ -0,0 +1,76 @@ +@model CheckDrive.ApiContracts.Car.CarDto + +@{ + ViewData["Title"] = "Details"; + Layout = "~/Views/Shared/_Layout.cshtml"; +} + +
+

Moshina haqida ma'lumot

+
+
+
+ ID: +
+
+ @Html.DisplayFor(model => model.Id) +
+
+ Model: +
+
+ @Html.DisplayFor(model => model.Model) +
+
+ Rangi: +
+
+ @Html.DisplayFor(model => model.Color) +
+
+ Davlat raqami: +
+
+ @Html.DisplayFor(model => model.Number) +
+
+ Avtomobildagi yoqilg'i hajmi: +
+
+ @Html.DisplayFor(model => model.RemainingFuel) +
+
+ O'rtacha yoqilg'i sarfi: +
+
+ @Html.DisplayFor(model => model.MeduimFuelConsumption) +
+
+ Yoqilg'i baki sig'imi: +
+
+ @Html.DisplayFor(model => model.FuelTankCapacity) +
+
+ Ishlab chiqarilgan yili: +
+
+ @Html.DisplayFor(model => model.ManufacturedYear) +
+
+
+ + diff --git a/CheckDrive.Web/CheckDrive.Web/Views/Cars/Edit.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/Cars/Edit.cshtml new file mode 100644 index 00000000..b667cf32 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/Cars/Edit.cshtml @@ -0,0 +1,62 @@ +@model CheckDrive.ApiContracts.Car.CarDto + +@{ + ViewData["Title"] = "Edit"; + Layout = "~/Views/Shared/_Layout.cshtml"; +} + +

Moshina ma`lumotini o`zgartirish

+
+
+
+
+
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ Yoqilg'i baki sig'imi + + +
+
+ + + +
+
+ + + Orqaga + + +
+
+
+
+ + diff --git a/CheckDrive.Web/CheckDrive.Web/Views/Cars/Index.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/Cars/Index.cshtml new file mode 100644 index 00000000..88cb51ff --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/Cars/Index.cshtml @@ -0,0 +1,95 @@ +@model CheckDrive.ApiContracts.Car.CarDto + +@{ + ViewData["Title"] = "Index"; + Layout = "~/Views/Shared/_Layout.cshtml"; +} +

Avtomobillar

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

@ViewBag.PageCount sahifadan @ViewBag.CurrentPage tasi ( umumiy mashinalar soni: @ViewBag.TotalCount)

+
+
+ + \ No newline at end of file diff --git a/CheckDrive.Web/CheckDrive.Web/Views/Dashboard/Index.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/Dashboard/Index.cshtml new file mode 100644 index 00000000..25f71c2d --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/Dashboard/Index.cshtml @@ -0,0 +1,103 @@ +@* + For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 +*@ +@{ +} + +
+
+
+
+ +
+
+ Avtomobillar soni: +

@ViewBag.CarsCount

+
+
+
+ +
+
+
+ +
+
+ Haydovchilar soni: +

@ViewBag.DriversCount

+
+
+
+ +
+
+
+ +
+
+ Umumiy yoqilg'i sarfi (Oylik) +

@ViewBag.MonthlyFuelConsumption

+
+
+
+
+ +
+
+
+
+
Kasblar bo'yicha ishchilar soni:
+
+ + + + + + + + + + + +
+
+
+
+
+
Yoqilg'i sarfi
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+
+
\ No newline at end of file diff --git a/CheckDrive.Web/CheckDrive.Web/Views/DispatcherReviews/Create.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/DispatcherReviews/Create.cshtml new file mode 100644 index 00000000..ce8dacb3 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/DispatcherReviews/Create.cshtml @@ -0,0 +1,102 @@ +@model CheckDrive.ApiContracts.DispatcherReview.DispatcherReviewForCreateDto + +@{ + ViewData["Title"] = "Create"; + Layout = "~/Views/Shared/_PersonalLayout.cshtml"; +} + +
+
+

Ro'yxatga olish

+
+
+
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + Orqaga + + +
+
+
+
+ +@section Scripts { + +} diff --git a/CheckDrive.Web/CheckDrive.Web/Views/DispatcherReviews/Index.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/DispatcherReviews/Index.cshtml new file mode 100644 index 00000000..935a2189 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/DispatcherReviews/Index.cshtml @@ -0,0 +1,84 @@ +@model IEnumerable + +@{ + ViewData["Title"] = "Index"; + Layout = "~/Views/Shared/_Layout.cshtml"; +} + +

Dispetcher

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

@ViewBag.PageCount sahifadan @ViewBag.CurrentPage tasi ( umumiy dispetcherlar amallari soni: @ViewBag.TotalCount)

+
+
\ No newline at end of file diff --git a/CheckDrive.Web/CheckDrive.Web/Views/DispatcherReviews/PersonalIndex.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/DispatcherReviews/PersonalIndex.cshtml new file mode 100644 index 00000000..eaeda49e --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/DispatcherReviews/PersonalIndex.cshtml @@ -0,0 +1,175 @@ +@model IEnumerable + + +@{ + ViewData["Title"] = "PersonalIndex"; + Layout = "~/Views/Shared/_PersonalLayout.cshtml"; +} +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + @foreach (var review in Model) + { + + + + + + + + + + + + + + } + +
Haydovchi F.I.MoshinaO`rtacha Yoqilg`iMasofaBoshlang`ichYakuniySarfQuyilgan yoqilg`iOperator F.I.Mexanik F.I.Sana
@review.DriverName@review.CarName@review.CarMeduimFuelConsumption + @if (!string.IsNullOrEmpty(review.DispatcherName)) + { + @review.DistanceCovered; + } + else + { + + @review.DistanceCovered + + } + @review.InitialDistance@review.FinalDistance + @if (!string.IsNullOrEmpty(review.DispatcherName)) + { + @review.FuelSpended; + } + else + { + + @review.FuelSpended + + } + @review.PouredFuel@review.OperatorName@review.MechanicName@review.Date
+
+ +
+

@ViewBag.PageCount sahifadan @ViewBag.CurrentPage tasi ( umumiy ishchilar soni: @ViewBag.TotalCount)

+
+
+
+
+ + diff --git a/CheckDrive.Web/CheckDrive.Web/Views/DoctorReviews/Create.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/DoctorReviews/Create.cshtml new file mode 100644 index 00000000..ae95f4eb --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/DoctorReviews/Create.cshtml @@ -0,0 +1,74 @@ +@model CheckDrive.ApiContracts.DoctorReview.DoctorReviewForCreateDto + +@{ + ViewData["Title"] = "Create"; + Layout = "~/Views/Shared/_PersonalLayout.cshtml"; +} + +
+
+

Ro`yxatga olish

+
+
+
+
+ + +
+
+ @if (ViewBag.SelectedDriverId != null && ViewBag.SelectedDriverId != 0) + { + + + } + else + { + @if (ViewBag.Drivers == null || !((IEnumerable)ViewBag.Drivers).Any()) + { + + } + else + { + + } + } +
+ +
+ + +
+
+ + +
+
+ + Back + + +
+
+
+
+ + + \ No newline at end of file diff --git a/CheckDrive.Web/CheckDrive.Web/Views/DoctorReviews/Index.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/DoctorReviews/Index.cshtml new file mode 100644 index 00000000..95a6c5cf --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/DoctorReviews/Index.cshtml @@ -0,0 +1,82 @@ +@model CheckDrive.ApiContracts.DoctorReview.DoctorReviewDto + +@{ + ViewData["Title"] = "Index"; + Layout = "~/Views/Shared/_Layout.cshtml"; +} + +

Shifokor ko'riklari

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

@ViewBag.PageCount sahifadan @ViewBag.CurrentPage tasi ( umumiy doctorlar ko'riklari soni: @ViewBag.TotalCount)

+
+
diff --git a/CheckDrive.Web/CheckDrive.Web/Views/DoctorReviews/PersonalIndex.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/DoctorReviews/PersonalIndex.cshtml new file mode 100644 index 00000000..c692bde0 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/DoctorReviews/PersonalIndex.cshtml @@ -0,0 +1,212 @@ +@model IEnumerable + + +@{ + ViewData["Title"] = "PersonalIndex"; + Layout = "~/Views/Shared/_PersonalLayout.cshtml"; +} +
+
+ +
+
+ +
+
+
+ +
+
+ +
+ +
+
+
+ + +
+ +
+
+
+ + + + + + + + + + + + @foreach (var review in Model) + { + + + + + + + + } + +
Haydovshi F.I.Shifokor F.I.Sog`lig`iIzohSana
+ @if (!string.IsNullOrEmpty(review.DoctorName)) + { + @review.DriverName + } + else + { + @review.DriverName + } + @review.DoctorName + @if (!string.IsNullOrEmpty(review.DoctorName)) + { + @if (review.IsHealthy == true) + { + Healthy + } + else if (review.IsHealthy == false) + { + Sick + } + } + @review.Comments@review.Date
+ +
+ +
+

@ViewBag.PageCount sahifadan @ViewBag.CurrentPage tasi ( umumiy ishchilar soni: @ViewBag.TotalCount)

+
+
+
+
+
+
+
+ + diff --git a/CheckDrive.Web/CheckDrive.Web/Views/Drivers/Index.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/Drivers/Index.cshtml new file mode 100644 index 00000000..ce9e178b --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/Drivers/Index.cshtml @@ -0,0 +1,22 @@ +@model CheckDrive.ApiContracts.Account.AccountDto + +@{ + ViewData["Title"] = "Index"; + Layout = "~/Views/Shared/_Layout.cshtml"; +} + +

Haydovchilar

+ +
+
+ + + + + + + + + +
+
diff --git a/CheckDrive.Web/CheckDrive.Web/Views/MechanicAcceptances/Create.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/MechanicAcceptances/Create.cshtml new file mode 100644 index 00000000..bbc3f3a7 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/MechanicAcceptances/Create.cshtml @@ -0,0 +1,112 @@ +@model CheckDrive.ApiContracts.MechanicAcceptance.MechanicAcceptanceForCreateDto + +@{ + ViewData["Title"] = "Create"; + Layout = "~/Views/Shared/_PersonalLayout.cshtml"; +} + +
+
+

Ro'yxatga olish

+
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+ + +
+
+ + +
+
+ + Orqaga + + +
+
+
+
+@section Scripts { + +} + diff --git a/CheckDrive.Web/CheckDrive.Web/Views/MechanicAcceptances/Index.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/MechanicAcceptances/Index.cshtml new file mode 100644 index 00000000..d3dbf320 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/MechanicAcceptances/Index.cshtml @@ -0,0 +1,94 @@ +@model IEnumerable + +@{ + ViewData["Title"] = "Mechanic Acceptances"; + Layout = "~/Views/Shared/_Layout.cshtml"; +} + +

Mexanik (Qabul qiluvchi)

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

@ViewBag.PageCount sahifadan @ViewBag.CurrentPage tasi ( umumiy mexaniklar qabul qilishlari soni: @ViewBag.TotalCount)

+
+
+ + diff --git a/CheckDrive.Web/CheckDrive.Web/Views/MechanicAcceptances/PersonalIndex.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/MechanicAcceptances/PersonalIndex.cshtml new file mode 100644 index 00000000..c999006a --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/MechanicAcceptances/PersonalIndex.cshtml @@ -0,0 +1,196 @@ +@model IEnumerable + + +@{ + ViewData["Title"] = "Mechanic Acceptances (Personal)"; + Layout = "~/Views/Shared/_PersonalLayout.cshtml"; +} +
+ +
+ +
+
+
+ +
+
+ +
+ +
+
+
+ +
+ +
+ + + + + + + + + + + + + + + @if (Model != null && Model.Any()) + { + foreach (var item in Model) + { + + + + + + + + + + } + } + else + { + + + + } + +
Haydovchi F.IMexanik F.IMashinaQabul qilishQabul qilish masofasiIzohSana
+ @if (!string.IsNullOrEmpty(item.MechanicName)) + { + @item.DriverName + } + else + { + @item.DriverName + } + @item.MechanicName@item.CarName + @if (item.Date != null && item.Date.Value.Date == DateTime.Today) + { + @if ((bool)item.IsAccepted) + { + Qabul qilindi + } + else + { + Rad etildi + } + } + @item.Distance@item.Comments@item.Date?.ToString("dd/MM/yyyy")
+ Maʼlumotlar mavjud emas +
+
+ +
+

@ViewBag.PageCount sahifadan @ViewBag.CurrentPage tasi ( umumiy ishchilar soni: @ViewBag.TotalCount)

+
+
+
+
+
+ + diff --git a/CheckDrive.Web/CheckDrive.Web/Views/MechanicHandovers/Create.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/MechanicHandovers/Create.cshtml new file mode 100644 index 00000000..7ccca104 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/MechanicHandovers/Create.cshtml @@ -0,0 +1,84 @@ +@model CheckDrive.ApiContracts.MechanicHandover.MechanicHandoverForCreateDto + +@{ + ViewData["Title"] = "Create"; + Layout = "~/Views/Shared/_PersonalLayout.cshtml"; +} + +
+
+

Ro'yxatga olish

+
+ +
+
+
+ + +
+
+ + @if (ViewBag.SelectedDriverId != null && ViewBag.SelectedDriverId != 0) + { + + + } + else + { + @if (ViewBag.Drivers == null || !((IEnumerable)ViewBag.Drivers.Items).Any()) + { + + } + else + { + + } + } +
+
+ +
+
+ + @if (ViewBag.Cars == null || !((IEnumerable)ViewBag.Cars.Items).Any()) + { + + } + else + { + + } +
+
+ + +
+ +
+ + +
+
+ + Orqaga + + +
+
+
+
+ +@section Scripts { + +} diff --git a/CheckDrive.Web/CheckDrive.Web/Views/MechanicHandovers/Index.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/MechanicHandovers/Index.cshtml new file mode 100644 index 00000000..f1f728e5 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/MechanicHandovers/Index.cshtml @@ -0,0 +1,89 @@ +@model IEnumerable + +@{ + ViewData["Title"] = "Index"; + Layout = "~/Views/Shared/_Layout.cshtml"; +} + +

Mexanik (Topshiruvchi)

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

@ViewBag.PageCount sahifadan @ViewBag.CurrentPage tasi ( umumiy mexaniklar topshirishlari soni: @ViewBag.TotalCount)

+
+
+ + \ No newline at end of file diff --git a/CheckDrive.Web/CheckDrive.Web/Views/MechanicHandovers/PersonalIndex.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/MechanicHandovers/PersonalIndex.cshtml new file mode 100644 index 00000000..d8658f59 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/MechanicHandovers/PersonalIndex.cshtml @@ -0,0 +1,196 @@ +@model IEnumerable + + +@{ + ViewData["Title"] = "Mechanic Handovers (Personal)"; + Layout = "~/Views/Shared/_PersonalLayout.cshtml"; +} + +
+ +
+ +
+
+
+ +
+
+ +
+ +
+
+
+ +
+ +
+ + + + + + + + + + + + + + @if (Model != null && Model.Any()) + { + foreach (var item in Model) + { + + + + + + + + + + } + } + else + { + + + + } + +
Haydovchi F.IMoshinaMexanik F.ITopshirishBoshlang'ich masofaIzohSana
+ @if (!string.IsNullOrEmpty(item.MechanicName)) + { + @item.DriverName + } + else + { + @item.DriverName + } + @item.CarName@item.MechanicName + @if (!string.IsNullOrEmpty(item.MechanicName)) + { + @if ((bool)item.IsHanded) + { + Topshirildi + } + else + { + Topshirilmadi + } + } + @item.Distance@item.Comments@item.Date
+ Maʼlumotlar mavjud emas +
+
+ +
+

@ViewBag.PageCount sahifadan @ViewBag.CurrentPage tasi ( umumiy ishchilar soni: @ViewBag.TotalCount)

+
+
+
+
+
+ + diff --git a/CheckDrive.Web/CheckDrive.Web/Views/OperatorReviews/Create.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/OperatorReviews/Create.cshtml new file mode 100644 index 00000000..77244845 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/OperatorReviews/Create.cshtml @@ -0,0 +1,130 @@ + @model CheckDrive.ApiContracts.OperatorReview.OperatorReviewForCreateDto + + @{ + ViewData["Title"] = "Create"; + Layout = "~/Views/Shared/_PersonalLayout.cshtml"; + } + +
+
+

Royxatga olish

+
+
+
+ + + + +
+ + +
+ +
+ + +
+ +
+ + +
+ + + +
+ +
+
+ + + +
+
+ + +
+
+ + +
+
+ + Back + + +
+
+
+ + diff --git a/CheckDrive.Web/CheckDrive.Web/Views/OperatorReviews/Index.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/OperatorReviews/Index.cshtml new file mode 100644 index 00000000..22f1fc27 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/OperatorReviews/Index.cshtml @@ -0,0 +1,87 @@ +@model CheckDrive.ApiContracts.OperatorReview.OperatorReviewDto + +@{ + ViewData["Title"] = "Index"; + Layout = "~/Views/Shared/_Layout.cshtml"; +} + +

Operator

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

@ViewBag.PageCount sahifadan @ViewBag.CurrentPage tasi ( umumiy operatorlar amallari soni: @ViewBag.TotalCount)

+
+
+ + \ No newline at end of file diff --git a/CheckDrive.Web/CheckDrive.Web/Views/OperatorReviews/PersonalIndex.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/OperatorReviews/PersonalIndex.cshtml new file mode 100644 index 00000000..ab509f67 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/OperatorReviews/PersonalIndex.cshtml @@ -0,0 +1,223 @@ +@model IEnumerable + + +@{ + ViewData["Title"] = "PersonalIndex"; + Layout = "~/Views/Shared/_PersonalLayout.cshtml"; +} +
+
+ +
+
+ +
+
+
+ +
+
+ +
+ +
+
+
+ + +
+ +
+
+
+ + + + + + + + + + + + + + + + + + @foreach (var review in Model) + { + + + + + + + + + + + + + + } + +
Haydovshi F.I.Operator F.I.Moshina markasiMoshina raqamiYoqilg`i sig`imiYoqilg`i qoldig`iQuyilgan yoqilg`i miqdoriYoqilg`i MarkasiYoqilg`i berildimi?IzohStatus
+ @if (!string.IsNullOrEmpty(review.OperatorName)) + { + @review.DriverName + } + else + { + @review.DriverName + } + @review.OperatorName@review.CarModel@review.CarNumber@review.CarOilCapacity@review.CarOilRemainig@review.OilAmount@review.OilMarks + @if (review.IsGiven == true) + { + Berildi + } + else if (review.IsGiven == false) + { + Berilmadi + } + else + { + + } + @review.Comments@review.Status
+
+ +
+

@ViewBag.PageCount sahifadan @ViewBag.CurrentPage tasi ( umumiy ishchilar soni: @ViewBag.TotalCount)

+
+
+
+
+
+
+
+ + diff --git a/CheckDrive.Web/CheckDrive.Web/Views/Shared/Error.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/Shared/Error.cshtml index a1e04783..b9d3e853 100644 --- a/CheckDrive.Web/CheckDrive.Web/Views/Shared/Error.cshtml +++ b/CheckDrive.Web/CheckDrive.Web/Views/Shared/Error.cshtml @@ -1,7 +1,4 @@ -@model ErrorViewModel -@{ - ViewData["Title"] = "Error"; -} +

Error.

An error occurred while processing your request.

diff --git a/CheckDrive.Web/CheckDrive.Web/Views/Shared/_CarDetailsForMechanicAcceptance.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/Shared/_CarDetailsForMechanicAcceptance.cshtml new file mode 100644 index 00000000..c3822ea9 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/Shared/_CarDetailsForMechanicAcceptance.cshtml @@ -0,0 +1,62 @@ +@model CheckDrive.ApiContracts.Car.CarDto + +@{ + ViewData["Title"] = "Details for Mechanic acceptances"; + Layout = "~/Views/Shared/_Layout.cshtml"; +} + +
+

Moshina haqida ma'lumot

+
+
+
+ ID: +
+
+ @Html.DisplayFor(model => model.Id) +
+
+ Model: +
+
+ @Html.DisplayFor(model => model.Model) +
+
+ Rangi: +
+
+ @Html.DisplayFor(model => model.Color) +
+
+ Davlat raqami: +
+
+ @Html.DisplayFor(model => model.Number) +
+
+ O'rtacha yoqilg'i sarfi: +
+
+ @Html.DisplayFor(model => model.MeduimFuelConsumption) +
+
+ Yoqilg'i baki sig'imi: +
+
+ @Html.DisplayFor(model => model.FuelTankCapacity) +
+
+ Ishlab chiqarilgan yili: +
+
+ @Html.DisplayFor(model => model.ManufacturedYear) +
+
+
+ + \ No newline at end of file diff --git a/CheckDrive.Web/CheckDrive.Web/Views/Shared/_CarDetailsForMechanicHandover.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/Shared/_CarDetailsForMechanicHandover.cshtml new file mode 100644 index 00000000..3046f7bb --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/Shared/_CarDetailsForMechanicHandover.cshtml @@ -0,0 +1,62 @@ +@model CheckDrive.ApiContracts.Car.CarDto + +@{ + ViewData["Title"] = "Details for Mechanic handovers"; + Layout = "~/Views/Shared/_Layout.cshtml"; +} + +
+

Moshina haqida ma'lumot

+
+
+
+ ID: +
+
+ @Html.DisplayFor(model => model.Id) +
+
+ Model: +
+
+ @Html.DisplayFor(model => model.Model) +
+
+ Rangi: +
+
+ @Html.DisplayFor(model => model.Color) +
+
+ Davlat raqami: +
+
+ @Html.DisplayFor(model => model.Number) +
+
+ O'rtacha yoqilg'i sarfi: +
+
+ @Html.DisplayFor(model => model.MeduimFuelConsumption) +
+
+ Yoqilg'i baki sig'imi: +
+
+ @Html.DisplayFor(model => model.FuelTankCapacity) +
+
+ Ishlab chiqarilgan yili: +
+
+ @Html.DisplayFor(model => model.ManufacturedYear) +
+
+
+ + \ No newline at end of file diff --git a/CheckDrive.Web/CheckDrive.Web/Views/Shared/_Layout.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/Shared/_Layout.cshtml index 45c1a664..9c280753 100644 --- a/CheckDrive.Web/CheckDrive.Web/Views/Shared/_Layout.cshtml +++ b/CheckDrive.Web/CheckDrive.Web/Views/Shared/_Layout.cshtml @@ -4,46 +4,54 @@ @ViewData["Title"] - CheckDrive.Web + + + + + + + + + -
- -
-
-
- @RenderBody() -
+
-
-
- © 2024 - CheckDrive.Web - Privacy +
+
+
+
+
+ @RenderBody() +
+
+
-
+ + @await RenderSectionAsync("Scripts", required: false) + diff --git a/CheckDrive.Web/CheckDrive.Web/Views/Shared/_LoginLayout.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/Shared/_LoginLayout.cshtml new file mode 100644 index 00000000..c3b76e08 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/Shared/_LoginLayout.cshtml @@ -0,0 +1,51 @@ + + + + + + + Diyor Market + + + + + + + + + + + + + +
+
+ @RenderBody() +
+
+ + + + + + + @await RenderSectionAsync("Scripts", required: false) + + + diff --git a/CheckDrive.Web/CheckDrive.Web/Views/Shared/_PersonalLayout.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/Shared/_PersonalLayout.cshtml new file mode 100644 index 00000000..b7a9d4a5 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/Shared/_PersonalLayout.cshtml @@ -0,0 +1,27 @@ + + + + + + @ViewData["Title"] - CheckDrive.Web + + + + + + + + + + + + @RenderBody() + + + + + + @await RenderSectionAsync("Scripts", required: false) + + + diff --git a/CheckDrive.Web/CheckDrive.Web/Views/Shared/_SideBar.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/Shared/_SideBar.cshtml new file mode 100644 index 00000000..96c24398 --- /dev/null +++ b/CheckDrive.Web/CheckDrive.Web/Views/Shared/_SideBar.cshtml @@ -0,0 +1,109 @@ +@* + For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 +*@ +@{ + List menuItems = new List(); + + menuItems.Add(new + { + text = "Dashboard", + url = "/dashboard", + iconCss = "fa-solid fa-home", + }); + + menuItems.Add(new + { + text = "Ishchilar", + separator = true, + }); + + menuItems.Add(new + { + text = "Ishchilar", + iconCss = "fas fa-users", + url = "/accounts" + }); + + menuItems.Add(new + { + text = "Avtomobillar", + iconCss = "fas fa-car", + url = "/cars" + }); + + menuItems.Add(new + { + text = "Xizmat ko'rsatish", + separator = true, + }); + menuItems.Add(new + { + text = "Doctor Ko'riklari", + iconCss = "fas fa-user-doctor", + url = "/doctorreviews" + }); + menuItems.Add(new + { + text = "Mexanik(Beruvchi)", + iconCss = "fa-solid fa-user-gear", + url = "/mechanichandovers" + }); + menuItems.Add(new + { + text = "Mexanik(Qabul qiluvchi)", + iconCss = "fa-solid fa-person-chalkboard", + url = "/mechanicacceptances" + }); + menuItems.Add(new + { + text = "Operatorlar", + iconCss = "fa-solid fa-user-doctor", + url = "/OperatorReviews" + }); + menuItems.Add(new + { + text = "Dispetcherlar", + iconCss = "fa-solid fa-person-chalkboard", + url = "/DispatcherReviews" + }); + +} + + + + +
+ +
+ +
+ +
+ +
+
@ViewBag.User
+
+
+ + +
+
+ + \ No newline at end of file diff --git a/CheckDrive.Web/CheckDrive.Web/Views/_ViewImports.cshtml b/CheckDrive.Web/CheckDrive.Web/Views/_ViewImports.cshtml index f09ed6e2..3ddd0cee 100644 --- a/CheckDrive.Web/CheckDrive.Web/Views/_ViewImports.cshtml +++ b/CheckDrive.Web/CheckDrive.Web/Views/_ViewImports.cshtml @@ -1,3 +1,4 @@ @using CheckDrive.Web @using CheckDrive.Web.Models @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers +@addTagHelper *, Syncfusion.EJ2 diff --git a/CheckDrive.Web/CheckDrive.Web/wwwroot/css/site.css b/CheckDrive.Web/CheckDrive.Web/wwwroot/css/site.css index f8d98fcb..b6aaac33 100644 --- a/CheckDrive.Web/CheckDrive.Web/wwwroot/css/site.css +++ b/CheckDrive.Web/CheckDrive.Web/wwwroot/css/site.css @@ -1,22 +1,341 @@ +/* */ html { - font-size: 14px; + font-size: 14px; } @media (min-width: 768px) { - html { - font-size: 16px; - } + html { + font-size: 16px; + } } .btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus { - box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb; + box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb; +} + +.main-content { + margin-left: 290px; + overflow-y: auto; + height: 92vh; } html { - position: relative; - min-height: 100%; + position: relative; + min-height: 100%; } body { - margin-bottom: 60px; -} \ No newline at end of file + overflow-y: auto; +} + +/* BreadCrumb */ +.e-breadcrumb a, .e-breadcrumb a:hover { + text-decoration: none !important; + color: inherit !important; +} + +/* Button */ +.btn:focus, .btn:active { + outline: none !important; + box-shadow: none; +} + +/* Hyperlink */ +.no-a-decoration, .no-a-decoration:hover { + text-decoration: none; + color: inherit; +} + +/* Grid */ +.e-grid { + border: 0; + border-radius: 5px; +} + + .e-grid .e-gridcontent, .e-grid .e-table { + background-color: whitesmoke; + } + + .e-grid .e-gridheader { + border: 5px; + border-top-left-radius: 5px; + border-top-right-radius: 5px; + padding: 10px; + background-color: whitesmoke; + } + + .e-grid .e-gridheader .e-headercell { + background-color: whitesmoke; + } + + .e-grid .e-gridpager { + background-color: whitesmoke; + } + + .e-grid .e-pagercontainer { + border: medium; + background-color: black; + } + + .e-grid .e-content table { + padding: 0px 10px; + } + +.e-pagercontainer .e-icons { + background-color: black; + border: none !important; +} + +.e-pager .e-numericitem { + color: black; + background-color: white; + padding: 15px !important; +} + + .e-pager .e-numericitem:not(.e-currentitem) { + border: none !important; + } + + .e-pager .e-numericitem:hover { + color: black; + } + + .e-pager .e-numericitem.e-currentitem { + color: black; + border: none !important; + background-color: whitesmoke; + } + +.e-pager div.e-icons:not(.e-disable) { + color: black; + cursor: pointer; + font-weight: bold; +} + +/* Logo */ +.logo-wrapper { + height: 70px; + display: flex; + flex-direction: row; + align-items: center; +} + +.app-logo { + padding: 10px 10px; +} + +/* Menu */ +#menu { + width: 100% !important; + background-color: inherit; + overflow: hidden; +} + + #menu .e-menu-item:not(.e-separator) { + height: 50px; + border-radius: 4px; + background-color: whitesmoke; + } + + #menu .e-menu-item { + box-sizing: border-box; + } + + #menu .e-menu-item a { + width: 100%; + color: #484f54; + font-weight: bold; + padding: 7px 5px; + box-sizing: border-box; + } + + #menu .e-anchor-wrap { + display: inline-block; + } + + #menu .e-menu-item .e-anchor-wrap span.e-menu-icon { + color: #292f33; + } + + #menu .e-menu-item.e-separator { + border: none; + margin: 5px 5px; + text-transform: uppercase; + font-weight: bold; + font-size: 13px; + color: purple; + } + + #menu .e-menu-item.e-separator:not(:first-child) { + margin-top: 35px; + } + +/* Navbar */ +nav.navbar { + background-color: rgba(18, 22, 29); +} + + nav.navbar i { + padding: 10px; + border-radius: 50%; + font-size: 1.2rem; + cursor: pointer; + } + + nav.navbar i:hover, nav.navbar img:hover { + cursor: pointer; + background-color: #48545f14; + transform: scale(1.05) translateZ(0px); + } + +nav.navbar { + margin-left: 290px; +} + +/* Profile Pic */ +img.profile-pic { + width: 45px; + height: 45px; + border-radius: 50%; +} + +.profile-wrapper { + display: flex; + flex-direction: row; + align-items: center; + background-color: rgba(72, 84, 95, 0.12); + padding: 16px 20px; + border-radius: 12px; + cursor: pointer; + margin-bottom: 30px; +} + + .profile-wrapper .titles { + line-height: 1; + } + +/* Radio Button Group */ +.e-btn-group.custom-rbt-group { + width: 100%; +} + + .e-btn-group.custom-rbt-group .e-btn { + width: 50%; + } + +.custom-rbt-group label.e-btn { + box-shadow: none !important; + border: 1px solid #fff; + background-color: rgb(34 43 51); + color: #fff; +} + +.e-btn-group.custom-rbt-group input:checked + label.e-btn { + background-color: #fff; + color: #212b36; + border: 1px solid #fff; +} + +/* SideBar */ +#sidebar { + background-color: whitesmoke; + border-right: 1px dashed rgba(75,82,85,0.24); + padding: 10px 20px; + overflow: hidden; +} + + #sidebar .e-menu-wrapper { + width: 100%; + background-color: inherit; + } + +#sidebar-toggler { + padding: 10px; + border-radius: 50%; + font-size: 1.2rem; + cursor: pointer; +} + + #sidebar-toggler:hover { + cursor: pointer; + background-color: #48545f14; + transform: scale(1.05) translateZ(0px); + } + +#sidebar.e-open .e-menu-item:hover { + background-color: #D2D2D2; +} + +#sidebar.e-close { + padding-left: 10px; + padding-right: 10px; +} + + #sidebar.e-close .app-logo { + display: none; + } + + #sidebar.e-close .e-anchor-wrap, #sidebar.e-close .e-menu-item.e-menu-caret-icon { + font-size: 0px; + } + + #sidebar.e-close .profile-wrapper .titles { + display: none !important; + } + + #sidebar.e-open .e-anchor-wrap, + #sidebar.e-close .e-menu-icon, #sidebar.e-open .e-menu-icon { + visibility: visible; + } + +#sidebar.e-open .profile-wrapper .titles, #sidebar.e-open .app-logo { + display: flex; +} + +#sidebar.e-sidebar.e-right.e-close { + visibility: visible; + transform: translateX(0%); +} + +#sidebar.e-open #sidebar-toggler:before { + content: '\f100' +} + +#sidebar.e-close #sidebar-toggler:before { + content: '\f101' +} + +/* Widget */ +.widget { + border-radius: 1rem; + background-color: white; + border: 1px solid #ccc; + margin-top: 10px; +} + + .widget.summary > div:first-child { + background-color: whitesmoke; + padding: 1rem; + border-top-left-radius: 1rem; + border-bottom-left-radius: 1rem; + } + + .widget.summary > div:first-child i { + font-weight: bold; + } + + .widget.total > div:first-child { + color: black; + } + + .widget.sales > div:first-child { + color: black; + } + + .widget.supplies > div:first-child { + color: black; + } + + .widget.chart { + padding: 5px; + } diff --git a/CheckDrive.Web/CheckDrive.Web/wwwroot/images/AI Images.jpg b/CheckDrive.Web/CheckDrive.Web/wwwroot/images/AI Images.jpg new file mode 100644 index 00000000..d42e8012 Binary files /dev/null and b/CheckDrive.Web/CheckDrive.Web/wwwroot/images/AI Images.jpg differ diff --git a/CheckDrive.Web/CheckDrive.Web/wwwroot/images/LogoCheakDrive.png b/CheckDrive.Web/CheckDrive.Web/wwwroot/images/LogoCheakDrive.png new file mode 100644 index 00000000..bcade093 Binary files /dev/null and b/CheckDrive.Web/CheckDrive.Web/wwwroot/images/LogoCheakDrive.png differ