diff --git a/NetinaShop.AdminPanel.PWA/Dialogs/ProductActionDialogBox.razor b/NetinaShop.AdminPanel.PWA/Dialogs/ProductActionDialogBox.razor index 41924fd..236cfd6 100644 --- a/NetinaShop.AdminPanel.PWA/Dialogs/ProductActionDialogBox.razor +++ b/NetinaShop.AdminPanel.PWA/Dialogs/ProductActionDialogBox.razor @@ -1,105 +1,270 @@ @using Radzen.Blazor +@using NetinaShop.AdminPanel.PWA.Extensions + +@inject ISnackbar Snackbar +@inject IRestWrapper RestWrapper +@inject IUserUtility UserUtility +@inject IDialogService DialogService + + + + + - - + + + - اطلاعات کلی - اطلاعات کلی محصول را به دقت وارد کنید - - - - - - - - - - - - - - - - - - - - - - - - - + اطلاعات کلی + اطلاعات کلی محصول را به دقت وارد کنید + + - توضیحات تکمیلی - می توانید توضیحاتــ تکمیلی محصول را کامل وارد کنید - - - - - - + + + + + + + - - + + + + +
+ +

منتظر بمانید

+
+
+
+
+ +

@e.Name

+
+
+
+ - - - - - + + + + +
+ +

منتظر بمانید

+
+
+
+
+ +

@e.Name

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + -
+ ویژگی های کلی + می توانید ویگی های تکمیلی محصول را کامل وارد کنید +
+ - - - + + + - تصاویر محصول - می توانید برای محصول چند تصویر اپلود کنید - - + + + + + + افزودن + + + + + + + + + + + حذف + + + + + + + + + + + + + توضیحات تکمیلی + می توانید توضیحاتــ تکمیلی محصول را کامل وارد کنید + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + تصاویر محصول + می توانید برای محصول چند تصویر اپلود کنید + + + + + @foreach (var item in ViewModel.Files) + { +
+ + + +
+ } + +
+ +
+
- - تایید - بستن + - + @if (ViewModel.IsEditing) + { + + } + else + { + + } + + بستن +
@code { - [CascadingParameter] MudDialogInstance MudDialog { get; set; } + [CascadingParameter] + MudDialogInstance MudDialog { get; set; } - void Submit() => MudDialog.Close(DialogResult.Ok(true)); - void Cancel() => MudDialog.Cancel(); - - private bool _isEditing = false; - private bool _isProcessing = false; - - private ProductSDto? _product = null; [Parameter] - public ProductSDto? Product + public ProductSDto? Product { get; set; } + + public ProductActionDialogBoxViewModel ViewModel { get; set; } + protected override async Task OnInitializedAsync() { - get => _product; - set - { - _product = value; - if (_product != null) - { - _isEditing = true; - } - } + if (Product == null) + ViewModel = new ProductActionDialogBoxViewModel(Snackbar, RestWrapper, UserUtility, DialogService, MudDialog); + else + ViewModel = new ProductActionDialogBoxViewModel(Snackbar, RestWrapper, UserUtility, DialogService, MudDialog, Product); + await ViewModel.InitializeAsync(); + await base.OnInitializedAsync(); } + } \ No newline at end of file diff --git a/NetinaShop.AdminPanel.PWA/Dialogs/ProductActionDialogBox.razor.cs b/NetinaShop.AdminPanel.PWA/Dialogs/ProductActionDialogBox.razor.cs new file mode 100644 index 0000000..52ea191 --- /dev/null +++ b/NetinaShop.AdminPanel.PWA/Dialogs/ProductActionDialogBox.razor.cs @@ -0,0 +1,272 @@ +namespace NetinaShop.AdminPanel.PWA.Dialogs; + +public class ProductActionDialogBoxViewModel : BaseViewModel +{ + private readonly ISnackbar _snackbar; + private readonly IRestWrapper _restWrapper; + private readonly IUserUtility _userUtility; + private readonly IDialogService _dialogService; + private readonly MudDialogInstance _mudDialog; + + public ProductActionDialogBoxViewModel(ISnackbar snackbar, IRestWrapper restWrapper, IUserUtility userUtility, IDialogService dialogService, MudDialogInstance mudDialog) + { + _snackbar = snackbar; + _restWrapper = restWrapper; + _userUtility = userUtility; + _dialogService = dialogService; + _mudDialog = mudDialog; + } + public ProductActionDialogBoxViewModel(ISnackbar snackbar, + IRestWrapper restWrapper, + IUserUtility userUtility, + IDialogService dialogService, + MudDialogInstance mudDialog, + ProductSDto product) + { + _snackbar = snackbar; + _restWrapper = restWrapper; + _userUtility = userUtility; + _dialogService = dialogService; + _mudDialog = mudDialog; + Product = product; + } + + private ProductSDto? _product = null; + public ProductSDto? Product + { + get => _product; + set + { + _product = value; + if (_product != null) + { + IsEditing = true; + } + } + } + + public void Cancel() => _mudDialog.Cancel(); + + public bool IsEditing = false; + public string ExpertCheck = string.Empty; + public string Summery = string.Empty; + public bool BeDisplayed = true; + public bool HasExpressDelivery = false; + public string PersianName = string.Empty; + public string EnglishName = string.Empty; + public double Cost; + public double PackingCost; + public int MaxOrder; + public string Warranty = string.Empty; + public string Tags = string.Empty; + + public string SpecificationTitle = string.Empty; + public string SpecificationValue = string.Empty; + public readonly ObservableCollection Specifications = new ObservableCollection(); + public readonly ObservableCollection Files = new ObservableCollection(); + + + + public async Task SubmitEditAsync() + { + try + { + IsProcessing = true; + if (Product == null || Product.Id == default) + throw new Exception("محصول اشتباه است"); + var token = await _userUtility.GetBearerTokenAsync(); + var request = new UpdateProductCommand(Product.Id, PersianName, EnglishName, Summery, ExpertCheck, Tags, Warranty, BeDisplayed, Cost, PackingCost, HasExpressDelivery, MaxOrder, _selectedBrand?.Id ?? default, _selectedCategory?.Id ?? default, Specifications.ToList(), Files.ToList()); + await _restWrapper.CrudApiRest(Address.ProductController).Update(request, token); + _snackbar.Add($"ویرایش محصول {PersianName} با موفقیت انجام شد", Severity.Success); + _mudDialog.Close(); + } + catch (ApiException ex) + { + var exe = await ex.GetContentAsAsync(); + if (exe != null) + _snackbar.Add(exe.Message, Severity.Error); + _snackbar.Add(ex.Content, Severity.Error); + _mudDialog.Cancel(); + } + catch (Exception e) + { + _snackbar.Add(e.Message, Severity.Error); + _mudDialog.Cancel(); + } + finally + { + + IsProcessing = false; + } + } + + public void AddSpecification() + { + try + { + if (SpecificationTitle.IsNullOrEmpty()) + throw new AppException("عنوان ویژگی مورد نظر را وارد کنید"); + if (SpecificationValue.IsNullOrEmpty()) + throw new AppException("مقدار ویژگی مورد نظر را وارد کنید"); + Specifications.Add(new SpecificationSDto { Title = SpecificationTitle.ToString(), Value = SpecificationValue.ToString() }); + + SpecificationTitle = string.Empty; + SpecificationValue = string.Empty; + } + catch (Exception e) + { + _snackbar.Add(e.Message, Severity.Error); + } + } + + public void RemoveSpecification(SpecificationSDto specification) + { + var spec = Specifications.FirstOrDefault(s => s.Value == specification.Value && s.Title == specification.Title); + if (spec != null) + Specifications.Remove(spec); + } + public async Task SubmitCreateAsync() + { + try + { + IsProcessing = true; + var token = await _userUtility.GetBearerTokenAsync(); + var request = new CreateProductCommand(PersianName, EnglishName, Summery, ExpertCheck, Tags, Warranty, BeDisplayed, Cost, PackingCost, HasExpressDelivery, MaxOrder, _selectedBrand?.Id ?? default, _selectedCategory?.Id ?? default, Specifications.ToList(), Files.ToList()); + await _restWrapper.CrudApiRest(Address.ProductController).Create(request, token); + + _snackbar.Add($"ساخت محصول {PersianName} با موفقیت انجام شد", Severity.Success); + _mudDialog.Close(); + } + catch (ApiException ex) + { + var exe = await ex.GetContentAsAsync(); + if (exe != null) + _snackbar.Add(exe.Message, Severity.Error); + _snackbar.Add(ex.Content, Severity.Error); + _mudDialog.Cancel(); + } + catch (Exception e) + { + _snackbar.Add(e.Message, Severity.Error); + _mudDialog.Cancel(); + } + finally + { + + IsProcessing = false; + } + } + public override async Task InitializeAsync() + { + if (IsEditing && _product != null) + { + try + { + IsProcessing = true; + var productLDto = await _restWrapper.CrudDtoApiRest(Address.ProductController).ReadOne(_product.Id); + ExpertCheck = productLDto.ExpertCheck; + Summery = productLDto.Summery; + BeDisplayed = productLDto.BeDisplayed; + HasExpressDelivery = productLDto.HasExpressDelivery; + PersianName = productLDto.PersianName; + EnglishName = productLDto.EnglishName; + Cost = productLDto.Cost; + PackingCost = productLDto.PackingCost; + MaxOrder = productLDto.MaxOrderCount; + Warranty = productLDto.Warranty; + productLDto.Specifications.ForEach(s => Specifications.Add(s)); + productLDto.Files.ForEach(f => Files.Add(f)); + _selectedCategory = new ProductCategorySDto { Id = productLDto.CategoryId, Name = productLDto.CategoryName }; + _selectedBrand = new BrandSDto { Id = productLDto.BrandId, Name = productLDto.BrandName }; + } + catch (ApiException ex) + { + var exe = await ex.GetContentAsAsync(); + if (exe != null) + _snackbar.Add(exe.Message, Severity.Error); + _snackbar.Add(ex.Content, Severity.Error); + _mudDialog.Cancel(); + } + catch (Exception e) + { + _snackbar.Add(e.Message, Severity.Error); + _mudDialog.Cancel(); + } + finally + { + + IsProcessing = false; + } + }; + } + + + public List _productCategories = new List(); + public ProductCategorySDto? _selectedCategory; + public async Task> SearchProductCategory(string category) + { + try + { + if (category.IsNullOrEmpty()) + _productCategories = await _restWrapper.ProductCategoryRestApi.ReadAll(0); + else + _productCategories = await _restWrapper.ProductCategoryRestApi.ReadAll(category); + return _productCategories; + } + catch (ApiException ex) + { + var exe = await ex.GetContentAsAsync(); + if (exe != null) + _snackbar.Add(exe.Message, Severity.Error); + _snackbar.Add(ex.Content, Severity.Error); + return _productCategories; + } + catch (Exception e) + { + _snackbar.Add(e.Message, Severity.Error); + return _productCategories; + } + } + + public List _brands = new List(); + public BrandSDto? _selectedBrand; + public async Task> SearchBrand(string brand) + { + try + { + if (brand.IsNullOrEmpty()) + _brands = await _restWrapper.BrandRestApi.ReadAll(0); + else + _brands = await _restWrapper.BrandRestApi.ReadAll(brand); + return _brands; + } + catch (ApiException ex) + { + var exe = await ex.GetContentAsAsync(); + if (exe != null) + _snackbar.Add(exe.Message, Severity.Error); + _snackbar.Add(ex.Content, Severity.Error); + return _brands; + } + catch (Exception e) + { + _snackbar.Add(e.Message, Severity.Error); + return _brands; + } + } + + public async Task SelectFileAsync() + { + DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, DisableBackdropClick = true }; + var dialog = await _dialogService.ShowAsync("انتخاب عکس", maxWidth); + var result = await dialog.Result; + var file = result.Data; + if (file is StorageFileSDto storageFile) + Files.Add(storageFile); + } + + public void RemoveFile(StorageFileSDto file) + { + Files.Remove(file); + } +} \ No newline at end of file diff --git a/NetinaShop.AdminPanel.PWA/Dialogs/ProductCategoryActionDialogBox.razor b/NetinaShop.AdminPanel.PWA/Dialogs/ProductCategoryActionDialogBox.razor index 7477667..0325e03 100644 --- a/NetinaShop.AdminPanel.PWA/Dialogs/ProductCategoryActionDialogBox.razor +++ b/NetinaShop.AdminPanel.PWA/Dialogs/ProductCategoryActionDialogBox.razor @@ -23,7 +23,7 @@ - + diff --git a/NetinaShop.AdminPanel.PWA/Dialogs/StorageDialogBox.razor b/NetinaShop.AdminPanel.PWA/Dialogs/StorageDialogBox.razor new file mode 100644 index 0000000..9ea5362 --- /dev/null +++ b/NetinaShop.AdminPanel.PWA/Dialogs/StorageDialogBox.razor @@ -0,0 +1,192 @@ +@using NetinaShop.AdminPanel.PWA.Extensions + +@inject IRestWrapper RestWrapper +@inject IUserUtility UserUtility +@inject ISnackbar Snackbar + + + +
+ + انتخاب یا اپلود عکس جدید + میتوانید از بین عکس های اپلود شده یکی را انتخاب کرده یا عکس جدیدی اپلود کنید + + + + + + + اپلود فایل جدید + + + +
+ + + +
+ @foreach (var item in _files) + { + @if (item.Selected) + { + + } + else + { + + } + } +
+
+
+ + + + + + + + بستن + + +
+@code +{ + + + private void SelectFile(StorageFileSDto item) + { + var pastSelect = _files.FirstOrDefault(f => f.Selected); + if (pastSelect != null) + pastSelect.Selected = false; + item.Selected = true; + } + + private void UnSelectFile(StorageFileSDto item) => item.Selected = false; + + public void SearchChanged(string search) + { + if (search.IsNullOrEmpty() && !_search.IsNullOrEmpty()) + { + _files.Clear(); + _originalFiles.ForEach(f=>_files.Add(f)); + } + _search = search; + } + public void SearchAsync() + { + try + { + if (_search.IsNullOrEmpty()) + throw new AppException("دسته بندی برای جست جو وارد نشده است"); + _files.Clear(); + foreach (var storageFileSDto in _originalFiles.Where(f => f.FileName.ToLower().Trim().Contains(_search.ToLower().Trim()))) + _files.Add(storageFileSDto); + } + catch (Exception e) + { + Snackbar.Add(e.Message, Severity.Error); + } + } + + public void SelectFile() + { + var selected = _files.FirstOrDefault(f => f.Selected); + if (selected == null) + throw new Exception("یک فایل را انتخاب کنید"); + MudDialog.Close(selected); + } + [CascadingParameter] + MudDialogInstance MudDialog { get; set; } + void Cancel() => MudDialog.Cancel(); + private readonly ObservableCollection _files = new ObservableCollection(); + private List _originalFiles = new List(); + private bool _isProcessing = false; + private string _search = string.Empty; + protected override async Task OnInitializedAsync() + { + try + { + _isProcessing = true; + _files.Clear(); + var token = await UserUtility.GetBearerTokenAsync(); + var files = await RestWrapper.FileRestApi.GetFilesAsync(token); + files.ForEach(f => _files.Add(f)); + _originalFiles = files; + } + catch (ApiException ex) + { + var exe = await ex.GetContentAsAsync(); + if (exe != null) + Snackbar.Add(exe.Message, Severity.Error); + Snackbar.Add(ex.Content, Severity.Error); + } + catch (Exception e) + { + Snackbar.Add(e.Message, Severity.Error); + } + finally + { + _isProcessing = false; + } + + await base.OnInitializedAsync(); + } + + private async Task FileChangeForUpload(InputFileChangeEventArgs obj) + { + try + { + _isProcessing = true; + using var memoryStream = new MemoryStream(); + var file = obj.File; + var stream = file.OpenReadStream(); + await stream.CopyToAsync(memoryStream); + + var fileUpload = new FileUploadRequest + { + ContentType = file.ContentType, + FileName = file.Name, + FileUploadType = FileUploadType.Image, + StringBaseFile = Convert.ToBase64String(memoryStream.ToArray()) + }; + var token = await UserUtility.GetBearerTokenAsync(); + var rest = await RestWrapper.FileRestApi.UploadFileAsync(fileUpload, token); + _files.Insert(0, new StorageFileSDto + { + FileLocation = rest.FileLocation, + FileName = rest.FileName, + FileType = StorageFileType.Image + }); + } + catch (ApiException ex) + { + var exe = await ex.GetContentAsAsync(); + if (exe != null) + Snackbar.Add(exe.Message, Severity.Error); + Snackbar.Add(ex.Content, Severity.Error); + } + catch (Exception e) + { + Snackbar.Add(e.Message, Severity.Error); + } + finally + { + _isProcessing = false; + } + } +} diff --git a/NetinaShop.AdminPanel.PWA/Extensions/StorageFileExtension.cs b/NetinaShop.AdminPanel.PWA/Extensions/StorageFileExtension.cs new file mode 100644 index 0000000..9f55872 --- /dev/null +++ b/NetinaShop.AdminPanel.PWA/Extensions/StorageFileExtension.cs @@ -0,0 +1,12 @@ +using NetinaShop.Common.Extensions; + +namespace NetinaShop.AdminPanel.PWA.Extensions; + +public static class StorageFileExtension +{ + public static string GetLink(this StorageFileSDto file) + { + var link = $"https://storage.vesmook.com/{file.FileLocation}"; + return link; + } +} \ No newline at end of file diff --git a/NetinaShop.AdminPanel.PWA/Models/Address.cs b/NetinaShop.AdminPanel.PWA/Models/Address.cs index a2bdea2..5034ac0 100644 --- a/NetinaShop.AdminPanel.PWA/Models/Address.cs +++ b/NetinaShop.AdminPanel.PWA/Models/Address.cs @@ -13,4 +13,5 @@ public static class Address public static string ProductCategoryController = $"{BaseAddress}/product/category"; public static string ProductController = $"{BaseAddress}/product"; public static string BrandController = $"{BaseAddress}/brand"; + public static string FileController => $"{BaseAddress}/file"; } \ No newline at end of file diff --git a/NetinaShop.AdminPanel.PWA/NetinaShop.AdminPanel.PWA.csproj b/NetinaShop.AdminPanel.PWA/NetinaShop.AdminPanel.PWA.csproj index db17d6e..6beefb3 100644 --- a/NetinaShop.AdminPanel.PWA/NetinaShop.AdminPanel.PWA.csproj +++ b/NetinaShop.AdminPanel.PWA/NetinaShop.AdminPanel.PWA.csproj @@ -53,6 +53,8 @@ + + diff --git a/NetinaShop.AdminPanel.PWA/Pages/ProductsPage.razor b/NetinaShop.AdminPanel.PWA/Pages/ProductsPage.razor index 83e94e7..2796cd4 100644 --- a/NetinaShop.AdminPanel.PWA/Pages/ProductsPage.razor +++ b/NetinaShop.AdminPanel.PWA/Pages/ProductsPage.razor @@ -46,12 +46,13 @@ + Color="@Color.Info" + OnClick="async()=>await ViewModel.EditProductClicked(context.Item)"/> + Color="@Color.Error"/> diff --git a/NetinaShop.AdminPanel.PWA/Services/RestServices/IBrandRestApi.cs b/NetinaShop.AdminPanel.PWA/Services/RestServices/IBrandRestApi.cs new file mode 100644 index 0000000..c9096d6 --- /dev/null +++ b/NetinaShop.AdminPanel.PWA/Services/RestServices/IBrandRestApi.cs @@ -0,0 +1,14 @@ +namespace NetinaShop.AdminPanel.PWA.Services.RestServices; + +public interface IBrandRestApi +{ + + [Get("")] + Task> ReadAll(); + [Get("")] + Task> ReadAll([Query] int page); + [Get("")] + Task> ReadAll([Query] int page, [Query] string brandName); + [Get("")] + Task> ReadAll([Query] string brandName); +} \ No newline at end of file diff --git a/NetinaShop.AdminPanel.PWA/Services/RestServices/ICrudApiRest.cs b/NetinaShop.AdminPanel.PWA/Services/RestServices/ICrudApiRest.cs index 441bb9e..118bfb6 100644 --- a/NetinaShop.AdminPanel.PWA/Services/RestServices/ICrudApiRest.cs +++ b/NetinaShop.AdminPanel.PWA/Services/RestServices/ICrudApiRest.cs @@ -34,7 +34,7 @@ public interface ICrudDtoApiRest where T : class where TDto : Task> ReadAll(); [Get("/{key}")] - Task ReadOne(TKey key, [Header("Authorization")] string authorization); + Task ReadOne(TKey key); [Put("")] Task Update([Body] T payload, [Header("Authorization")] string authorization); diff --git a/NetinaShop.AdminPanel.PWA/Services/RestServices/IFileRestApi.cs b/NetinaShop.AdminPanel.PWA/Services/RestServices/IFileRestApi.cs new file mode 100644 index 0000000..baeba34 --- /dev/null +++ b/NetinaShop.AdminPanel.PWA/Services/RestServices/IFileRestApi.cs @@ -0,0 +1,9 @@ +namespace NetinaShop.AdminPanel.PWA.Services.RestServices; + +public interface IFileRestApi +{ + [Get("")] + Task> GetFilesAsync([Header("Authorization")] string authorization); + [Post("")] + Task UploadFileAsync([Body] FileUploadRequest request, [Header("Authorization")] string authorization); +} \ No newline at end of file diff --git a/NetinaShop.AdminPanel.PWA/Services/RestServices/IRestWrapper.cs b/NetinaShop.AdminPanel.PWA/Services/RestServices/IRestWrapper.cs index e6bcedd..2cb0bbd 100644 --- a/NetinaShop.AdminPanel.PWA/Services/RestServices/IRestWrapper.cs +++ b/NetinaShop.AdminPanel.PWA/Services/RestServices/IRestWrapper.cs @@ -10,4 +10,6 @@ public interface IRestWrapper public IUserRestApi UserRestApi { get; } public IProductCategoryRestApi ProductCategoryRestApi { get; } public IProductRestApi ProductRestApi { get; } + public IBrandRestApi BrandRestApi { get; } + public IFileRestApi FileRestApi { get; } } \ No newline at end of file diff --git a/NetinaShop.AdminPanel.PWA/Services/RestServices/RestWrapper.cs b/NetinaShop.AdminPanel.PWA/Services/RestServices/RestWrapper.cs index 6edcf56..6c8ac7c 100644 --- a/NetinaShop.AdminPanel.PWA/Services/RestServices/RestWrapper.cs +++ b/NetinaShop.AdminPanel.PWA/Services/RestServices/RestWrapper.cs @@ -22,4 +22,6 @@ public class RestWrapper : IRestWrapper public IUserRestApi UserRestApi => RestService.For(Address.UserController, setting); public IProductCategoryRestApi ProductCategoryRestApi => RestService.For(Address.ProductCategoryController, setting); public IProductRestApi ProductRestApi => RestService.For(Address.ProductController, setting); + public IBrandRestApi BrandRestApi => RestService.For(Address.BrandController, setting); + public IFileRestApi FileRestApi => RestService.For(Address.FileController, setting); } \ No newline at end of file diff --git a/NetinaShop.AdminPanel.PWA/wwwroot/css/app.min.css b/NetinaShop.AdminPanel.PWA/wwwroot/css/app.min.css index 0590746..c8c40aa 100644 --- a/NetinaShop.AdminPanel.PWA/wwwroot/css/app.min.css +++ b/NetinaShop.AdminPanel.PWA/wwwroot/css/app.min.css @@ -501,6 +501,19 @@ video { --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; } +.absolute { + position: absolute; +} +.m-1 { + margin: 0.25rem; +} +.m-1\.5 { + margin: 0.375rem; +} +.mx-1 { + margin-left: 0.25rem; + margin-right: 0.25rem; +} .mx-3 { margin-left: 0.75rem; margin-right: 0.75rem; @@ -537,9 +550,6 @@ video { .-mt-3 { margin-top: -0.75rem; } -.mb-10 { - margin-bottom: 2.5rem; -} .mb-2 { margin-bottom: 0.5rem; } @@ -585,9 +595,15 @@ video { .h-12 { height: 3rem; } +.h-28 { + height: 7rem; +} .h-5 { height: 1.25rem; } +.h-52 { + height: 13rem; +} .h-64 { height: 16rem; } @@ -600,6 +616,9 @@ video { .h-screen { height: 100vh; } +.max-h-\[30rem\] { + max-height: 30rem; +} .min-h-\[10rem\] { min-height: 10rem; } @@ -609,9 +628,15 @@ video { .w-12 { width: 3rem; } +.w-28 { + width: 7rem; +} .w-5 { width: 1.25rem; } +.w-52 { + width: 13rem; +} .w-64 { width: 16rem; } @@ -624,30 +649,58 @@ video { .w-screen { width: 100vw; } +.flex-none { + flex: none; +} +.grow { + flex-grow: 1; +} .basis-full { flex-basis: 100%; } +.cursor-pointer { + cursor: pointer; +} .flex-row { flex-direction: row; } .flex-col-reverse { flex-direction: column-reverse; } +.flex-wrap { + flex-wrap: wrap; +} .items-center { align-items: center; } .justify-end { justify-content: flex-end; } +.justify-center { + justify-content: center; +} .overflow-hidden { overflow: hidden; } +.rounded-lg { + border-radius: 0.5rem; +} .rounded-md { border-radius: 0.375rem; } .border { border-width: 1px; } +.border-4 { + border-width: 4px; +} +.border-solid { + border-style: solid; +} +.border-blue-500 { + --tw-border-opacity: 1; + border-color: rgb(59 130 246 / var(--tw-border-opacity)); +} .bg-\[\#000000\] { --tw-bg-opacity: 1; background-color: rgb(0 0 0 / var(--tw-bg-opacity)); diff --git a/NetinaShop.AdminPanel.PWA/wwwroot/css/app.output.css b/NetinaShop.AdminPanel.PWA/wwwroot/css/app.output.css index 03cb8ef..8ba49f1 100644 --- a/NetinaShop.AdminPanel.PWA/wwwroot/css/app.output.css +++ b/NetinaShop.AdminPanel.PWA/wwwroot/css/app.output.css @@ -554,6 +554,23 @@ video { --tw-backdrop-sepia: ; } +.absolute { + position: absolute; +} + +.m-1 { + margin: 0.25rem; +} + +.m-1\.5 { + margin: 0.375rem; +} + +.mx-1 { + margin-left: 0.25rem; + margin-right: 0.25rem; +} + .mx-3 { margin-left: 0.75rem; margin-right: 0.75rem; @@ -600,10 +617,6 @@ video { margin-top: -0.75rem; } -.mb-10 { - margin-bottom: 2.5rem; -} - .mb-2 { margin-bottom: 0.5rem; } @@ -663,10 +676,18 @@ video { height: 3rem; } +.h-28 { + height: 7rem; +} + .h-5 { height: 1.25rem; } +.h-52 { + height: 13rem; +} + .h-64 { height: 16rem; } @@ -683,6 +704,10 @@ video { height: 100vh; } +.max-h-\[30rem\] { + max-height: 30rem; +} + .min-h-\[10rem\] { min-height: 10rem; } @@ -695,10 +720,18 @@ video { width: 3rem; } +.w-28 { + width: 7rem; +} + .w-5 { width: 1.25rem; } +.w-52 { + width: 13rem; +} + .w-64 { width: 16rem; } @@ -715,10 +748,22 @@ video { width: 100vw; } +.flex-none { + flex: none; +} + +.grow { + flex-grow: 1; +} + .basis-full { flex-basis: 100%; } +.cursor-pointer { + cursor: pointer; +} + .flex-row { flex-direction: row; } @@ -727,6 +772,10 @@ video { flex-direction: column-reverse; } +.flex-wrap { + flex-wrap: wrap; +} + .items-center { align-items: center; } @@ -735,10 +784,18 @@ video { justify-content: flex-end; } +.justify-center { + justify-content: center; +} + .overflow-hidden { overflow: hidden; } +.rounded-lg { + border-radius: 0.5rem; +} + .rounded-md { border-radius: 0.375rem; } @@ -747,6 +804,19 @@ video { border-width: 1px; } +.border-4 { + border-width: 4px; +} + +.border-solid { + border-style: solid; +} + +.border-blue-500 { + --tw-border-opacity: 1; + border-color: rgb(59 130 246 / var(--tw-border-opacity)); +} + .bg-\[\#000000\] { --tw-bg-opacity: 1; background-color: rgb(0 0 0 / var(--tw-bg-opacity));