feat: CRUD for product barcode images
This commit is contained in:
@@ -25,8 +25,10 @@ export type { BaseEnumListSchema } from './models/BaseEnumListSchema';
|
|||||||
export type { BaseEnumSchema } from './models/BaseEnumSchema';
|
export type { BaseEnumSchema } from './models/BaseEnumSchema';
|
||||||
export type { BaseMarketplaceSchema } from './models/BaseMarketplaceSchema';
|
export type { BaseMarketplaceSchema } from './models/BaseMarketplaceSchema';
|
||||||
export type { BaseShippingWarehouseSchema } from './models/BaseShippingWarehouseSchema';
|
export type { BaseShippingWarehouseSchema } from './models/BaseShippingWarehouseSchema';
|
||||||
|
export type { BillPaymentInfo } from './models/BillPaymentInfo';
|
||||||
export type { BillPaymentStatus } from './models/BillPaymentStatus';
|
export type { BillPaymentStatus } from './models/BillPaymentStatus';
|
||||||
export type { BillStatusUpdateRequest } from './models/BillStatusUpdateRequest';
|
export type { BillStatusUpdateRequest } from './models/BillStatusUpdateRequest';
|
||||||
|
export type { Body_upload_product_barcode_image } from './models/Body_upload_product_barcode_image';
|
||||||
export type { Body_upload_product_image } from './models/Body_upload_product_image';
|
export type { Body_upload_product_image } from './models/Body_upload_product_image';
|
||||||
export type { CancelDealBillRequest } from './models/CancelDealBillRequest';
|
export type { CancelDealBillRequest } from './models/CancelDealBillRequest';
|
||||||
export type { CancelDealBillResponse } from './models/CancelDealBillResponse';
|
export type { CancelDealBillResponse } from './models/CancelDealBillResponse';
|
||||||
@@ -173,16 +175,19 @@ export type { ProductAddBarcodeRequest } from './models/ProductAddBarcodeRequest
|
|||||||
export type { ProductAddBarcodeResponse } from './models/ProductAddBarcodeResponse';
|
export type { ProductAddBarcodeResponse } from './models/ProductAddBarcodeResponse';
|
||||||
export type { ProductCreateRequest } from './models/ProductCreateRequest';
|
export type { ProductCreateRequest } from './models/ProductCreateRequest';
|
||||||
export type { ProductCreateResponse } from './models/ProductCreateResponse';
|
export type { ProductCreateResponse } from './models/ProductCreateResponse';
|
||||||
|
export type { ProductDeleteBarcodeImageResponse } from './models/ProductDeleteBarcodeImageResponse';
|
||||||
export type { ProductDeleteRequest } from './models/ProductDeleteRequest';
|
export type { ProductDeleteRequest } from './models/ProductDeleteRequest';
|
||||||
export type { ProductDeleteResponse } from './models/ProductDeleteResponse';
|
export type { ProductDeleteResponse } from './models/ProductDeleteResponse';
|
||||||
export type { ProductExistsBarcodeResponse } from './models/ProductExistsBarcodeResponse';
|
export type { ProductExistsBarcodeResponse } from './models/ProductExistsBarcodeResponse';
|
||||||
export type { ProductGenerateBarcodeRequest } from './models/ProductGenerateBarcodeRequest';
|
export type { ProductGenerateBarcodeRequest } from './models/ProductGenerateBarcodeRequest';
|
||||||
export type { ProductGenerateBarcodeResponse } from './models/ProductGenerateBarcodeResponse';
|
export type { ProductGenerateBarcodeResponse } from './models/ProductGenerateBarcodeResponse';
|
||||||
|
export type { ProductGetBarcodeImageResponse } from './models/ProductGetBarcodeImageResponse';
|
||||||
export type { ProductGetResponse } from './models/ProductGetResponse';
|
export type { ProductGetResponse } from './models/ProductGetResponse';
|
||||||
export type { ProductImageSchema } from './models/ProductImageSchema';
|
export type { ProductImageSchema } from './models/ProductImageSchema';
|
||||||
export type { ProductSchema } from './models/ProductSchema';
|
export type { ProductSchema } from './models/ProductSchema';
|
||||||
export type { ProductUpdateRequest } from './models/ProductUpdateRequest';
|
export type { ProductUpdateRequest } from './models/ProductUpdateRequest';
|
||||||
export type { ProductUpdateResponse } from './models/ProductUpdateResponse';
|
export type { ProductUpdateResponse } from './models/ProductUpdateResponse';
|
||||||
|
export type { ProductUploadBarcodeImageResponse } from './models/ProductUploadBarcodeImageResponse';
|
||||||
export type { ProductUploadImageResponse } from './models/ProductUploadImageResponse';
|
export type { ProductUploadImageResponse } from './models/ProductUploadImageResponse';
|
||||||
export type { RoleSchema } from './models/RoleSchema';
|
export type { RoleSchema } from './models/RoleSchema';
|
||||||
export type { ServiceCategoryPriceSchema } from './models/ServiceCategoryPriceSchema';
|
export type { ServiceCategoryPriceSchema } from './models/ServiceCategoryPriceSchema';
|
||||||
|
|||||||
@@ -2,11 +2,12 @@
|
|||||||
/* istanbul ignore file */
|
/* istanbul ignore file */
|
||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
import type { BillPaymentInfo } from './BillPaymentInfo';
|
||||||
import type { BillPaymentStatus } from './BillPaymentStatus';
|
import type { BillPaymentStatus } from './BillPaymentStatus';
|
||||||
import type { NotificationChannel } from './NotificationChannel';
|
import type { NotificationChannel } from './NotificationChannel';
|
||||||
export type BillStatusUpdateRequest = {
|
export type BillStatusUpdateRequest = {
|
||||||
listenerTransactionId: number;
|
listenerTransactionId: number;
|
||||||
channel: NotificationChannel;
|
channel: NotificationChannel;
|
||||||
info: BillPaymentStatus;
|
info: (BillPaymentInfo | BillPaymentStatus);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
/* istanbul ignore file */
|
/* istanbul ignore file */
|
||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
import type { Body_upload_product_barcode_image } from '../models/Body_upload_product_barcode_image';
|
||||||
import type { Body_upload_product_image } from '../models/Body_upload_product_image';
|
import type { Body_upload_product_image } from '../models/Body_upload_product_image';
|
||||||
import type { GetProductBarcodePdfRequest } from '../models/GetProductBarcodePdfRequest';
|
import type { GetProductBarcodePdfRequest } from '../models/GetProductBarcodePdfRequest';
|
||||||
import type { GetProductBarcodePdfResponse } from '../models/GetProductBarcodePdfResponse';
|
import type { GetProductBarcodePdfResponse } from '../models/GetProductBarcodePdfResponse';
|
||||||
@@ -11,15 +12,18 @@ import type { ProductAddBarcodeRequest } from '../models/ProductAddBarcodeReques
|
|||||||
import type { ProductAddBarcodeResponse } from '../models/ProductAddBarcodeResponse';
|
import type { ProductAddBarcodeResponse } from '../models/ProductAddBarcodeResponse';
|
||||||
import type { ProductCreateRequest } from '../models/ProductCreateRequest';
|
import type { ProductCreateRequest } from '../models/ProductCreateRequest';
|
||||||
import type { ProductCreateResponse } from '../models/ProductCreateResponse';
|
import type { ProductCreateResponse } from '../models/ProductCreateResponse';
|
||||||
|
import type { ProductDeleteBarcodeImageResponse } from '../models/ProductDeleteBarcodeImageResponse';
|
||||||
import type { ProductDeleteRequest } from '../models/ProductDeleteRequest';
|
import type { ProductDeleteRequest } from '../models/ProductDeleteRequest';
|
||||||
import type { ProductDeleteResponse } from '../models/ProductDeleteResponse';
|
import type { ProductDeleteResponse } from '../models/ProductDeleteResponse';
|
||||||
import type { ProductExistsBarcodeResponse } from '../models/ProductExistsBarcodeResponse';
|
import type { ProductExistsBarcodeResponse } from '../models/ProductExistsBarcodeResponse';
|
||||||
import type { ProductGenerateBarcodeRequest } from '../models/ProductGenerateBarcodeRequest';
|
import type { ProductGenerateBarcodeRequest } from '../models/ProductGenerateBarcodeRequest';
|
||||||
import type { ProductGenerateBarcodeResponse } from '../models/ProductGenerateBarcodeResponse';
|
import type { ProductGenerateBarcodeResponse } from '../models/ProductGenerateBarcodeResponse';
|
||||||
|
import type { ProductGetBarcodeImageResponse } from '../models/ProductGetBarcodeImageResponse';
|
||||||
import type { ProductGetResponse } from '../models/ProductGetResponse';
|
import type { ProductGetResponse } from '../models/ProductGetResponse';
|
||||||
import type { ProductSchema } from '../models/ProductSchema';
|
import type { ProductSchema } from '../models/ProductSchema';
|
||||||
import type { ProductUpdateRequest } from '../models/ProductUpdateRequest';
|
import type { ProductUpdateRequest } from '../models/ProductUpdateRequest';
|
||||||
import type { ProductUpdateResponse } from '../models/ProductUpdateResponse';
|
import type { ProductUpdateResponse } from '../models/ProductUpdateResponse';
|
||||||
|
import type { ProductUploadBarcodeImageResponse } from '../models/ProductUploadBarcodeImageResponse';
|
||||||
import type { ProductUploadImageResponse } from '../models/ProductUploadImageResponse';
|
import type { ProductUploadImageResponse } from '../models/ProductUploadImageResponse';
|
||||||
import type { CancelablePromise } from '../core/CancelablePromise';
|
import type { CancelablePromise } from '../core/CancelablePromise';
|
||||||
import { OpenAPI } from '../core/OpenAPI';
|
import { OpenAPI } from '../core/OpenAPI';
|
||||||
@@ -265,4 +269,71 @@ export class ProductService {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Upload Product Barcode Image
|
||||||
|
* @returns ProductUploadBarcodeImageResponse Successful Response
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public static uploadProductBarcodeImage({
|
||||||
|
productId,
|
||||||
|
formData,
|
||||||
|
}: {
|
||||||
|
productId: number,
|
||||||
|
formData: Body_upload_product_barcode_image,
|
||||||
|
}): CancelablePromise<ProductUploadBarcodeImageResponse> {
|
||||||
|
return __request(OpenAPI, {
|
||||||
|
method: 'POST',
|
||||||
|
url: '/product/barcode/upload-image/{product_id}',
|
||||||
|
path: {
|
||||||
|
'product_id': productId,
|
||||||
|
},
|
||||||
|
formData: formData,
|
||||||
|
mediaType: 'multipart/form-data',
|
||||||
|
errors: {
|
||||||
|
422: `Validation Error`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Delete Product Barcode Image
|
||||||
|
* @returns ProductDeleteBarcodeImageResponse Successful Response
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public static deleteProductBarcodeImage({
|
||||||
|
productId,
|
||||||
|
}: {
|
||||||
|
productId: number,
|
||||||
|
}): CancelablePromise<ProductDeleteBarcodeImageResponse> {
|
||||||
|
return __request(OpenAPI, {
|
||||||
|
method: 'POST',
|
||||||
|
url: '/product/barcode/delete-image/{product_id}',
|
||||||
|
path: {
|
||||||
|
'product_id': productId,
|
||||||
|
},
|
||||||
|
errors: {
|
||||||
|
422: `Validation Error`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Get Product Barcode Image
|
||||||
|
* @returns ProductGetBarcodeImageResponse Successful Response
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public static getProductBarcodeImage({
|
||||||
|
productId,
|
||||||
|
}: {
|
||||||
|
productId: number,
|
||||||
|
}): CancelablePromise<ProductGetBarcodeImageResponse> {
|
||||||
|
return __request(OpenAPI, {
|
||||||
|
method: 'POST',
|
||||||
|
url: '/product/barcode/image/{product_id}',
|
||||||
|
path: {
|
||||||
|
'product_id': productId,
|
||||||
|
},
|
||||||
|
errors: {
|
||||||
|
422: `Validation Error`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
208
src/components/BarcodeImageDropzone/BarcodeImageDropzone.tsx
Normal file
208
src/components/BarcodeImageDropzone/BarcodeImageDropzone.tsx
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
import { Dropzone, DropzoneProps, FileWithPath } from "@mantine/dropzone";
|
||||||
|
import { FC, useEffect, useState } from "react";
|
||||||
|
import { Button, Fieldset, Flex, Group, Loader, rem, Text } from "@mantine/core";
|
||||||
|
import { IconPhoto, IconUpload, IconX } from "@tabler/icons-react";
|
||||||
|
import { omit } from "lodash";
|
||||||
|
import { notifications } from "../../shared/lib/notifications.ts";
|
||||||
|
import { ProductService } from "../../client";
|
||||||
|
|
||||||
|
// Barcode image aspects ratio should be equal 58/40
|
||||||
|
const BARCODE_IMAGE_RATIO = 1.45;
|
||||||
|
|
||||||
|
interface RestProps {
|
||||||
|
productId?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
type Props = Omit<DropzoneProps, "onDrop"> & RestProps;
|
||||||
|
|
||||||
|
const BarcodeImageDropzone: FC<Props> = (props: Props) => {
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const restProps = omit(props, [
|
||||||
|
"productId",
|
||||||
|
]);
|
||||||
|
const [barcodeImageUrl, setBarcodeImageUrl] = useState<string>();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getBarcodeImage();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const getBarcodeImage = () => {
|
||||||
|
if (!props.productId) return;
|
||||||
|
|
||||||
|
ProductService.getProductBarcodeImage({
|
||||||
|
productId: props.productId,
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
if (res.barcodeImageUrl) {
|
||||||
|
setBarcodeImageUrl(res.barcodeImageUrl);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const showIncorrectImageSizeError = () => {
|
||||||
|
notifications.error({
|
||||||
|
message: "Изображение должно быть размером 58 х 40.",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const uploadImage = (productId: number, file: File) => {
|
||||||
|
ProductService.uploadProductBarcodeImage({
|
||||||
|
productId: productId,
|
||||||
|
formData: {
|
||||||
|
upload_file: file,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(({ ok, message, barcodeImageUrl }) => {
|
||||||
|
notifications.guess(ok, { message });
|
||||||
|
setIsLoading(false);
|
||||||
|
|
||||||
|
if (ok && barcodeImageUrl) {
|
||||||
|
setBarcodeImageUrl(barcodeImageUrl);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
notifications.error({ message: error.toString() });
|
||||||
|
setIsLoading(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const uploadImageWrapper = (productId: number, file: File) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onloadend = () => {
|
||||||
|
const img = new Image();
|
||||||
|
img.src = reader.result as string;
|
||||||
|
img.onload = () => {
|
||||||
|
const ratio = img.width / img.height;
|
||||||
|
if (Math.abs(ratio - BARCODE_IMAGE_RATIO) > 0.01) {
|
||||||
|
showIncorrectImageSizeError();
|
||||||
|
setIsLoading(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uploadImage(productId, file);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDrop = (files: FileWithPath[]) => {
|
||||||
|
if (!props.productId) return;
|
||||||
|
if (files.length > 1) {
|
||||||
|
notifications.error({ message: "Прикрепите одно изображение" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const file = files[0];
|
||||||
|
setIsLoading(true);
|
||||||
|
uploadImageWrapper(props.productId, file);
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteImage = () => {
|
||||||
|
if (!props.productId) return;
|
||||||
|
ProductService.deleteProductBarcodeImage({ productId: props.productId })
|
||||||
|
.then(({ ok, message }) => {
|
||||||
|
notifications.guess(ok, { message });
|
||||||
|
|
||||||
|
if (!ok) return;
|
||||||
|
setBarcodeImageUrl("");
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
notifications.error({ message: error.toString() });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const getBody = () => {
|
||||||
|
return barcodeImageUrl ? (
|
||||||
|
<object style={{
|
||||||
|
aspectRatio: BARCODE_IMAGE_RATIO,
|
||||||
|
width: "240px",
|
||||||
|
}} data={barcodeImageUrl} />
|
||||||
|
) : (
|
||||||
|
<Dropzone
|
||||||
|
{...restProps}
|
||||||
|
accept={[
|
||||||
|
"image/png",
|
||||||
|
"image/jpeg",
|
||||||
|
"image/bmp",
|
||||||
|
"image/tiff",
|
||||||
|
"image/x-icon",
|
||||||
|
"image/webp",
|
||||||
|
"image/svg+xml",
|
||||||
|
"image/heic",
|
||||||
|
]}
|
||||||
|
multiple={false}
|
||||||
|
onDrop={onDrop}>
|
||||||
|
<Group
|
||||||
|
justify="center"
|
||||||
|
gap="xl"
|
||||||
|
style={{ pointerEvents: "none" }}>
|
||||||
|
<Dropzone.Accept>
|
||||||
|
<IconUpload
|
||||||
|
style={{
|
||||||
|
width: rem(52),
|
||||||
|
height: rem(52),
|
||||||
|
color: "var(--mantine-color-blue-6)",
|
||||||
|
}}
|
||||||
|
stroke={1.5}
|
||||||
|
/>
|
||||||
|
</Dropzone.Accept>
|
||||||
|
<Dropzone.Reject>
|
||||||
|
<IconX
|
||||||
|
style={{
|
||||||
|
width: rem(52),
|
||||||
|
height: rem(52),
|
||||||
|
color: "var(--mantine-color-red-6)",
|
||||||
|
}}
|
||||||
|
stroke={1.5}
|
||||||
|
/>
|
||||||
|
</Dropzone.Reject>
|
||||||
|
<Dropzone.Idle>
|
||||||
|
<IconPhoto
|
||||||
|
style={{
|
||||||
|
width: rem(52),
|
||||||
|
height: rem(52),
|
||||||
|
color: "var(--mantine-color-dimmed)",
|
||||||
|
}}
|
||||||
|
stroke={1.5}
|
||||||
|
/>
|
||||||
|
</Dropzone.Idle>
|
||||||
|
|
||||||
|
<div style={{ textAlign: "center" }}>
|
||||||
|
<Text
|
||||||
|
size="xl"
|
||||||
|
inline>
|
||||||
|
Перенесите изображение или нажмите чтоб выбрать файл
|
||||||
|
Изображение должно быть 58 х 40
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
</Group>
|
||||||
|
</Dropzone>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Flex
|
||||||
|
gap={rem(10)}
|
||||||
|
direction={"column"}>
|
||||||
|
<Fieldset legend={"Штрихкод"}>
|
||||||
|
<Flex justify={"center"}>
|
||||||
|
{isLoading ? <Loader /> : getBody()}
|
||||||
|
</Flex>
|
||||||
|
</Fieldset>
|
||||||
|
{barcodeImageUrl && (
|
||||||
|
<>
|
||||||
|
<Button
|
||||||
|
onClick={() => setBarcodeImageUrl("")}
|
||||||
|
variant={"default"}>
|
||||||
|
Заменить штрихкод
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={() => deleteImage()}
|
||||||
|
variant={"default"}>
|
||||||
|
Удалить штрихкод
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default BarcodeImageDropzone;
|
||||||
@@ -1,18 +1,12 @@
|
|||||||
import { ContextModalProps } from "@mantine/modals";
|
import { ContextModalProps } from "@mantine/modals";
|
||||||
import {
|
import { Button, Fieldset, Flex, rem, TagsInput, TextInput } from "@mantine/core";
|
||||||
Button,
|
|
||||||
Fieldset,
|
|
||||||
Flex,
|
|
||||||
rem,
|
|
||||||
TagsInput,
|
|
||||||
TextInput,
|
|
||||||
} from "@mantine/core";
|
|
||||||
import { useForm } from "@mantine/form";
|
import { useForm } from "@mantine/form";
|
||||||
import { BaseProduct, CreateProductRequest } from "../../types.ts";
|
import { BaseProduct, CreateProductRequest } from "../../types.ts";
|
||||||
import { ProductSchema } from "../../../../client";
|
import { ProductSchema } from "../../../../client";
|
||||||
import BarcodeTemplateSelect from "../../../../components/Selects/BarcodeTemplateSelect/BarcodeTemplateSelect.tsx";
|
import BarcodeTemplateSelect from "../../../../components/Selects/BarcodeTemplateSelect/BarcodeTemplateSelect.tsx";
|
||||||
import ImageDropzone from "../../../../components/ImageDropzone/ImageDropzone.tsx";
|
import ImageDropzone from "../../../../components/ImageDropzone/ImageDropzone.tsx";
|
||||||
import { BaseFormInputProps } from "../../../../types/utils.ts";
|
import { BaseFormInputProps } from "../../../../types/utils.ts";
|
||||||
|
import BarcodeImageDropzone from "../../../../components/BarcodeImageDropzone/BarcodeImageDropzone.tsx";
|
||||||
|
|
||||||
type CreateProps = {
|
type CreateProps = {
|
||||||
clientId: number;
|
clientId: number;
|
||||||
@@ -29,7 +23,7 @@ const CreateProductModal = ({
|
|||||||
context,
|
context,
|
||||||
id,
|
id,
|
||||||
innerProps,
|
innerProps,
|
||||||
}: ContextModalProps<Props>) => {
|
}: ContextModalProps<Props>) => {
|
||||||
const isEditProps = "product" in innerProps;
|
const isEditProps = "product" in innerProps;
|
||||||
const isCreatingProps = "clientId" in innerProps;
|
const isCreatingProps = "clientId" in innerProps;
|
||||||
const initialValues: Omit<ProductSchema, "id"> = isEditProps
|
const initialValues: Omit<ProductSchema, "id"> = isEditProps
|
||||||
@@ -122,14 +116,19 @@ const CreateProductModal = ({
|
|||||||
{
|
{
|
||||||
isEditProps && (
|
isEditProps && (
|
||||||
// <Fieldset legend={"Изображение"}>
|
// <Fieldset legend={"Изображение"}>
|
||||||
|
<>
|
||||||
<ImageDropzone
|
<ImageDropzone
|
||||||
imageUrlInputProps={
|
imageUrlInputProps={
|
||||||
form.getInputProps(
|
form.getInputProps(
|
||||||
"imageUrl"
|
"imageUrl",
|
||||||
) as BaseFormInputProps<string>
|
) as BaseFormInputProps<string>
|
||||||
}
|
}
|
||||||
productId={innerProps.product.id}
|
productId={innerProps.product.id}
|
||||||
/>
|
/>
|
||||||
|
<BarcodeImageDropzone
|
||||||
|
productId={innerProps.product.id}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
// </Fieldset>
|
// </Fieldset>
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user