import React, {useEffect, useState} from 'react'; // Hooks import {useDispatch, useSelector} from 'react-redux'; import { RootState } from '../../../../../redux/reducers'; import {AppDispatch} from '../../../../../redux/store'; // Actions import {success} from '../../../../../redux/actions/snackbarActions'; // Utils import {post} from '../../../../../utils/api'; import { getItem, removeItem, setItem } from '../../../../../utils/local-storage'; import { dataURLtoBlob } from '../../../../../utils/helper'; import {EMAIL_REGEX, VIDEO_URL_REGEX} from '../../../../../utils/constants'; import { MESSAGES } from '../../../../../utils/message'; // Components import Dialog from '../../../../GenericUIBlocks/Dialog'; import Input from '../../../../GenericUIBlocks/Input'; import Typography from '../../../../GenericUIBlocks/Typography'; import Button from '../../../../GenericUIBlocks/Button'; // Icons import PDF from '../../../../../assets/images/modal-icons/pdf'; import PNG from '../../../../../assets/images/modal-icons/png'; import DOC from '../../../../../assets/images/modal-icons/doc'; import DOCX from '../../../../../assets/images/modal-icons/docx'; import JPG from '../../../../../assets/images/modal-icons/jpg'; import JPEG from '../../../../../assets/images/modal-icons/jpeg'; import CancelFile from '../../../../../assets/images/modal-icons/cancel-file'; import Add from '../../../../../assets/images/modal-icons/add'; // Styles import './styles.scss'; const hireModalStyles = { maxWidth: '725px', minHeight: '760px', }; const hireModalButtonStyles = { fontWeight: '600', fontSize: '18px', maxWidth: '643px', minHeight: '55px', }; const errorStyles = { color: 'var(--error-color)', fontWeight: '400', fontSize: '14px', margin: '0', }; const HireDesigner = (props: any) => { const { open, onClose, onCreateCustomTemplateQuery, productId } = props; const [queryTitle, setQueryTitle] = useState(''); const [queryEmail, setQueryEmail] = useState(''); const [queryFile, setQueryFile] = useState([]); const [queryVideoUrl, setQueryVideoUrl] = useState(''); const [queryComments, setQueryComments] = useState(''); const [isLoading, setIsLoading] = useState(false); const [formErrors, setFormErrors] = useState({ title: '', email: '', files: '', videoUrl: '', comments: '', }); const dispatch: AppDispatch = useDispatch(); const designerFormStates = useSelector((state: RootState) => state.templates.hireDesignerForm); const handleTitleChange = (event: any) => { const newTitle = event.target.value; setQueryTitle(newTitle); setFormErrors((prevErrors) => ({ ...prevErrors, title: newTitle.trim() && '', })); dispatch({type: 'SET_HIRE_DESIGNER_FORM_FIELDS', payload: { queryTitle: newTitle }}); }; const handleEmailChange = (event: any) => { const newEmail = event.target.value; setQueryEmail(newEmail); setFormErrors((prevErrors) => ({ ...prevErrors, email: newEmail.trim() && '', })); dispatch({type: 'SET_HIRE_DESIGNER_FORM_FIELDS', payload: { queryEmail: newEmail }}); }; const handleVideoUrlChange = (event: any) => { const newVideoUrl = event.target.value; setQueryVideoUrl(newVideoUrl); setFormErrors((prevErrors) => ({ ...prevErrors, videoUrl: newVideoUrl.trim() && '', })); dispatch({type: 'SET_HIRE_DESIGNER_FORM_FIELDS', payload: { queryVideoUrl: newVideoUrl }}); }; const handleCommentsChange = (event: any) => { const newComments = event.target.value; setQueryComments(newComments); setFormErrors((prevErrors: any) => ({ ...prevErrors, comments: newComments.trim() && '', })); dispatch({type: 'SET_HIRE_DESIGNER_FORM_FIELDS', payload: { queryComments: newComments }}) }; const saveFilesToLocalStorage = (files: File[]) => { const fileData = files.map((file) => ({ name: file.name, type: file.type, size: file.size, content: "", })); files.forEach((file, index) => { const reader = new FileReader(); reader.onload = () => { fileData[index].content = reader.result as string; if (index === files.length - 1) { dispatch({type: 'SET_HIRE_DESIGNER_FORM_FIELDS', payload: { queryFiles: fileData }}); } }; reader.readAsDataURL(file); }); }; // Retrieve files from localStorage const getFilesFromLocalStorage = () => { const savedFiles = designerFormStates.queryFiles; if (!savedFiles) return []; const fileData = savedFiles; return fileData.map((file: any) => { const blob = dataURLtoBlob(file.content, file.type); return new File([blob], file.name, { type: file.type }); }); }; const handleFileChange = (event: any) => { const newFilesArray = Array.from(event.target.files); const acceptableTypes = ['image/png', 'image/jpeg', 'image/jpg', 'application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document']; const validFiles = newFilesArray.filter((file: any) => acceptableTypes.includes(file.type)); const invalidFiles = newFilesArray.filter((file: any) => !acceptableTypes.includes(file.type)); if (invalidFiles.length > 0) { setFormErrors((prevErrors) => ({ ...prevErrors, files: MESSAGES.TEMPLATE.HIRE_DESIGNER.FILE_VALLIDATION, })); setTimeout(() => { setFormErrors((prevErrors) => ({ ...prevErrors, files: '', })); }, 6000); } else { setFormErrors((prevErrors) => ({ ...prevErrors, files: '', })); } if (validFiles.length > 0) { setQueryFile((prevFiles: any) => [...prevFiles, ...validFiles] as never[]); saveFilesToLocalStorage([...queryFile, ...validFiles] as never[]); } event.target.value = null; }; const handleFileRemove = (file: any) => { const updatedFiles = queryFile.filter((f: any) => f.name !== file.name); setQueryFile(updatedFiles); updatedFiles.length ? saveFilesToLocalStorage([...updatedFiles] as never[]) : dispatch({ type: 'SET_HIRE_DESIGNER_FORM_FIELDS', payload: { queryFiles: [] as never[] } }); }; const validateForm = (formData: any, setFormErrors: any) => { const errors: any = {}; if (!formData.queryTitle.trim()) { errors.title = MESSAGES.TEMPLATE.HIRE_DESIGNER.TITLE_REQUIRED; } if (!formData.queryVideoUrl.trim()) { errors.videoUrl = MESSAGES.TEMPLATE.HIRE_DESIGNER.URL_REQUIRED; } else if (!VIDEO_URL_REGEX.test(formData.queryVideoUrl.trim())) { errors.videoUrl = MESSAGES.TEMPLATE.HIRE_DESIGNER.URL_VAIDATION; } if (!formData.queryComments.trim()) { errors.comments = MESSAGES.TEMPLATE.HIRE_DESIGNER.COMMENT_REQUIRED; } if (!formData.queryEmail.trim()) { errors.email = MESSAGES.TEMPLATE.HIRE_DESIGNER.EMAIL_REQUIRED; } else if (!EMAIL_REGEX.test(formData.queryEmail.trim())) { errors.email = MESSAGES.TEMPLATE.HIRE_DESIGNER.EMAIL_VALIDATION; } setFormErrors(errors); return Object.keys(errors).length === 0; }; const resetForm = () => { setQueryTitle(''); setQueryEmail(''); setQueryVideoUrl(''); setQueryFile([]); setQueryComments(''); setFormErrors({ title: '', email: '', files: '', videoUrl: '', comments: '', }); removeItem('hireDesignerFormState'); removeItem('queryFiles'); dispatch({type: 'CLEAR_HIRE_DESIGNER_FORM_FIELDS'}); }; const handleSubmit = async (event: any) => { try { event.preventDefault(); const formData = { queryTitle, queryVideoUrl, queryComments, queryFile, queryEmail, }; const isValid = validateForm(formData, setFormErrors); if (!isValid) return; setIsLoading(true); const form = new FormData(); form.append('title', queryTitle); form.append('comments', queryComments); form.append('email', queryEmail); form.append('productId', productId); form.append('url', queryVideoUrl); queryFile.forEach((file: any) => { form.append('files', file); }); const response: any = await post('/custom-template-queries/create', form); if (response && response.status === 200) { setIsLoading(false); closeHireModal(); dispatch(success(response.data.message)); onCreateCustomTemplateQuery(response.data); } else { throw new Error(`HTTP error! status: ${response.status}`); } } catch (error) { return error; } finally { setIsLoading(false); } }; const closeHireModal = () => { onClose(); resetForm(); } useEffect(() => { setQueryTitle(designerFormStates.queryTitle); setQueryEmail(designerFormStates.queryEmail); setQueryVideoUrl(designerFormStates.queryVideoUrl); setQueryComments(designerFormStates.queryComments); const savedFiles: any = getFilesFromLocalStorage(); setQueryFile(savedFiles); }, [open]) return (
{MESSAGES.TEMPLATE.HIRE_DESIGNER.TITLE}
{' '} or drag and drop
Supported formats: .png, .jpg, .jpeg, .pdf, .doc, .docx
{formErrors.files && ( {formErrors.files} )} {queryFile.length > 0 && (

{MESSAGES.TEMPLATE.HIRE_DESIGNER.UPLOADED_TEXT}

{queryFile.map((file: File, index: number) => (
{file.type === 'application/pdf' ? ( ) : file.type === 'image/jpeg' ? ( ) : file.type === 'image/png' ? ( ) : file.type === 'image/jpg' ? ( ) : file.type === 'application/msword' ? ( ) : file.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' ? ( ) : null}

{file.name}

{(file.size / (1024 * 1024)).toFixed(2)} MB

handleFileRemove(file)} >
))}
)}
); }; export default HireDesigner;