import { Avatar, IconButton, Skeleton, Tooltip } from '@mui/material'; import { Photo, Resume } from '@reactive-resume/schema'; import get from 'lodash/get'; import isEmpty from 'lodash/isEmpty'; import { useTranslation } from 'next-i18next'; import React, { useRef } from 'react'; import toast from 'react-hot-toast'; import { useMutation } from 'react-query'; import { ServerError } from '@/services/axios'; import { deletePhoto, DeletePhotoParams, uploadPhoto, UploadPhotoParams } from '@/services/resume'; import { useAppDispatch, useAppSelector } from '@/store/hooks'; import { setResumeState } from '@/store/resume/resumeSlice'; const FILE_UPLOAD_MAX_SIZE = 2000000; // 2 MB const PhotoUpload: React.FC = () => { const { t } = useTranslation(); const dispatch = useAppDispatch(); const fileInputRef = useRef(null); const id: number = useAppSelector((state) => get(state.resume, 'id')); const photo: Photo = useAppSelector((state) => get(state.resume, 'basics.photo')); const { mutateAsync: uploadMutation, isLoading } = useMutation(uploadPhoto); const { mutateAsync: deleteMutation } = useMutation(deletePhoto); const handleClick = async () => { if (fileInputRef.current) { if (!isEmpty(photo.url)) { try { await deleteMutation({ id }); } finally { dispatch(setResumeState({ path: 'basics.photo.url', value: '' })); } } else { fileInputRef.current.click(); } fileInputRef.current.value = ''; } }; const handleChange = async (event: React.ChangeEvent) => { if (event.target.files && event.target.files[0]) { const file = event.target.files[0]; if (file.size > FILE_UPLOAD_MAX_SIZE) { toast.error(t('common.toast.error.upload-photo-size')); return; } const resume = await uploadMutation({ id, file }); dispatch(setResumeState({ path: 'basics.photo.url', value: get(resume, 'basics.photo.url', '') })); } }; return ( {isLoading ? ( ) : ( ('builder.leftSidebar.sections.basics.photo-upload.tooltip.upload') : t('builder.leftSidebar.sections.basics.photo-upload.tooltip.remove') } > )} ); }; export default PhotoUpload;