feat: upload image on product
This commit is contained in:
		@@ -1,6 +1,6 @@
 | 
			
		||||
import {Dropzone, DropzoneProps, FileWithPath} from "@mantine/dropzone";
 | 
			
		||||
import {FC, useState} from "react";
 | 
			
		||||
import {Button, Fieldset, Flex, Group, Image, rem, Text} from "@mantine/core";
 | 
			
		||||
import {Button, Fieldset, Flex, Group, Image, Loader, rem, Text} from "@mantine/core";
 | 
			
		||||
import {IconPhoto, IconUpload, IconX} from "@tabler/icons-react";
 | 
			
		||||
import {omit} from "lodash";
 | 
			
		||||
import {BaseFormInputProps} from "../../types/utils.ts";
 | 
			
		||||
@@ -20,8 +20,7 @@ const ImageDropzone: FC<Props> = (props: Props) => {
 | 
			
		||||
        !(typeof props.imageUrlInputProps?.value === 'string' &&
 | 
			
		||||
            props.imageUrlInputProps.value.trim() !== '')
 | 
			
		||||
    );
 | 
			
		||||
    console.log(props.imageUrlInputProps);
 | 
			
		||||
    console.log(showDropzone);
 | 
			
		||||
    const [isLoading, setIsLoading] = useState(false);
 | 
			
		||||
    const restProps = omit(props, ['imageUrl', 'productId', 'imageUrlInputProps']);
 | 
			
		||||
    const onDrop = (files: FileWithPath[]) => {
 | 
			
		||||
        if (!props.productId || !props.imageUrlInputProps) return;
 | 
			
		||||
@@ -31,6 +30,7 @@ const ImageDropzone: FC<Props> = (props: Props) => {
 | 
			
		||||
        }
 | 
			
		||||
        const file = files[0];
 | 
			
		||||
        // TODO check if file is image
 | 
			
		||||
        setIsLoading(true);
 | 
			
		||||
        ProductService.uploadProductImage({
 | 
			
		||||
            productId: props.productId,
 | 
			
		||||
            formData: {
 | 
			
		||||
@@ -38,19 +38,37 @@ const ImageDropzone: FC<Props> = (props: Props) => {
 | 
			
		||||
            }
 | 
			
		||||
        }).then(({ok, message, imageUrl}) => {
 | 
			
		||||
            notifications.guess(ok, {message});
 | 
			
		||||
            setIsLoading(false);
 | 
			
		||||
 | 
			
		||||
            if (!ok || !imageUrl) {
 | 
			
		||||
                setShowDropzone(true);
 | 
			
		||||
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            props.imageUrlInputProps?.onChange(imageUrl);
 | 
			
		||||
            setShowDropzone(false);
 | 
			
		||||
        }).catch(error => {
 | 
			
		||||
            notifications.error({message: error.toString()});
 | 
			
		||||
            setShowDropzone(true);
 | 
			
		||||
            setIsLoading(false);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    const getBody = () => {
 | 
			
		||||
        return props.imageUrlInputProps?.value && showDropzone ? (
 | 
			
		||||
        return props.imageUrlInputProps?.value && !showDropzone ? (
 | 
			
		||||
            <Image src={props.imageUrlInputProps.value}/>
 | 
			
		||||
        ) : (
 | 
			
		||||
 | 
			
		||||
            <Dropzone
 | 
			
		||||
                {...restProps}
 | 
			
		||||
                accept={["image/png",
 | 
			
		||||
                    "image/jpeg",
 | 
			
		||||
                    "image/gif",
 | 
			
		||||
                    "image/bmp",
 | 
			
		||||
                    "image/tiff",
 | 
			
		||||
                    "image/x-icon",
 | 
			
		||||
                    "image/webp",
 | 
			
		||||
                    "image/svg+xml",
 | 
			
		||||
                    "image/heic"]}
 | 
			
		||||
                multiple={false}
 | 
			
		||||
                onDrop={onDrop}
 | 
			
		||||
 | 
			
		||||
@@ -75,25 +93,30 @@ const ImageDropzone: FC<Props> = (props: Props) => {
 | 
			
		||||
                        />
 | 
			
		||||
                    </Dropzone.Idle>
 | 
			
		||||
 | 
			
		||||
                    <div>
 | 
			
		||||
                    <div style={{textAlign: "center"}}>
 | 
			
		||||
                        <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()}
 | 
			
		||||
        <Flex
 | 
			
		||||
            gap={rem(10)}
 | 
			
		||||
            direction={"column"}
 | 
			
		||||
 | 
			
		||||
        >
 | 
			
		||||
            <Fieldset
 | 
			
		||||
                legend={'Изображение'}>
 | 
			
		||||
                <Flex justify={"center"}>
 | 
			
		||||
                    {isLoading ? <Loader/> : getBody()}
 | 
			
		||||
                </Flex>
 | 
			
		||||
            </Fieldset>
 | 
			
		||||
            {!showDropzone &&
 | 
			
		||||
                <Button variant={"default"}>Заменить изображение {}</Button>
 | 
			
		||||
                <Button onClick={() => setShowDropzone(true)} variant={"default"}>Заменить изображение {}</Button>
 | 
			
		||||
            }
 | 
			
		||||
        </Flex>
 | 
			
		||||
    )
 | 
			
		||||
 
 | 
			
		||||
@@ -24,4 +24,24 @@ export const getPluralForm = (amount: number, one: string, twoFour: string, many
 | 
			
		||||
        default:
 | 
			
		||||
            return many;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
type KeysOf<T> = (keyof T)[];
 | 
			
		||||
 | 
			
		||||
// Универсальная функция для получения ключей интерфейса
 | 
			
		||||
export function getKeys<T extends object>(): KeysOf<T> {
 | 
			
		||||
    return Object.keys({} as T) as KeysOf<T>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export const IMAGE_MIME_TYPES = [
 | 
			
		||||
    "image/png",
 | 
			
		||||
    "image/jpeg",
 | 
			
		||||
    "image/gif",
 | 
			
		||||
    "image/bmp",
 | 
			
		||||
    "image/tiff",
 | 
			
		||||
    "image/x-icon",
 | 
			
		||||
    "image/webp",
 | 
			
		||||
    "image/svg+xml",
 | 
			
		||||
    "image/heic"
 | 
			
		||||
];
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user