| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- import React, { useCallback, useEffect, useRef, useState } from "react";
- import PropTypes from "prop-types";
- import {
- AddFile,
- AddIcon,
- ImageOverlay,
- ImagePickerContainer,
- ImageUploaded,
- Tools,
- } from "./ImagePicker.styled";
- import { IconButton } from "../Buttons/IconButton/IconButton";
- import { ReactComponent as EditIcon } from "../../assets/images/svg/edit.svg";
- import { ReactComponent as TrashIcon } from "../../assets/images/svg/trash.svg";
- import { getImageUrl, variants } from "../../util/helpers/imageUrlGetter";
-
- const ImagePicker = (props) => {
- const fileInputRef = useRef(null);
- const imageRef = useRef(null);
- const [image, setImage] = useState("");
- const [isEditing, setIsEditing] = useState(false);
-
- // Check if file is type of string or File
- useEffect(() => {
- if (props.image) {
- if (typeof props.image === "string") {
- setImage(getImageUrl(props.image, variants.offerCard));
- } else {
- handleImage(props.image);
- }
- }
- }, [props.image]);
-
- const listener = useCallback(
- (event) => {
- if (imageRef.current) {
- if (imageRef.current.contains(event.target)) {
- setIsEditing(true);
- } else {
- setIsEditing(false);
- }
- }
- },
- [imageRef.current]
- );
- useEffect(() => {
- window.addEventListener("click", listener);
- return () => window.removeEventListener("click", listener);
- }, []);
-
- // Simulate click on file input
- const handleChange = () => {
- fileInputRef.current.value = "";
- fileInputRef.current.click();
- };
-
- // Reads image as both base64 and multipart type
- const handleImage = (file) => {
- if (
- file.type !== "image/jpeg" &&
- file.type !== "image/jpg" &&
- file.type !== "image/png"
- )
- return;
- let reader = new FileReader();
- reader.readAsDataURL(file);
- reader.onload = () => {
- if (props.setImage) props.setImage(file);
- setImage(reader.result);
- };
- reader.onerror = (error) => {
- console.dir(error);
- };
- };
-
- const handleDelete = () => {
- if (props.deleteImage) props.deleteImage();
- setImage("");
- setIsEditing(false);
- };
-
- return (
- <ImagePickerContainer
- className={props.className}
- onClick={!image ? handleChange : () => {}}
- hasImage={props.image}
- component="form"
- singleImage={props.singleImage}
- >
- <AddFile
- type="file"
- ref={fileInputRef}
- onInput={(event) => handleImage(event.target.files[0])}
- accept=".jpg, .jpeg, .png"
- formEncType="multipart/form-data"
- />
- {image ? (
- <React.Fragment>
- <ImageUploaded src={image} draggable={false} ref={imageRef} />
- {isEditing && (
- <React.Fragment>
- <ImageOverlay />
- <Tools showDeleteIcon={props.showDeleteIcon}>
- <IconButton onClick={handleChange}>
- <EditIcon />
- </IconButton>
- {props.showDeleteIcon && (
- <IconButton onClick={handleDelete}>
- <TrashIcon />
- </IconButton>
- )}
- </Tools>
- </React.Fragment>
- )}
- </React.Fragment>
- ) : (
- <AddIcon />
- )}
- {props.children}
- </ImagePickerContainer>
- );
- };
- ImagePicker.propTypes = {
- children: PropTypes.node,
- className: PropTypes.string,
- setImage: PropTypes.func,
- image: PropTypes.func,
- deleteImage: PropTypes.func,
- showDeleteIcon: PropTypes.bool,
- singleImage: PropTypes.bool,
- };
- export default ImagePicker;
|