feat: passport images for user

This commit is contained in:
2024-12-04 20:21:01 +04:00
parent 1795cacc5b
commit 2cb62a4e0b
15 changed files with 260 additions and 60 deletions

View File

@@ -1,77 +1,34 @@
import { Dropzone, DropzoneProps, FileWithPath } from "@mantine/dropzone";
import { FC, useState } from "react";
import {
Button,
Fieldset,
Flex,
Group,
Image,
Loader,
rem,
Text,
} from "@mantine/core";
import { FC } from "react";
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";
import { notifications } from "../../shared/lib/notifications.ts";
import { ProductService } from "../../client";
import UseImageDropzone from "../../types/UseImageDropzone.tsx";
interface RestProps {
imageUrlInputProps?: BaseFormInputProps<string>;
productId?: number;
imageDropzone: UseImageDropzone;
onDrop: (files: FileWithPath[]) => void;
}
type Props = Omit<DropzoneProps, "onDrop"> & RestProps;
const ImageDropzone: FC<Props> = (props: Props) => {
const [showDropzone, setShowDropzone] = useState(
!(
typeof props.imageUrlInputProps?.value === "string" &&
props.imageUrlInputProps.value.trim() !== ""
)
);
const [isLoading, setIsLoading] = useState(false);
const {
showDropzone,
setShowDropzone,
isLoading,
imageUrlInputProps,
} = props.imageDropzone;
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
setIsLoading(true);
ProductService.uploadProductImage({
productId: props.productId,
formData: {
upload_file: file,
},
})
.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 ? (
<Image src={props.imageUrlInputProps.value} />
return imageUrlInputProps?.value && !showDropzone ? (
<Image src={imageUrlInputProps.value} />
) : (
<Dropzone
{...restProps}
@@ -87,7 +44,7 @@ const ImageDropzone: FC<Props> = (props: Props) => {
"image/heic",
]}
multiple={false}
onDrop={onDrop}>
onDrop={props.onDrop}>
<Group
justify="center"
gap="xl"