diff --git a/src/Imprink.Application/Domains/Categories/CreateCategoryHandler.cs b/src/Imprink.Application/Categories/Commands/CreateCategoryHandler.cs similarity index 93% rename from src/Imprink.Application/Domains/Categories/CreateCategoryHandler.cs rename to src/Imprink.Application/Categories/Commands/CreateCategoryHandler.cs index 2b67a75..dfc5a1b 100644 --- a/src/Imprink.Application/Domains/Categories/CreateCategoryHandler.cs +++ b/src/Imprink.Application/Categories/Commands/CreateCategoryHandler.cs @@ -1,8 +1,9 @@ +using Imprink.Application.Categories.Dtos; using Imprink.Application.Products.Dtos; -using Imprink.Domain.Entities.Product; +using Imprink.Domain.Entities.Products; using MediatR; -namespace Imprink.Application.Domains.Categories; +namespace Imprink.Application.Categories.Commands; public class CreateCategoryCommand : IRequest { diff --git a/src/Imprink.Application/Domains/Categories/DeleteCategoryHandler.cs b/src/Imprink.Application/Categories/Commands/DeleteCategoryHandler.cs similarity index 95% rename from src/Imprink.Application/Domains/Categories/DeleteCategoryHandler.cs rename to src/Imprink.Application/Categories/Commands/DeleteCategoryHandler.cs index b3d5850..7220027 100644 --- a/src/Imprink.Application/Domains/Categories/DeleteCategoryHandler.cs +++ b/src/Imprink.Application/Categories/Commands/DeleteCategoryHandler.cs @@ -1,6 +1,6 @@ using MediatR; -namespace Imprink.Application.Domains.Categories; +namespace Imprink.Application.Categories.Commands; public class DeleteCategoryCommand : IRequest { diff --git a/src/Imprink.Application/Domains/Categories/GetCategoriesHandler.cs b/src/Imprink.Application/Categories/Commands/GetCategoriesHandler.cs similarity index 91% rename from src/Imprink.Application/Domains/Categories/GetCategoriesHandler.cs rename to src/Imprink.Application/Categories/Commands/GetCategoriesHandler.cs index a0b13f1..5c4b3e3 100644 --- a/src/Imprink.Application/Domains/Categories/GetCategoriesHandler.cs +++ b/src/Imprink.Application/Categories/Commands/GetCategoriesHandler.cs @@ -1,8 +1,9 @@ +using Imprink.Application.Categories.Dtos; using Imprink.Application.Products.Dtos; -using Imprink.Domain.Entities.Product; +using Imprink.Domain.Entities.Products; using MediatR; -namespace Imprink.Application.Domains.Categories; +namespace Imprink.Application.Categories.Commands; public class GetCategoriesQuery : IRequest> { diff --git a/src/Imprink.Application/Domains/Categories/UpdateCategoryHandler.cs b/src/Imprink.Application/Categories/Commands/UpdateCategoryHandler.cs similarity index 96% rename from src/Imprink.Application/Domains/Categories/UpdateCategoryHandler.cs rename to src/Imprink.Application/Categories/Commands/UpdateCategoryHandler.cs index a10eb1f..c236880 100644 --- a/src/Imprink.Application/Domains/Categories/UpdateCategoryHandler.cs +++ b/src/Imprink.Application/Categories/Commands/UpdateCategoryHandler.cs @@ -1,8 +1,9 @@ +using Imprink.Application.Categories.Dtos; using Imprink.Application.Exceptions; using Imprink.Application.Products.Dtos; using MediatR; -namespace Imprink.Application.Domains.Categories; +namespace Imprink.Application.Categories.Commands; public class UpdateCategoryCommand : IRequest { diff --git a/src/Imprink.Application/Domains/Categories/Dtos/CategoryDto.cs b/src/Imprink.Application/Categories/Dtos/CategoryDto.cs similarity index 89% rename from src/Imprink.Application/Domains/Categories/Dtos/CategoryDto.cs rename to src/Imprink.Application/Categories/Dtos/CategoryDto.cs index fbc701b..64b9e19 100644 --- a/src/Imprink.Application/Domains/Categories/Dtos/CategoryDto.cs +++ b/src/Imprink.Application/Categories/Dtos/CategoryDto.cs @@ -1,4 +1,4 @@ -namespace Imprink.Application.Products.Dtos; +namespace Imprink.Application.Categories.Dtos; public class CategoryDto { diff --git a/src/Imprink.Application/Validation/Categories/CreateCategoryCommandValidator.cs b/src/Imprink.Application/Categories/Validation/CreateCategoryCommandValidator.cs similarity index 91% rename from src/Imprink.Application/Validation/Categories/CreateCategoryCommandValidator.cs rename to src/Imprink.Application/Categories/Validation/CreateCategoryCommandValidator.cs index 6f20535..88e9f22 100644 --- a/src/Imprink.Application/Validation/Categories/CreateCategoryCommandValidator.cs +++ b/src/Imprink.Application/Categories/Validation/CreateCategoryCommandValidator.cs @@ -1,7 +1,7 @@ using FluentValidation; -using Imprink.Application.Domains.Categories; +using Imprink.Application.Categories.Commands; -namespace Imprink.Application.Validation.Categories; +namespace Imprink.Application.Categories.Validation; public class CreateCategoryCommandValidator : AbstractValidator { diff --git a/src/Imprink.Application/Validation/Categories/DeleteCategoryCommandValidator.cs b/src/Imprink.Application/Categories/Validation/DeleteCategoryCommandValidator.cs similarity index 76% rename from src/Imprink.Application/Validation/Categories/DeleteCategoryCommandValidator.cs rename to src/Imprink.Application/Categories/Validation/DeleteCategoryCommandValidator.cs index d1f9cb3..89c8c7e 100644 --- a/src/Imprink.Application/Validation/Categories/DeleteCategoryCommandValidator.cs +++ b/src/Imprink.Application/Categories/Validation/DeleteCategoryCommandValidator.cs @@ -1,7 +1,7 @@ using FluentValidation; -using Imprink.Application.Domains.Categories; +using Imprink.Application.Categories.Commands; -namespace Imprink.Application.Validation.Categories; +namespace Imprink.Application.Categories.Validation; public class DeleteCategoryCommandValidator : AbstractValidator { diff --git a/src/Imprink.Application/Validation/Categories/UpdateCategoryCommandValidator.cs b/src/Imprink.Application/Categories/Validation/UpdateCategoryCommandValidator.cs similarity index 93% rename from src/Imprink.Application/Validation/Categories/UpdateCategoryCommandValidator.cs rename to src/Imprink.Application/Categories/Validation/UpdateCategoryCommandValidator.cs index 7e493bf..dfb0af8 100644 --- a/src/Imprink.Application/Validation/Categories/UpdateCategoryCommandValidator.cs +++ b/src/Imprink.Application/Categories/Validation/UpdateCategoryCommandValidator.cs @@ -1,7 +1,7 @@ using FluentValidation; -using Imprink.Application.Domains.Categories; +using Imprink.Application.Categories.Commands; -namespace Imprink.Application.Validation.Categories; +namespace Imprink.Application.Categories.Validation; public class UpdateCategoryCommandValidator : AbstractValidator { diff --git a/src/Imprink.Application/Domains/ProductVariants/CreateProductVariantHandler.cs b/src/Imprink.Application/Domains/ProductVariants/CreateProductVariantHandler.cs deleted file mode 100644 index 9a6aef9..0000000 --- a/src/Imprink.Application/Domains/ProductVariants/CreateProductVariantHandler.cs +++ /dev/null @@ -1,65 +0,0 @@ -using Imprink.Application.Products.Dtos; -using Imprink.Domain.Entities.Product; -using MediatR; - -namespace Imprink.Application.Domains.ProductVariants; - -public class CreateProductVariantCommand : IRequest -{ - public Guid ProductId { get; set; } - public string Size { get; set; } = null!; - public string? Color { get; set; } - public decimal Price { get; set; } - public string? ImageUrl { get; set; } - public string Sku { get; set; } = null!; - public int StockQuantity { get; set; } - public bool IsActive { get; set; } = true; -} - -public class CreateProductVariantHandler(IUnitOfWork unitOfWork) - : IRequestHandler -{ - public async Task Handle(CreateProductVariantCommand request, CancellationToken cancellationToken) - { - await unitOfWork.BeginTransactionAsync(cancellationToken); - - try - { - var productVariant = new ProductVariant - { - ProductId = request.ProductId, - Size = request.Size, - Color = request.Color, - Price = request.Price, - ImageUrl = request.ImageUrl, - Sku = request.Sku, - StockQuantity = request.StockQuantity, - IsActive = request.IsActive, - Product = null! - }; - - var createdVariant = await unitOfWork.ProductVariantRepository.AddAsync(productVariant, cancellationToken); - await unitOfWork.CommitTransactionAsync(cancellationToken); - - return new ProductVariantDto - { - Id = createdVariant.Id, - ProductId = createdVariant.ProductId, - Size = createdVariant.Size, - Color = createdVariant.Color, - Price = createdVariant.Price, - ImageUrl = createdVariant.ImageUrl, - Sku = createdVariant.Sku, - StockQuantity = createdVariant.StockQuantity, - IsActive = createdVariant.IsActive, - CreatedAt = createdVariant.CreatedAt, - ModifiedAt = createdVariant.ModifiedAt - }; - } - catch - { - await unitOfWork.RollbackTransactionAsync(cancellationToken); - throw; - } - } -} \ No newline at end of file diff --git a/src/Imprink.Application/Domains/Products/CreateProductHandler.cs b/src/Imprink.Application/Domains/Products/CreateProductHandler.cs deleted file mode 100644 index a9a0df7..0000000 --- a/src/Imprink.Application/Domains/Products/CreateProductHandler.cs +++ /dev/null @@ -1,76 +0,0 @@ -using Imprink.Application.Products.Dtos; -using Imprink.Domain.Entities.Product; -using MediatR; - -namespace Imprink.Application.Domains.Products; - -public class CreateProductCommand : IRequest -{ - public string Name { get; set; } = null!; - public string? Description { get; set; } - public decimal BasePrice { get; set; } - public bool IsCustomizable { get; set; } - public bool IsActive { get; set; } = true; - public string? ImageUrl { get; set; } - public Guid? CategoryId { get; set; } -} - -public class CreateProductHandler(IUnitOfWork unitOfWork) : IRequestHandler -{ - public async Task Handle(CreateProductCommand request, CancellationToken cancellationToken) - { - await unitOfWork.BeginTransactionAsync(cancellationToken); - - try - { - var product = new Product - { - Name = request.Name, - Description = request.Description, - BasePrice = request.BasePrice, - IsCustomizable = request.IsCustomizable, - IsActive = request.IsActive, - ImageUrl = request.ImageUrl, - CategoryId = request.CategoryId, - Category = null! - }; - - var createdProduct = await unitOfWork.ProductRepository.AddAsync(product, cancellationToken); - - var categoryDto = new CategoryDto - { - Id = createdProduct.Category.Id, - Name = createdProduct.Category.Name, - Description = createdProduct.Category.Description, - ImageUrl = createdProduct.Category.ImageUrl, - SortOrder = createdProduct.Category.SortOrder, - IsActive = createdProduct.Category.IsActive, - ParentCategoryId = createdProduct.Category.ParentCategoryId, - CreatedAt = createdProduct.Category.CreatedAt, - ModifiedAt = createdProduct.Category.ModifiedAt - }; - - await unitOfWork.CommitTransactionAsync(cancellationToken); - - return new ProductDto - { - Id = createdProduct.Id, - Name = createdProduct.Name, - Description = createdProduct.Description, - BasePrice = createdProduct.BasePrice, - IsCustomizable = createdProduct.IsCustomizable, - IsActive = createdProduct.IsActive, - ImageUrl = createdProduct.ImageUrl, - CategoryId = createdProduct.CategoryId, - Category = categoryDto, - CreatedAt = createdProduct.CreatedAt, - ModifiedAt = createdProduct.ModifiedAt - }; - } - catch - { - await unitOfWork.RollbackTransactionAsync(cancellationToken); - throw; - } - } -} \ No newline at end of file diff --git a/src/Imprink.Application/Imprink.Application.csproj b/src/Imprink.Application/Imprink.Application.csproj index 5a13bfc..17480c4 100644 --- a/src/Imprink.Application/Imprink.Application.csproj +++ b/src/Imprink.Application/Imprink.Application.csproj @@ -19,8 +19,4 @@ - - - - diff --git a/src/Imprink.Application/MappingProfile.cs b/src/Imprink.Application/MappingProfile.cs new file mode 100644 index 0000000..9391d58 --- /dev/null +++ b/src/Imprink.Application/MappingProfile.cs @@ -0,0 +1,5 @@ +using AutoMapper; + +namespace Imprink.Application; + +public abstract class MappingProfile : Profile { } \ No newline at end of file diff --git a/src/Imprink.Application/Validation/Models/OrderFilterParametersValidator.cs b/src/Imprink.Application/Orders/Validation/OrderFilterParametersValidator.cs similarity index 98% rename from src/Imprink.Application/Validation/Models/OrderFilterParametersValidator.cs rename to src/Imprink.Application/Orders/Validation/OrderFilterParametersValidator.cs index 0efcdad..243f5e8 100644 --- a/src/Imprink.Application/Validation/Models/OrderFilterParametersValidator.cs +++ b/src/Imprink.Application/Orders/Validation/OrderFilterParametersValidator.cs @@ -1,7 +1,7 @@ using FluentValidation; using Imprink.Domain.Models; -namespace Imprink.Application.Validation.Models; +namespace Imprink.Application.Orders.Validation; public class OrderFilterParametersValidator : AbstractValidator { diff --git a/src/Imprink.Application/ProductVariants/Commands/CreateProductVariantHandler.cs b/src/Imprink.Application/ProductVariants/Commands/CreateProductVariantHandler.cs new file mode 100644 index 0000000..fbb3f1a --- /dev/null +++ b/src/Imprink.Application/ProductVariants/Commands/CreateProductVariantHandler.cs @@ -0,0 +1,46 @@ +using AutoMapper; +using Imprink.Application.ProductVariants.Dtos; +using Imprink.Domain.Entities.Products; +using MediatR; + +namespace Imprink.Application.ProductVariants.Commands; + +public class CreateProductVariantCommand : IRequest +{ + public Guid ProductId { get; set; } + public string Size { get; set; } = null!; + public string? Color { get; set; } + public decimal Price { get; set; } + public string? ImageUrl { get; set; } + public string Sku { get; set; } = null!; + public int StockQuantity { get; set; } + public bool IsActive { get; set; } = true; +} + +public class CreateProductVariantHandler(IUnitOfWork unitOfWork, IMapper mapper) + : IRequestHandler +{ + public async Task Handle(CreateProductVariantCommand request, CancellationToken cancellationToken) + { + await unitOfWork.BeginTransactionAsync(cancellationToken); + + try + { + var productVariant = mapper.Map(request); + + productVariant.Product = null!; + + var createdVariant = await unitOfWork.ProductVariantRepository.AddAsync(productVariant, cancellationToken); + + await unitOfWork.SaveAsync(cancellationToken); + await unitOfWork.CommitTransactionAsync(cancellationToken); + + return mapper.Map(createdVariant); + } + catch + { + await unitOfWork.RollbackTransactionAsync(cancellationToken); + throw; + } + } +} \ No newline at end of file diff --git a/src/Imprink.Application/Domains/ProductVariants/DeleteProductVariantHandler.cs b/src/Imprink.Application/ProductVariants/Commands/DeleteProductVariantHandler.cs similarity index 87% rename from src/Imprink.Application/Domains/ProductVariants/DeleteProductVariantHandler.cs rename to src/Imprink.Application/ProductVariants/Commands/DeleteProductVariantHandler.cs index 10e257e..3c6609f 100644 --- a/src/Imprink.Application/Domains/ProductVariants/DeleteProductVariantHandler.cs +++ b/src/Imprink.Application/ProductVariants/Commands/DeleteProductVariantHandler.cs @@ -1,6 +1,6 @@ using MediatR; -namespace Imprink.Application.Domains.ProductVariants; +namespace Imprink.Application.ProductVariants.Commands; public class DeleteProductVariantCommand : IRequest { @@ -16,6 +16,7 @@ public class DeleteProductVariantHandler(IUnitOfWork unitOfWork) : IRequestHandl try { var exists = await unitOfWork.ProductVariantRepository.ExistsAsync(request.Id, cancellationToken); + if (!exists) { await unitOfWork.RollbackTransactionAsync(cancellationToken); @@ -23,7 +24,10 @@ public class DeleteProductVariantHandler(IUnitOfWork unitOfWork) : IRequestHandl } await unitOfWork.ProductVariantRepository.DeleteAsync(request.Id, cancellationToken); + + await unitOfWork.SaveAsync(cancellationToken); await unitOfWork.CommitTransactionAsync(cancellationToken); + return true; } catch diff --git a/src/Imprink.Application/Domains/ProductVariants/GetProductVariantsHandler.cs b/src/Imprink.Application/ProductVariants/Commands/GetProductVariantsHandler.cs similarity index 51% rename from src/Imprink.Application/Domains/ProductVariants/GetProductVariantsHandler.cs rename to src/Imprink.Application/ProductVariants/Commands/GetProductVariantsHandler.cs index 609036b..92deb03 100644 --- a/src/Imprink.Application/Domains/ProductVariants/GetProductVariantsHandler.cs +++ b/src/Imprink.Application/ProductVariants/Commands/GetProductVariantsHandler.cs @@ -1,8 +1,10 @@ -using Imprink.Application.Products.Dtos; -using Imprink.Domain.Entities.Product; +using AutoMapper; +using Imprink.Application.ProductVariants.Dtos; +using Imprink.Domain.Entities.Products; using MediatR; +using Microsoft.Extensions.Logging; -namespace Imprink.Application.Domains.ProductVariants; +namespace Imprink.Application.ProductVariants.Commands; public class GetProductVariantsQuery : IRequest> { @@ -11,7 +13,7 @@ public class GetProductVariantsQuery : IRequest> public bool InStockOnly { get; set; } = false; } -public class GetProductVariantsHandler(IUnitOfWork unitOfWork) +public class GetProductVariantsHandler(IUnitOfWork unitOfWork, IMapper mapper, ILogger logger) : IRequestHandler> { public async Task> Handle(GetProductVariantsQuery request, CancellationToken cancellationToken) @@ -37,33 +39,7 @@ public class GetProductVariantsHandler(IUnitOfWork unitOfWork) { variants = new List(); } - - return variants.Select(pv => new ProductVariantDto - { - Id = pv.Id, - ProductId = pv.ProductId, - Size = pv.Size, - Color = pv.Color, - Price = pv.Price, - ImageUrl = pv.ImageUrl, - Sku = pv.Sku, - StockQuantity = pv.StockQuantity, - IsActive = pv.IsActive, - Product = new ProductDto - { - Id = pv.Product.Id, - Name = pv.Product.Name, - Description = pv.Product.Description, - BasePrice = pv.Product.BasePrice, - IsCustomizable = pv.Product.IsCustomizable, - IsActive = pv.Product.IsActive, - ImageUrl = pv.Product.ImageUrl, - CategoryId = pv.Product.CategoryId, - CreatedAt = pv.Product.CreatedAt, - ModifiedAt = pv.Product.ModifiedAt - }, - CreatedAt = pv.CreatedAt, - ModifiedAt = pv.ModifiedAt - }); + + return mapper.Map>(variants); } } \ No newline at end of file diff --git a/src/Imprink.Application/Domains/ProductVariants/UpdateProductVariantHandler.cs b/src/Imprink.Application/ProductVariants/Commands/UpdateProductVariantHandler.cs similarity index 53% rename from src/Imprink.Application/Domains/ProductVariants/UpdateProductVariantHandler.cs rename to src/Imprink.Application/ProductVariants/Commands/UpdateProductVariantHandler.cs index b7574b1..53eefc2 100644 --- a/src/Imprink.Application/Domains/ProductVariants/UpdateProductVariantHandler.cs +++ b/src/Imprink.Application/ProductVariants/Commands/UpdateProductVariantHandler.cs @@ -1,8 +1,9 @@ +using AutoMapper; using Imprink.Application.Exceptions; -using Imprink.Application.Products.Dtos; +using Imprink.Application.ProductVariants.Dtos; using MediatR; -namespace Imprink.Application.Domains.ProductVariants; +namespace Imprink.Application.ProductVariants.Commands; public class UpdateProductVariantCommand : IRequest { @@ -17,7 +18,7 @@ public class UpdateProductVariantCommand : IRequest public bool IsActive { get; set; } } -public class UpdateProductVariantHandler(IUnitOfWork unitOfWork) +public class UpdateProductVariantHandler(IUnitOfWork unitOfWork, IMapper mapper) : IRequestHandler { public async Task Handle(UpdateProductVariantCommand request, CancellationToken cancellationToken) @@ -29,36 +30,16 @@ public class UpdateProductVariantHandler(IUnitOfWork unitOfWork) var existingVariant = await unitOfWork.ProductVariantRepository.GetByIdAsync(request.Id, cancellationToken); if (existingVariant == null) - { throw new NotFoundException($"Product variant with ID {request.Id} not found."); - } - - existingVariant.ProductId = request.ProductId; - existingVariant.Size = request.Size; - existingVariant.Color = request.Color; - existingVariant.Price = request.Price; - existingVariant.ImageUrl = request.ImageUrl; - existingVariant.Sku = request.Sku; - existingVariant.StockQuantity = request.StockQuantity; - existingVariant.IsActive = request.IsActive; + + mapper.Map(request, existingVariant); var updatedVariant = await unitOfWork.ProductVariantRepository.UpdateAsync(existingVariant, cancellationToken); + + await unitOfWork.SaveAsync(cancellationToken); await unitOfWork.CommitTransactionAsync(cancellationToken); - return new ProductVariantDto - { - Id = updatedVariant.Id, - ProductId = updatedVariant.ProductId, - Size = updatedVariant.Size, - Color = updatedVariant.Color, - Price = updatedVariant.Price, - ImageUrl = updatedVariant.ImageUrl, - Sku = updatedVariant.Sku, - StockQuantity = updatedVariant.StockQuantity, - IsActive = updatedVariant.IsActive, - CreatedAt = updatedVariant.CreatedAt, - ModifiedAt = updatedVariant.ModifiedAt - }; + return mapper.Map(updatedVariant); } catch { diff --git a/src/Imprink.Application/Domains/ProductVariants/Dtos/ProductVariantDto.cs b/src/Imprink.Application/ProductVariants/Dtos/ProductVariantDto.cs similarity index 85% rename from src/Imprink.Application/Domains/ProductVariants/Dtos/ProductVariantDto.cs rename to src/Imprink.Application/ProductVariants/Dtos/ProductVariantDto.cs index 881c54d..0afec2c 100644 --- a/src/Imprink.Application/Domains/ProductVariants/Dtos/ProductVariantDto.cs +++ b/src/Imprink.Application/ProductVariants/Dtos/ProductVariantDto.cs @@ -1,4 +1,6 @@ -namespace Imprink.Application.Products.Dtos; +using Imprink.Application.Products.Dtos; + +namespace Imprink.Application.ProductVariants.Dtos; public class ProductVariantDto { diff --git a/src/Imprink.Application/Validation/ProductVariants/CreateProducVariantCommandValidator.cs b/src/Imprink.Application/ProductVariants/Validation/CreateProducVariantCommandValidator.cs similarity index 92% rename from src/Imprink.Application/Validation/ProductVariants/CreateProducVariantCommandValidator.cs rename to src/Imprink.Application/ProductVariants/Validation/CreateProducVariantCommandValidator.cs index c3d3957..8897c47 100644 --- a/src/Imprink.Application/Validation/ProductVariants/CreateProducVariantCommandValidator.cs +++ b/src/Imprink.Application/ProductVariants/Validation/CreateProducVariantCommandValidator.cs @@ -1,7 +1,7 @@ using FluentValidation; -using Imprink.Application.Domains.ProductVariants; +using Imprink.Application.ProductVariants.Commands; -namespace Imprink.Application.Validation.ProductVariants; +namespace Imprink.Application.ProductVariants.Validation; public class CreateProductVariantCommandValidator : AbstractValidator { diff --git a/src/Imprink.Application/Validation/ProductVariants/DeleteProductVariantCommandValidator.cs b/src/Imprink.Application/ProductVariants/Validation/DeleteProductVariantCommandValidator.cs similarity index 75% rename from src/Imprink.Application/Validation/ProductVariants/DeleteProductVariantCommandValidator.cs rename to src/Imprink.Application/ProductVariants/Validation/DeleteProductVariantCommandValidator.cs index acda88f..419aa93 100644 --- a/src/Imprink.Application/Validation/ProductVariants/DeleteProductVariantCommandValidator.cs +++ b/src/Imprink.Application/ProductVariants/Validation/DeleteProductVariantCommandValidator.cs @@ -1,7 +1,7 @@ using FluentValidation; -using Imprink.Application.Domains.ProductVariants; +using Imprink.Application.ProductVariants.Commands; -namespace Imprink.Application.Validation.ProductVariants; +namespace Imprink.Application.ProductVariants.Validation; public class DeleteProductVariantCommandValidator : AbstractValidator { diff --git a/src/Imprink.Application/Validation/ProductVariants/GetProductVariantsQueryValidator.cs b/src/Imprink.Application/ProductVariants/Validation/GetProductVariantsQueryValidator.cs similarity index 76% rename from src/Imprink.Application/Validation/ProductVariants/GetProductVariantsQueryValidator.cs rename to src/Imprink.Application/ProductVariants/Validation/GetProductVariantsQueryValidator.cs index 2ad4d09..9aa11b1 100644 --- a/src/Imprink.Application/Validation/ProductVariants/GetProductVariantsQueryValidator.cs +++ b/src/Imprink.Application/ProductVariants/Validation/GetProductVariantsQueryValidator.cs @@ -1,7 +1,7 @@ using FluentValidation; -using Imprink.Application.Domains.ProductVariants; +using Imprink.Application.ProductVariants.Commands; -namespace Imprink.Application.Validation.ProductVariants; +namespace Imprink.Application.ProductVariants.Validation; public class GetProductVariantsQueryValidator : AbstractValidator { diff --git a/src/Imprink.Application/Validation/ProductVariants/UpdateProductVariantCommandValidator.cs b/src/Imprink.Application/ProductVariants/Validation/UpdateProductVariantCommandValidator.cs similarity index 93% rename from src/Imprink.Application/Validation/ProductVariants/UpdateProductVariantCommandValidator.cs rename to src/Imprink.Application/ProductVariants/Validation/UpdateProductVariantCommandValidator.cs index dd9fe23..d01b1b2 100644 --- a/src/Imprink.Application/Validation/ProductVariants/UpdateProductVariantCommandValidator.cs +++ b/src/Imprink.Application/ProductVariants/Validation/UpdateProductVariantCommandValidator.cs @@ -1,7 +1,7 @@ using FluentValidation; -using Imprink.Application.Domains.ProductVariants; +using Imprink.Application.ProductVariants.Commands; -namespace Imprink.Application.Validation.ProductVariants; +namespace Imprink.Application.ProductVariants.Validation; public class UpdateProductVariantCommandValidator : AbstractValidator { diff --git a/src/Imprink.Application/Products/Commands/CreateProductHandler.cs b/src/Imprink.Application/Products/Commands/CreateProductHandler.cs new file mode 100644 index 0000000..a36e606 --- /dev/null +++ b/src/Imprink.Application/Products/Commands/CreateProductHandler.cs @@ -0,0 +1,46 @@ +using AutoMapper; +using Imprink.Application.Products.Dtos; +using Imprink.Domain.Entities.Products; +using MediatR; + +namespace Imprink.Application.Products.Commands; + +public class CreateProductCommand : IRequest +{ + public string Name { get; set; } = null!; + public string? Description { get; set; } + public decimal BasePrice { get; set; } + public bool IsCustomizable { get; set; } + public bool IsActive { get; set; } = true; + public string? ImageUrl { get; set; } + public Guid? CategoryId { get; set; } +} + +public class CreateProductHandler(IUnitOfWork unitOfWork, IMapper mapper) : IRequestHandler +{ + public async Task Handle(CreateProductCommand request, CancellationToken cancellationToken) + { + await unitOfWork.BeginTransactionAsync(cancellationToken); + + try + { + var product = mapper.Map(request); + + var createdProduct = await unitOfWork.ProductRepository.AddAsync(product, cancellationToken); + + if (createdProduct.CategoryId.HasValue) + { + createdProduct.Category = (await unitOfWork.CategoryRepository.GetByIdAsync(createdProduct.CategoryId.Value, cancellationToken))!; + } + + await unitOfWork.CommitTransactionAsync(cancellationToken); + + return mapper.Map(createdProduct); + } + catch + { + await unitOfWork.RollbackTransactionAsync(cancellationToken); + throw; + } + } +} \ No newline at end of file diff --git a/src/Imprink.Application/Domains/Products/DeleteProductHandler.cs b/src/Imprink.Application/Products/Commands/DeleteProductHandler.cs similarity index 95% rename from src/Imprink.Application/Domains/Products/DeleteProductHandler.cs rename to src/Imprink.Application/Products/Commands/DeleteProductHandler.cs index c81d3d8..2983496 100644 --- a/src/Imprink.Application/Domains/Products/DeleteProductHandler.cs +++ b/src/Imprink.Application/Products/Commands/DeleteProductHandler.cs @@ -1,6 +1,6 @@ using MediatR; -namespace Imprink.Application.Domains.Products; +namespace Imprink.Application.Products.Commands; public class DeleteProductCommand : IRequest { diff --git a/src/Imprink.Application/Domains/Products/GetProductsHandler.cs b/src/Imprink.Application/Products/Commands/GetProductsHandler.cs similarity index 95% rename from src/Imprink.Application/Domains/Products/GetProductsHandler.cs rename to src/Imprink.Application/Products/Commands/GetProductsHandler.cs index 615553d..ea83640 100644 --- a/src/Imprink.Application/Domains/Products/GetProductsHandler.cs +++ b/src/Imprink.Application/Products/Commands/GetProductsHandler.cs @@ -1,8 +1,9 @@ +using Imprink.Application.Categories.Dtos; using Imprink.Application.Products.Dtos; using Imprink.Domain.Models; using MediatR; -namespace Imprink.Application.Domains.Products; +namespace Imprink.Application.Products.Commands; public class GetProductsQuery : IRequest> { diff --git a/src/Imprink.Application/Domains/Products/UpdateProductCommand.cs b/src/Imprink.Application/Products/Commands/UpdateProductCommand.cs similarity index 97% rename from src/Imprink.Application/Domains/Products/UpdateProductCommand.cs rename to src/Imprink.Application/Products/Commands/UpdateProductCommand.cs index 3aadffa..f6c3e8c 100644 --- a/src/Imprink.Application/Domains/Products/UpdateProductCommand.cs +++ b/src/Imprink.Application/Products/Commands/UpdateProductCommand.cs @@ -1,8 +1,9 @@ +using Imprink.Application.Categories.Dtos; using Imprink.Application.Exceptions; using Imprink.Application.Products.Dtos; using MediatR; -namespace Imprink.Application.Domains.Products; +namespace Imprink.Application.Products.Commands; public class UpdateProductCommand : IRequest { diff --git a/src/Imprink.Application/Domains/Products/Dtos/PagedResultDto.cs b/src/Imprink.Application/Products/Dtos/PagedResultDto.cs similarity index 100% rename from src/Imprink.Application/Domains/Products/Dtos/PagedResultDto.cs rename to src/Imprink.Application/Products/Dtos/PagedResultDto.cs diff --git a/src/Imprink.Application/Domains/Products/Dtos/ProductDto.cs b/src/Imprink.Application/Products/Dtos/ProductDto.cs similarity index 92% rename from src/Imprink.Application/Domains/Products/Dtos/ProductDto.cs rename to src/Imprink.Application/Products/Dtos/ProductDto.cs index abb8403..cc71be2 100644 --- a/src/Imprink.Application/Domains/Products/Dtos/ProductDto.cs +++ b/src/Imprink.Application/Products/Dtos/ProductDto.cs @@ -1,3 +1,5 @@ +using Imprink.Application.Categories.Dtos; + namespace Imprink.Application.Products.Dtos; public class ProductDto diff --git a/src/Imprink.Application/Products/Mappings/ProductMappingProfile.cs b/src/Imprink.Application/Products/Mappings/ProductMappingProfile.cs new file mode 100644 index 0000000..97d1fd7 --- /dev/null +++ b/src/Imprink.Application/Products/Mappings/ProductMappingProfile.cs @@ -0,0 +1,44 @@ +using AutoMapper; +using Imprink.Application.Categories.Dtos; +using Imprink.Application.Products.Commands; +using Imprink.Application.Products.Dtos; +using Imprink.Application.ProductVariants.Commands; +using Imprink.Application.ProductVariants.Dtos; +using Imprink.Domain.Entities.Products; + +namespace Imprink.Application.Products.Mappings; + +public class ProductMappingProfile: Profile +{ + public ProductMappingProfile() + { + CreateMap() + .ForMember(dest => dest.Id, opt => opt.Ignore()) + .ForMember(dest => dest.CreatedAt, opt => opt.Ignore()) + .ForMember(dest => dest.ModifiedAt, opt => opt.Ignore()) + .ForMember(dest => dest.CreatedBy, opt => opt.Ignore()) + .ForMember(dest => dest.ModifiedBy, opt => opt.Ignore()) + .ForMember(dest => dest.Product, opt => opt.Ignore()) + .ForMember(dest => dest.OrderItems, opt => opt.Ignore()); + + CreateMap(); + CreateMap() + .ForMember(dest => dest.CreatedBy, opt => opt.Ignore()) + .ForMember(dest => dest.ModifiedBy, opt => opt.Ignore()) + .ForMember(dest => dest.OrderItems, opt => opt.Ignore()); + + CreateMap(); + + CreateMap() + .ForMember(dest => dest.Id, opt => opt.Ignore()) + .ForMember(dest => dest.CreatedAt, opt => opt.Ignore()) + .ForMember(dest => dest.ModifiedAt, opt => opt.Ignore()) + .ForMember(dest => dest.CreatedBy, opt => opt.Ignore()) + .ForMember(dest => dest.ModifiedBy, opt => opt.Ignore()) + .ForMember(dest => dest.Category, opt => opt.Ignore()) + .ForMember(dest => dest.ProductVariants, opt => opt.Ignore()) + .ForMember(dest => dest.OrderItems, opt => opt.Ignore()); + + CreateMap(); + } +} \ No newline at end of file diff --git a/src/Imprink.Application/Validation/Products/CreateProductCommandValidator.cs b/src/Imprink.Application/Products/Validation/CreateProductCommandValidator.cs similarity index 92% rename from src/Imprink.Application/Validation/Products/CreateProductCommandValidator.cs rename to src/Imprink.Application/Products/Validation/CreateProductCommandValidator.cs index 60da2bd..d79875a 100644 --- a/src/Imprink.Application/Validation/Products/CreateProductCommandValidator.cs +++ b/src/Imprink.Application/Products/Validation/CreateProductCommandValidator.cs @@ -1,7 +1,7 @@ using FluentValidation; -using Imprink.Application.Domains.Products; +using Imprink.Application.Products.Commands; -namespace Imprink.Application.Validation.Products; +namespace Imprink.Application.Products.Validation; public class CreateProductCommandValidator : AbstractValidator { diff --git a/src/Imprink.Application/Validation/Products/DeleteProductCommandValidator.cs b/src/Imprink.Application/Products/Validation/DeleteProductCommandValidator.cs similarity index 77% rename from src/Imprink.Application/Validation/Products/DeleteProductCommandValidator.cs rename to src/Imprink.Application/Products/Validation/DeleteProductCommandValidator.cs index 5cb3cea..53903ab 100644 --- a/src/Imprink.Application/Validation/Products/DeleteProductCommandValidator.cs +++ b/src/Imprink.Application/Products/Validation/DeleteProductCommandValidator.cs @@ -1,7 +1,7 @@ using FluentValidation; -using Imprink.Application.Domains.Products; +using Imprink.Application.Products.Commands; -namespace Imprink.Application.Validation.Products; +namespace Imprink.Application.Products.Validation; public class DeleteProductCommandValidator : AbstractValidator { diff --git a/src/Imprink.Application/Validation/Products/GetProductsQueryValidator.cs b/src/Imprink.Application/Products/Validation/GetProductsQueryValidator.cs similarity index 67% rename from src/Imprink.Application/Validation/Products/GetProductsQueryValidator.cs rename to src/Imprink.Application/Products/Validation/GetProductsQueryValidator.cs index 9026474..1194b72 100644 --- a/src/Imprink.Application/Validation/Products/GetProductsQueryValidator.cs +++ b/src/Imprink.Application/Products/Validation/GetProductsQueryValidator.cs @@ -1,8 +1,7 @@ using FluentValidation; -using Imprink.Application.Domains.Products; -using Imprink.Application.Validation.Models; +using Imprink.Application.Products.Commands; -namespace Imprink.Application.Validation.Products; +namespace Imprink.Application.Products.Validation; public class GetProductsQueryValidator : AbstractValidator { diff --git a/src/Imprink.Application/Validation/Models/ProductFilterParametersValidator.cs b/src/Imprink.Application/Products/Validation/ProductFilterParametersValidator.cs similarity index 97% rename from src/Imprink.Application/Validation/Models/ProductFilterParametersValidator.cs rename to src/Imprink.Application/Products/Validation/ProductFilterParametersValidator.cs index 08131c9..55cd4d0 100644 --- a/src/Imprink.Application/Validation/Models/ProductFilterParametersValidator.cs +++ b/src/Imprink.Application/Products/Validation/ProductFilterParametersValidator.cs @@ -1,7 +1,7 @@ using FluentValidation; using Imprink.Domain.Models; -namespace Imprink.Application.Validation.Models; +namespace Imprink.Application.Products.Validation; public class ProductFilterParametersValidator : AbstractValidator { diff --git a/src/Imprink.Application/Validation/Products/UpdateProductCommandValidator.cs b/src/Imprink.Application/Products/Validation/UpdateProductCommandValidator.cs similarity index 92% rename from src/Imprink.Application/Validation/Products/UpdateProductCommandValidator.cs rename to src/Imprink.Application/Products/Validation/UpdateProductCommandValidator.cs index afc7cbf..3c49ebe 100644 --- a/src/Imprink.Application/Validation/Products/UpdateProductCommandValidator.cs +++ b/src/Imprink.Application/Products/Validation/UpdateProductCommandValidator.cs @@ -1,7 +1,7 @@ using FluentValidation; -using Imprink.Application.Domains.Products; +using Imprink.Application.Products.Commands; -namespace Imprink.Application.Validation.Products; +namespace Imprink.Application.Products.Validation; public class UpdateProductCommandValidator : AbstractValidator { diff --git a/src/Imprink.Application/Domains/Users/DeleteUserRoleHandler.cs b/src/Imprink.Application/Users/Commands/DeleteUserRoleHandler.cs similarity index 80% rename from src/Imprink.Application/Domains/Users/DeleteUserRoleHandler.cs rename to src/Imprink.Application/Users/Commands/DeleteUserRoleHandler.cs index 28bed6d..6d1888a 100644 --- a/src/Imprink.Application/Domains/Users/DeleteUserRoleHandler.cs +++ b/src/Imprink.Application/Users/Commands/DeleteUserRoleHandler.cs @@ -1,12 +1,13 @@ +using AutoMapper; using Imprink.Application.Exceptions; using Imprink.Application.Users.Dtos; using MediatR; -namespace Imprink.Application.Domains.Users; +namespace Imprink.Application.Users.Commands; public record DeleteUserRoleCommand(string Sub, Guid RoleId) : IRequest; -public class DeleteUserRoleHandler(IUnitOfWork uw) : IRequestHandler +public class DeleteUserRoleHandler(IUnitOfWork uw, IMapper mapper) : IRequestHandler { public async Task Handle(DeleteUserRoleCommand request, CancellationToken cancellationToken) { @@ -27,11 +28,7 @@ public class DeleteUserRoleHandler(IUnitOfWork uw) : IRequestHandler(removedRole); } catch { diff --git a/src/Imprink.Application/Users/Commands/GetAllRolesHandler.cs b/src/Imprink.Application/Users/Commands/GetAllRolesHandler.cs new file mode 100644 index 0000000..4d9ab5e --- /dev/null +++ b/src/Imprink.Application/Users/Commands/GetAllRolesHandler.cs @@ -0,0 +1,17 @@ +using AutoMapper; +using Imprink.Application.Users.Dtos; +using MediatR; + +namespace Imprink.Application.Users.Commands; + +public record GetAllRolesCommand : IRequest>; + +public class GetAllRolesHandler(IUnitOfWork uw, IMapper mapper): IRequestHandler> +{ + public async Task> Handle(GetAllRolesCommand request, CancellationToken cancellationToken) + { + var roles = await uw.RoleRepository.GetAllRolesAsync(cancellationToken); + + return mapper.Map>(roles); + } +} \ No newline at end of file diff --git a/src/Imprink.Application/Domains/Users/GetUserRolesHandler.cs b/src/Imprink.Application/Users/Commands/GetUserRolesHandler.cs similarity index 66% rename from src/Imprink.Application/Domains/Users/GetUserRolesHandler.cs rename to src/Imprink.Application/Users/Commands/GetUserRolesHandler.cs index acd95a2..9c39568 100644 --- a/src/Imprink.Application/Domains/Users/GetUserRolesHandler.cs +++ b/src/Imprink.Application/Users/Commands/GetUserRolesHandler.cs @@ -1,12 +1,13 @@ +using AutoMapper; using Imprink.Application.Exceptions; using Imprink.Application.Users.Dtos; using MediatR; -namespace Imprink.Application.Domains.Users; +namespace Imprink.Application.Users.Commands; public record GetUserRolesCommand(string Sub) : IRequest>; -public class GetUserRolesHandler(IUnitOfWork uw): IRequestHandler> +public class GetUserRolesHandler(IUnitOfWork uw, IMapper mapper): IRequestHandler> { public async Task> Handle(GetUserRolesCommand request, CancellationToken cancellationToken) { @@ -15,10 +16,6 @@ public class GetUserRolesHandler(IUnitOfWork uw): IRequestHandler new RoleDto - { - RoleId = role.Id, - RoleName = role.RoleName - }).ToList(); + return mapper.Map>(roles); } } \ No newline at end of file diff --git a/src/Imprink.Application/Domains/Users/SetUserFullNameHandler.cs b/src/Imprink.Application/Users/Commands/SetUserFullNameHandler.cs similarity index 62% rename from src/Imprink.Application/Domains/Users/SetUserFullNameHandler.cs rename to src/Imprink.Application/Users/Commands/SetUserFullNameHandler.cs index b8b4ce1..d7865d8 100644 --- a/src/Imprink.Application/Domains/Users/SetUserFullNameHandler.cs +++ b/src/Imprink.Application/Users/Commands/SetUserFullNameHandler.cs @@ -1,13 +1,14 @@ +using AutoMapper; using Imprink.Application.Exceptions; -using Imprink.Application.Services; using Imprink.Application.Users.Dtos; +using Imprink.Application.Users.Services; using MediatR; -namespace Imprink.Application.Domains.Users; +namespace Imprink.Application.Users.Commands; public record SetUserFullNameCommand(string FirstName, string LastName) : IRequest; -public class SetUserFullNameHandler(IUnitOfWork uw, ICurrentUserService userService) : IRequestHandler +public class SetUserFullNameHandler(IUnitOfWork uw, IMapper mapper, ICurrentUserService userService) : IRequestHandler { public async Task Handle(SetUserFullNameCommand request, CancellationToken cancellationToken) { @@ -16,28 +17,19 @@ public class SetUserFullNameHandler(IUnitOfWork uw, ICurrentUserService userServ try { var currentUser = userService.GetCurrentUserId(); + if (currentUser == null) throw new NotFoundException("User token could not be accessed."); var user = await uw.UserRepository.SetUserFullNameAsync(currentUser, request.FirstName, request.LastName, cancellationToken); + if (user == null) throw new DataUpdateException("User name could not be updated."); await uw.SaveAsync(cancellationToken); await uw.CommitTransactionAsync(cancellationToken); - return new UserDto - { - Id = user.Id, - Name = user.Name, - Nickname = user.Nickname, - Email = user.Email, - EmailVerified = user.EmailVerified, - FirstName = user.FirstName, - LastName = user.LastName, - PhoneNumber = user.PhoneNumber, - IsActive = user.IsActive - }; + return mapper.Map(user); } catch { diff --git a/src/Imprink.Application/Domains/Users/SetUserPhoneHandler.cs b/src/Imprink.Application/Users/Commands/SetUserPhoneHandler.cs similarity index 61% rename from src/Imprink.Application/Domains/Users/SetUserPhoneHandler.cs rename to src/Imprink.Application/Users/Commands/SetUserPhoneHandler.cs index b7b5289..d1e3ca7 100644 --- a/src/Imprink.Application/Domains/Users/SetUserPhoneHandler.cs +++ b/src/Imprink.Application/Users/Commands/SetUserPhoneHandler.cs @@ -1,13 +1,14 @@ +using AutoMapper; using Imprink.Application.Exceptions; -using Imprink.Application.Services; using Imprink.Application.Users.Dtos; +using Imprink.Application.Users.Services; using MediatR; -namespace Imprink.Application.Domains.Users; +namespace Imprink.Application.Users.Commands; public record SetUserPhoneCommand(string PhoneNumber) : IRequest; -public class SetUserPhoneHandler(IUnitOfWork uw, ICurrentUserService userService) : IRequestHandler +public class SetUserPhoneHandler(IUnitOfWork uw, IMapper mapper, ICurrentUserService userService) : IRequestHandler { public async Task Handle(SetUserPhoneCommand request, CancellationToken cancellationToken) { @@ -16,28 +17,19 @@ public class SetUserPhoneHandler(IUnitOfWork uw, ICurrentUserService userService try { var currentUser = userService.GetCurrentUserId(); + if (currentUser == null) throw new NotFoundException("User token could not be accessed."); var user = await uw.UserRepository.SetUserPhoneAsync(currentUser, request.PhoneNumber, cancellationToken); + if (user == null) throw new DataUpdateException("User phone could not be updated."); await uw.SaveAsync(cancellationToken); await uw.CommitTransactionAsync(cancellationToken); - return new UserDto - { - Id = user.Id, - Name = user.Name, - Nickname = user.Nickname, - Email = user.Email, - EmailVerified = user.EmailVerified, - FirstName = user.FirstName, - LastName = user.LastName, - PhoneNumber = user.PhoneNumber, - IsActive = user.IsActive - }; + return mapper.Map(user); } catch { diff --git a/src/Imprink.Application/Domains/Users/SetUserRoleHandler.cs b/src/Imprink.Application/Users/Commands/SetUserRoleHandler.cs similarity index 79% rename from src/Imprink.Application/Domains/Users/SetUserRoleHandler.cs rename to src/Imprink.Application/Users/Commands/SetUserRoleHandler.cs index 426eb8b..bb9d892 100644 --- a/src/Imprink.Application/Domains/Users/SetUserRoleHandler.cs +++ b/src/Imprink.Application/Users/Commands/SetUserRoleHandler.cs @@ -1,13 +1,14 @@ +using AutoMapper; using Imprink.Application.Exceptions; using Imprink.Application.Users.Dtos; using Imprink.Domain.Entities.Users; using MediatR; -namespace Imprink.Application.Domains.Users; +namespace Imprink.Application.Users.Commands; public record SetUserRoleCommand(string Sub, Guid RoleId) : IRequest; -public class SetUserRoleHandler(IUnitOfWork uw) : IRequestHandler +public class SetUserRoleHandler(IUnitOfWork uw, IMapper mapper) : IRequestHandler { public async Task Handle(SetUserRoleCommand request, CancellationToken cancellationToken) { @@ -29,11 +30,7 @@ public class SetUserRoleHandler(IUnitOfWork uw) : IRequestHandler(addedRole); } catch { diff --git a/src/Imprink.Application/Domains/Users/SyncUserHandler.cs b/src/Imprink.Application/Users/Commands/SyncUserHandler.cs similarity index 53% rename from src/Imprink.Application/Domains/Users/SyncUserHandler.cs rename to src/Imprink.Application/Users/Commands/SyncUserHandler.cs index 503521a..99bdc9f 100644 --- a/src/Imprink.Application/Domains/Users/SyncUserHandler.cs +++ b/src/Imprink.Application/Users/Commands/SyncUserHandler.cs @@ -1,12 +1,13 @@ +using AutoMapper; using Imprink.Application.Users.Dtos; using Imprink.Domain.Models; using MediatR; -namespace Imprink.Application.Domains.Users; +namespace Imprink.Application.Users.Commands; public record SyncUserCommand(Auth0User User) : IRequest; -public class SyncUserHandler(IUnitOfWork uw): IRequestHandler +public class SyncUserHandler(IUnitOfWork uw, IMapper mapper): IRequestHandler { public async Task Handle(SyncUserCommand request, CancellationToken cancellationToken) { @@ -16,23 +17,13 @@ public class SyncUserHandler(IUnitOfWork uw): IRequestHandler(user); } catch { diff --git a/src/Imprink.Application/Domains/Users/Dtos/RoleDto.cs b/src/Imprink.Application/Users/Dtos/RoleDto.cs similarity index 100% rename from src/Imprink.Application/Domains/Users/Dtos/RoleDto.cs rename to src/Imprink.Application/Users/Dtos/RoleDto.cs diff --git a/src/Imprink.Application/Domains/Users/Dtos/UserDto.cs b/src/Imprink.Application/Users/Dtos/UserDto.cs similarity index 100% rename from src/Imprink.Application/Domains/Users/Dtos/UserDto.cs rename to src/Imprink.Application/Users/Dtos/UserDto.cs diff --git a/src/Imprink.Application/Domains/Users/Dtos/UserRoleDto.cs b/src/Imprink.Application/Users/Dtos/UserRoleDto.cs similarity index 100% rename from src/Imprink.Application/Domains/Users/Dtos/UserRoleDto.cs rename to src/Imprink.Application/Users/Dtos/UserRoleDto.cs diff --git a/src/Imprink.Application/Users/Mappings/UserMappingProfile.cs b/src/Imprink.Application/Users/Mappings/UserMappingProfile.cs new file mode 100644 index 0000000..16a8a43 --- /dev/null +++ b/src/Imprink.Application/Users/Mappings/UserMappingProfile.cs @@ -0,0 +1,42 @@ +using System.Security.Claims; +using AutoMapper; +using Imprink.Application.Users.Dtos; +using Imprink.Domain.Entities.Users; +using Imprink.Domain.Models; + +namespace Imprink.Application.Users.Mappings; + +public class UserMappingProfile: Profile +{ + public UserMappingProfile() + { + CreateMap() + .ForMember(dest => dest.DefaultAddress, opt => opt.Ignore()) + .ForMember(dest => dest.Roles, opt => opt.Ignore()); + + CreateMap() + .ForMember(dest => dest.DefaultAddress, opt => opt.Ignore()) + .ForMember(dest => dest.Roles, opt => opt.Ignore()); + + CreateMap(); + CreateMap(); + + CreateMap() + .ForMember(dest => dest.RoleId, opt => opt.MapFrom(src => src.Id)); + CreateMap() + .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.RoleId)) + .ForMember(dest => dest.UserRoles, opt => opt.Ignore()); + + CreateMap() + .ForMember(dest => dest.Sub, opt => opt.MapFrom(src => + src.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)!.Value)) + .ForMember(dest => dest.Name, opt => opt.MapFrom(src => + src.Claims.FirstOrDefault(c => c.Type == "name")!.Value)) + .ForMember(dest => dest.Nickname, opt => opt.MapFrom(src => + src.Claims.FirstOrDefault(c => c.Type == "nickname")!.Value)) + .ForMember(dest => dest.Email, opt => opt.MapFrom(src => + src.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email)!.Value)) + .ForMember(dest => dest.EmailVerified, opt => opt.MapFrom(src => + src.Claims.FirstOrDefault(c => c.Type == "email_verified")!.Value == "true")); + } +} \ No newline at end of file diff --git a/src/Imprink.Application/Services/ICurrentUserService.cs b/src/Imprink.Application/Users/Services/ICurrentUserService.cs similarity index 61% rename from src/Imprink.Application/Services/ICurrentUserService.cs rename to src/Imprink.Application/Users/Services/ICurrentUserService.cs index 83bbe41..86b15a4 100644 --- a/src/Imprink.Application/Services/ICurrentUserService.cs +++ b/src/Imprink.Application/Users/Services/ICurrentUserService.cs @@ -1,4 +1,4 @@ -namespace Imprink.Application.Services; +namespace Imprink.Application.Users.Services; public interface ICurrentUserService { diff --git a/src/Imprink.Application/Validation/Models/Auth0UserValidator.cs b/src/Imprink.Application/Users/Validation/Auth0UserValidator.cs similarity index 89% rename from src/Imprink.Application/Validation/Models/Auth0UserValidator.cs rename to src/Imprink.Application/Users/Validation/Auth0UserValidator.cs index 4df6070..309558b 100644 --- a/src/Imprink.Application/Validation/Models/Auth0UserValidator.cs +++ b/src/Imprink.Application/Users/Validation/Auth0UserValidator.cs @@ -1,7 +1,7 @@ using FluentValidation; using Imprink.Domain.Models; -namespace Imprink.Application.Validation.Models; +namespace Imprink.Application.Users.Validation; public class Auth0UserValidator : AbstractValidator { diff --git a/src/Imprink.Application/Validation/Users/SetUserFullNameCommandValidator.cs b/src/Imprink.Application/Users/Validation/SetUserFullNameCommandValidator.cs similarity index 85% rename from src/Imprink.Application/Validation/Users/SetUserFullNameCommandValidator.cs rename to src/Imprink.Application/Users/Validation/SetUserFullNameCommandValidator.cs index b97eed6..cadda16 100644 --- a/src/Imprink.Application/Validation/Users/SetUserFullNameCommandValidator.cs +++ b/src/Imprink.Application/Users/Validation/SetUserFullNameCommandValidator.cs @@ -1,7 +1,7 @@ using FluentValidation; -using Imprink.Application.Domains.Users; +using Imprink.Application.Users.Commands; -namespace Imprink.Application.Validation.Users; +namespace Imprink.Application.Users.Validation; public class SetUserFullNameCommandValidator : AbstractValidator { diff --git a/src/Imprink.Application/Validation/Users/SetUserPhoneCommandValidator.cs b/src/Imprink.Application/Users/Validation/SetUserPhoneCommandValidator.cs similarity index 80% rename from src/Imprink.Application/Validation/Users/SetUserPhoneCommandValidator.cs rename to src/Imprink.Application/Users/Validation/SetUserPhoneCommandValidator.cs index 54a73a8..b0c0508 100644 --- a/src/Imprink.Application/Validation/Users/SetUserPhoneCommandValidator.cs +++ b/src/Imprink.Application/Users/Validation/SetUserPhoneCommandValidator.cs @@ -1,7 +1,7 @@ using FluentValidation; -using Imprink.Application.Domains.Users; +using Imprink.Application.Users.Commands; -namespace Imprink.Application.Validation.Users; +namespace Imprink.Application.Users.Validation; public class SetUserPhoneCommandValidator : AbstractValidator { diff --git a/src/Imprink.Domain/Entities/Orders/OrderItem.cs b/src/Imprink.Domain/Entities/Orders/OrderItem.cs index 4013d51..7f63ce2 100644 --- a/src/Imprink.Domain/Entities/Orders/OrderItem.cs +++ b/src/Imprink.Domain/Entities/Orders/OrderItem.cs @@ -1,4 +1,4 @@ -using Imprink.Domain.Entities.Product; +using Imprink.Domain.Entities.Products; namespace Imprink.Domain.Entities.Orders; @@ -14,6 +14,6 @@ public class OrderItem : EntityBase public string CustomizationDescription { get; set; } = null!; public Order Order { get; set; } = null!; - public Product.Product Product { get; set; } = null!; + public Product Product { get; set; } = null!; public ProductVariant ProductVariant { get; set; } = null!; } \ No newline at end of file diff --git a/src/Imprink.Domain/Entities/Products/Category.cs b/src/Imprink.Domain/Entities/Products/Category.cs index 3bbf53c..19d4299 100644 --- a/src/Imprink.Domain/Entities/Products/Category.cs +++ b/src/Imprink.Domain/Entities/Products/Category.cs @@ -1,4 +1,4 @@ -namespace Imprink.Domain.Entities.Product; +namespace Imprink.Domain.Entities.Products; public class Category : EntityBase { diff --git a/src/Imprink.Domain/Entities/Products/Product.cs b/src/Imprink.Domain/Entities/Products/Product.cs index d728d5b..e551681 100644 --- a/src/Imprink.Domain/Entities/Products/Product.cs +++ b/src/Imprink.Domain/Entities/Products/Product.cs @@ -1,6 +1,6 @@ using Imprink.Domain.Entities.Orders; -namespace Imprink.Domain.Entities.Product; +namespace Imprink.Domain.Entities.Products; public class Product : EntityBase { diff --git a/src/Imprink.Domain/Entities/Products/ProductVariant.cs b/src/Imprink.Domain/Entities/Products/ProductVariant.cs index 5dd781e..a802569 100644 --- a/src/Imprink.Domain/Entities/Products/ProductVariant.cs +++ b/src/Imprink.Domain/Entities/Products/ProductVariant.cs @@ -1,6 +1,6 @@ using Imprink.Domain.Entities.Orders; -namespace Imprink.Domain.Entities.Product; +namespace Imprink.Domain.Entities.Products; public class ProductVariant : EntityBase { @@ -13,6 +13,6 @@ public class ProductVariant : EntityBase public int StockQuantity { get; set; } public bool IsActive { get; set; } - public virtual required Imprink.Domain.Entities.Product.Product Product { get; set; } + public virtual required Product Product { get; set; } public virtual ICollection OrderItems { get; set; } = new List(); } \ No newline at end of file diff --git a/src/Imprink.Domain/Repositories/Products/ICategoryRepository.cs b/src/Imprink.Domain/Repositories/Products/ICategoryRepository.cs index 3308a6e..ba41959 100644 --- a/src/Imprink.Domain/Repositories/Products/ICategoryRepository.cs +++ b/src/Imprink.Domain/Repositories/Products/ICategoryRepository.cs @@ -1,4 +1,4 @@ -using Imprink.Domain.Entities.Product; +using Imprink.Domain.Entities.Products; namespace Imprink.Domain.Repositories.Products; diff --git a/src/Imprink.Domain/Repositories/Products/IProductRepository.cs b/src/Imprink.Domain/Repositories/Products/IProductRepository.cs index 9fd577e..a4dd90a 100644 --- a/src/Imprink.Domain/Repositories/Products/IProductRepository.cs +++ b/src/Imprink.Domain/Repositories/Products/IProductRepository.cs @@ -1,4 +1,4 @@ -using Imprink.Domain.Entities.Product; +using Imprink.Domain.Entities.Products; using Imprink.Domain.Models; namespace Imprink.Domain.Repositories.Products; diff --git a/src/Imprink.Domain/Repositories/Products/IProductVariantRepository.cs b/src/Imprink.Domain/Repositories/Products/IProductVariantRepository.cs index ae8af5e..8f01e7e 100644 --- a/src/Imprink.Domain/Repositories/Products/IProductVariantRepository.cs +++ b/src/Imprink.Domain/Repositories/Products/IProductVariantRepository.cs @@ -1,4 +1,4 @@ -using Imprink.Domain.Entities.Product; +using Imprink.Domain.Entities.Products; namespace Imprink.Domain.Repositories.Products; diff --git a/src/Imprink.Domain/Repositories/Users/IRoleRepository.cs b/src/Imprink.Domain/Repositories/Users/IRoleRepository.cs index f92043c..f2dfee2 100644 --- a/src/Imprink.Domain/Repositories/Users/IRoleRepository.cs +++ b/src/Imprink.Domain/Repositories/Users/IRoleRepository.cs @@ -1,6 +1,6 @@ using Imprink.Domain.Entities.Users; -namespace Imprink.Domain.Repositories; +namespace Imprink.Domain.Repositories.Users; public interface IRoleRepository { diff --git a/src/Imprink.Infrastructure/Configuration/Products/CategoryConfiguration.cs b/src/Imprink.Infrastructure/Configuration/Products/CategoryConfiguration.cs index 0867cb7..b019efa 100644 --- a/src/Imprink.Infrastructure/Configuration/Products/CategoryConfiguration.cs +++ b/src/Imprink.Infrastructure/Configuration/Products/CategoryConfiguration.cs @@ -1,4 +1,4 @@ -using Imprink.Domain.Entities.Product; +using Imprink.Domain.Entities.Products; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; diff --git a/src/Imprink.Infrastructure/Configuration/Products/ProductConfiguration.cs b/src/Imprink.Infrastructure/Configuration/Products/ProductConfiguration.cs index ed3054e..49bb909 100644 --- a/src/Imprink.Infrastructure/Configuration/Products/ProductConfiguration.cs +++ b/src/Imprink.Infrastructure/Configuration/Products/ProductConfiguration.cs @@ -1,4 +1,4 @@ -using Imprink.Domain.Entities.Product; +using Imprink.Domain.Entities.Products; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; diff --git a/src/Imprink.Infrastructure/Configuration/Products/ProductVariantConfiguration.cs b/src/Imprink.Infrastructure/Configuration/Products/ProductVariantConfiguration.cs index 7593b6b..42dd79a 100644 --- a/src/Imprink.Infrastructure/Configuration/Products/ProductVariantConfiguration.cs +++ b/src/Imprink.Infrastructure/Configuration/Products/ProductVariantConfiguration.cs @@ -1,4 +1,4 @@ -using Imprink.Domain.Entities.Product; +using Imprink.Domain.Entities.Products; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; diff --git a/src/Imprink.Infrastructure/Database/ApplicationDbContext.cs b/src/Imprink.Infrastructure/Database/ApplicationDbContext.cs index 4fe7a92..96eaeed 100644 --- a/src/Imprink.Infrastructure/Database/ApplicationDbContext.cs +++ b/src/Imprink.Infrastructure/Database/ApplicationDbContext.cs @@ -1,5 +1,5 @@ using Imprink.Domain.Entities.Orders; -using Imprink.Domain.Entities.Product; +using Imprink.Domain.Entities.Products; using Imprink.Domain.Entities.Users; using Imprink.Infrastructure.Configuration.Orders; using Imprink.Infrastructure.Configuration.Products; diff --git a/src/Imprink.Infrastructure/Repositories/Products/CategoryRepository.cs b/src/Imprink.Infrastructure/Repositories/Products/CategoryRepository.cs index b5d9873..89afab7 100644 --- a/src/Imprink.Infrastructure/Repositories/Products/CategoryRepository.cs +++ b/src/Imprink.Infrastructure/Repositories/Products/CategoryRepository.cs @@ -1,4 +1,4 @@ -using Imprink.Domain.Entities.Product; +using Imprink.Domain.Entities.Products; using Imprink.Domain.Repositories.Products; using Imprink.Infrastructure.Database; using Microsoft.EntityFrameworkCore; diff --git a/src/Imprink.Infrastructure/Repositories/Products/ProductRepository.cs b/src/Imprink.Infrastructure/Repositories/Products/ProductRepository.cs index 95af010..7c8acdd 100644 --- a/src/Imprink.Infrastructure/Repositories/Products/ProductRepository.cs +++ b/src/Imprink.Infrastructure/Repositories/Products/ProductRepository.cs @@ -1,4 +1,4 @@ -using Imprink.Domain.Entities.Product; +using Imprink.Domain.Entities.Products; using Imprink.Domain.Models; using Imprink.Domain.Repositories.Products; using Imprink.Infrastructure.Database; diff --git a/src/Imprink.Infrastructure/Repositories/Products/ProductVariantRepository.cs b/src/Imprink.Infrastructure/Repositories/Products/ProductVariantRepository.cs index 1c892bf..e97babf 100644 --- a/src/Imprink.Infrastructure/Repositories/Products/ProductVariantRepository.cs +++ b/src/Imprink.Infrastructure/Repositories/Products/ProductVariantRepository.cs @@ -1,4 +1,4 @@ -using Imprink.Domain.Entities.Product; +using Imprink.Domain.Entities.Products; using Imprink.Domain.Repositories.Products; using Imprink.Infrastructure.Database; using Microsoft.EntityFrameworkCore; diff --git a/src/Imprink.Infrastructure/Repositories/Users/RoleRepository.cs b/src/Imprink.Infrastructure/Repositories/Users/RoleRepository.cs index bf64712..23ce386 100644 --- a/src/Imprink.Infrastructure/Repositories/Users/RoleRepository.cs +++ b/src/Imprink.Infrastructure/Repositories/Users/RoleRepository.cs @@ -1,5 +1,6 @@ using Imprink.Domain.Entities.Users; using Imprink.Domain.Repositories; +using Imprink.Domain.Repositories.Users; using Imprink.Infrastructure.Database; using Microsoft.EntityFrameworkCore; diff --git a/src/Imprink.Infrastructure/Services/CurrentUserService.cs b/src/Imprink.Infrastructure/Services/CurrentUserService.cs index 89ffbe9..52102cc 100644 --- a/src/Imprink.Infrastructure/Services/CurrentUserService.cs +++ b/src/Imprink.Infrastructure/Services/CurrentUserService.cs @@ -1,5 +1,5 @@ using System.Security.Claims; -using Imprink.Application.Services; +using Imprink.Application.Users.Services; using Microsoft.AspNetCore.Http; namespace Imprink.Infrastructure.Services; diff --git a/src/Imprink.WebApi/Controllers/Products/CategoriesController.cs b/src/Imprink.WebApi/Controllers/Products/CategoriesController.cs index ba087ae..04d9b32 100644 --- a/src/Imprink.WebApi/Controllers/Products/CategoriesController.cs +++ b/src/Imprink.WebApi/Controllers/Products/CategoriesController.cs @@ -1,4 +1,5 @@ -using Imprink.Application.Domains.Categories; +using Imprink.Application.Categories.Commands; +using Imprink.Application.Categories.Dtos; using Imprink.Application.Products.Dtos; using MediatR; using Microsoft.AspNetCore.Authorization; diff --git a/src/Imprink.WebApi/Controllers/Products/ProductVariantsController.cs b/src/Imprink.WebApi/Controllers/Products/ProductVariantsController.cs index 745de3e..7b065a2 100644 --- a/src/Imprink.WebApi/Controllers/Products/ProductVariantsController.cs +++ b/src/Imprink.WebApi/Controllers/Products/ProductVariantsController.cs @@ -1,5 +1,6 @@ -using Imprink.Application.Domains.ProductVariants; using Imprink.Application.Products.Dtos; +using Imprink.Application.ProductVariants.Commands; +using Imprink.Application.ProductVariants.Dtos; using MediatR; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; diff --git a/src/Imprink.WebApi/Controllers/Products/ProductsController.cs b/src/Imprink.WebApi/Controllers/Products/ProductsController.cs index e1f7fc5..be28cd5 100644 --- a/src/Imprink.WebApi/Controllers/Products/ProductsController.cs +++ b/src/Imprink.WebApi/Controllers/Products/ProductsController.cs @@ -1,5 +1,5 @@ -using Imprink.Application.Domains.Products; using Imprink.Application.Products; +using Imprink.Application.Products.Commands; using Imprink.Application.Products.Dtos; using Imprink.Domain.Models; using MediatR; diff --git a/src/Imprink.WebApi/Controllers/Users/UsersController.cs b/src/Imprink.WebApi/Controllers/Users/UsersController.cs index 53b6830..42b43de 100644 --- a/src/Imprink.WebApi/Controllers/Users/UsersController.cs +++ b/src/Imprink.WebApi/Controllers/Users/UsersController.cs @@ -1,5 +1,7 @@ using System.Security.Claims; -using Imprink.Application.Domains.Users; +using AutoMapper; +using Imprink.Application.Users.Commands; +using Imprink.Application.Users.Dtos; using Imprink.Domain.Models; using MediatR; using Microsoft.AspNetCore.Authorization; @@ -9,30 +11,21 @@ namespace Imprink.WebApi.Controllers.Users; [ApiController] [Route("/api/users")] -public class UsersController(IMediator mediator) : ControllerBase +public class UsersController(IMediator mediator, IMapper mapper) : ControllerBase { [Authorize] [HttpPost("me/sync")] public async Task SyncMyProfile() { - var claims = User.Claims as Claim[] ?? User.Claims.ToArray(); - - var auth0User = new Auth0User - { - Sub = claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value ?? string.Empty, - Name = claims.FirstOrDefault(c => c.Type == "name")?.Value ?? string.Empty, - Nickname = claims.FirstOrDefault(c => c.Type == "nickname")?.Value ?? string.Empty, - Email = claims.FirstOrDefault(c => c.Type == ClaimTypes.Email)?.Value ?? string.Empty, - EmailVerified = bool.TryParse(claims.FirstOrDefault(c => c.Type == "email_verified")?.Value, out var emailVerified) && emailVerified - }; + var auth0User = mapper.Map(User); await mediator.Send(new SyncUserCommand(auth0User)); - return Ok("User profile synchronized."); + return Ok("Synced"); } [Authorize] [HttpGet("me/roles")] - public async Task GetMyRoles() + public async Task>> GetMyRoles() { var sub = User.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? string.Empty; return Ok(await mediator.Send(new GetUserRolesCommand(sub))); @@ -40,21 +33,29 @@ public class UsersController(IMediator mediator) : ControllerBase [Authorize] [HttpPut("me/phone")] - public async Task UpdateMyPhone([FromBody] SetUserPhoneCommand command) + public async Task> UpdateMyPhone([FromBody] SetUserPhoneCommand command) { return Ok(await mediator.Send(command)); } [Authorize] [HttpPut("me/fullname")] - public async Task UpdateMyFullName([FromBody] SetUserFullNameCommand command) + public async Task> UpdateMyFullName([FromBody] SetUserFullNameCommand command) { return Ok(await mediator.Send(command)); } + [Authorize] + [HttpGet("roles")] + public async Task> GetAllRoles() + { + var command = new GetAllRolesCommand(); + return Ok(await mediator.Send(command)); + } + [Authorize(Roles = "Admin")] [HttpPut("{userId}/roles/{roleId:guid}")] - public async Task AddUserRole(string userId, Guid roleId) + public async Task> AddUserRole(string userId, Guid roleId) { var command = new SetUserRoleCommand(userId, roleId); return Ok(await mediator.Send(command)); @@ -62,7 +63,7 @@ public class UsersController(IMediator mediator) : ControllerBase [Authorize(Roles = "Admin")] [HttpDelete("{userId}/roles/{roleId:guid}")] - public async Task RemoveUserRole(string userId, Guid roleId) + public async Task> RemoveUserRole(string userId, Guid roleId) { var command = new DeleteUserRoleCommand(userId, roleId); return Ok(await mediator.Send(command)); diff --git a/src/Imprink.WebApi/Middleware/ExceptionHandlingMiddleware.cs b/src/Imprink.WebApi/Middleware/ExceptionHandlingMiddleware.cs index eb70eab..9e88443 100644 --- a/src/Imprink.WebApi/Middleware/ExceptionHandlingMiddleware.cs +++ b/src/Imprink.WebApi/Middleware/ExceptionHandlingMiddleware.cs @@ -61,6 +61,7 @@ public class ExceptionHandlingMiddleware( return exception switch { NotFoundException => (HttpStatusCode.NotFound, exception.Message, false), + DataUpdateException => (HttpStatusCode.Conflict, exception.Message, false), _ => (HttpStatusCode.InternalServerError, "An internal server error occurred", true) }; } diff --git a/src/Imprink.WebApi/Program.cs b/src/Imprink.WebApi/Program.cs index 3992d18..120a9d8 100644 --- a/src/Imprink.WebApi/Program.cs +++ b/src/Imprink.WebApi/Program.cs @@ -13,5 +13,3 @@ var app = builder.Build(); Startup.Configure(app, app.Environment); app.Run(); - -public partial class Program { } \ No newline at end of file diff --git a/src/Imprink.WebApi/Seeder.cs b/src/Imprink.WebApi/Seeder.cs index 14f4016..fa66f6f 100644 --- a/src/Imprink.WebApi/Seeder.cs +++ b/src/Imprink.WebApi/Seeder.cs @@ -1,4 +1,4 @@ -using Imprink.Domain.Entities.Product; +using Imprink.Domain.Entities.Products; using Imprink.Infrastructure.Database; using Microsoft.EntityFrameworkCore; diff --git a/src/Imprink.WebApi/Startup.cs b/src/Imprink.WebApi/Startup.cs index 0f7403d..40b612b 100644 --- a/src/Imprink.WebApi/Startup.cs +++ b/src/Imprink.WebApi/Startup.cs @@ -1,10 +1,10 @@ using System.Security.Claims; using FluentValidation; using Imprink.Application; -using Imprink.Application.Domains.Products; using Imprink.Application.Products; -using Imprink.Application.Services; -using Imprink.Application.Validation.Models; +using Imprink.Application.Products.Commands; +using Imprink.Application.Users.Services; +using Imprink.Application.Users.Validation; using Imprink.Domain.Repositories; using Imprink.Domain.Repositories.Orders; using Imprink.Domain.Repositories.Products; @@ -39,8 +39,9 @@ public static class Startup services.AddScoped(); services.AddScoped(); services.AddScoped(); - services.AddScoped(); + + services.AddAutoMapper(typeof(MappingProfile).Assembly); services.AddHttpContextAccessor(); diff --git a/webui/src/app/page.js b/webui/src/app/page.js index c2d8331..141ace0 100644 --- a/webui/src/app/page.js +++ b/webui/src/app/page.js @@ -1,423 +1,192 @@ -'use client' +'use client'; -import {useEffect, useState} from 'react'; -import axios from 'axios'; -import { - Alert, - AppBar, - Badge, - Box, - Button, - Card, - CardActions, - CardContent, - CardMedia, - Chip, - Container, - Fab, - Grid, - IconButton, - Skeleton, - Toolbar, - Typography -} from '@mui/material'; -import {createTheme, ThemeProvider} from '@mui/material/styles'; -import CssBaseline from '@mui/material/CssBaseline'; -import {Menu, Palette, Search, ShoppingCart} from 'lucide-react'; +import { useUser } from "@auth0/nextjs-auth0"; +import {useEffect, useState} from "react"; -const theme = createTheme({ - palette: { - mode: 'dark', - primary: { - main: '#D0BCFF', - light: '#EADDFF', - dark: '#9A82DB', - contrastText: '#21005D' - }, - secondary: { - main: '#CCC2DC', - light: '#E8DEF8', - dark: '#A8A2BA', - contrastText: '#332D41' - }, - background: { - default: '#101418', - paper: '#1D1B20' - }, - surface: { - main: '#1D1B20', - variant: '#49454F' - }, - error: { - main: '#F2B8B5', - light: '#FFDAD6', - dark: '#BA1A1A', - contrastText: '#410002' - }, - success: { - main: '#A6D4A3', - light: '#C4F0B8', - dark: '#52B788' - }, - text: { - primary: '#E6E0E9', - secondary: '#CAC4D0' - } - }, - shape: { - borderRadius: 16 - }, - typography: { - fontFamily: '"Google Sans", "Roboto", "Helvetica", "Arial", sans-serif', - h4: { - fontWeight: 400, - fontSize: '2rem' - }, - h6: { - fontWeight: 500, - fontSize: '1.25rem' - }, - body1: { - fontSize: '1rem', - lineHeight: 1.5 - }, - body2: { - fontSize: '0.875rem', - lineHeight: 1.43 - } - }, - components: { - MuiCard: { - styleOverrides: { - root: { - backgroundImage: 'none', - backgroundColor: '#1D1B20', - border: '1px solid #49454F', - transition: 'all 0.3s ease', - '&:hover': { - transform: 'translateY(-4px)', - borderColor: '#D0BCFF', - boxShadow: '0 8px 32px rgba(208, 188, 255, 0.1)' - } - } - } - }, - MuiButton: { - styleOverrides: { - root: { - textTransform: 'none', - fontWeight: 500, - borderRadius: 20, - paddingLeft: 24, - paddingRight: 24, - height: 40 - } - } - }, - MuiTextField: { - styleOverrides: { - root: { - '& .MuiOutlinedInput-root': { - borderRadius: 12, - backgroundColor: '#1D1B20', - '& fieldset': { - borderColor: '#49454F' - }, - '&:hover fieldset': { - borderColor: '#CAC4D0' - } - } - } - } - }, - MuiChip: { - styleOverrides: { - root: { - borderRadius: 8 - } - } - } - } -}); - -const ProductCard = ({ product }) => { - const [imageLoaded, setImageLoaded] = useState(false); - - return ( - - - {!imageLoaded && ( - - )} - setImageLoaded(true)} - sx={{ - display: imageLoaded ? 'block' : 'none', - objectFit: 'cover', - transition: 'transform 0.3s ease', - '&:hover': { - transform: 'scale(1.05)' - } - }} - /> - - {product.isCustomizable && ( - } - label="Customizable" - size="small" - color="primary" - sx={{ fontSize: '0.75rem' }} - /> - )} - - - - - - - {product.name} - - - {product.description} - - - ${product.basePrice.toFixed(2)} - - - - - - - - ); -}; - -const LoadingSkeleton = () => ( - - {[...Array(8)].map((_, index) => ( - - - - - - - - - - - - ))} - -); - -const ImprintLanding = () => { - const [products, setProducts] = useState([]); - const [loading, setLoading] = useState(true); - const [error, setError] = useState(null); - const [cartCount, setCartCount] = useState(0); +export default function Home() { + const { user, error, isLoading } = useUser(); useEffect(() => { - const fetchProducts = async () => { - try { - setLoading(true); - const response = await axios.get('https://impr.ink/api/products', { - params: { - PageNumber: 1, - PageSize: 20 - } - }); - setProducts(response.data.items); - } catch (err) { - setError('Failed to load products. Please try again later.'); - console.error('Error fetching products:', err); - } finally { - setLoading(false); + const fetchAccessToken = async () => { + if (user) { + try { + await fetch('/token'); + } catch (error) { + console.error("Error fetching token"); + } + } else { + try { + await fetch('/untoken'); + } catch (e) { + console.error('Error in /api/untoken:', e); + } } }; - fetchProducts().then(r => console.log(r)); - }, []); + fetchAccessToken().then(r => console.log(r)); + }, [user]); + + if (isLoading) { + return ( +
+
+
+
+
+
+
+
+ ); + } + + if (error) { + return ( + + ); + } - const featuredProducts = products.slice(0, 4); return ( - - - - {/* App Bar */} - - - - - - - impr.ink - - - - - - - - - - - +
+
+ {user ? ( +
+
+
+ {user.picture ? ( + Profile + ) : ( +
+ {user.name?.charAt(0) || user.email?.charAt(0) || '👤'} +
+ )} +
+

+ Just testing :P +

+
- {/* Hero Section */} - - - - - Custom Printing Made Beautiful - - - High-quality custom printing solutions for caps, flyers, coasters, and more. - Premium materials with excellent print adhesion and longevity. - -
+ + + + Check + + + - Load More Products - - - )} - - - {/* Floating Action Button */} - - - - - - - +
+ + Sign Out + +
+
+
+ ) : ( +
+ )} + + ); -}; - -export default ImprintLanding; \ No newline at end of file +} \ No newline at end of file