From 9cdfdbe4b29d440ff3218cc0b35343e38099f322 Mon Sep 17 00:00:00 2001 From: Jason Croft Date: Mon, 4 May 2026 23:13:15 -0400 Subject: [PATCH] Commit work --- .../.idea/.gitignore | 15 +++++ .../.idea/encodings.xml | 4 ++ .../.idea/indexLayout.xml | 8 +++ .../.idea.Development Project/.idea/vcs.xml | 6 ++ .../Interview.Web/Contexts/CategoryContext.cs | 35 ++++++++++++ .../Interview.Web/Contexts/ProductContext.cs | 25 +++++++++ .../Controllers/CategoryController.cs | 54 ++++++++++++++++++ .../Controllers/ProductController.cs | 56 +++++++++++++++++-- .../Models/CategoryAttributeModel.cs | 9 +++ .../Interview.Web/Models/CategoryModel.cs | 30 ++++++++++ .../Models/ProductAttributeModel.cs | 9 +++ .../Models/ProductCategoryModel.cs | 8 +++ .../Interview.Web/Models/ProductModel.cs | 44 +++++++++++++++ .../Interview.Web/wwwroot/js/site.js | 3 + 14 files changed, 302 insertions(+), 4 deletions(-) create mode 100644 Development Project/.idea/.idea.Development Project/.idea/.gitignore create mode 100644 Development Project/.idea/.idea.Development Project/.idea/encodings.xml create mode 100644 Development Project/.idea/.idea.Development Project/.idea/indexLayout.xml create mode 100644 Development Project/.idea/.idea.Development Project/.idea/vcs.xml create mode 100644 Development Project/Interview.Web/Contexts/CategoryContext.cs create mode 100644 Development Project/Interview.Web/Contexts/ProductContext.cs create mode 100644 Development Project/Interview.Web/Controllers/CategoryController.cs create mode 100644 Development Project/Interview.Web/Models/CategoryAttributeModel.cs create mode 100644 Development Project/Interview.Web/Models/CategoryModel.cs create mode 100644 Development Project/Interview.Web/Models/ProductAttributeModel.cs create mode 100644 Development Project/Interview.Web/Models/ProductCategoryModel.cs create mode 100644 Development Project/Interview.Web/Models/ProductModel.cs diff --git a/Development Project/.idea/.idea.Development Project/.idea/.gitignore b/Development Project/.idea/.idea.Development Project/.idea/.gitignore new file mode 100644 index 0000000..ca5297b --- /dev/null +++ b/Development Project/.idea/.idea.Development Project/.idea/.gitignore @@ -0,0 +1,15 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/.idea.Development Project.iml +/modules.xml +/contentModel.xml +/projectSettingsUpdater.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/Development Project/.idea/.idea.Development Project/.idea/encodings.xml b/Development Project/.idea/.idea.Development Project/.idea/encodings.xml new file mode 100644 index 0000000..df87cf9 --- /dev/null +++ b/Development Project/.idea/.idea.Development Project/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Development Project/.idea/.idea.Development Project/.idea/indexLayout.xml b/Development Project/.idea/.idea.Development Project/.idea/indexLayout.xml new file mode 100644 index 0000000..7b08163 --- /dev/null +++ b/Development Project/.idea/.idea.Development Project/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/Development Project/.idea/.idea.Development Project/.idea/vcs.xml b/Development Project/.idea/.idea.Development Project/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/Development Project/.idea/.idea.Development Project/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Development Project/Interview.Web/Contexts/CategoryContext.cs b/Development Project/Interview.Web/Contexts/CategoryContext.cs new file mode 100644 index 0000000..68e8374 --- /dev/null +++ b/Development Project/Interview.Web/Contexts/CategoryContext.cs @@ -0,0 +1,35 @@ +using Interview.Web.Models; +using System.Collections.Generic; + +namespace Interview.Web.Contexts; + +#region DTOs + +public class CreateCategoryDto +{ + public string Description { get; set; } + public string Name { get; set; } +} + +#endregion + +public class CategoryContext +{ + public static CategoryModel CreateCategory(CreateCategoryDto category) + { + var sql = @"INSERT INTO Categories + ([Description], [Name]) + VALUES + (@Description, @Name) + "; + // TODO: Exectue SQL ~ var newCat = ... + return new CategoryModel(); + } + + public static List GetCategories() + { + var sql = "SELECT * FROM Categories"; + // TODO: Execute SQL ~ var categories = ... + return new List(); + } +} \ No newline at end of file diff --git a/Development Project/Interview.Web/Contexts/ProductContext.cs b/Development Project/Interview.Web/Contexts/ProductContext.cs new file mode 100644 index 0000000..83f80e0 --- /dev/null +++ b/Development Project/Interview.Web/Contexts/ProductContext.cs @@ -0,0 +1,25 @@ +using Interview.Web.Models; +using System.Collections.Generic; + +namespace Interview.Web.Contexts; + +public class ProductContext +{ + public static ProductModel CreateProduct(CreateProductDto product) + { + var sql = @"INSERT INTO Products + ([Description], [Name], ProductImageUris, ValidSkus) + VALUES + (@Description, @Name, @ProductImageUris, @ValidSkus) + "; + // TODO: Execute SQL ~ var newProd = ... + return new ProductModel(); + } + + public static List GetAllProducts() + { + var sql = "SELECT * FROM Products"; + // TODO: Execute SQL ~ var products = ... + return new List(); + } +} \ No newline at end of file diff --git a/Development Project/Interview.Web/Controllers/CategoryController.cs b/Development Project/Interview.Web/Controllers/CategoryController.cs new file mode 100644 index 0000000..4dbe1a8 --- /dev/null +++ b/Development Project/Interview.Web/Controllers/CategoryController.cs @@ -0,0 +1,54 @@ +using Interview.Web.Contexts; +using Interview.Web.Models; +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Interview.Web.Contexts; +using Microsoft.Extensions.Logging; + +namespace Interview.Web.Controllers +{ + [ApiController] + [Route("api/v1/categories")] + public class CategoryController : ControllerBase + { + private ILogger _logger; + + public CategoryController(ILogger logger) + { + _logger = logger; + } + + [HttpGet] + public ActionResult> GetAllCategories() + { + try + { + var categories = CategoryContext.GetCategories(); + return Ok(categories); + } + catch (Exception ex) + { + _logger.LogError(ex.Message); + return Problem(); + } + } + + [HttpPost] + public ActionResult CreateCategory([FromBody] CreateCategoryDto category) + { + try + { + var newCat = CategoryContext.CreateCategory(category); + return Ok(newCat); + } + catch (Exception ex) + { + _logger.LogError(ex.Message); + return Problem(); + } + } + } +} \ No newline at end of file diff --git a/Development Project/Interview.Web/Controllers/ProductController.cs b/Development Project/Interview.Web/Controllers/ProductController.cs index 267f4ec..1db9ea9 100644 --- a/Development Project/Interview.Web/Controllers/ProductController.cs +++ b/Development Project/Interview.Web/Controllers/ProductController.cs @@ -1,19 +1,67 @@ -using Microsoft.AspNetCore.Mvc; +using Interview.Web.Contexts; +using Interview.Web.Models; +using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Interview.Web.Contexts; +using Microsoft.Extensions.Logging; + +/* + * EVAL: Was not aware that Visual Studio would be a requirement. I am running on Endeavour + * and, as such, do not have access to Visual Studio. Sparcpoint.Inventory.Database + * does not load in Rider. I'm doing my best to extrapolate what I can from the + * *.sqlproj file and associated *.sql files. + * + * ERROR: "$(MSBuildExtensionsPath)/Microsoft/VisualStudio/v$(VisualStudioVersion)/SSDT/Microsoft.Data.Tools.Schema.SqlTasks.targets" + * does not exist and appears to be part of a Visual Studio component. This file may require MSBuild.exe in order to be imported + * successfully, and so may fail to build in the dotnet CLI. + * /home/jcroft/Git/Development-Project-CSharp/Development Project/Sparcpoint.Inventory.Database/Sparcpoint.Inventory.Database.sqlproj at (84:3) + */ namespace Interview.Web.Controllers { + [ApiController] [Route("api/v1/products")] - public class ProductController : Controller + public class ProductController : ControllerBase { + private ILogger _logger; + + public ProductController(ILogger logger) + { + _logger = logger; + } + // NOTE: Sample Action [HttpGet] - public Task GetAllProducts() + public ActionResult> GetAllProducts() + { + try + { + var products = ProductContext.GetAllProducts(); + return Ok(products); + } + catch (Exception e) + { + _logger.LogError(e.Message); + return Problem(); + } + } + + [HttpPost] + public ActionResult CreateProduct([FromBody] CreateProductDto product) { - return Task.FromResult((IActionResult)Ok(new object[] { })); + try + { + var newProd = ProductContext.CreateProduct(product); + return Ok(newProd); + } + catch (Exception e) + { + _logger.LogError(e.Message); + return Problem(); + } } } } diff --git a/Development Project/Interview.Web/Models/CategoryAttributeModel.cs b/Development Project/Interview.Web/Models/CategoryAttributeModel.cs new file mode 100644 index 0000000..1445f46 --- /dev/null +++ b/Development Project/Interview.Web/Models/CategoryAttributeModel.cs @@ -0,0 +1,9 @@ +namespace Interview.Web.Models; + +public class CategoryAttributeModel +{ + // EVAL: I would, personally have named this CategoryInstanceId + public int InstanceId { get; set; } + public string Key { get; set; } + public string Value { get; set; } +} \ No newline at end of file diff --git a/Development Project/Interview.Web/Models/CategoryModel.cs b/Development Project/Interview.Web/Models/CategoryModel.cs new file mode 100644 index 0000000..ace9c50 --- /dev/null +++ b/Development Project/Interview.Web/Models/CategoryModel.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; + +namespace Interview.Web.Models; + +public class CategoryModel +{ + public DateTime CreatedTimestamp { get; set; } + public string Description { get; set; } + public int InstanceId { get; set; } + public string Name { get; set; } + + private List? _products; + + public List? Products + { + get => _products; + } + + public void HydrateProducts() + { + if (_products != null) + { + return; + } + + // EVAL: This will populate the Products property with ProductModel entities via the + // ProductCategories relation. + } +} \ No newline at end of file diff --git a/Development Project/Interview.Web/Models/ProductAttributeModel.cs b/Development Project/Interview.Web/Models/ProductAttributeModel.cs new file mode 100644 index 0000000..5a83308 --- /dev/null +++ b/Development Project/Interview.Web/Models/ProductAttributeModel.cs @@ -0,0 +1,9 @@ +namespace Interview.Web.Models; + +public class ProductAttributeModel +{ + // EVAL: I would have, personally named this ProductInstanceId + public int InstanceId { get; set; } + public string Key { get; set; } + public string Value { get; set; } +} \ No newline at end of file diff --git a/Development Project/Interview.Web/Models/ProductCategoryModel.cs b/Development Project/Interview.Web/Models/ProductCategoryModel.cs new file mode 100644 index 0000000..5ee1c26 --- /dev/null +++ b/Development Project/Interview.Web/Models/ProductCategoryModel.cs @@ -0,0 +1,8 @@ +namespace Interview.Web.Models; + +public class ProductCategoryModel +{ + public int CategoryInstanceId { get; set; } + // EVAL: I would have, personally, named this ProductInstanceId + public int InstanceId { get; set; } +} \ No newline at end of file diff --git a/Development Project/Interview.Web/Models/ProductModel.cs b/Development Project/Interview.Web/Models/ProductModel.cs new file mode 100644 index 0000000..9515f0d --- /dev/null +++ b/Development Project/Interview.Web/Models/ProductModel.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; + +namespace Interview.Web.Models; + +#region DTOs + +public class CreateProductDto +{ + public string Description { get; set; } + public string Name { get; set; } + public string ProductImageUris { get; set; } + public string ValidSkus { get; set; } +} + +#endregion + +public class ProductModel +{ + public DateTime CreatedTimestamp { get; set; } + public string Description { get; set; } + public int InstanceId { get; set; } + public string Name { get; set; } + public string ProductImageUris { get; set; } + public string ValidSkus { get; set; } + + private List? _categories = null; + + public List? Categories + { + get => _categories; + } + + public void HydrateCategories() + { + if (_categories != null) + { + return; + } + + // EVAL: This will populate the Categories property with CategoryModel entities via the + // ProductCategories relation. + } +} \ No newline at end of file diff --git a/Development Project/Interview.Web/wwwroot/js/site.js b/Development Project/Interview.Web/wwwroot/js/site.js index 3c76e6d..ee50256 100644 --- a/Development Project/Interview.Web/wwwroot/js/site.js +++ b/Development Project/Interview.Web/wwwroot/js/site.js @@ -2,3 +2,6 @@ // for details on configuring this project to bundle and minify static web assets. // Write your Javascript code. +window.addEventListener("DOMContentLoaded", () => { + // TODO +}); \ No newline at end of file