temp image upload
This commit is contained in:
		@@ -14,5 +14,6 @@ export type ProductCreateRequest = {
 | 
				
			|||||||
    composition?: (string | null);
 | 
					    composition?: (string | null);
 | 
				
			||||||
    size?: (string | null);
 | 
					    size?: (string | null);
 | 
				
			||||||
    additionalInfo?: (string | null);
 | 
					    additionalInfo?: (string | null);
 | 
				
			||||||
 | 
					    imageUrl?: (string | null);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,7 @@ export type ProductSchema = {
 | 
				
			|||||||
    composition?: (string | null);
 | 
					    composition?: (string | null);
 | 
				
			||||||
    size?: (string | null);
 | 
					    size?: (string | null);
 | 
				
			||||||
    additionalInfo?: (string | null);
 | 
					    additionalInfo?: (string | null);
 | 
				
			||||||
 | 
					    imageUrl?: (string | null);
 | 
				
			||||||
    id: number;
 | 
					    id: number;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,53 +1,101 @@
 | 
				
			|||||||
import {Dropzone, DropzoneProps} from "@mantine/dropzone";
 | 
					import {Dropzone, DropzoneProps, FileWithPath} from "@mantine/dropzone";
 | 
				
			||||||
import {FC} from "react";
 | 
					import {FC, useState} from "react";
 | 
				
			||||||
import {Group, rem, Text} from "@mantine/core";
 | 
					import {Button, Fieldset, Flex, Group, Image, rem, Text} from "@mantine/core";
 | 
				
			||||||
import {IconPhoto, IconUpload, IconX} from "@tabler/icons-react";
 | 
					import {IconPhoto, IconUpload, IconX} from "@tabler/icons-react";
 | 
				
			||||||
import {omit} from "lodash";
 | 
					import {omit} from "lodash";
 | 
				
			||||||
 | 
					import {BaseFormInputProps} from "../../types/utils.ts";
 | 
				
			||||||
 | 
					import {notifications} from "../../shared/lib/notifications.ts";
 | 
				
			||||||
 | 
					import {ProductService} from "../../client";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type RestProps = {
 | 
					interface RestProps {
 | 
				
			||||||
    imageUrl?: string;
 | 
					    imageUrlInputProps?: BaseFormInputProps<string>;
 | 
				
			||||||
};
 | 
					    productId?: number;
 | 
				
			||||||
const ALL_PROPERTIES = Object.keys(colDefProperties) as (keyof ColDef)[];
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Props = DropzoneProps & RestProps;
 | 
					type Props = Omit<DropzoneProps, 'onDrop'> & RestProps;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const ImageDropzone: FC<Props> = (props: Props) => {
 | 
					const ImageDropzone: FC<Props> = (props: Props) => {
 | 
				
			||||||
    const restProps = omit()
 | 
					    const [showDropzone, setShowDropzone] = useState(
 | 
				
			||||||
    return (
 | 
					        !(typeof props.imageUrlInputProps?.value === 'string' &&
 | 
				
			||||||
        <Dropzone
 | 
					            props.imageUrlInputProps.value.trim() !== '')
 | 
				
			||||||
            {...props}
 | 
					    );
 | 
				
			||||||
        >
 | 
					    console.log(props.imageUrlInputProps);
 | 
				
			||||||
            <Group justify="center" gap="xl" style={{pointerEvents: 'none'}}>
 | 
					    console.log(showDropzone);
 | 
				
			||||||
                <Dropzone.Accept>
 | 
					    const restProps = omit(props, ['imageUrl', 'productId', 'imageUrlInputProps']);
 | 
				
			||||||
                    <IconUpload
 | 
					    const onDrop = (files: FileWithPath[]) => {
 | 
				
			||||||
                        style={{width: rem(52), height: rem(52), color: 'var(--mantine-color-blue-6)'}}
 | 
					        if (!props.productId || !props.imageUrlInputProps) return;
 | 
				
			||||||
                        stroke={1.5}
 | 
					        if (files.length > 1) {
 | 
				
			||||||
                    />
 | 
					            notifications.error({message: "Прикрепите одно изображение"});
 | 
				
			||||||
                </Dropzone.Accept>
 | 
					            return;
 | 
				
			||||||
                <Dropzone.Reject>
 | 
					        }
 | 
				
			||||||
                    <IconX
 | 
					        const file = files[0];
 | 
				
			||||||
                        style={{width: rem(52), height: rem(52), color: 'var(--mantine-color-red-6)'}}
 | 
					        // TODO check if file is image
 | 
				
			||||||
                        stroke={1.5}
 | 
					        ProductService.uploadProductImage({
 | 
				
			||||||
                    />
 | 
					            productId: props.productId,
 | 
				
			||||||
                </Dropzone.Reject>
 | 
					            formData: {
 | 
				
			||||||
                <Dropzone.Idle>
 | 
					                upload_file: file
 | 
				
			||||||
                    <IconPhoto
 | 
					            }
 | 
				
			||||||
                        style={{width: rem(52), height: rem(52), color: 'var(--mantine-color-dimmed)'}}
 | 
					        }).then(({ok, message, imageUrl}) => {
 | 
				
			||||||
                        stroke={1.5}
 | 
					            notifications.guess(ok, {message});
 | 
				
			||||||
                    />
 | 
					            if (!ok || !imageUrl) {
 | 
				
			||||||
                </Dropzone.Idle>
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            props.imageUrlInputProps?.onChange(imageUrl);
 | 
				
			||||||
 | 
					            setShowDropzone(false);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const getBody = () => {
 | 
				
			||||||
 | 
					        return props.imageUrlInputProps?.value && showDropzone ? (
 | 
				
			||||||
 | 
					            <Image src={props.imageUrlInputProps.value}/>
 | 
				
			||||||
 | 
					        ) : (
 | 
				
			||||||
 | 
					            <Dropzone
 | 
				
			||||||
 | 
					                {...restProps}
 | 
				
			||||||
 | 
					                multiple={false}
 | 
				
			||||||
 | 
					                onDrop={onDrop}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                <div>
 | 
					            >
 | 
				
			||||||
                    <Text size="xl" inline>
 | 
					                <Group justify="center" gap="xl" style={{pointerEvents: 'none'}}>
 | 
				
			||||||
                        Drag images here or click to select files
 | 
					                    <Dropzone.Accept>
 | 
				
			||||||
                    </Text>
 | 
					                        <IconUpload
 | 
				
			||||||
                    <Text size="sm" c="dimmed" inline mt={7}>
 | 
					                            style={{width: rem(52), height: rem(52), color: 'var(--mantine-color-blue-6)'}}
 | 
				
			||||||
                        Attach as many files as you like, each file should not exceed 5mb
 | 
					                            stroke={1.5}
 | 
				
			||||||
                    </Text>
 | 
					                        />
 | 
				
			||||||
                </div>
 | 
					                    </Dropzone.Accept>
 | 
				
			||||||
            </Group>
 | 
					                    <Dropzone.Reject>
 | 
				
			||||||
        </Dropzone>
 | 
					                        <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>
 | 
				
			||||||
 | 
					                        <Text size="xl" inline>
 | 
				
			||||||
 | 
					                            Drag images here or click to select files
 | 
				
			||||||
 | 
					                        </Text>
 | 
				
			||||||
 | 
					                        <Text size="sm" c="dimmed" inline mt={7}>
 | 
				
			||||||
 | 
					                            Attach as many files as you like, each file should not exceed 5mb
 | 
				
			||||||
 | 
					                        </Text>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                </Group>
 | 
				
			||||||
 | 
					            </Dropzone>
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					        <Flex gap={rem(10)} direction={"column"}>
 | 
				
			||||||
 | 
					            <Fieldset legend={'Изображение'}>
 | 
				
			||||||
 | 
					                {getBody()}
 | 
				
			||||||
 | 
					            </Fieldset>
 | 
				
			||||||
 | 
					            {!showDropzone &&
 | 
				
			||||||
 | 
					                <Button variant={"default"}>Заменить изображение {}</Button>
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        </Flex>
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,7 @@ 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";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type CreateProps = {
 | 
					type CreateProps = {
 | 
				
			||||||
    clientId: number;
 | 
					    clientId: number;
 | 
				
			||||||
@@ -25,12 +26,13 @@ const CreateProductModal = ({
 | 
				
			|||||||
                            }: 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 = isEditProps ? innerProps.product : {
 | 
					    const initialValues: Omit<ProductSchema, 'id'> = isEditProps ? innerProps.product : {
 | 
				
			||||||
        name: '',
 | 
					        name: '',
 | 
				
			||||||
        article: '',
 | 
					        article: '',
 | 
				
			||||||
        barcodes: []
 | 
					        barcodes: [],
 | 
				
			||||||
 | 
					        clientId: innerProps.clientId
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    const form = useForm({
 | 
					    const form = useForm<Omit<ProductSchema, 'id'>>({
 | 
				
			||||||
        initialValues: initialValues,
 | 
					        initialValues: initialValues,
 | 
				
			||||||
        validate: {
 | 
					        validate: {
 | 
				
			||||||
            name: (name) => name.trim() !== '' ? null : "Необходимо ввести название товара",
 | 
					            name: (name) => name.trim() !== '' ? null : "Необходимо ввести название товара",
 | 
				
			||||||
@@ -99,11 +101,15 @@ const CreateProductModal = ({
 | 
				
			|||||||
                            label={"Доп. информация"}
 | 
					                            label={"Доп. информация"}
 | 
				
			||||||
                            {...form.getInputProps('additionalInfo')} />
 | 
					                            {...form.getInputProps('additionalInfo')} />
 | 
				
			||||||
                    </Fieldset>
 | 
					                    </Fieldset>
 | 
				
			||||||
                    <Fieldset legend={"Изображение"}>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        <ImageDropzone onDrop={(data) => {
 | 
					                    {isEditProps &&
 | 
				
			||||||
                        }}/>
 | 
					                        // <Fieldset legend={"Изображение"}>
 | 
				
			||||||
                    </Fieldset>
 | 
					                        <ImageDropzone
 | 
				
			||||||
 | 
					                            imageUrlInputProps={form.getInputProps('imageUrl') as BaseFormInputProps<string>}
 | 
				
			||||||
 | 
					                            productId={innerProps.product.id}
 | 
				
			||||||
 | 
					                        />
 | 
				
			||||||
 | 
					                        // </Fieldset>
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                    <Flex justify={"flex-end"} mt={rem(5)} gap={rem(10)}>
 | 
					                    <Flex justify={"flex-end"} mt={rem(5)} gap={rem(10)}>
 | 
				
			||||||
                        <Button onClick={() => onCancelClick()} variant={"subtle"}>Отменить</Button>
 | 
					                        <Button onClick={() => onCancelClick()} variant={"subtle"}>Отменить</Button>
 | 
				
			||||||
                        {isEditProps ?
 | 
					                        {isEditProps ?
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user