@@ -79,7 +79,7 @@ export default function TagsInput({ tags, onSetTags }) {
onChange={handleTag}
id="tags"
name="tags"
- className=" min-w-[1ch] -outline-offset-2 overflow-hidden min-h-10 h-10"
+ className=" min-w-[3ch] -outline-offset-2 overflow-hidden min-h-10 h-10"
style={{ width: `${typingInputWidth}ch` }}
placeholder="Type here"
onKeyDown={handleKeyDown}
diff --git a/admin-client/components/Input/InputError.jsx b/admin-client/components/Input/InputError.jsx
new file mode 100644
index 0000000..b4506a6
--- /dev/null
+++ b/admin-client/components/Input/InputError.jsx
@@ -0,0 +1,3 @@
+export default function InputError(props) {
+ return
{props.children}
;
+}
diff --git a/admin-client/components/Input/InputText.jsx b/admin-client/components/Input/InputText.jsx
index 2b09988..a1bf9b0 100644
--- a/admin-client/components/Input/InputText.jsx
+++ b/admin-client/components/Input/InputText.jsx
@@ -10,6 +10,7 @@ function InputText({
labelTitle,
labelStyle,
containerStyle,
+ inputStyle,
}) {
return (
diff --git a/admin-client/constants/index.js b/admin-client/constants/index.js
index 6f13ab0..98e124a 100644
--- a/admin-client/constants/index.js
+++ b/admin-client/constants/index.js
@@ -1,5 +1,16 @@
-export const SIZES = ["XS", "S", "M", "L", "XL", "2XL", "3XL"];
-export const PRODUCT_VISIBILITY = ["Hidden", "Published"];
+export const SIZES = {
+ xs: 1,
+ s: 2,
+ m: 3,
+ l: 4,
+ xl: 5,
+ xxl: 6,
+ xxxl: 7,
+};
+export const ProductVisibility = {
+ VISIBLE: "VISIBLE",
+ HIDDEN: "HIDDEN",
+};
export const ROLES = {
ADMIN: 1,
USER: 2,
diff --git a/admin-client/services/api/services/categories.js b/admin-client/services/api/services/categories.js
new file mode 100644
index 0000000..657791a
--- /dev/null
+++ b/admin-client/services/api/services/categories.js
@@ -0,0 +1,17 @@
+import { useCallback } from "react";
+import { API_URL } from "../config";
+import useFetchBase from "../use-fetch-base";
+import wrapperFetchJsonResponse from "../wrapper-fetch-json-response";
+
+export function useGetCategoriesService() {
+ const fetchBase = useFetchBase();
+
+ return useCallback(
+ async (data) => {
+ return fetchBase(`${API_URL}/v1/categories`, {
+ method: "GET",
+ }).then(wrapperFetchJsonResponse);
+ },
+ [fetchBase]
+ );
+}
diff --git a/admin-client/services/api/services/product.js b/admin-client/services/api/services/product.js
index e69de29..c94f3b0 100644
--- a/admin-client/services/api/services/product.js
+++ b/admin-client/services/api/services/product.js
@@ -0,0 +1,78 @@
+import { useCallback } from "react";
+import { API_URL } from "../config";
+import useFetch from "../use-fetch";
+import wrapperFetchJsonResponse from "../wrapper-fetch-json-response";
+
+export function useUploadProductImagesService() {
+ const fetch = useFetch();
+
+ return useCallback(
+ async (data, reqConfig) => {
+ return fetch(`${API_URL}/v1/products/image/add`, {
+ method: "POST",
+ "Content-Type": "multipart/form-data",
+ body: data,
+ ...reqConfig,
+ }).then(wrapperFetchJsonResponse);
+ },
+ [fetch]
+ );
+}
+
+export function useGetProductService() {
+ const fetch = useFetch();
+
+ return useCallback(
+ async (reqConfig) => {
+ return fetch(`${API_URL}/v1/products`, {
+ method: "GET",
+ ...reqConfig,
+ }).then(wrapperFetchJsonResponse);
+ },
+ [fetch]
+ );
+}
+
+export function useGetProductByIdService() {
+ const fetch = useFetch();
+
+ return useCallback(
+ async (id, reqConfig) => {
+ return fetch(`${API_URL}/v1/products/${id}`, {
+ method: "GET",
+ ...reqConfig,
+ }).then(wrapperFetchJsonResponse);
+ },
+ [fetch]
+ );
+}
+
+export function useCreateProductService() {
+ const fetch = useFetch();
+
+ return useCallback(
+ async (data, reqConfig) => {
+ return fetch(`${API_URL}/v1/products`, {
+ method: "POST",
+ body: JSON.stringify(data),
+ ...reqConfig,
+ }).then(wrapperFetchJsonResponse);
+ },
+ [fetch]
+ );
+}
+
+export function useUpdateProductService() {
+ const fetch = useFetch();
+
+ return useCallback(
+ async (id, data, reqConfig) => {
+ return fetch(`${API_URL}/v1/products/${id}`, {
+ method: "PUT",
+ body: JSON.stringify(data),
+ ...reqConfig,
+ }).then(wrapperFetchJsonResponse);
+ },
+ [fetch]
+ );
+}
diff --git a/server/src/products/domain/product.ts b/server/src/products/domain/product.ts
index 9735418..3f1dce8 100644
--- a/server/src/products/domain/product.ts
+++ b/server/src/products/domain/product.ts
@@ -1,5 +1,6 @@
import { Expose } from 'class-transformer';
import { Category } from 'src/categories/domain/category';
+import { ProductVisibility } from '../product-visibility.enum';
export class Size {
id: number;
name?: string;
@@ -41,5 +42,5 @@ export class Product {
productInfo: ProductInfo[];
@Expose({ groups: ['admin'] })
- visibility: 'Hidden' | 'Visible';
+ visibility: ProductVisibility;
}
diff --git a/server/src/products/dto/create-product.dto.ts b/server/src/products/dto/create-product.dto.ts
index 8e13f90..3995b41 100644
--- a/server/src/products/dto/create-product.dto.ts
+++ b/server/src/products/dto/create-product.dto.ts
@@ -9,6 +9,7 @@ import {
IsString,
ValidateNested,
} from 'class-validator';
+import { ProductVisibility } from '../product-visibility.enum';
class SizeDto {
@IsNumber()
@@ -74,8 +75,8 @@ export class CreateProductDto {
@ValidateNested({ each: true })
images: ImageDto[];
- @IsEnum(['Hidden', 'Visible'])
- visibility: 'Hidden' | 'Visible';
+ @IsEnum(ProductVisibility)
+ visibility: ProductVisibility;
@IsArray()
@Type(() => ProductInfoDto)
diff --git a/server/src/products/infrastructure/entities/product.entity.ts b/server/src/products/infrastructure/entities/product.entity.ts
index 45520e1..17d11b1 100644
--- a/server/src/products/infrastructure/entities/product.entity.ts
+++ b/server/src/products/infrastructure/entities/product.entity.ts
@@ -9,16 +9,17 @@ import {
OneToMany,
PrimaryGeneratedColumn,
UpdateDateColumn,
-} from 'typeorm';
+} from "typeorm";
-import { CategoryEntity } from 'src/categories/infrastructure/entities/category.entity';
-import { ProductSizeEntity } from 'src/product-sizes/infrastructure/entities/product-size.entity';
-import { EntityHelper } from 'src/utils/entity-helper';
-import { ProductColorEntity } from './product-color.entity';
-import { ProductImageEntity } from './product-image.entity';
+import { CategoryEntity } from "src/categories/infrastructure/entities/category.entity";
+import { ProductSizeEntity } from "src/product-sizes/infrastructure/entities/product-size.entity";
+import { ProductVisibility } from "src/products/product-visibility.enum";
+import { EntityHelper } from "src/utils/entity-helper";
+import { ProductColorEntity } from "./product-color.entity";
+import { ProductImageEntity } from "./product-image.entity";
@Entity({
- name: 'product',
+ name: "product",
})
export class ProductEntity extends EntityHelper {
@PrimaryGeneratedColumn()
@@ -27,13 +28,13 @@ export class ProductEntity extends EntityHelper {
@Column()
title: string;
- @Column({ type: 'text' })
+ @Column({ type: "text" })
description: string;
- @Column({ type: 'float' })
+ @Column({ type: "float" })
buyPrice: number;
- @Column({ type: 'float' })
+ @Column({ type: "float" })
sellPrice: number;
@ManyToOne(() => CategoryEntity, (category) => category.products, {
@@ -44,11 +45,11 @@ export class ProductEntity extends EntityHelper {
@Column()
quantity: number;
- @Column({ type: 'decimal', precision: 5, scale: 2 })
+ @Column({ type: "decimal", precision: 5, scale: 2 })
discount: number;
- @Column({ type: 'enum', enum: ['Hidden', 'Visible'] })
- visibility: 'Hidden' | 'Visible';
+ @Column({ type: "enum", enum: ProductVisibility })
+ visibility: ProductVisibility;
@OneToMany(() => ProductColorEntity, (productColor) => productColor.product, {
cascade: true,
diff --git a/server/src/products/infrastructure/mappers/product.mapper.ts b/server/src/products/infrastructure/mappers/product.mapper.ts
index b3edb7f..cd9a2ea 100644
--- a/server/src/products/infrastructure/mappers/product.mapper.ts
+++ b/server/src/products/infrastructure/mappers/product.mapper.ts
@@ -2,6 +2,7 @@ import { Category } from 'src/categories/domain/category';
import { CategoryEntity } from 'src/categories/infrastructure/entities/category.entity';
import { ProductSizeEntity } from 'src/product-sizes/infrastructure/entities/product-size.entity';
import { Image, Product, ProductInfo, Size } from 'src/products/domain/product';
+import { ProductVisibility } from 'src/products/product-visibility.enum';
import { ProductColorEntity } from '../entities/product-color.entity';
import { ProductImageEntity } from '../entities/product-image.entity';
import { ProductEntity } from '../entities/product.entity';
@@ -60,9 +61,11 @@ export class ProductMapper {
product.sizes = domainSizes;
product.images = domainImages;
product.productInfo = domainProductInfo;
+ product.visibility = ProductVisibility[raw.visibility];
return product;
}
+
static toPersistence(product: Product): ProductEntity {
let category: CategoryEntity | undefined = undefined;
if (product.category && product.category.id) {
@@ -116,6 +119,7 @@ export class ProductMapper {
productEntity.sizes = sizes;
productEntity.images = images;
productEntity.productColors = productColors;
+ console.log({ visi: product.visibility });
productEntity.visibility = product.visibility;
return productEntity;
diff --git a/server/src/products/infrastructure/repositories/product.repository.impl.ts b/server/src/products/infrastructure/repositories/product.repository.impl.ts
index 6079f93..1af41bb 100644
--- a/server/src/products/infrastructure/repositories/product.repository.impl.ts
+++ b/server/src/products/infrastructure/repositories/product.repository.impl.ts
@@ -30,6 +30,8 @@ export class ProductRepositoryImpl implements ProductRepository {
async create(data: Product): Promise
{
const persistenceModel = ProductMapper.toPersistence(data);
+ console.log({ fromPer: persistenceModel.visibility });
+
const entities = await this.productRepository.save(
this.productRepository.create(persistenceModel),
);
diff --git a/server/src/products/products.controller.ts b/server/src/products/products.controller.ts
index 3bd2dae..5019f58 100644
--- a/server/src/products/products.controller.ts
+++ b/server/src/products/products.controller.ts
@@ -72,6 +72,7 @@ export class ProductsController {
@Post()
@HttpCode(HttpStatus.CREATED)
async createProduct(@Body() data: CreateProductDto): Promise {
+ console.log(data.visibility);
return this.productsService.create(data);
}
diff --git a/server/src/products/products.service.ts b/server/src/products/products.service.ts
index de47f43..f9a42b8 100644
--- a/server/src/products/products.service.ts
+++ b/server/src/products/products.service.ts
@@ -132,7 +132,7 @@ export class ProductsService {
}
});
}
-
+ console.log({ formService: clonedPayload.visibility });
return await this.productsRepo.create(clonedPayload);
// // Save product sizes