-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
implement functionality to add tyres
some things had to change to make this work as expected and unfortunately, it has come at the cost of yet another modal. bootstrap modals don't play well with aspnetcore. since a file is uploaded and validated against, it is done on the server side so the add tyre modal had to be rewriiten as a view
- Loading branch information
1 parent
7b3f628
commit 2ae5c65
Showing
16 changed files
with
272 additions
and
129 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
using System.ComponentModel.DataAnnotations; | ||
using System.ComponentModel.DataAnnotations.Schema; | ||
|
||
namespace SeelansTyres.Data.Models; | ||
|
||
public class CreateTyreModel | ||
{ | ||
[Required] | ||
[MinLength(3)] | ||
[MaxLength(40)] | ||
public string Name { get; set; } = string.Empty; | ||
[Required] | ||
[Range(115, 355)] | ||
public int Width { get; set; } | ||
[Required] | ||
[Range(13, 19)] | ||
public int Ratio { get; set; } | ||
[Required] | ||
[Range(25, 75)] | ||
public int Diameter { get; set; } | ||
[Required] | ||
[MaxLength(40)] | ||
public string VehicleType { get; set; } = string.Empty; | ||
[Required] | ||
[Column(TypeName = "decimal")] | ||
public decimal Price { get; set; } | ||
public bool Available { get; set; } = true; | ||
public string ImageUrl { get; set; } = string.Empty; | ||
[Required] | ||
public int BrandId { get; set; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,34 +1,15 @@ | ||
using System.ComponentModel.DataAnnotations; | ||
using System.ComponentModel.DataAnnotations.Schema; | ||
|
||
namespace SeelansTyres.Data.Models; | ||
namespace SeelansTyres.Data.Models; | ||
|
||
public class TyreModel | ||
{ | ||
[Key] | ||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)] | ||
public int Id { get; set; } | ||
[Required] | ||
[MinLength(3)] | ||
[MaxLength(40)] | ||
public string Name { get; set; } = string.Empty; | ||
[Required] | ||
[Range(115, 335)] | ||
public int Width { get; set; } | ||
[Required] | ||
[Range(13, 19)] | ||
public int Ratio { get; set; } | ||
[Required] | ||
[Range(25, 75)] | ||
public int Diameter { get; set; } | ||
[Required] | ||
[MaxLength(40)] | ||
public string VehicleType { get; set; } = string.Empty; | ||
[Required] | ||
[Column(TypeName = "decimal")] | ||
public decimal Price { get; set; } | ||
public bool Available { get; set; } = true; | ||
public string ImageUrl { get; set; } = string.Empty; | ||
[ForeignKey("BrandId")] | ||
public BrandModel? Brand { get; set; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,87 @@ | ||
using Microsoft.AspNetCore.Authorization; | ||
using Microsoft.AspNetCore.Mvc; | ||
using SeelansTyres.Data.Models; | ||
using SeelansTyres.Mvc.Models; | ||
|
||
namespace SeelansTyres.Mvc.Controllers; | ||
|
||
[Authorize(Roles = "Administrator")] | ||
public class AdminController : Controller | ||
{ | ||
private readonly ILogger<AdminController> logger; | ||
private readonly IHttpClientFactory httpClientFactory; | ||
private readonly IWebHostEnvironment environment; | ||
private readonly HttpClient client; | ||
|
||
public AdminController( | ||
ILogger<AdminController> logger, | ||
IHttpClientFactory httpClientFactory, | ||
IWebHostEnvironment environment) | ||
{ | ||
this.logger = logger; | ||
this.httpClientFactory = httpClientFactory; | ||
this.environment = environment; | ||
client = httpClientFactory.CreateClient("SeelansTyresAPI"); | ||
} | ||
|
||
public IActionResult Index() | ||
{ | ||
return View(); | ||
} | ||
|
||
public IActionResult AddTyre() | ||
{ | ||
return View(); | ||
} | ||
|
||
[HttpPost] | ||
public async Task<IActionResult> AddTyre(AddNewTyreModel model) | ||
{ | ||
if (ModelState.IsValid is false) | ||
{ | ||
return View(model); | ||
} | ||
|
||
// integrate with azure storage later on. | ||
// upload the file to azure storage, get the url | ||
// and set the ImageUrl | ||
|
||
var filePath = "/images/no-image.png"; | ||
|
||
if (model.Image is not null) | ||
{ | ||
var fileName = $"{Guid.NewGuid()}{Path.GetExtension(model.Image.FileName)}"; | ||
|
||
filePath = Path.Combine( | ||
environment.WebRootPath, | ||
"images", | ||
fileName); | ||
|
||
using (var fileStream = new FileStream(filePath, FileMode.Create)) | ||
{ | ||
await model.Image.CopyToAsync(fileStream); | ||
} | ||
|
||
filePath = $"/images/{fileName}"; | ||
} | ||
|
||
var createTyreModel = new CreateTyreModel | ||
{ | ||
Name = model.Name, | ||
Width = model.Width, | ||
Ratio = model.Ratio, | ||
Diameter = model.Diameter, | ||
VehicleType = model.VehicleType, | ||
Price = model.Price, | ||
Available = model.Available, | ||
ImageUrl = filePath, | ||
BrandId = model.BrandId | ||
}; | ||
|
||
var jsonContent = JsonContent.Create(createTyreModel); | ||
|
||
var response = await client.PostAsync("api/tyres", jsonContent); | ||
|
||
return RedirectToAction("Index"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
using System.ComponentModel.DataAnnotations; | ||
using System.ComponentModel.DataAnnotations.Schema; | ||
|
||
namespace SeelansTyres.Mvc.Models; | ||
|
||
public class AddNewTyreModel | ||
{ | ||
[Required] | ||
[MinLength(3)] | ||
[MaxLength(40)] | ||
public string Name { get; set; } = string.Empty; | ||
[Required] | ||
[Range(115, 355)] | ||
public int Width { get; set; } | ||
[Required] | ||
[Range(13, 19)] | ||
public int Ratio { get; set; } | ||
[Required] | ||
[Range(25, 75)] | ||
public int Diameter { get; set; } | ||
[Required] | ||
[MaxLength(40)] | ||
public string VehicleType { get; set; } = string.Empty; | ||
[Required] | ||
[Column(TypeName = "decimal")] | ||
public decimal Price { get; set; } | ||
public bool Available { get; set; } = true; | ||
public IFormFile? Image { get; set; } | ||
[FileExtensions(Extensions = "jpg,jpeg,png")] | ||
public string? ImageFileName => Image is not null ? Image.FileName : null; | ||
[Required] | ||
public int BrandId { get; set; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
@model AddNewTyreModel | ||
|
||
@section Scripts { | ||
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script> | ||
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script> | ||
} | ||
|
||
<h1 class="seelanstyres-color text-center p-5">Admin Portal</h1> | ||
|
||
<div class="col-8 offset-2 col-md-6 offset-md-3 col-xl-4 offset-xl-4"> | ||
<h3>Add Tyre</h3> | ||
<hr /> | ||
<form method="post" enctype="multipart/form-data"> | ||
<div asp-validation-summary="ModelOnly" class="alert alert-danger"></div> | ||
<div class="col-md-12 mb-3"> | ||
<label class="form-label" asp-for="Name">Name</label> | ||
<input type="text" asp-for="Name" class="form-control"> | ||
<span asp-validation-for="Name"></span> | ||
</div> | ||
<div class="col-md-12 mb-3"> | ||
<label class="form-label" asp-for="Width">Width</label> | ||
<select asp-for="Width" class="form-control"> | ||
@for (int i = 115; i <= 355; i += 10) | ||
{ | ||
<option value="@i">@i</option> | ||
} | ||
</select> | ||
<span asp-validation-for="Width"></span> | ||
</div> | ||
<div class="col-md-12 mb-3"> | ||
<label class="form-label" asp-for="Ratio">Ratio</label> | ||
<select asp-for="Ratio" class="form-control"> | ||
@for (int i = 13; i <= 19; i++) | ||
{ | ||
<option value="@i">@i</option> | ||
} | ||
</select> | ||
<span asp-validation-for="Ratio"></span> | ||
</div> | ||
<div class="col-md-12 mb-3"> | ||
<label class="form-label" asp-for="Diameter">Diameter</label> | ||
<select asp-for="Diameter" class="form-control"> | ||
@for (int i = 25; i <= 75; i += 5) | ||
{ | ||
<option value="@i">@i</option> | ||
} | ||
</select> | ||
<span asp-validation-for="Diameter"></span> | ||
</div> | ||
<div class="col-md-12 mb-3"> | ||
<label class="form-label" asp-for="VehicleType">Vehicle Type</label> | ||
<select asp-for="VehicleType" class="form-control"> | ||
<option value="Car">Car</option> | ||
<option value="SUV">SUV</option> | ||
<option value="Van / Light Truck">Van / Light Truck</option> | ||
<option value="Truck / Bus">Truck / Bus</option> | ||
</select> | ||
<span asp-validation-for="VehicleType"></span> | ||
</div> | ||
<div class="col-md-12 mb-3"> | ||
<label class="form-label" asp-for="Price">Price</label> | ||
<div class="input-group"> | ||
<div class="input-group-prepend"> | ||
<span class="input-group-text">R</span> | ||
</div> | ||
<input type="text" asp-for="Price" class="form-control" aria-label="Amount"> | ||
<div class="input-group-append"> | ||
<span class="input-group-text">.00</span> | ||
</div> | ||
</div> | ||
<span asp-validation-for="Price"></span> | ||
</div> | ||
<div class="col-md-12 mb-3"> | ||
<label class="form-label" asp-for="BrandId">Brand</label> | ||
<select asp-for="BrandId" class="form-control"> | ||
<option value="1">BFGoodrich</option> | ||
<option value="2">Continental</option> | ||
<option value="3">Goodyear</option> | ||
<option value="4">Hankook</option> | ||
<option value="5">Michelin</option> | ||
<option value="6">Pirelli</option> | ||
</select> | ||
<span asp-validation-for="BrandId"></span> | ||
</div> | ||
<div class="col-md-12 mb-4"> | ||
<label class="form-label" asp-for="Image">Upload an Image</label> | ||
<div class="input-group"> | ||
<input type="file" class="form-control" asp-for="Image"> | ||
<label class="input-group-text" asp-for="Image">Upload</label> | ||
</div> | ||
<span asp-validation-for="ImageFileName"></span> | ||
</div> | ||
<div class="text-center mb-4"> | ||
<button class="btn btn-dark w-50" type="submit">Add New Tyre</button> | ||
</div> | ||
</form> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.