From d76758975c07d48f440b46df56f8d2b09fbccd16 Mon Sep 17 00:00:00 2001 From: Rushikesh-Sonawane99 Date: Wed, 24 Jul 2024 12:10:27 +0530 Subject: [PATCH 1/2] Issue #PS-1265 chore: Created dynamic routing for TL and FL profile --- src/components/Header.tsx | 7 +- src/pages/user-profile/[userId].tsx | 1181 +++++++++++++++++++++++++++ 2 files changed, 1185 insertions(+), 3 deletions(-) create mode 100644 src/pages/user-profile/[userId].tsx diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 8593eafa..1306aa87 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -24,6 +24,7 @@ const Header: React.FC = () => { const { t } = useTranslation(); const pathname = usePathname(); const theme = useTheme(); + const userId = localStorage.getItem('userId'); const StyledMenu = styled((props: MenuProps) => ( { })); const handleProfileClick = () => { - if (pathname !== '/profile') { - router.push('/profile'); + if (pathname !== `/user-profile/${userId}`) { + router.push(`/user-profile/${userId}`); logEvent({ action: 'my-profile-clicked-header', category: 'Dashboard', @@ -227,7 +228,7 @@ const Header: React.FC = () => { open={open} onClose={handleClose} > - {pathname !== '/profile' && ( + {pathname !== `/user-profile/${userId}` && ( void; + } + + const TeacherProfile = () => { + const user_placeholder_img: string = user_placeholder.src; + + const { t } = useTranslation(); + const router = useRouter(); + const { userId }: any = router.query; + const theme = useTheme(); + const [open, setOpen] = React.useState(false); + const handleOpen = () => { + setOpen(true); + logEvent({ + action: 'edit-teacher-profile-modal-open', + category: 'Profile Page', + label: 'Edit Teacher Profile Modal Open', + }); + }; + const [errors, setErrors] = useState<{ [key: string]: boolean }>({}); + + const handleClose = () => { + setOpen(false); + initialFormData(); + setHasInputChanged(false); + setHasErrors(false); + setErrors({}); + logEvent({ + action: 'edit-teacher-profile-modal-close', + category: 'Profile Page', + label: 'Edit Teacher Profile Modal Close', + }); + }; + const [userData, setUserData] = useState(null); + const [userName, setUserName] = useState(null); + const [updatedCustomFields, setUpdatedCustomFields] = useState([]); + const isDesktop = useMediaQuery(theme.breakpoints.up('md')); + const fileInputRef = useRef(null); + const [dropdownValues, setDropdownValues] = useState({}); + const [customFieldsData, setCustomFieldsData] = useState([]); + + const [loading, setLoading] = useState(false); + const [image, setImage] = useState(user_placeholder_img); + const [gender, setGender] = React.useState(''); + const [isAuthenticated, setIsAuthenticated] = React.useState(false); + const [unitName, setUnitName] = useState(''); + const [blockName, setBlockName] = useState(''); + const [radioValues, setRadioValues] = useState([]); + const [isError, setIsError] = React.useState(false); + const [isData, setIsData] = React.useState(false); + const [hasInputChanged, setHasInputChanged] = React.useState(false); + const [isValidationTriggered, setIsValidationTriggered] = + React.useState(false); + // const [userId, setUserId] = useState(null); + + const handleNameFieldChange = (event: ChangeEvent) => { + const { value } = event.target; + setUserName(value); + }; + + const style = { + position: 'absolute', + top: '50%', + width: '85%', + left: '50%', + transform: 'translate(-50%, -50%)', + bgcolor: theme.palette.warning.A400, + height: '526px', + textAlign: 'center', + '@media (min-width: 600px)': { + width: '450px', + }, + }; + + useEffect(() => { + if (typeof window !== 'undefined' && window.localStorage) { + const token = localStorage.getItem('token'); + // const storedUserId = localStorage.getItem('userId'); + if (token) { + setIsAuthenticated(true); + } else { + router.push('/login'); + } + // setUserId(storedUserId); + } + }, []); + + // find Address + const getFieldValue = (data: any, label: string) => { + const field = data.find((item: any) => item.label === label); + return field ? field.value[0] : null; + }; + + const { data, error, isLoading } = useProfileInfo(userId ?? '', true); + + useEffect(() => { + setLoading(isLoading); + + if (error) { + setIsError(true); + showToastMessage(t('COMMON.SOMETHING_WENT_WRONG'), 'error'); + console.error('Error fetching user details:', error); + } else { + setIsError(false); + } + + if (data) { + const userData = data?.result?.userData; + setUserData(userData); + setUserName(userData?.name); + const customDataFields = userData?.customFields; + setIsData(true); + if (customDataFields?.length > 0) { + setCustomFieldsData(customDataFields); + + const unitName = getFieldValue(customDataFields, 'Unit Name'); + setUnitName(unitName); + const blockName = getFieldValue(customDataFields, 'Block Name'); + setBlockName(blockName); + } + } else { + setIsData(false); + console.log('No data Found'); + } + }, [data, error, isLoading]); + + const handleClickImage = () => { + fileInputRef.current && fileInputRef.current.click(); + }; + + const handleImageUpload = (e: any) => { + const image: any[] = [e.target.files[0]]; + const newImageUrl: any = []; + image.forEach((dataImage: any) => + newImageUrl.push(URL.createObjectURL(dataImage)) + ); + setImage(newImageUrl); + }; + + // Find fields for "Subjects I Teach" and "My Main Subjects" + const teachSubjectsField = customFieldsData?.find( + (field) => field.name === 'subject_taught' + ); + const mainSubjectsField = customFieldsData?.find( + (field) => field.name === 'main_subject' + ); + + const teachSubjects: string[] = Array.isArray(teachSubjectsField?.value) + ? teachSubjectsField?.value + : []; + const mainSubjects: string[] = Array.isArray(mainSubjectsField?.value) + ? mainSubjectsField?.value + : []; + + // Find mutual and remaining subjects + const mutualSubjects = teachSubjects?.filter((subject) => + mainSubjects?.includes(subject) + ); + const remainingSubjects = teachSubjects?.filter( + (subject) => !mainSubjects?.includes(subject) + ); + const orderedSubjects = [...mutualSubjects, ...remainingSubjects]; + + // Function to get label for a subject from the options array + const getLabelForSubject = (subject: string) => { + const option = teachSubjectsField?.options?.find( + (opt: any) => opt.value === subject + ); + return option ? option.label : subject; + }; + + //fields for view profile by order + const filteredSortedForView = [...customFieldsData] + ?.filter((field) => field.order !== 0 && field.name !== 'main_subject') + ?.sort((a, b) => a.order - b.order); + + // fields for showing in basic details + const getLabelForValue = (field: any, value: string) => { + if ( + field.type === 'radio' || + field.type === 'Radio' || + field.type === 'drop_down' || + field.type === 'dropdown' + ) { + const option = field?.options?.find((opt: any) => opt?.value === value); + return option ? option?.label : value; + } + return value; + }; + + // address find + const address = [unitName, blockName, userData?.district, userData?.state] + ?.filter(Boolean) + ?.join(', '); + + //------------edit teacher profile------------ + + const [formData, setFormData] = useState<{ + userData: UserDatas; + customFields: { fieldId: string; type: string; value: string[] | string }[]; + }>({ + userData: { + name: userName || '', + }, + customFields: customFieldsData?.map((field) => ({ + fieldId: field.fieldId, + type: field.type, + value: field.value ? field.value : '', + })), + }); + + const initialFormData = () => { + setFormData({ + userData: { + name: userName || '', + }, + customFields: customFieldsData?.map((field) => ({ + fieldId: field.fieldId, + type: field.type, + value: field.value ? field.value : '', + })), + }); + }; + + useEffect(() => { + initialFormData(); + }, [userData, customFieldsData]); + + const [hasErrors, setHasErrors] = useState(false); + + const handleInputChange = (e: React.ChangeEvent) => { + const { value } = e.target; + const sanitizedValue = value + .replace(/[^a-zA-Z_ ]/g, '') + .replace(/^\s+/, '') + .replace(/\s+/g, ' '); + + setFormData((prevData) => ({ + ...prevData, + userData: { + ...prevData.userData, + name: sanitizedValue, + }, + })); + setHasInputChanged(true); + setIsValidationTriggered(true); + validateFields(); + // setHasErrors(!sanitizedValue.trim()); + }; + + //fields for edit popup by order + const filteredSortedForEdit = [...customFieldsData] + ?.filter((field) => field.isEditable) + ?.sort((a, b) => a.order - b.order); + + const validateFields = () => { + const newErrors: { [key: string]: boolean } = {}; + + filteredSortedForEdit?.forEach((field) => { + const value = + formData?.customFields?.find((f) => f.fieldId === field.fieldId) + ?.value[0] || ''; + + if (field.type === 'text') { + newErrors[field.fieldId] = !value.trim(); + } else if (field.type === 'numeric') { + newErrors[field.fieldId] = !/^\d{1,4}$/.test(value); + } else if (field.type === 'dropdown' || field.type === 'drop_down') { + newErrors[field.fieldId] = !value.trim(); + } + }); + + newErrors['name'] = !formData.userData.name.trim(); + + setErrors(newErrors); + setHasErrors(Object.values(newErrors).some((error) => error)); + }; + + useEffect(() => { + if (hasInputChanged) { + validateFields(); + } + }, [formData, customFieldsData]); + + const handleFieldChange = (fieldId: string, value: string) => { + const sanitizedValue = value.replace(/^\s+/, '').replace(/\s+/g, ' '); + + setFormData((prevState) => ({ + ...prevState, + customFields: prevState.customFields.map((field) => + field.fieldId === fieldId + ? { ...field, value: [sanitizedValue] } + : field + ), + })); + setHasInputChanged(true); + setIsValidationTriggered(true); + validateFields(); + }; + + const handleCheckboxChange = ( + fieldId: string, + optionName: string, + isChecked: boolean + ) => { + setFormData((prevState) => ({ + ...prevState, + customFields: prevState.customFields.map((field) => + field.fieldId === fieldId + ? { + ...field, + value: isChecked + ? [...(field.value as string[]), optionName] + : (field.value as string[]).filter( + (item) => item !== optionName + ), + } + : field + ), + })); + setHasInputChanged(true); + setIsValidationTriggered(true); + validateFields(); + }; + + const handleDropdownChange = (fieldId: string, value: string) => { + setFormData((prevState) => ({ + ...prevState, + customFields: prevState.customFields.map((field) => + field.fieldId === fieldId ? { ...field, value: [value] } : field + ), + })); + setHasInputChanged(true); + setIsValidationTriggered(true); + validateFields(); + }; + + const handleRadioChange = (fieldId: string, value: string) => { + setFormData((prevState) => ({ + ...prevState, + customFields: prevState.customFields.map((field) => + field.fieldId === fieldId ? { ...field, value: [value] } : field + ), + })); + setHasInputChanged(true); + setIsValidationTriggered(true); + validateFields(); + }; + + const handleSubmit = async ( + e: React.MouseEvent + ) => { + e.preventDefault(); + logEvent({ + action: 'save-button-clicked-edit-teacher-profile', + category: 'Profile Page', + label: 'Teacher Profile Save Button Clicked', + }); + setLoading(true); + // const userId = localStorage.getItem('userId'); + const data = { + userData: formData?.userData, + customFields: formData?.customFields?.map((field) => ({ + fieldId: field.fieldId, + // type: field.type, + value: Array.isArray(field?.value) + ? field?.value?.length > 0 + ? field?.value + : '' + : field?.value, + })), + }; + const userDetails = data; + try { + if (userId) { + const response = await editEditUser(userId, userDetails); + ReactGA.event('edit-teacher-profile-successful', { userId: userId }); + if (response.responseCode !== 200 || response.params.err) { + ReactGA.event('edit-teacher-profile-error', { userId: userId }); + throw new Error( + response.params.errmsg || + 'An error occurred while updating the user.' + ); + } + + handleClose(); + + console.log(response.params.successmessage); + + setIsError(false); + setLoading(false); + } + } catch (error) { + setIsError(true); + showToastMessage(t('COMMON.SOMETHING_WENT_WRONG'), 'error'); + console.error('Error:', error); + } + + console.log('payload', data); + }; + + return ( + <> + +
+ {loading && ( + + )} + {isData && isData ? ( + + + + {t('PROFILE.MY_PROFILE')} + + + + + + user + + + + + {userData?.name} + + + + + {address ? ( + + ) : ( + '' + )} + + + {address} + + + + + + + + + + + {filteredSortedForView?.map((item, index) => { + if (item.order === 5) { + return ( + + + {item?.label && item.name + ? t( + `FIELDS.${item.name.toUpperCase()}`, + item.label + ) + : item.label} + {/* {item?.label} */} + + + {orderedSubjects && + orderedSubjects?.map((subject, index) => ( + + ))} + + + ); + } else if (item.order === 7) { + return ( + + + {item?.label && item.name + ? t( + `FIELDS.${item.name.toUpperCase()}`, + item.label + ) + : item.label} + {/* {item.label} */} + + + {item.value} + + + ); + } else { + return ( + + + {item?.label && item.name + ? t( + `FIELDS.${item.name.toUpperCase()}`, + item.label + ) + : item.label} + {/* {item.label} */} + + + {getLabelForValue(item, item.value[0])} + + + ); + } + })} + + + + {/* modal for edit profile */} + + + {loading && ( + + )} + + + {t('PROFILE.EDIT_PROFILE')} + + + + + + + + + + {/* user */} + + + + {/* ------- comment for temp + */} + + + + + {customFieldsData + ?.filter((field) => field.isEditable) + ?.sort((a, b) => a.order - b.order) + ?.map((field) => { + const fieldValue = + formData?.customFields?.find( + (f) => f.fieldId === field.fieldId + )?.value[0] || ''; + const isError = errors[field.fieldId]; + + return ( + + {field.type === 'text' ? ( + { + handleFieldChange( + field.fieldId, + e.target.value + ); + validateFields(); + }} + error={isError} + helperText={ + isError && t('PROFILE.ENTER_CHARACTER') + } + /> + ) : field.type === 'numeric' ? ( + { + // Allow only numeric keys, Backspace, and Delete + if ( + !( + ( + /[0-9]/.test(e.key) || + e.key === 'Backspace' || + e.key === 'Delete' + ) // Allow decimal point if needed + ) + ) { + e.preventDefault(); + } + }} + onChange={(e) => { + const inputValue = e.target.value; + if (/^\d{0,4}$/.test(inputValue)) { + handleFieldChange(field.fieldId, inputValue); + validateFields(); + } + }} + error={isError} + helperText={isError && t('PROFILE.ENTER_NUMBER')} + /> + ) : field.type === 'checkbox' ? ( + + + {field?.label && field.name + ? t( + `FIELDS.${field.name.toUpperCase()}`, + field.label + ) + : field.label} + + {field.options?.map((option: any) => ( + + f.fieldId === field.fieldId + )?.value || [] + )?.includes(option.value)} + onChange={(e) => + handleCheckboxChange( + field.fieldId, + option.value, + e.target.checked + ) + } + /> + } + label={option.label} + /> + + ))} + + ) : field.type === 'drop_down' || + field.type === 'dropdown' ? ( + + + + {field?.label && field.name + ? t( + `FIELDS.${field.name.toUpperCase()}`, + field.label + ) + : field.label} + + + {errors[field.fieldId] && ( + + {t('PROFILE.SELECT_OPTION')} + + )} + + + ) : field.type === 'radio' || + field.type === 'Radio' ? ( + + + {field?.label && field.name + ? t( + `FIELDS.${field.name.toUpperCase()}`, + field.label + ) + : field.label} + + + handleRadioChange( + field.fieldId, + e.target.value + ) + } + > + + {field?.options?.map((option: any) => ( + } + label={option.label} + /> + ))} + + + + ) : null} + + ); + })} + + + + + + + + + + ) : ( + + {t('COMMON.LOADING')} + + )}{' '} + + + ); + }; + + export async function getStaticProps({ locale }: any) { + return { + props: { + ...(await serverSideTranslations(locale, ['common'])), + // Will be passed to the page component as props + }, + }; + } + + export const getStaticPaths: GetStaticPaths<{ slug: string }> = async () => { + return { + paths: [], //indicates that no page needs be created at build time + fallback: 'blocking', //indicates the type of fallback + }; + }; + + export default withAccessControl( + 'accessProfile', + accessControl + )(TeacherProfile); + \ No newline at end of file From b442a7ed556a9a73074d98a0f53b9825fc6c670f Mon Sep 17 00:00:00 2001 From: Rushikesh-Sonawane99 Date: Wed, 24 Jul 2024 12:23:42 +0530 Subject: [PATCH 2/2] Removed Profile File code as code moved to dynamic route --- src/pages/profile.tsx | 1172 ----------------------------------------- 1 file changed, 1172 deletions(-) delete mode 100644 src/pages/profile.tsx diff --git a/src/pages/profile.tsx b/src/pages/profile.tsx deleted file mode 100644 index 469ba5d4..00000000 --- a/src/pages/profile.tsx +++ /dev/null @@ -1,1172 +0,0 @@ -import { - Box, - Checkbox, - Divider, - FormControl, - FormControlLabel, - FormGroup, - FormHelperText, - Grid, - IconButton, - InputLabel, - MenuItem, - Radio, - RadioGroup, - Select, - SelectChangeEvent, - TextField, - Typography, - useMediaQuery, -} from '@mui/material'; -import { CustomField, UserDatas, updateCustomField } from '@/utils/Interfaces'; -import React, { ChangeEvent, useEffect, useRef, useState } from 'react'; -import { editEditUser, getUserDetails } from '@/services/ProfileService'; -import { useTheme, withStyles } from '@mui/material/styles'; - -import Button from '@mui/material/Button'; -import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'; -import CloseIcon from '@mui/icons-material/Close'; -import CreateOutlinedIcon from '@mui/icons-material/CreateOutlined'; -import Header from '@/components/Header'; -import Image from 'next/image'; -import Loader from '@/components/Loader'; -import Modal from '@mui/material/Modal'; -import PlaceOutlinedIcon from '@mui/icons-material/PlaceOutlined'; -import ReactGA from 'react-ga4'; -import { accessControl } from '../../app.config'; -import { getLabelForValue } from '@/utils/Helper'; -import { logEvent } from '@/utils/googleAnalytics'; -import { serverSideTranslations } from 'next-i18next/serverSideTranslations'; -import { showToastMessage } from '@/components/Toastify'; -import { useProfileInfo } from '@/services/queries'; -import { useRouter } from 'next/router'; -import { useTranslation } from 'next-i18next'; -import userPicture from '@/assets/images/imageOne.jpg'; -import user_placeholder from '../assets/images/user_placeholder.png'; -import withAccessControl from '@/utils/hoc/withAccessControl'; - -interface FieldOption { - name: string; - label: string; - value: string; - order: string; -} - -interface UserData { - name: string; -} - -interface EditFormProps { - userData: UserData; - customFieldsData: CustomField[]; - updateUser: (payload: any) => void; -} - -const TeacherProfile = () => { - const user_placeholder_img: string = user_placeholder.src; - - const { t } = useTranslation(); - const router = useRouter(); - const theme = useTheme(); - const [open, setOpen] = React.useState(false); - const handleOpen = () => { - setOpen(true); - logEvent({ - action: 'edit-teacher-profile-modal-open', - category: 'Profile Page', - label: 'Edit Teacher Profile Modal Open', - }); - }; - const [errors, setErrors] = useState<{ [key: string]: boolean }>({}); - - const handleClose = () => { - setOpen(false); - initialFormData(); - setHasInputChanged(false); - setHasErrors(false); - setErrors({}); - logEvent({ - action: 'edit-teacher-profile-modal-close', - category: 'Profile Page', - label: 'Edit Teacher Profile Modal Close', - }); - }; - const [userData, setUserData] = useState(null); - const [userName, setUserName] = useState(null); - const [updatedCustomFields, setUpdatedCustomFields] = useState([]); - const isDesktop = useMediaQuery(theme.breakpoints.up('md')); - const fileInputRef = useRef(null); - const [dropdownValues, setDropdownValues] = useState({}); - const [customFieldsData, setCustomFieldsData] = useState([]); - - const [loading, setLoading] = useState(false); - const [image, setImage] = useState(user_placeholder_img); - const [gender, setGender] = React.useState(''); - const [isAuthenticated, setIsAuthenticated] = React.useState(false); - const [unitName, setUnitName] = useState(''); - const [blockName, setBlockName] = useState(''); - const [radioValues, setRadioValues] = useState([]); - const [isError, setIsError] = React.useState(false); - const [isData, setIsData] = React.useState(false); - const [hasInputChanged, setHasInputChanged] = React.useState(false); - const [isValidationTriggered, setIsValidationTriggered] = - React.useState(false); - const [userId, setUserId] = useState(null); - - const handleNameFieldChange = (event: ChangeEvent) => { - const { value } = event.target; - setUserName(value); - }; - - const style = { - position: 'absolute', - top: '50%', - width: '85%', - left: '50%', - transform: 'translate(-50%, -50%)', - bgcolor: theme.palette.warning.A400, - height: '526px', - textAlign: 'center', - '@media (min-width: 600px)': { - width: '450px', - }, - }; - - useEffect(() => { - if (typeof window !== 'undefined' && window.localStorage) { - const token = localStorage.getItem('token'); - const storedUserId = localStorage.getItem('userId'); - if (token) { - setIsAuthenticated(true); - } else { - router.push('/login'); - } - setUserId(storedUserId); - } - }, []); - - // find Address - const getFieldValue = (data: any, label: string) => { - const field = data.find((item: any) => item.label === label); - return field ? field.value[0] : null; - }; - - const { data, error, isLoading } = useProfileInfo(userId ?? '', true); - - useEffect(() => { - setLoading(isLoading); - - if (error) { - setIsError(true); - showToastMessage(t('COMMON.SOMETHING_WENT_WRONG'), 'error'); - console.error('Error fetching user details:', error); - } else { - setIsError(false); - } - - if (data) { - const userData = data?.result?.userData; - setUserData(userData); - setUserName(userData?.name); - const customDataFields = userData?.customFields; - setIsData(true); - if (customDataFields?.length > 0) { - setCustomFieldsData(customDataFields); - - const unitName = getFieldValue(customDataFields, 'Unit Name'); - setUnitName(unitName); - const blockName = getFieldValue(customDataFields, 'Block Name'); - setBlockName(blockName); - } - } else { - setIsData(false); - console.log('No data Found'); - } - }, [data, error, isLoading]); - - const handleClickImage = () => { - fileInputRef.current && fileInputRef.current.click(); - }; - - const handleImageUpload = (e: any) => { - const image: any[] = [e.target.files[0]]; - const newImageUrl: any = []; - image.forEach((dataImage: any) => - newImageUrl.push(URL.createObjectURL(dataImage)) - ); - setImage(newImageUrl); - }; - - // Find fields for "Subjects I Teach" and "My Main Subjects" - const teachSubjectsField = customFieldsData?.find( - (field) => field.name === 'subject_taught' - ); - const mainSubjectsField = customFieldsData?.find( - (field) => field.name === 'main_subject' - ); - - const teachSubjects: string[] = Array.isArray(teachSubjectsField?.value) - ? teachSubjectsField?.value - : []; - const mainSubjects: string[] = Array.isArray(mainSubjectsField?.value) - ? mainSubjectsField?.value - : []; - - // Find mutual and remaining subjects - const mutualSubjects = teachSubjects?.filter((subject) => - mainSubjects?.includes(subject) - ); - const remainingSubjects = teachSubjects?.filter( - (subject) => !mainSubjects?.includes(subject) - ); - const orderedSubjects = [...mutualSubjects, ...remainingSubjects]; - - // Function to get label for a subject from the options array - const getLabelForSubject = (subject: string) => { - const option = teachSubjectsField?.options?.find( - (opt: any) => opt.value === subject - ); - return option ? option.label : subject; - }; - - //fields for view profile by order - const filteredSortedForView = [...customFieldsData] - ?.filter((field) => field.order !== 0 && field.name !== 'main_subject') - ?.sort((a, b) => a.order - b.order); - - // fields for showing in basic details - const getLabelForValue = (field: any, value: string) => { - if ( - field.type === 'radio' || - field.type === 'Radio' || - field.type === 'drop_down' || - field.type === 'dropdown' - ) { - const option = field?.options?.find((opt: any) => opt?.value === value); - return option ? option?.label : value; - } - return value; - }; - - // address find - const address = [unitName, blockName, userData?.district, userData?.state] - ?.filter(Boolean) - ?.join(', '); - - //------------edit teacher profile------------ - - const [formData, setFormData] = useState<{ - userData: UserDatas; - customFields: { fieldId: string; type: string; value: string[] | string }[]; - }>({ - userData: { - name: userName || '', - }, - customFields: customFieldsData?.map((field) => ({ - fieldId: field.fieldId, - type: field.type, - value: field.value ? field.value : '', - })), - }); - - const initialFormData = () => { - setFormData({ - userData: { - name: userName || '', - }, - customFields: customFieldsData?.map((field) => ({ - fieldId: field.fieldId, - type: field.type, - value: field.value ? field.value : '', - })), - }); - }; - - useEffect(() => { - initialFormData(); - }, [userData, customFieldsData]); - - const [hasErrors, setHasErrors] = useState(false); - - const handleInputChange = (e: React.ChangeEvent) => { - const { value } = e.target; - const sanitizedValue = value - .replace(/[^a-zA-Z_ ]/g, '') - .replace(/^\s+/, '') - .replace(/\s+/g, ' '); - - setFormData((prevData) => ({ - ...prevData, - userData: { - ...prevData.userData, - name: sanitizedValue, - }, - })); - setHasInputChanged(true); - setIsValidationTriggered(true); - validateFields(); - // setHasErrors(!sanitizedValue.trim()); - }; - - //fields for edit popup by order - const filteredSortedForEdit = [...customFieldsData] - ?.filter((field) => field.isEditable) - ?.sort((a, b) => a.order - b.order); - - const validateFields = () => { - const newErrors: { [key: string]: boolean } = {}; - - filteredSortedForEdit?.forEach((field) => { - const value = - formData?.customFields?.find((f) => f.fieldId === field.fieldId) - ?.value[0] || ''; - - if (field.type === 'text') { - newErrors[field.fieldId] = !value.trim(); - } else if (field.type === 'numeric') { - newErrors[field.fieldId] = !/^\d{1,4}$/.test(value); - } else if (field.type === 'dropdown' || field.type === 'drop_down') { - newErrors[field.fieldId] = !value.trim(); - } - }); - - newErrors['name'] = !formData.userData.name.trim(); - - setErrors(newErrors); - setHasErrors(Object.values(newErrors).some((error) => error)); - }; - - useEffect(() => { - if (hasInputChanged) { - validateFields(); - } - }, [formData, customFieldsData]); - - const handleFieldChange = (fieldId: string, value: string) => { - const sanitizedValue = value.replace(/^\s+/, '').replace(/\s+/g, ' '); - - setFormData((prevState) => ({ - ...prevState, - customFields: prevState.customFields.map((field) => - field.fieldId === fieldId - ? { ...field, value: [sanitizedValue] } - : field - ), - })); - setHasInputChanged(true); - setIsValidationTriggered(true); - validateFields(); - }; - - const handleCheckboxChange = ( - fieldId: string, - optionName: string, - isChecked: boolean - ) => { - setFormData((prevState) => ({ - ...prevState, - customFields: prevState.customFields.map((field) => - field.fieldId === fieldId - ? { - ...field, - value: isChecked - ? [...(field.value as string[]), optionName] - : (field.value as string[]).filter( - (item) => item !== optionName - ), - } - : field - ), - })); - setHasInputChanged(true); - setIsValidationTriggered(true); - validateFields(); - }; - - const handleDropdownChange = (fieldId: string, value: string) => { - setFormData((prevState) => ({ - ...prevState, - customFields: prevState.customFields.map((field) => - field.fieldId === fieldId ? { ...field, value: [value] } : field - ), - })); - setHasInputChanged(true); - setIsValidationTriggered(true); - validateFields(); - }; - - const handleRadioChange = (fieldId: string, value: string) => { - setFormData((prevState) => ({ - ...prevState, - customFields: prevState.customFields.map((field) => - field.fieldId === fieldId ? { ...field, value: [value] } : field - ), - })); - setHasInputChanged(true); - setIsValidationTriggered(true); - validateFields(); - }; - - const handleSubmit = async ( - e: React.MouseEvent - ) => { - e.preventDefault(); - logEvent({ - action: 'save-button-clicked-edit-teacher-profile', - category: 'Profile Page', - label: 'Teacher Profile Save Button Clicked', - }); - setLoading(true); - const userId = localStorage.getItem('userId'); - const data = { - userData: formData?.userData, - customFields: formData?.customFields?.map((field) => ({ - fieldId: field.fieldId, - // type: field.type, - value: Array.isArray(field?.value) - ? field?.value?.length > 0 - ? field?.value - : '' - : field?.value, - })), - }; - const userDetails = data; - try { - if (userId) { - const response = await editEditUser(userId, userDetails); - ReactGA.event('edit-teacher-profile-successful', { userId: userId }); - if (response.responseCode !== 200 || response.params.err) { - ReactGA.event('edit-teacher-profile-error', { userId: userId }); - throw new Error( - response.params.errmsg || - 'An error occurred while updating the user.' - ); - } - - handleClose(); - - console.log(response.params.successmessage); - - setIsError(false); - setLoading(false); - } - } catch (error) { - setIsError(true); - showToastMessage(t('COMMON.SOMETHING_WENT_WRONG'), 'error'); - console.error('Error:', error); - } - - console.log('payload', data); - }; - - return ( - <> - -
- {loading && ( - - )} - {isData && isData ? ( - - - - {t('PROFILE.MY_PROFILE')} - - - - - - user - - - - - {userData?.name} - - - - - {address ? ( - - ) : ( - '' - )} - - - {address} - - - - - - - - - - - {filteredSortedForView?.map((item, index) => { - if (item.order === 5) { - return ( - - - {item?.label && item.name - ? t( - `FIELDS.${item.name.toUpperCase()}`, - item.label - ) - : item.label} - {/* {item?.label} */} - - - {orderedSubjects && - orderedSubjects?.map((subject, index) => ( - - ))} - - - ); - } else if (item.order === 7) { - return ( - - - {item?.label && item.name - ? t( - `FIELDS.${item.name.toUpperCase()}`, - item.label - ) - : item.label} - {/* {item.label} */} - - - {item.value} - - - ); - } else { - return ( - - - {item?.label && item.name - ? t( - `FIELDS.${item.name.toUpperCase()}`, - item.label - ) - : item.label} - {/* {item.label} */} - - - {getLabelForValue(item, item.value[0])} - - - ); - } - })} - - - - {/* modal for edit profile */} - - - {loading && ( - - )} - - - {t('PROFILE.EDIT_PROFILE')} - - - - - - - - - - {/* user */} - - - - {/* ------- comment for temp - */} - - - - - {customFieldsData - ?.filter((field) => field.isEditable) - ?.sort((a, b) => a.order - b.order) - ?.map((field) => { - const fieldValue = - formData?.customFields?.find( - (f) => f.fieldId === field.fieldId - )?.value[0] || ''; - const isError = errors[field.fieldId]; - - return ( - - {field.type === 'text' ? ( - { - handleFieldChange( - field.fieldId, - e.target.value - ); - validateFields(); - }} - error={isError} - helperText={ - isError && t('PROFILE.ENTER_CHARACTER') - } - /> - ) : field.type === 'numeric' ? ( - { - // Allow only numeric keys, Backspace, and Delete - if ( - !( - ( - /[0-9]/.test(e.key) || - e.key === 'Backspace' || - e.key === 'Delete' - ) // Allow decimal point if needed - ) - ) { - e.preventDefault(); - } - }} - onChange={(e) => { - const inputValue = e.target.value; - if (/^\d{0,4}$/.test(inputValue)) { - handleFieldChange(field.fieldId, inputValue); - validateFields(); - } - }} - error={isError} - helperText={isError && t('PROFILE.ENTER_NUMBER')} - /> - ) : field.type === 'checkbox' ? ( - - - {field?.label && field.name - ? t( - `FIELDS.${field.name.toUpperCase()}`, - field.label - ) - : field.label} - - {field.options?.map((option: any) => ( - - f.fieldId === field.fieldId - )?.value || [] - )?.includes(option.value)} - onChange={(e) => - handleCheckboxChange( - field.fieldId, - option.value, - e.target.checked - ) - } - /> - } - label={option.label} - /> - - ))} - - ) : field.type === 'drop_down' || - field.type === 'dropdown' ? ( - - - - {field?.label && field.name - ? t( - `FIELDS.${field.name.toUpperCase()}`, - field.label - ) - : field.label} - - - {errors[field.fieldId] && ( - - {t('PROFILE.SELECT_OPTION')} - - )} - - - ) : field.type === 'radio' || - field.type === 'Radio' ? ( - - - {field?.label && field.name - ? t( - `FIELDS.${field.name.toUpperCase()}`, - field.label - ) - : field.label} - - - handleRadioChange( - field.fieldId, - e.target.value - ) - } - > - - {field?.options?.map((option: any) => ( - } - label={option.label} - /> - ))} - - - - ) : null} - - ); - })} - - - - - - - - - - ) : ( - - {t('COMMON.LOADING')} - - )}{' '} - - - ); -}; - -export async function getStaticProps({ locale }: any) { - return { - props: { - ...(await serverSideTranslations(locale, ['common'])), - // Will be passed to the page component as props - }, - }; -} - -export default withAccessControl( - 'accessProfile', - accessControl -)(TeacherProfile);