temp image upload
This commit is contained in:
		@@ -14,5 +14,6 @@ export type ProductCreateRequest = {
 | 
			
		||||
    composition?: (string | null);
 | 
			
		||||
    size?: (string | null);
 | 
			
		||||
    additionalInfo?: (string | null);
 | 
			
		||||
    imageUrl?: (string | null);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -14,6 +14,7 @@ export type ProductSchema = {
 | 
			
		||||
    composition?: (string | null);
 | 
			
		||||
    size?: (string | null);
 | 
			
		||||
    additionalInfo?: (string | null);
 | 
			
		||||
    imageUrl?: (string | null);
 | 
			
		||||
    id: number;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,53 +1,101 @@
 | 
			
		||||
import {Dropzone, DropzoneProps} from "@mantine/dropzone";
 | 
			
		||||
import {FC} from "react";
 | 
			
		||||
import {Group, rem, Text} from "@mantine/core";
 | 
			
		||||
import {Dropzone, DropzoneProps, FileWithPath} from "@mantine/dropzone";
 | 
			
		||||
import {FC, useState} from "react";
 | 
			
		||||
import {Button, Fieldset, Flex, Group, Image, rem, Text} from "@mantine/core";
 | 
			
		||||
import {IconPhoto, IconUpload, IconX} from "@tabler/icons-react";
 | 
			
		||||
import {omit} from "lodash";
 | 
			
		||||
import {BaseFormInputProps} from "../../types/utils.ts";
 | 
			
		||||
import {notifications} from "../../shared/lib/notifications.ts";
 | 
			
		||||
import {ProductService} from "../../client";
 | 
			
		||||
 | 
			
		||||
type RestProps = {
 | 
			
		||||
    imageUrl?: string;
 | 
			
		||||
};
 | 
			
		||||
const ALL_PROPERTIES = Object.keys(colDefProperties) as (keyof ColDef)[];
 | 
			
		||||
interface RestProps {
 | 
			
		||||
    imageUrlInputProps?: BaseFormInputProps<string>;
 | 
			
		||||
    productId?: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
type Props = DropzoneProps & RestProps;
 | 
			
		||||
type Props = Omit<DropzoneProps, 'onDrop'> & RestProps;
 | 
			
		||||
 | 
			
		||||
const ImageDropzone: FC<Props> = (props: Props) => {
 | 
			
		||||
    const restProps = omit()
 | 
			
		||||
    return (
 | 
			
		||||
        <Dropzone
 | 
			
		||||
            {...props}
 | 
			
		||||
        >
 | 
			
		||||
            <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>
 | 
			
		||||
    const [showDropzone, setShowDropzone] = useState(
 | 
			
		||||
        !(typeof props.imageUrlInputProps?.value === 'string' &&
 | 
			
		||||
            props.imageUrlInputProps.value.trim() !== '')
 | 
			
		||||
    );
 | 
			
		||||
    console.log(props.imageUrlInputProps);
 | 
			
		||||
    console.log(showDropzone);
 | 
			
		||||
    const restProps = omit(props, ['imageUrl', 'productId', 'imageUrlInputProps']);
 | 
			
		||||
    const onDrop = (files: FileWithPath[]) => {
 | 
			
		||||
        if (!props.productId || !props.imageUrlInputProps) return;
 | 
			
		||||
        if (files.length > 1) {
 | 
			
		||||
            notifications.error({message: "Прикрепите одно изображение"});
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        const file = files[0];
 | 
			
		||||
        // TODO check if file is image
 | 
			
		||||
        ProductService.uploadProductImage({
 | 
			
		||||
            productId: props.productId,
 | 
			
		||||
            formData: {
 | 
			
		||||
                upload_file: file
 | 
			
		||||
            }
 | 
			
		||||
        }).then(({ok, message, imageUrl}) => {
 | 
			
		||||
            notifications.guess(ok, {message});
 | 
			
		||||
            if (!ok || !imageUrl) {
 | 
			
		||||
                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>
 | 
			
		||||
                        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>
 | 
			
		||||
            >
 | 
			
		||||
                <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>
 | 
			
		||||
                        <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 BarcodeTemplateSelect from "../../../../components/Selects/BarcodeTemplateSelect/BarcodeTemplateSelect.tsx";
 | 
			
		||||
import ImageDropzone from "../../../../components/ImageDropzone/ImageDropzone.tsx";
 | 
			
		||||
import {BaseFormInputProps} from "../../../../types/utils.ts";
 | 
			
		||||
 | 
			
		||||
type CreateProps = {
 | 
			
		||||
    clientId: number;
 | 
			
		||||
@@ -25,12 +26,13 @@ const CreateProductModal = ({
 | 
			
		||||
                            }: ContextModalProps<Props>) => {
 | 
			
		||||
    const isEditProps = 'product' in innerProps;
 | 
			
		||||
    const isCreatingProps = 'clientId' in innerProps;
 | 
			
		||||
    const initialValues = isEditProps ? innerProps.product : {
 | 
			
		||||
    const initialValues: Omit<ProductSchema, 'id'> = isEditProps ? innerProps.product : {
 | 
			
		||||
        name: '',
 | 
			
		||||
        article: '',
 | 
			
		||||
        barcodes: []
 | 
			
		||||
        barcodes: [],
 | 
			
		||||
        clientId: innerProps.clientId
 | 
			
		||||
    };
 | 
			
		||||
    const form = useForm({
 | 
			
		||||
    const form = useForm<Omit<ProductSchema, 'id'>>({
 | 
			
		||||
        initialValues: initialValues,
 | 
			
		||||
        validate: {
 | 
			
		||||
            name: (name) => name.trim() !== '' ? null : "Необходимо ввести название товара",
 | 
			
		||||
@@ -99,11 +101,15 @@ const CreateProductModal = ({
 | 
			
		||||
                            label={"Доп. информация"}
 | 
			
		||||
                            {...form.getInputProps('additionalInfo')} />
 | 
			
		||||
                    </Fieldset>
 | 
			
		||||
                    <Fieldset legend={"Изображение"}>
 | 
			
		||||
 | 
			
		||||
                        <ImageDropzone onDrop={(data) => {
 | 
			
		||||
                        }}/>
 | 
			
		||||
                    </Fieldset>
 | 
			
		||||
                    {isEditProps &&
 | 
			
		||||
                        // <Fieldset legend={"Изображение"}>
 | 
			
		||||
                        <ImageDropzone
 | 
			
		||||
                            imageUrlInputProps={form.getInputProps('imageUrl') as BaseFormInputProps<string>}
 | 
			
		||||
                            productId={innerProps.product.id}
 | 
			
		||||
                        />
 | 
			
		||||
                        // </Fieldset>
 | 
			
		||||
                    }
 | 
			
		||||
                    <Flex justify={"flex-end"} mt={rem(5)} gap={rem(10)}>
 | 
			
		||||
                        <Button onClick={() => onCancelClick()} variant={"subtle"}>Отменить</Button>
 | 
			
		||||
                        {isEditProps ?
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user