temp image upload

This commit is contained in:
2024-05-25 11:35:24 +03:00
parent f41999dfbc
commit 1e40e79be1
4 changed files with 105 additions and 49 deletions

View File

@@ -14,5 +14,6 @@ export type ProductCreateRequest = {
composition?: (string | null);
size?: (string | null);
additionalInfo?: (string | null);
imageUrl?: (string | null);
};

View File

@@ -14,6 +14,7 @@ export type ProductSchema = {
composition?: (string | null);
size?: (string | null);
additionalInfo?: (string | null);
imageUrl?: (string | null);
id: number;
};

View File

@@ -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>
)
}

View File

@@ -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 ?