From 875fd0b4623d9056e738f3ce72775b198171e056 Mon Sep 17 00:00:00 2001 From: ttpl-rt-214 Date: Mon, 26 Aug 2024 11:40:52 +0530 Subject: [PATCH 01/34] #PS-1769 Course Planner bottom drawer desktop view UI --- src/components/SessionCard.tsx | 2 +- src/pages/centers/[cohortId]/index.tsx | 4 ++-- src/styles/globals.css | 8 ++------ 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/components/SessionCard.tsx b/src/components/SessionCard.tsx index 9918609c..6444f091 100644 --- a/src/components/SessionCard.tsx +++ b/src/components/SessionCard.tsx @@ -89,7 +89,7 @@ const SessionsCard: React.FC = ({ sx={{ border: `1px solid ${theme.palette.warning['A100']}`, borderRadius: '8px', - marginBottom: '25px', + marginBottom: '38px', }} > { - + {sessions?.map((item) => ( - + diff --git a/src/styles/globals.css b/src/styles/globals.css index 13654df8..9a8d7fec 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -1069,12 +1069,8 @@ legend.Mui-focused { .swiper-pagination-fraction{ position: absolute; width: fit-content !important; - bottom: 0px !important; + bottom: 13px !important; } -.swiper-pagination-fraction{ - color: var(--mui-palette-warning-400) !important; - font-size: 12px; - font-weight: 500; -} + From ed900a386edf92d5bb795b2e9a2db8018e51bac5 Mon Sep 17 00:00:00 2001 From: suvarnakale Date: Mon, 26 Aug 2024 14:06:35 +0530 Subject: [PATCH 02/34] Issue #PS-1625 feat: edit events data mapping for planned/extra/online and offline events --- src/components/PlannedSession.tsx | 122 ++++++++++++++++++++---------- src/components/SessionCard.tsx | 1 + src/utils/Interfaces.ts | 1 + 3 files changed, 84 insertions(+), 40 deletions(-) diff --git a/src/components/PlannedSession.tsx b/src/components/PlannedSession.tsx index ffeb98e3..6a9ae010 100644 --- a/src/components/PlannedSession.tsx +++ b/src/components/PlannedSession.tsx @@ -50,14 +50,17 @@ import SessionMode from './SessionMode'; import { showToastMessage } from './Toastify'; import WeekDays from './WeekDays'; import ConfirmationModal from './ConfirmationModal'; +import timezone from 'dayjs/plugin/timezone'; +dayjs.extend(utc); +dayjs.extend(timezone); type mode = (typeof sessionMode)[keyof typeof sessionMode]; -type type = (typeof sessionType)[keyof typeof sessionType]; +// type type = (typeof sessionType)[keyof typeof sessionType]; interface Session { id?: number | string; sessionMode?: string; - sessionType?: string; + // sessionType?: string; selectedWeekDays?: string[]; DaysOfWeek?: number[]; startDatetime?: string; @@ -84,17 +87,21 @@ const PlannedSession: React.FC = ({ onCloseModal, editSession, onEventDeleted, + eventData, }) => { const [mode, setMode] = useState(sessionMode.OFFLINE); - const [eventType, setEventType] = useState(sessionType.JUST); + // const [eventType, setEventType] = useState(sessionType.JUST); const [link, setLink] = useState(''); const [linkError, setLinkError] = useState(''); const [selectedWeekDays, setSelectedWeekDays] = useState(); + const [editEventData, setEditEventData] = useState(eventData); const [modalOpen, setModalOpen] = React.useState(false); const [selectedSubject, setSelectedSubject] = useState(); const [selectedBlockId, setSelectedBlockId] = useState(0); const [editSelection, setEditSelection] = React.useState('EDIT_SESSION'); const [subjects, setSubjects] = useState(); + const [shortDescription, setShortDescription] = useState(); + const [meetingPasscode, setMeetingPasscode] = useState(); dayjs.extend(utc); const [startDate, setStartDate] = useState(dayjs()); const [endDate, setEndDate] = useState(dayjs()); @@ -106,7 +113,7 @@ const PlannedSession: React.FC = ({ selectedWeekDays: [], DaysOfWeek: [], sessionMode: mode, - sessionType: eventType, + // sessionType: eventType, startDatetime: '', endDatetime: '', endDateValue: '', @@ -122,6 +129,40 @@ const PlannedSession: React.FC = ({ sessionEndTime: endTime, }, ]); + + useEffect(() => { + console.log(eventData); + console.log(eventData?.metadata?.framework?.subject); + + if (eventData) { + const mode = + eventData?.meetingDetails?.url !== undefined + ? sessionMode.ONLINE + : sessionMode.OFFLINE; + setMode(mode); + let sub = eventData?.metadata?.framework?.subject; + setSelectedSubject(sub); + let sessionTitle = eventData?.shortDescription; + setShortDescription(sessionTitle); + const url = eventData?.meetingDetails?.url; + setLink(url); + const passcode = eventData?.meetingDetails?.password; + setMeetingPasscode(passcode); + + const startDateTime = eventData?.startDateTime; + const endDateTime = eventData?.endDateTime; + + const localStartDateTime = dayjs.utc(startDateTime).tz('Asia/Kolkata'); + const localEndDateTime = dayjs.utc(endDateTime).tz('Asia/Kolkata'); + // const localEndDateValue = dayjs.utc(endDateValue).tz('Asia/Kolkata'); + + setStartDate(localStartDateTime.startOf('day')); + setStartTime(localStartDateTime); + setEndDate(localEndDateTime.startOf('day')); + setEndTime(localEndDateTime); + } + }, [eventData]); + const handleOpenModel = () => { setModalOpen(true); }; @@ -173,16 +214,16 @@ const PlannedSession: React.FC = ({ setSessionBlocks(updatedSessionBlocks); }; - const handleSessionTypeChange = ( - event: ChangeEvent, - id: string | number | undefined - ) => { - setEventType(event.target.value as type); - const updatedSessionBlocks = sessionBlocks.map((block) => - block.id === id ? { ...block, sessionType: event.target.value } : block - ); - setSessionBlocks(updatedSessionBlocks); - }; + // const handleSessionTypeChange = ( + // event: ChangeEvent, + // id: string | number | undefined + // ) => { + // setEventType(event.target.value as type); + // const updatedSessionBlocks = sessionBlocks.map((block) => + // block.id === id ? { ...block, sessionType: event.target.value } : block + // ); + // setSessionBlocks(updatedSessionBlocks); + // }; useEffect(() => { const getAddFacilitatorFormData = async () => { @@ -312,7 +353,7 @@ const PlannedSession: React.FC = ({ const startDatetime = convertToUTC(combinedStartDateTime); const endDatetime = convertToUTC(combinedEndDateTime); const endDateValue = - eventType && eventType === t('CENTER_SESSION.JUST_ONCE') + clickedBox === 'EXTRA_SESSION' ? endDatetime : convertToUTC(combinedEndDateValue); @@ -346,7 +387,7 @@ const PlannedSession: React.FC = ({ const startDatetime = convertToUTC(combinedStartDateTime); const endDatetime = convertToUTC(combinedEndDateTime); const endDateValue = - eventType && eventType === t('CENTER_SESSION.JUST_ONCE') + clickedBox === 'EXTRA_SESSION' ? endDatetime : convertToUTC(combinedEndDateValue); @@ -418,7 +459,7 @@ const PlannedSession: React.FC = ({ id: string | number | undefined ) => { const value = event?.target?.value; - + setMeetingPasscode(value); setSessionBlocks( sessionBlocks.map((block) => block.id === id @@ -460,6 +501,7 @@ const PlannedSession: React.FC = ({ id: string | number | undefined ) => { const value = event?.target?.value; + setShortDescription(value); setSessionBlocks( sessionBlocks.map((block) => block.id === id @@ -482,7 +524,7 @@ const PlannedSession: React.FC = ({ selectedWeekDays: [], DaysOfWeek: [], sessionMode: '', - sessionType: '', + // sessionType: '', startDatetime: '', endDatetime: '', subject: '', @@ -564,7 +606,7 @@ const PlannedSession: React.FC = ({ const apiBodies: CreateEvent[] = sessionBlocks.map((block) => { const baseBody: CreateEvent = { title, - shortDescription: '', + shortDescription: block?.subjectTitle || shortDescription, description: '', eventType: block?.sessionMode || mode, isRestricted: true, @@ -708,7 +750,7 @@ const PlannedSession: React.FC = ({ row aria-labelledby="session-mode-label" name="session-mode-group" - value={mode} + value={mode || editSelection} onChange={handleEditSession} > = ({ handleSessionModeChange(e, block?.id) } @@ -785,7 +827,7 @@ const PlannedSession: React.FC = ({ }} /> - {clickedBox === 'PLANNED_SESSION' && ( + {(clickedBox === 'PLANNED_SESSION' || editSession) && ( <> @@ -803,7 +845,11 @@ const PlannedSession: React.FC = ({ onChange={(event: any) => handleSubjectChange(block?.id, event) } - value={selectedSubject} + value={ + selectedSubject + ? selectedSubject + : t('CENTER_SESSION.SUBJECT') + } > {subjects?.map((subject: string) => ( @@ -822,7 +868,7 @@ const PlannedSession: React.FC = ({ id="outlined-basic" label={t('CENTER_SESSION.SESSION_TITLE_OPTIONAL')} variant="outlined" - value={block?.subjectTitle} + value={block?.subjectTitle || shortDescription} onChange={(e) => { handleSubjectTitleChange(e, block?.id); }} @@ -831,7 +877,8 @@ const PlannedSession: React.FC = ({ )} - {block?.sessionMode === sessionMode.ONLINE && ( + {(block?.sessionMode === sessionMode.ONLINE || + mode === sessionMode.ONLINE) && ( <> {/* = ({ label={t('CENTER_SESSION.MEETING_PASSCODE')} variant="outlined" onChange={(e: any) => handlePasscodeChange(block?.id, e)} + value={ + meetingPasscode + ? meetingPasscode + : t('CENTER_SESSION.MEETING_PASSCODE') + } /> @@ -926,22 +978,10 @@ const PlannedSession: React.FC = ({ )} - {clickedBox === 'EXTRA_SESSION' && ( + {(clickedBox === 'EXTRA_SESSION' || + (editSession && editSelection === 'EDIT_SESSION')) && ( <> - {/* - handleSessionTypeChange(e, block?.id) - } - sessions={{ - tile: t('CENTER_SESSION.TYPE_OF_SESSION'), - mode1: t('CENTER_SESSION.REPEATING'), - mode2: t('CENTER_SESSION.JUST_ONCE'), - }} - /> */} - {/* {block?.sessionType === sessionType.JUST && ( - )} */} @@ -991,7 +1031,9 @@ const PlannedSession: React.FC = ({ )} - {clickedBox !== 'EXTRA_SESSION' && ( + + {(clickedBox === 'PLANNED_SESSION' || + (editSession && editSelection === 'FOLLOWING_SESSION')) && ( diff --git a/src/components/SessionCard.tsx b/src/components/SessionCard.tsx index 9918609c..0468298f 100644 --- a/src/components/SessionCard.tsx +++ b/src/components/SessionCard.tsx @@ -178,6 +178,7 @@ const SessionsCard: React.FC = ({ handleEditSelection={handleEditSelection} onEventDeleted={onEventDeleted} eventDeleted={eventDeleted} + eventData={data} /> diff --git a/src/utils/Interfaces.ts b/src/utils/Interfaces.ts index 222aba39..df2ce199 100644 --- a/src/utils/Interfaces.ts +++ b/src/utils/Interfaces.ts @@ -156,6 +156,7 @@ export interface PlannedModalProps { handleEditSelection?: (selection: string) => void; onEventDeleted?: () => void; editSession?: any; + eventData?: any; } export interface ScheduleModalProps { From fb45791d259624f29815212edca8c1f200b5b35f Mon Sep 17 00:00:00 2001 From: vivek kasture Date: Mon, 26 Aug 2024 14:09:52 +0530 Subject: [PATCH 03/34] Issue #PS-000 feat: Updated centers list based on status --- src/pages/centers/index.tsx | 232 +++++++++++++++++------------- src/services/CreateUserService.ts | 2 +- 2 files changed, 133 insertions(+), 101 deletions(-) diff --git a/src/pages/centers/index.tsx b/src/pages/centers/index.tsx index c9a25bf1..2516c441 100644 --- a/src/pages/centers/index.tsx +++ b/src/pages/centers/index.tsx @@ -21,7 +21,7 @@ import ManageUser from '@/components/ManageUser'; import { showToastMessage } from '@/components/Toastify'; import CreateCenterModal from '@/components/center/CreateCenterModal'; import useStore from '@/store/store'; -import { CenterType, Role } from '@/utils/app.constant'; +import { CenterType, Role, Status } from '@/utils/app.constant'; import { ArrowDropDown, Clear, Search } from '@mui/icons-material'; import AddIcon from '@mui/icons-material/Add'; import ChevronRightIcon from '@mui/icons-material/ChevronRight'; @@ -97,9 +97,19 @@ const CentersPage = () => { userId && accessGranted('showBlockLevelCohort', accessControl, userRole) ) { - const response = await getCohortList(userId, { + let response = await getCohortList(userId, { customField: 'true', }); + + response = response.filter((block: any) => { + if ( + block?.cohortMemberStatus === Status.ACTIVE && + block?.cohortStatus === Status.ACTIVE + ) { + return block; + } + }); + const blockData = response.map((block: any) => { const blockName = block.cohortName; const blockId = block.cohortId; @@ -370,23 +380,23 @@ const CentersPage = () => { accessControl, userRole ) && ( - - - - )} + + + + )} { onCenterAdded={handleCenterAdded} /> - {accessGranted('showBlockLevelCenterData', accessControl, userRole) && + {accessGranted( + 'showBlockLevelCenterData', + accessControl, + userRole + ) && (filteredCenters && filteredCenters.length > 0 ? ( <> {/* Regular Centers */} {filteredCenters.some( (center) => - center.centerType?.toUpperCase() === CenterType.REGULAR || - center.centerType === '' + center.centerType?.toUpperCase() === + CenterType.REGULAR || center.centerType === '' ) && ( - - center.centerType?.toUpperCase() === CenterType.REGULAR || - center.centerType === '' - )} - router={router} - theme={theme} - t={t} - /> - )} + + center.centerType?.toUpperCase() === + CenterType.REGULAR || center.centerType === '' + )} + router={router} + theme={theme} + t={t} + /> + )} {/* Remote Centers */} {filteredCenters.some( - (center) => center.centerType?.toUpperCase() === CenterType.REMOTE + (center) => + center.centerType?.toUpperCase() === CenterType.REMOTE ) && ( - - center.centerType?.toUpperCase() === CenterType.REMOTE - )} - router={router} - theme={theme} - t={t} - /> - )} + + center.centerType?.toUpperCase() === + CenterType.REMOTE + )} + router={router} + theme={theme} + t={t} + /> + )} ) : ( { fontWeight: '500', color: theme.palette.warning['400'], m: 2, + textAlign: 'center', }} > {t('COMMON.NO_DATA_FOUND')} ))} - {/* Teacher-Level Centers */} - - - {accessGranted('showTeacherLevelCenterData', accessControl, userRole) && - cohortsData?.map((cohort: any) => { - return ( - - { - router.push(`/centers/${cohort?.cohortId}/`); - localStorage.setItem('classId', cohort.cohortId); - }} + {cohortsData?.length > 0 && ( + + + {accessGranted( + 'showTeacherLevelCenterData', + accessControl, + userRole + ) && + cohortsData?.map((cohort: any) => { + return ( + { + router.push(`/centers/${cohort?.cohortId}/`); + localStorage.setItem( + 'classId', + cohort.cohortId + ); }} > - center - + + center + - - {cohort?.cohortName} + + {cohort?.cohortName} + + - - - - ); - })} - - - + + ); + })} + + + )} )} diff --git a/src/services/CreateUserService.ts b/src/services/CreateUserService.ts index 83b9dd66..15f933c9 100644 --- a/src/services/CreateUserService.ts +++ b/src/services/CreateUserService.ts @@ -1,5 +1,5 @@ import axios from 'axios'; -import { get, post } from './RestClient'; +import { post } from './RestClient'; import { tenantId } from '../../app.config'; export const getFormRead = async ( From a249f1e57fb66d2e8fb78c93f05f7467910e4ac6 Mon Sep 17 00:00:00 2001 From: suvarnakale Date: Mon, 26 Aug 2024 15:27:14 +0530 Subject: [PATCH 04/34] Issue #PS-1625 chore: comments resolved --- app.config.ts | 1 + src/components/PlannedSession.tsx | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app.config.ts b/app.config.ts index b745c878..aaeaff03 100644 --- a/app.config.ts +++ b/app.config.ts @@ -8,6 +8,7 @@ export const eventDaysLimit: number = 7; export const toastAutoHideDuration: number = 5000; // 5 seconds export const tenantId: string = 'ef99949b-7f3a-4a5f-806a-e67e683e38f3'; export const idealTimeForSession: string = '120'; +export const timeZone: string = 'Asia/Kolkata'; export const dropoutReasons = [ { label: 'UNABLE_TO_COPE_WITH_STUDIES', diff --git a/src/components/PlannedSession.tsx b/src/components/PlannedSession.tsx index 6a9ae010..42136668 100644 --- a/src/components/PlannedSession.tsx +++ b/src/components/PlannedSession.tsx @@ -45,6 +45,7 @@ import { DaysOfWeek, eventDaysLimit, idealTimeForSession, + timeZone, } from '../../app.config'; import SessionMode from './SessionMode'; import { showToastMessage } from './Toastify'; @@ -152,8 +153,8 @@ const PlannedSession: React.FC = ({ const startDateTime = eventData?.startDateTime; const endDateTime = eventData?.endDateTime; - const localStartDateTime = dayjs.utc(startDateTime).tz('Asia/Kolkata'); - const localEndDateTime = dayjs.utc(endDateTime).tz('Asia/Kolkata'); + const localStartDateTime = dayjs.utc(startDateTime).tz(timeZone); + const localEndDateTime = dayjs.utc(endDateTime).tz(timeZone); // const localEndDateValue = dayjs.utc(endDateValue).tz('Asia/Kolkata'); setStartDate(localStartDateTime.startOf('day')); From 8292c2f59b0adac7ed79d6439345ddbcb45fe22c Mon Sep 17 00:00:00 2001 From: vivek kasture Date: Mon, 26 Aug 2024 16:04:00 +0530 Subject: [PATCH 05/34] Issue #PS-000 feat: Updated getCohortList api --- src/services/CohortServices.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/services/CohortServices.ts b/src/services/CohortServices.ts index fa07db96..cb2cde73 100644 --- a/src/services/CohortServices.ts +++ b/src/services/CohortServices.ts @@ -1,6 +1,7 @@ import { CohortListParam } from '@/utils/Interfaces'; import { get, post } from './RestClient'; import { BulkCreateCohortMembersRequest } from '@/utils/Interfaces'; +import { Status } from '@/utils/app.constant'; export const cohortList = async ({ limit, @@ -39,6 +40,18 @@ export const getCohortList = async ( } try { const response = await get(apiUrl); + if (response?.data?.result?.length) { + let res = response?.data?.result; + res = res.filter((block: any) => { + if ( + block?.cohortMemberStatus === Status.ACTIVE && + block?.cohortStatus === Status.ACTIVE + ) { + return block; + } + }); + return res + } return response?.data?.result; } catch (error) { console.error('Error in getting cohort details', error); From 58d1025f5602d4d0dc5a210093b9820acf350032 Mon Sep 17 00:00:00 2001 From: vivek kasture Date: Mon, 26 Aug 2024 19:53:36 +0530 Subject: [PATCH 06/34] Issue #PS-000 feat: Updated getCohortList api --- src/components/CohortSelectionSection.tsx | 113 ++++++++++++++++++---- src/components/MarkBulkAttendance.tsx | 4 +- src/pages/assessments/index.tsx | 1 + src/pages/centers/index.tsx | 8 -- src/pages/login.tsx | 57 ++++++++++- src/store/manageUserStore.js | 6 ++ 6 files changed, 155 insertions(+), 34 deletions(-) diff --git a/src/components/CohortSelectionSection.tsx b/src/components/CohortSelectionSection.tsx index c8d8ab77..c34536ae 100644 --- a/src/components/CohortSelectionSection.tsx +++ b/src/components/CohortSelectionSection.tsx @@ -14,7 +14,12 @@ import { getCohortList } from '@/services/CohortServices'; import useStore from '@/store/store'; import { ICohort } from '@/utils/Interfaces'; import { CustomField } from '@/utils/Interfaces'; -import { CenterType, cohortHierarchy, Telemetry } from '@/utils/app.constant'; +import { + CenterType, + cohortHierarchy, + Status, + Telemetry, +} from '@/utils/app.constant'; import { useTheme } from '@mui/material/styles'; import { useTranslation } from 'next-i18next'; import ReactGA from 'react-ga4'; @@ -46,6 +51,7 @@ interface CohortSelectionSectionProps { setHandleSaveHasRun?: React.Dispatch>; isCustomFieldRequired?: boolean; showFloatingLabel?: boolean; + showDisabledDropDown?: boolean; } interface ChildData { @@ -82,6 +88,7 @@ const CohortSelectionSection: React.FC = ({ setHandleSaveHasRun, isCustomFieldRequired = true, showFloatingLabel = false, + showDisabledDropDown = false, }) => { const router = useRouter(); const theme = useTheme(); @@ -91,6 +98,7 @@ const CohortSelectionSection: React.FC = ({ const setBlock = useStore((state) => state.setBlock); const store = manageUserStore(); + const setDistrictCode = manageUserStore( (state: { setDistrictCode: any }) => state.setDistrictCode ); @@ -132,26 +140,43 @@ const CohortSelectionSection: React.FC = ({ const response = await getCohortList(userId, { customField: 'true', }); + // response = response.filter((block: any) => { + // if ( + // block?.cohortMemberStatus === Status.ACTIVE && + // block?.cohortStatus === Status.ACTIVE + // ) { + // return block; + // } + // }); console.log('Response:', response); const cohortData = response[0]; if (cohortData?.customField?.length) { const district = cohortData?.customField?.find( (item: CustomField) => item?.label === 'DISTRICTS' ); - setDistrictCode(district?.code); - setDistrictId(district?.fieldId); + + if (district) { + setDistrictCode(district?.code); + setDistrictId(district?.fieldId); + } const state = cohortData?.customField?.find( (item: CustomField) => item?.label === 'STATES' ); - setStateCode(state?.code); - setStateId(state?.fieldId); + + if (state) { + setStateCode(state?.code); + setStateId(state?.fieldId); + } const blockField = cohortData?.customField?.find( (field: any) => field?.label === 'BLOCKS' ); - setBlockCode(blockField?.code); - setBlockId(blockField?.fieldId); + + if (blockField) { + setBlockCode(blockField?.code); + setBlockId(blockField?.fieldId); + } } if (response && response?.length > 0) { @@ -323,11 +348,13 @@ const CohortSelectionSection: React.FC = ({ const isAttendanceOverview = pathname === '/attendance-overview'; - const isAssessment = pathname === '/assessments' + const isAssessment = pathname === '/assessments'; return ( - {loading && } + {loading && ( + + )} {!loading && cohortsData && ( {!loading && cohortsData && ( @@ -421,7 +448,7 @@ const CohortSelectionSection: React.FC = ({ {cohortsData?.length > 1 ? ( {showFloatingLabel && ( @@ -438,13 +465,21 @@ const CohortSelectionSection: React.FC = ({ // style={{ borderRadius: '4px' }} inputProps={{ 'aria-label': 'Without label' }} - className={showFloatingLabel ? '' : "select-languages fs-14 fw-500 bg-white"} - style={showFloatingLabel ? { borderRadius: '4px' } : { - borderRadius: '0.5rem', - color: theme.palette.warning['200'], - width: '100%', - marginBottom: '0rem', - }} + className={ + showFloatingLabel + ? '' + : 'select-languages fs-14 fw-500 bg-white' + } + style={ + showFloatingLabel + ? { borderRadius: '4px' } + : { + borderRadius: '0.5rem', + color: theme.palette.warning['200'], + width: '100%', + marginBottom: '0rem', + } + } > {cohortsData?.length !== 0 ? ( manipulatedCohortData?.map((cohort) => ( @@ -476,9 +511,47 @@ const CohortSelectionSection: React.FC = ({ ) : ( - - {cohortsData[0]?.name} - + <> + {showDisabledDropDown ? ( + + {showFloatingLabel && ( + + {t('COMMON.CENTER')} + + )} + + + ) : ( + + {cohortsData[0]?.name} + + )} + )} diff --git a/src/components/MarkBulkAttendance.tsx b/src/components/MarkBulkAttendance.tsx index c9f66545..1a21d064 100644 --- a/src/components/MarkBulkAttendance.tsx +++ b/src/components/MarkBulkAttendance.tsx @@ -76,7 +76,7 @@ const MarkBulkAttendance: React.FC = ({ bgcolor: theme.palette.warning['A400'], boxShadow: 24, p: 4, - Height: '526px', + height: '526px', '@media (min-width: 600px)': { width: '450px', }, @@ -671,7 +671,7 @@ const MarkBulkAttendance: React.FC = ({ ) : ( - + {t('COMMON.NO_DATA_FOUND')} )} diff --git a/src/pages/assessments/index.tsx b/src/pages/assessments/index.tsx index 53607037..0841e0f9 100644 --- a/src/pages/assessments/index.tsx +++ b/src/pages/assessments/index.tsx @@ -413,6 +413,7 @@ const Assessments = () => { isManipulationRequired={false} isCustomFieldRequired={true} showFloatingLabel={true} + showDisabledDropDown={true} /> diff --git a/src/pages/centers/index.tsx b/src/pages/centers/index.tsx index 2516c441..ae5171f6 100644 --- a/src/pages/centers/index.tsx +++ b/src/pages/centers/index.tsx @@ -101,14 +101,6 @@ const CentersPage = () => { customField: 'true', }); - response = response.filter((block: any) => { - if ( - block?.cohortMemberStatus === Status.ACTIVE && - block?.cohortStatus === Status.ACTIVE - ) { - return block; - } - }); const blockData = response.map((block: any) => { const blockName = block.cohortName; diff --git a/src/pages/login.tsx b/src/pages/login.tsx index 24831440..96e3c4fe 100644 --- a/src/pages/login.tsx +++ b/src/pages/login.tsx @@ -39,6 +39,39 @@ const LoginPage = () => { const setUserRole = useStore( (state: { setUserRole: any }) => state.setUserRole ); + + const setDistrictCode = manageUserStore( + (state: { setDistrictCode: any }) => state.setDistrictCode + ); + const setDistrictId = manageUserStore( + (state: { setDistrictId: any }) => state.setDistrictId + ); + + const setDistrictName = manageUserStore( + (state: { setDistrictName: any }) => state.setDistrictName + ); + + const setStateCode = manageUserStore( + (state: { setStateCode: any }) => state.setStateCode + ); + const setStateId = manageUserStore( + (state: { setStateId: any }) => state.setStateId + ); + + const setStateName = manageUserStore( + (state: { setStateName: any }) => state.setStateName + ); + + const setBlockCode = manageUserStore( + (state: { setBlockCode: any }) => state.setBlockCode + ); + const setBlockId = manageUserStore( + (state: { setBlockId: any }) => state.setBlockId + ); + const setBlockName = manageUserStore( + (state: { setBlockName: any }) => state.setBlockName + ); + const [showPassword, setShowPassword] = useState(false); const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); @@ -146,10 +179,26 @@ const LoginPage = () => { true ); if (userDetails?.result?.userData) { - if (userDetails.result.userData?.customFields?.length) { - const state = userDetails.result.userData?.customFields.find((field: any) => field?.label === "STATES"); + const customFields = userDetails?.result?.userData?.customFields; + if (customFields?.length) { + const state = customFields.find((field: any) => field?.label === "STATES"); + const district = customFields.find((field: any) => field?.label === "DISTRICTS"); + const block = customFields.find((field: any) => field?.label === "BLOCKS"); + if(state) { localStorage.setItem('stateName', state?.value); + setStateName(state?.value); + setStateCode(state?.id); + } + + if (district) { + setDistrictName(district?.value); + setDistrictCode(district?.code); + } + + if (block) { + setBlockName(block?.value); + setBlockCode(block?.code); } } @@ -411,7 +460,7 @@ const LoginPage = () => { /> - { + {/* { { {t('LOGIN_PAGE.FORGOT_PASSWORD')} - } + } */} setRememberMe(e.target.checked)} diff --git a/src/store/manageUserStore.js b/src/store/manageUserStore.js index b5663d33..1aeacb9c 100644 --- a/src/store/manageUserStore.js +++ b/src/store/manageUserStore.js @@ -14,6 +14,9 @@ const manageUserStore = create( stateId: '', districtId: '', blockId: '', + districtName: '', + blockName: '', + stateName: '', setUserId: (newUserId) => set((state) => ({ userId: newUserId })), setCohortDeleteId: (newCohortDeleteId) => set((state) => ({ deleteId: newCohortDeleteId })), @@ -27,6 +30,9 @@ const manageUserStore = create( setDistrictId: (newDistrictId) => set(() => ({ districtId: newDistrictId })), setStateId: (newStateId) => set(() => ({ stateId: newStateId })), + setDistrictName: (newDistrictName) => set(() => ({ districtName: newDistrictName })), + setBlockName: (newBlockName) => set(() => ({ blockName: newBlockName })), + setStateName: (newStateName) => set(() => ({ stateName: newStateName })), }), { name: 'fieldData', From 7227359438ede57d0245746d61ff1d55574787d6 Mon Sep 17 00:00:00 2001 From: suvarnakale Date: Mon, 26 Aug 2024 20:23:19 +0530 Subject: [PATCH 07/34] Issue #PS-1625 feat: edit events data mapping for planned/extra/online and offline events --- public/locales/en/common.json | 4 +- src/components/PlannedSession.tsx | 90 +++++++++++++++++++------- src/components/SessionCard.tsx | 25 ++++--- src/components/WeekDays.tsx | 82 ++++++++++++----------- src/pages/centers/[cohortId]/index.tsx | 43 ++++++------ src/utils/Interfaces.ts | 8 ++- 6 files changed, 156 insertions(+), 96 deletions(-) diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 85a15e17..a777c5c6 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -373,8 +373,8 @@ "ZOOM": "Zoom", "GOOGLEMEET": "GoogleMeet", "SET_UP": "Set-Up", - "EDIT_THIS_SESSION": " Edit this session", - "EDIT_FOLLOWING_SESSIONS": " Edit this and following sessions", + "EDIT_THIS_SESSION": "Edit this session", + "EDIT_FOLLOWING_SESSIONS": "Edit this and following sessions", "DELETE_SESSION_MSG": "Are you sure you want to delete this session?", "DELETE_ALL_SESSION_MSG": "Are you sure you want to delete all sessions in this series?", "DELETE_THIS_SESSION": "Delete this session", diff --git a/src/components/PlannedSession.tsx b/src/components/PlannedSession.tsx index 42136668..8c8aa161 100644 --- a/src/components/PlannedSession.tsx +++ b/src/components/PlannedSession.tsx @@ -89,7 +89,10 @@ const PlannedSession: React.FC = ({ editSession, onEventDeleted, eventData, + onEventEdited, }) => { + const { t } = useTranslation(); + const theme = useTheme(); const [mode, setMode] = useState(sessionMode.OFFLINE); // const [eventType, setEventType] = useState(sessionType.JUST); const [link, setLink] = useState(''); @@ -99,14 +102,17 @@ const PlannedSession: React.FC = ({ const [modalOpen, setModalOpen] = React.useState(false); const [selectedSubject, setSelectedSubject] = useState(); const [selectedBlockId, setSelectedBlockId] = useState(0); - const [editSelection, setEditSelection] = React.useState('EDIT_SESSION'); + const [editSelection, setEditSelection] = React.useState( + t('CENTER_SESSION.EDIT_THIS_SESSION') + ); const [subjects, setSubjects] = useState(); const [shortDescription, setShortDescription] = useState(); const [meetingPasscode, setMeetingPasscode] = useState(); - dayjs.extend(utc); + const [selectedDays, setSelectedDays] = useState(); const [startDate, setStartDate] = useState(dayjs()); const [endDate, setEndDate] = useState(dayjs()); const [startTime, setStartTime] = useState(dayjs()); + dayjs.extend(utc); const [endTime, setEndTime] = useState(dayjs()); const [sessionBlocks, setSessionBlocks] = useState([ { @@ -152,17 +158,26 @@ const PlannedSession: React.FC = ({ const startDateTime = eventData?.startDateTime; const endDateTime = eventData?.endDateTime; + const endDateValue = eventData?.recurrencePattern?.endCondition?.value; const localStartDateTime = dayjs.utc(startDateTime).tz(timeZone); const localEndDateTime = dayjs.utc(endDateTime).tz(timeZone); - // const localEndDateValue = dayjs.utc(endDateValue).tz('Asia/Kolkata'); + const localEndDateValue = dayjs.utc(endDateValue).tz('Asia/Kolkata'); setStartDate(localStartDateTime.startOf('day')); setStartTime(localStartDateTime); - setEndDate(localEndDateTime.startOf('day')); + if (editSelection === t('CENTER_SESSION.EDIT_THIS_SESSION')) { + setEndDate(localEndDateTime.startOf('day')); + } else { + setEndDate(localEndDateValue.startOf('day')); + } + setEndTime(localEndDateTime); + + const recurrencePattern = eventData?.recurrencePattern?.daysOfWeek; + setSelectedDays(recurrencePattern); } - }, [eventData]); + }, [eventData, editSelection]); const handleOpenModel = () => { setModalOpen(true); @@ -207,6 +222,8 @@ const PlannedSession: React.FC = ({ event: ChangeEvent, id: string | number | undefined ) => { + const mode = event.target.value; + setMode(mode as mode); const updatedSessionBlocks = sessionBlocks.map((block) => block.id === id ? { ...block, sessionMode: event.target.value.toLowerCase() } @@ -473,9 +490,6 @@ const PlannedSession: React.FC = ({ ); }; - const { t } = useTranslation(); - const theme = useTheme(); - const handleSelectionChange = ( id: string | number | undefined, newSelectedDays: string[] @@ -483,6 +497,7 @@ const PlannedSession: React.FC = ({ const mappedSelectedDays = newSelectedDays?.map( (day) => DaysOfWeek[day as keyof typeof DaysOfWeek] ); + setSelectedDays(mappedSelectedDays); setSessionBlocks( sessionBlocks.map((block) => @@ -713,13 +728,14 @@ const PlannedSession: React.FC = ({ }, [scheduleEvent, cohortId]); const handleEditSession = (event: any) => { - setMode(event.target.value); + setEditSelection(event.target.value); }; const handelDeleteEvent = async (eventData: any, deleteSelection: string) => { try { const isMainEvent = - !eventData?.isRecurring || deleteSelection !== 'EDIT_SESSION'; + !eventData?.isRecurring || + deleteSelection !== t('CENTER_SESSION.EDIT_THIS_SESSION'); const eventRepetitionId = eventData?.eventRepetitionId; @@ -741,6 +757,10 @@ const PlannedSession: React.FC = ({ } }; + const handelEditEvent = (eventData: any, deleteSelection: string) => { + console.log(eventData); + }; + return ( {sessionBlocks.map((block, index) => ( @@ -751,13 +771,16 @@ const PlannedSession: React.FC = ({ row aria-labelledby="session-mode-label" name="session-mode-group" - value={mode || editSelection} + value={editSelection} onChange={handleEditSession} > - handleEditSelection?.('EDIT_SESSION', editSession) + handleEditSelection?.( + t('CENTER_SESSION.EDIT_THIS_SESSION'), + editSession + ) } label={ = ({ - handleEditSelection?.('FOLLOWING_SESSION', editSession) + handleEditSelection?.( + t('CENTER_SESSION.EDIT_FOLLOWING_SESSIONS'), + editSession + ) } control={ @@ -817,7 +843,7 @@ const PlannedSession: React.FC = ({ handleSessionModeChange(e, block?.id) } @@ -914,11 +940,7 @@ const PlannedSession: React.FC = ({ label={t('CENTER_SESSION.MEETING_PASSCODE')} variant="outlined" onChange={(e: any) => handlePasscodeChange(block?.id, e)} - value={ - meetingPasscode - ? meetingPasscode - : t('CENTER_SESSION.MEETING_PASSCODE') - } + value={meetingPasscode ? meetingPasscode : null} /> @@ -980,7 +1002,8 @@ const PlannedSession: React.FC = ({ )} {(clickedBox === 'EXTRA_SESSION' || - (editSession && editSelection === 'EDIT_SESSION')) && ( + (editSession && + editSelection === t('CENTER_SESSION.EDIT_THIS_SESSION'))) && ( <> @@ -1034,7 +1057,9 @@ const PlannedSession: React.FC = ({ )} {(clickedBox === 'PLANNED_SESSION' || - (editSession && editSelection === 'FOLLOWING_SESSION')) && ( + (editSession && + editSelection === + t('CENTER_SESSION.EDIT_FOLLOWING_SESSIONS'))) && ( @@ -1045,7 +1070,11 @@ const PlannedSession: React.FC = ({ { handleSelectionChange(block?.id, newSelectedDays); }} @@ -1158,7 +1187,7 @@ const PlannedSession: React.FC = ({ }} onClick={handleOpenModel} > - {editSelection === 'EDIT_SESSION' + {editSelection === t('CENTER_SESSION.EDIT_THIS_SESSION') ? t('CENTER_SESSION.DELETE_THIS_SESSION') : t('CENTER_SESSION.DELETE_FOLLOWING_SESSION')} @@ -1225,7 +1254,7 @@ const PlannedSession: React.FC = ({ {editSession && ( = ({ modalOpen={modalOpen} /> )} + + {onEventEdited && ( + handelEditEvent(editSession, editSelection)} + modalOpen={modalOpen} + /> + )} ); }; diff --git a/src/components/SessionCard.tsx b/src/components/SessionCard.tsx index 0468298f..80481c3d 100644 --- a/src/components/SessionCard.tsx +++ b/src/components/SessionCard.tsx @@ -16,12 +16,15 @@ const SessionsCard: React.FC = ({ data, children, isEventDeleted, + isEventEdited, }) => { const theme = useTheme(); const { t } = useTranslation(); const [open, setOpen] = React.useState(false); const [snackbarOpen, setSnackbarOpen] = React.useState(false); const [eventDeleted, setEventDeleted] = React.useState(false); + const [eventEdited, setEventEdited] = React.useState(false); + const [onEventEdited, setOnEventEdited] = React.useState(false); const [startTime, setStartTime] = React.useState(''); const [endTime, setEndTime] = React.useState(''); const [startDate, setStartDate] = React.useState(''); @@ -34,6 +37,7 @@ const SessionsCard: React.FC = ({ const handleOpen = (eventData: any) => { setOpen(true); setEditSession(eventData); + setEventEdited(true); }; const handleClose = () => setOpen(false); @@ -46,6 +50,14 @@ const SessionsCard: React.FC = ({ } }; + // const onEventEdited = () => { + // setOpen(false); + // setEventEdited(true); + // if (isEventEdited) { + // isEventEdited(); + // } + // }; + const handleSnackbarClose = () => setSnackbarOpen(false); const handleCopyUrl = () => { @@ -82,6 +94,7 @@ const SessionsCard: React.FC = ({ const handleEditModal = () => { setModalOpen(true); + setOnEventEdited(true); }; return ( @@ -170,13 +183,14 @@ const SessionsCard: React.FC = ({ open={open} handleClose={handleClose} title={'Home Science'} - primary={editSession === 'EDIT_SESSION' ? 'Update' : 'Schedule'} + primary={eventEdited ? 'Update' : 'Schedule'} handleEditModal={handleEditModal} > @@ -189,15 +203,6 @@ const SessionsCard: React.FC = ({ onClose={handleSnackbarClose} message="URL copied to clipboard" /> - ); }; diff --git a/src/components/WeekDays.tsx b/src/components/WeekDays.tsx index 029ac416..e1e9a4ba 100644 --- a/src/components/WeekDays.tsx +++ b/src/components/WeekDays.tsx @@ -7,11 +7,9 @@ import { useTheme } from '@mui/material/styles'; interface WeekDaysProps { useAbbreviation?: boolean; onSelectionChange?: (selectedDays: string[]) => void; - selectedDays?: string[]; + selectedDays?: any[]; } - - const WeekDays: React.FC = ({ useAbbreviation, onSelectionChange, @@ -39,45 +37,47 @@ const WeekDays: React.FC = ({ const scrollPosition = itemLeft - containerWidth / 2 + itemWidth / 2; scrollContainer.scrollTo({ left: scrollPosition, behavior: 'smooth' }); } + setLocalSelectedDays(selectedDays); }, []); const handleDayClick = (index: number) => { - if (useAbbreviation) { - // setLocalSelectedDays((prev) => - // prev.includes(index) - // ? prev.filter((day) => day !== index) - // : [...prev, index] - // ); - const newSelectedDays = localSelectedDays.includes(index) - ? localSelectedDays.filter((day) => day !== index) - : [...localSelectedDays, index]; - - setLocalSelectedDays(newSelectedDays); - - if (onSelectionChange) { - const selectedWeekDays = newSelectedDays.map( - (dayIndex) => fullDays[dayIndex] - ); - onSelectionChange(selectedWeekDays); - } + // if (useAbbreviation) { + // setLocalSelectedDays((prev) => + // prev.includes(index) + // ? prev.filter((day) => day !== index) + // : [...prev, index] + // ); + console.log(index); + const newSelectedDays = localSelectedDays.includes(index) + ? localSelectedDays.filter((day) => day !== index) + : [...localSelectedDays, index]; + + setLocalSelectedDays(newSelectedDays); + + if (onSelectionChange) { + const selectedWeekDays = newSelectedDays.map( + (dayIndex) => fullDays[dayIndex] + ); + onSelectionChange(selectedWeekDays); } + // } }; - useEffect(() => { - if (useAbbreviation) { - // const selectedWeekDays = selectedDays.map( - // (dayIndex) => fullDays[dayIndex] - // ); - // console.log('Selected days:', selectedWeekDays); + // useEffect(() => { + // if (useAbbreviation) { + // const selectedWeekDays = selectedDays.map( + // (dayIndex) => fullDays[dayIndex] + // ); + // console.log('Selected days:', selectedWeekDays); - // if (onSelectionChange) { - // onSelectionChange(selectedWeekDays); - // } + // if (onSelectionChange) { + // onSelectionChange(selectedWeekDays); + // } - const selectedIndices = selectedDays.map((day) => fullDays.indexOf(day)); - setLocalSelectedDays(selectedIndices); - } - }, [selectedDays, useAbbreviation, fullDays, onSelectionChange]); + // const selectedIndices = selectedDays.map((day) => fullDays.indexOf(day)); + // setLocalSelectedDays(selectedIndices); + // } + // }, [selectedDays, useAbbreviation, fullDays, onSelectionChange]); return ( = ({ display: 'flex', gap: '14.5px', overflowX: 'auto', - overflowY: "hidden", + overflowY: 'hidden', paddingTop: '10px', - paddingBottom: '10px' + paddingBottom: '10px', }} > {days.map((day, index) => ( @@ -110,8 +110,7 @@ const WeekDays: React.FC = ({ border: `1px solid ${theme?.palette?.warning['A100']}`, borderRadius: '4px', justifyContent: 'center', - alignItems: 'center' - + alignItems: 'center', }} onClick={() => handleDayClick(index)} > @@ -120,7 +119,12 @@ const WeekDays: React.FC = ({ sx={{ width: 'auto', height: '50px' }} > - {day} + + {day} + diff --git a/src/pages/centers/[cohortId]/index.tsx b/src/pages/centers/[cohortId]/index.tsx index d6ed6b10..25443ed1 100644 --- a/src/pages/centers/[cohortId]/index.tsx +++ b/src/pages/centers/[cohortId]/index.tsx @@ -118,6 +118,7 @@ const CohortPage = () => { const [isLearnerAdded, setIsLearnerAdded] = useState(false); const [createEvent, setCreateEvent] = useState(false); const [eventCreated, setEventCreated] = useState(false); + const [onEditEvent, setOnEditEvent] = useState(false); const handleClick = (selection: string) => { setClickedBox(selection); @@ -330,6 +331,10 @@ const CohortPage = () => { setIsLearnerAdded(true); }; + const handleEditEvent = () => { + setOnEditEvent(true); + }; + return ( <>
@@ -498,7 +503,9 @@ const CohortPage = () => { ? t('COMMON.OK') : openSchedule ? t('CENTER_SESSION.SCHEDULE') - : t('GUIDE_TOUR.NEXT') + : onEditEvent + ? t('CENTER_SESSION.UPDATE') + : t('GUIDE_TOUR.NEXT') } secondary={deleteModal ? t('COMMON.CANCEL') : undefined} handlePrimaryModel={ @@ -506,8 +513,11 @@ const CohortPage = () => { ? undefined : openSchedule ? handleSchedule - : handleCentermodel + : onEditEvent + ? handleEditEvent + : handleCentermodel } + handleEditModal={handleEditEvent} > {deleteModal ? ( @@ -532,19 +542,19 @@ const CohortPage = () => { > {t('COMMON.UPCOMING_EXTRA_SESSION', { days: eventDaysLimit })} - + { modules={[Pagination, Navigation]} className="mySwiper" > - {extraSessions?.map((item) => ( <> - - - - - + + + + + ))} - - {extraSessions && extraSessions?.length === 0 && ( void; + isEventEdited?: () => void; } export interface SessionsModalProps { children?: React.ReactNode; @@ -155,6 +156,7 @@ export interface PlannedModalProps { editSelection?: string; handleEditSelection?: (selection: string) => void; onEventDeleted?: () => void; + onEventEdited?: boolean; editSession?: any; eventData?: any; } @@ -616,9 +618,9 @@ export interface EditEvent { } export interface ISearchAssessment { - userId: string, - contentId: string, - batchId: string + userId: string; + contentId: string; + batchId: string; } export interface IQuestion { From ea79ddb67ed376d002b3eea37e576a17da940b43 Mon Sep 17 00:00:00 2001 From: ttpl-rt-214 Date: Tue, 27 Aug 2024 00:51:56 +0530 Subject: [PATCH 08/34] #PS-1769 Course Planner bottom drawer desktop view UI --- public/locales/en/common.json | 42 +++++- src/components/MenuDrawer.tsx | 40 +++++ src/pages/board-enrollment/index.tsx | 214 +++++++++++++++++++++++++++ 3 files changed, 295 insertions(+), 1 deletion(-) create mode 100644 src/pages/board-enrollment/index.tsx diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 85a15e17..a38fc5a9 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -511,5 +511,45 @@ "OVERALL_SCORE": "Overall Score", "ASSESSMENT_NOT_STARTED_YET": "Assessment not started yet", "NUMBER_OUT_OF_COMPLETED": "{{completedCount}} out of {{totalCount}} completed" - } + }, + "BOARD_ENROOLMENT": { + "BOARD_ENROLLMENT": "Board Enrollment", + "BOARD": "Board", + "BOARD_NAME": "Board Name", + "BOARD_CODE": "Board Code", + "BOARD_TYPE": "Board Type", + "BOARD_TYPE_NAME": "Board Type Name", + "BOARD_TYPE_CODE": "Board Type Code", + "BOARD_TYPE_DESCRIPTION": "Board Type Description", + "BOARD_TYPE_STATUS": "Board Type Status", + "BOARD_TYPE_CREATED_BY": "Board Type Created By", + "BOARD_TYPE_CREATED_ON": "Board Type Created On", + "BOARD_TYPE_UPDATED_BY": "Board Type Updated By", + "BOARD_TYPE_UPDATED_ON": "Board Type Updated On", + "BOARD_TYPE_ACTION": "Board Type Action", + "BOARD_TYPE_ADD": "Add Board Type", + "BOARD_TYPE_EDIT": "Edit Board Type", + "BOARD_TYPE_DELETE": "Delete Board Type", + "BOARD_TYPE_CONFIRM_DELETE": "Are you sure you want to delete this board type?", + "BOARD_TYPE_CONFIRM_DELETE_SUCCESS": "Board type deleted successfully", + "BOARD_TYPE_CONFIRM_DELETE_FAILURE": "Failed to delete board type", + "BOARD_TYPE_CONFIRM_UPDATE_SUCCESS": "Board type updated successfully", + "BOARD_TYPE_CONFIRM_UPDATE_FAILURE": "Failed to update board type", + "BOARD_TYPE_CONFIRM_ADD_SUCCESS": "Board type added successfully", + "BOARD_TYPE_CONFIRM_ADD_FAILURE": "Failed to add board type", + "BOARD_TYPE_CONFIRM_STATUS_SUCCESS": "Board type status updated successfully", + "BOARD_TYPE_CONFIRM_STATUS_FAILURE": "Failed to update board type status", + "BOARD_TYPE_CONFIRM_STATUS": "Are you sure you want to update the status of this board type?", + "BOARD_TYPE_CONFIRM_STATUS_ACTIVE": "Are you sure you want to activate this board type?", + "BOARD_TYPE_CONFIRM_STATUS_INACTIVE": "Are you sure you want to deactivate this board type?", + "BOARD_TYPE_CONFIRM_STATUS_DISABLED": "Are you sure you want to disable this board type?", + "BOARD_TYPE_CONFIRM_STATUS_ENABLED": "Are you sure you want to enable this board type?", + "BOARD_TYPE_CONFIRM_STATUS_PENDING": "Are you sure you want to set this board type to pending?", + "BOARD_TYPE_CONFIRM_STATUS_REJECTED": "Are you sure you want to reject this board type?", + "BOARD_TYPE_CONFIRM_STATUS_APPROVED": "Are you sure you want to approve this board type?", + "BOARD_TYPE_CONFIRM_STATUS_CANCELLED": "Are you sure you want to cancel this board type?", + "BOARD_TYPE_CONFIRM_STATUS_DELETED": "Are you sure you want to delete this board type?", + "BOARD_TYPE_CONFIRM_STATUS_ARCHIVED": "Are you sure you want to archive this board type?", + "BOARD_TYPE_CONFIRM_STATUS_UNARCHIVED": "Are you sure you want to unarchive this board type?" + } } diff --git a/src/components/MenuDrawer.tsx b/src/components/MenuDrawer.tsx index 15d6ddd1..0e439b61 100644 --- a/src/components/MenuDrawer.tsx +++ b/src/components/MenuDrawer.tsx @@ -93,6 +93,9 @@ const MenuDrawer: React.FC = ({ const isTeacherCenter = router.pathname === '/centers'; const isCoursePlanner = router.pathname === '/course-planner'; const isAssessments = router.pathname === '/assessments'; + const isBoard = router.pathname === '/board-enrollment'; + + // const isManageUser = router.pathname === '/manageUser'; @@ -352,6 +355,41 @@ const MenuDrawer: React.FC = ({ {t('ASSESSMENTS.ASSESSMENTS')} + + + + + {/* + + + + + + + Stages and Number of Students + + + + + + + {data.map((entry, index) => ( + + ))} + + + {isMobile ? ( + + ) : ( + + )} + + + + + + + + + + {steps.map((label) => ( + + {label} + + ))} + + + + + ); +}; + +export async function getStaticProps({ locale }: any) { + return { + props: { + ...(await serverSideTranslations(locale, ['common'])), + }, + }; +} + +export default BoardEnrollment; From 8ba1e11316572ab183d3e204cc1bfe108a95296f Mon Sep 17 00:00:00 2001 From: vivek kasture Date: Tue, 27 Aug 2024 11:05:51 +0530 Subject: [PATCH 09/34] Issue #PS-000 feat: Updated env and telemetry batchsize --- .env | 10 ++++++---- src/utils/telemetry.js | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/.env b/.env index 840b1f00..7d4c6e71 100644 --- a/.env +++ b/.env @@ -1,7 +1,9 @@ NEXT_PUBLIC_BASE_URL=https://qa.prathamteacherapp.tekdinext.com/user/v1 -# NEXT_PUBLIC_BASE_URL=https://backend.prathamdigital.org/user/v1 NEXT_PUBLIC_EVENT_BASE_URL=https://event-pratham.tekdinext.com/event-service/event/v1 -NEXT_PUBLIC_NOTIFICATION_BASE_URL=https://notification.prathamdigital.org -NEXT_PUBLIC_TELEMETRY_URL=https://qa.prathamteacherapp.tekdinext.com +NEXT_PUBLIC_NOTIFICATION_BASE_URL=https://notification-pratham.tekdinext.com +NEXT_PUBLIC_TELEMETRY_URL=https://qa.prathamteacherapp.tekdinext.com/telemetry NEXT_PUBLIC_MEASUREMENT_ID= G-GNMQZ8Z65Z -NEXT_PUBLIC_TRACKING_API_URL=https://tracking-pratham.tekdinext.com \ No newline at end of file +NEXT_PUBLIC_TRACKING_API_URL=https://tracking-pratham.tekdinext.com +# NEXT_PUBLIC_BASE_URL=https://backend.prathamdigital.org/user/v1 +# NEXT_PUBLIC_NOTIFICATION_BASE_URL=https://notification.prathamdigital.org +# NEXT_PUBLIC_TRACKING_API_URL=https://tracking.prathamdigital.org \ No newline at end of file diff --git a/src/utils/telemetry.js b/src/utils/telemetry.js index 1205644a..7f7ff159 100644 --- a/src/utils/telemetry.js +++ b/src/utils/telemetry.js @@ -34,10 +34,10 @@ const telemetryConfig = { (typeof window !== 'undefined' && localStorage.getItem('userName')) || 'Anonymous', sid: generateUUID(), - batchsize: 1, + batchsize: 20, mode: '', host: hostURL, - endpoint: '/telemetry/v1/telemetry', + endpoint: '/v1/telemetry', tags: [], enableValidation: true }; From bb0df0124237e28e6801adb69824181ef711494a Mon Sep 17 00:00:00 2001 From: vivek kasture Date: Tue, 27 Aug 2024 14:53:48 +0530 Subject: [PATCH 10/34] Issue #PS-000 feat: Bug fixes --- src/components/AttendanceStatusListView.tsx | 2 +- src/components/DynamicForm.tsx | 5 +++++ src/components/MarkBulkAttendance.tsx | 2 +- src/components/SimpleModal.tsx | 19 ++++++++++--------- src/pages/centers/index.tsx | 2 +- 5 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/components/AttendanceStatusListView.tsx b/src/components/AttendanceStatusListView.tsx index 6695330a..f2885b45 100644 --- a/src/components/AttendanceStatusListView.tsx +++ b/src/components/AttendanceStatusListView.tsx @@ -150,7 +150,7 @@ const AttendanceStatusListView: React.FC = ({ className="two-line-text" > {isBulkAction ? ( - t('ATTENDANCE.MARK_ALL') + t('COMMON.MARK_ALL_AS') ) : showLink ? ( {userData?.name} diff --git a/src/components/DynamicForm.tsx b/src/components/DynamicForm.tsx index 34d68847..cd60b2b7 100644 --- a/src/components/DynamicForm.tsx +++ b/src/components/DynamicForm.tsx @@ -86,6 +86,11 @@ const DynamicForm: React.FC = ({ const currentYearPattern = new RegExp(getCurrentYearPattern()); const emailPattern = new RegExp(getEmailPattern()); + errors = errors.filter( + (item: any, index: number, self: any) => + index === self.findIndex((t: any) => t.property === item.property) + ); + return errors.map((error: any) => { switch (error.name) { case 'required': { diff --git a/src/components/MarkBulkAttendance.tsx b/src/components/MarkBulkAttendance.tsx index 1a21d064..7833a10f 100644 --- a/src/components/MarkBulkAttendance.tsx +++ b/src/components/MarkBulkAttendance.tsx @@ -665,7 +665,7 @@ const MarkBulkAttendance: React.FC = ({ onClick={attendanceUpdate} > {presentCount == 0 && absentCount == 0 - ? t('COMMON.MARK_ALL_AS') + ? t('COMMON.MARK') : t('COMMON.MODIFY')} diff --git a/src/components/SimpleModal.tsx b/src/components/SimpleModal.tsx index a1c74be4..772c1fb5 100644 --- a/src/components/SimpleModal.tsx +++ b/src/components/SimpleModal.tsx @@ -92,10 +92,10 @@ const SimpleModal: React.FC = ({ {showFooter ? ( - {primaryText && ( + {secondaryText && ( )} - - {secondaryText && ( + {primaryText && ( )} diff --git a/src/pages/centers/index.tsx b/src/pages/centers/index.tsx index ae5171f6..373edd64 100644 --- a/src/pages/centers/index.tsx +++ b/src/pages/centers/index.tsx @@ -123,7 +123,7 @@ const CentersPage = () => { response.map((res: any) => { const centerData = res?.childData.map((child: any) => { - const cohortName = child.name; + const cohortName = toPascalCase(child.name); const cohortId = child.cohortId; const centerTypeField = child?.customField.find( (field: any) => field.label === 'TYPE_OF_COHORT' From 35cd3f4d86c190056a724c202096d377aeb75c0a Mon Sep 17 00:00:00 2001 From: vivek kasture Date: Tue, 27 Aug 2024 15:10:37 +0530 Subject: [PATCH 11/34] Issue #PS-000 feat: Bug fixes --- src/components/AttendanceComparison.tsx | 284 +++++++++++++----------- 1 file changed, 154 insertions(+), 130 deletions(-) diff --git a/src/components/AttendanceComparison.tsx b/src/components/AttendanceComparison.tsx index ec21bfa8..742c5ec5 100644 --- a/src/components/AttendanceComparison.tsx +++ b/src/components/AttendanceComparison.tsx @@ -74,7 +74,9 @@ const AttendanceComparison: React.FC = ({ useEffect(() => { const cohortIds = - store?.cohorts?.filter((item: Cohort) => item?.cohortType === centerType).map((pair: Cohort) => pair?.cohortId) || []; + store?.cohorts + ?.filter((item: Cohort) => item?.cohortType === centerType) + .map((pair: Cohort) => pair?.cohortId) || []; const fetchData = async () => { const promises = cohortIds?.map((cohortId: string) => @@ -158,146 +160,168 @@ const AttendanceComparison: React.FC = ({ {t('DASHBOARD.CENTER_TYPE')} - - } - label="Regular" - sx={{ - '& .MuiFormControlLabel-label': { - color: 'black', - fontSize: '18px', - }, - }} - /> - - } - label="Remote" - sx={{ - '& .MuiFormControlLabel-label': { - color: 'black', - fontSize: '18px', - }, - }} - /> - - - - {centerType === CenterType.REMOTE - ? t('DASHBOARD.REMOTE_AVERAGE_ATTENDANCE') - : t('DASHBOARD.REGULAR_AVERAGE_ATTENDANCE')} - : {averageAttendance.toFixed(2)}% - - - - - + row + aria-label="center type" + name="centerType" + value={centerType} + onChange={handleCenterTypeChange} + > + + } + label={t('CENTERS.REGULAR')} + sx={{ + '& .MuiFormControlLabel-label': { + color: 'black', + fontSize: '18px', + }, + }} + /> + + } + label={t('CENTERS.REMOTE')} + sx={{ + '& .MuiFormControlLabel-label': { + color: 'black', + fontSize: '18px', + }, + }} + /> + + + {data?.length > 0 && ( + <> + + + {centerType === CenterType.REMOTE + ? t('DASHBOARD.REMOTE_AVERAGE_ATTENDANCE') + : t('DASHBOARD.REGULAR_AVERAGE_ATTENDANCE')} + : {averageAttendance.toFixed(2)}% + + + + + + + `${value}%`} + height={0} + /> + { + const { x, y, payload } = props; + const name = payload.value; + const firstLine = name.slice(0, 7); + const secondLine = name.slice(7, 13); + const thirdLine = name.slice(13, 19); + const capitalizedFirstLine = + firstLine.charAt(0).toUpperCase() + firstLine.slice(1); + + return ( + + + {capitalizedFirstLine} + + {secondLine && ( + + {secondLine} + + )} + {thirdLine && ( + + {thirdLine} + + )} + + ); + }} + /> + + `${value}%`} /> + + + + + + + - `${value}%`} - height={0} - /> - { - const { x, y, payload } = props; - const name = payload.value; - const firstLine = name.slice(0, 7); - const secondLine = name.slice(7, 13); - const thirdLine = name.slice(13, 19); - const capitalizedFirstLine = - firstLine.charAt(0).toUpperCase() + firstLine.slice(1); - - return ( - - - {capitalizedFirstLine} - - {secondLine && ( - - {secondLine} - - )} - {thirdLine && ( - - {thirdLine} - - )} - - ); - }} + domain={[0, 100]} /> - `${value}%`} /> - - - + + + + + {t('DASHBOARD.ATTENDANCE')} + + + + )} + + {data?.length === 0 && ( + + {t('COMMON.NO_DATA_FOUND')} - - - `${value}%`} - domain={[0, 100]} - /> - `${value}%`} /> - - - - - - - {t('DASHBOARD.ATTENDANCE')} - - - - + )} + ); }; From 20da6560e59e24b0654e5683aed6ddbdcfe73ef1 Mon Sep 17 00:00:00 2001 From: ttpl-rt-214 Date: Tue, 27 Aug 2024 15:18:25 +0530 Subject: [PATCH 12/34] #PS-1804 Pie chart graph implementation --- src/components/PieChartGraph.tsx | 108 +++++++++++++++++++++ src/components/SimpleModal.tsx | 2 +- src/components/Stepper.tsx | 55 +++++++++++ src/pages/board-enrollment/index.tsx | 138 +++++---------------------- src/styles/globals.css | 2 +- 5 files changed, 189 insertions(+), 116 deletions(-) create mode 100644 src/components/PieChartGraph.tsx create mode 100644 src/components/Stepper.tsx diff --git a/src/components/PieChartGraph.tsx b/src/components/PieChartGraph.tsx new file mode 100644 index 00000000..31da63ae --- /dev/null +++ b/src/components/PieChartGraph.tsx @@ -0,0 +1,108 @@ +import { Box } from '@mui/material' +import React, { useEffect, useState } from 'react' +import { PieChart, Pie, Cell, ResponsiveContainer, Legend } from 'recharts'; + +interface DataItem { + name: string; + value: number; +} + +const PieChartGraph = () => { + + const data: DataItem[] = [ + { name: 'Not Started', value: 4 }, + { name: 'Board Selection', value: 5 }, + { name: 'Subjects Selection', value: 10 }, + { name: 'Registration Completed', value: 5 }, + ]; + + + const COLORS = ['#C0C0C0', '#8000FE', '#FF8042', '#FFBB28']; + + const [isMobile, setIsMobile] = useState(false); + + useEffect(() => { + const handleResize = () => { + setIsMobile(window.innerWidth <= 700); + }; + + handleResize(); // Check initial size + window.addEventListener('resize', handleResize); + + return () => window.removeEventListener('resize', handleResize); + }, []); + + const renderLegendText = (value: string, entry: any) => { + const isNotStarted = value === 'Not Started'; + return ( + + {value} ({entry.payload.value}) + + ); + }; + return ( + <> + + + Stages and Number of Students + + + + + + + {data.map((entry, index) => ( + + ))} + + + {isMobile ? ( + + ) : ( + + )} + + + + + + ) +} + +export default PieChartGraph \ No newline at end of file diff --git a/src/components/SimpleModal.tsx b/src/components/SimpleModal.tsx index a1c74be4..2b0cd4e9 100644 --- a/src/components/SimpleModal.tsx +++ b/src/components/SimpleModal.tsx @@ -85,7 +85,7 @@ const SimpleModal: React.FC = ({ - + {children} diff --git a/src/components/Stepper.tsx b/src/components/Stepper.tsx new file mode 100644 index 00000000..b52c4476 --- /dev/null +++ b/src/components/Stepper.tsx @@ -0,0 +1,55 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import Stepper from '@mui/material/Stepper'; +import Step from '@mui/material/Step'; +import StepLabel from '@mui/material/StepLabel'; +import StepConnector from '@mui/material/StepConnector'; +import RadioButtonCheckedIcon from '@mui/icons-material/RadioButtonChecked'; +import RadioButtonUncheckedIcon from '@mui/icons-material/RadioButtonUnchecked'; +import CheckCircleIcon from '@mui/icons-material/CheckCircle'; + +const steps: string[] = ['Board', 'Subjects', 'Registration']; + +export default function HorizontalLinearStepper() { + const [activeStep, setActiveStep] = React.useState(1); + + // Custom StepIcon to switch between CheckCircleIcon, RadioButtonCheckedIcon, and RadioButtonUncheckedIcon + const CustomStepIcon = (props: any) => { + const { icon, active, completed } = props; + + if (completed) { + return ; + } else if (active) { + return ; + } else { + return ; + } + }; + + return ( + + }> + {steps.map((label, index) => ( + + + {label} + + + ))} + + + ); +} diff --git a/src/pages/board-enrollment/index.tsx b/src/pages/board-enrollment/index.tsx index de82f3ac..930a7902 100644 --- a/src/pages/board-enrollment/index.tsx +++ b/src/pages/board-enrollment/index.tsx @@ -7,54 +7,16 @@ import ArrowDropDownSharpIcon from '@mui/icons-material/ArrowDropDownSharp'; import React, { useEffect, useState } from 'react'; import SearchIcon from '@mui/icons-material/Search'; import { PieChart, Pie, Cell, ResponsiveContainer, Legend } from 'recharts'; +import EastIcon from '@mui/icons-material/East'; +import HorizontalLinearStepper from '@/components/Stepper'; +import PieChartGraph from '@/components/PieChartGraph'; + -interface DataItem { - name: string; - value: number; -} const BoardEnrollment = () => { const theme = useTheme(); const { t } = useTranslation(); - const data: DataItem[] = [ - { name: 'Not Started', value: 4 }, - { name: 'Board Selection', value: 5 }, - { name: 'Subjects Selection', value: 10 }, - { name: 'Registration Completed', value: 5 }, - ]; - - const COLORS = ['#C0C0C0', '#8000FE', '#FF8042', '#FFBB28']; - - const [isMobile, setIsMobile] = useState(false); - - useEffect(() => { - const handleResize = () => { - setIsMobile(window.innerWidth <= 700); - }; - - handleResize(); // Check initial size - window.addEventListener('resize', handleResize); - - return () => window.removeEventListener('resize', handleResize); - }, []); - - const renderLegendText = (value: string, entry: any) => { - const isNotStarted = value === 'Not Started'; - return ( - - {value} ({entry.payload.value}) - - ); - }; - - - const steps = [ - 'Select master blaster campaign settings', - 'Create an ad group', - 'Create an ad', - ]; - return ( <>
@@ -103,8 +65,8 @@ const BoardEnrollment = () => { marginBottom: '0rem', }} > - - All Centers + + All Centers @@ -127,78 +89,26 @@ const BoardEnrollment = () => { - - - Stages and Number of Students - - - - - - - {data.map((entry, index) => ( - - ))} - - - {isMobile ? ( - - ) : ( - - )} - - - - + - - - - {steps.map((label) => ( - - {label} - - ))} - - - + + + + + Aanya Gupta + + + + Khapari Dharmu (Chimur, Chandrapur) + + + + + + + + ); }; diff --git a/src/styles/globals.css b/src/styles/globals.css index 9a8d7fec..a8cfbb8e 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -991,7 +991,7 @@ legend.Mui-focused { .form-parent .rjsf .field-object{ min-height: 100%; - max-height: 55vh; + max-height: 48vh; overflow-y: auto; padding-left: 16px; padding-right: 16px; From 4d6c93c6ae0b2409fcfe030c75e4ca9acff92cf2 Mon Sep 17 00:00:00 2001 From: vivek kasture Date: Tue, 27 Aug 2024 15:21:57 +0530 Subject: [PATCH 13/34] Issue #PS-000 feat: Bug fixes --- src/components/SessionCard.tsx | 13 ++++++------- src/pages/dashboard.tsx | 12 ++++++------ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/components/SessionCard.tsx b/src/components/SessionCard.tsx index 80481c3d..6b178897 100644 --- a/src/components/SessionCard.tsx +++ b/src/components/SessionCard.tsx @@ -1,16 +1,15 @@ +import { SessionsCardProps } from '@/utils/Interfaces'; import { Box, Snackbar, Typography } from '@mui/material'; -import { Session, SessionsCardProps } from '@/utils/Interfaces'; -import CenterSessionModal from './CenterSessionModal'; +import { convertUTCToIST } from '@/utils/Helper'; +import CalendarMonthIcon from '@mui/icons-material/CalendarMonth'; import ContentCopyIcon from '@mui/icons-material/ContentCopy'; import EditOutlined from '@mui/icons-material/EditOutlined'; -import PlannedSession from './PlannedSession'; -import React, { useEffect, useState } from 'react'; import { useTheme } from '@mui/material/styles'; -import { convertUTCToIST } from '@/utils/Helper'; import { useTranslation } from 'next-i18next'; -import CalendarMonthIcon from '@mui/icons-material/CalendarMonth'; -import ConfirmationModal from './ConfirmationModal'; +import React, { useEffect } from 'react'; +import CenterSessionModal from './CenterSessionModal'; +import PlannedSession from './PlannedSession'; const SessionsCard: React.FC = ({ data, diff --git a/src/pages/dashboard.tsx b/src/pages/dashboard.tsx index 80f220dc..9682d21b 100644 --- a/src/pages/dashboard.tsx +++ b/src/pages/dashboard.tsx @@ -1080,8 +1080,8 @@ const Dashboard: React.FC = () => { {sessions?.map((item) => ( - - + + @@ -1089,7 +1089,7 @@ const Dashboard: React.FC = () => { {sessions && sessions?.length === 0 && ( {t('COMMON.NO_SESSIONS_SCHEDULED')} @@ -1107,10 +1107,10 @@ const Dashboard: React.FC = () => { })} - + {extraSessions?.map((item) => ( - - + + From 24841b4b7a8736d59932fbbebe0aac989dc17b5b Mon Sep 17 00:00:00 2001 From: ttpl-rt-214 Date: Tue, 27 Aug 2024 15:51:31 +0530 Subject: [PATCH 14/34] #PS-1769 Course Planner bottom drawer desktop view UI --- public/locales/en/common.json | 42 ++----------------- ...tepper.tsx => HorizontalLinearStepper.tsx} | 18 ++++---- src/components/MenuDrawer.tsx | 3 -- src/components/PieChartGraph.tsx | 27 ++++++------ src/pages/board-enrollment/index.tsx | 12 +++--- 5 files changed, 36 insertions(+), 66 deletions(-) rename src/components/{Stepper.tsx => HorizontalLinearStepper.tsx} (76%) diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 0459054c..eea9c919 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -514,42 +514,8 @@ }, "BOARD_ENROOLMENT": { "BOARD_ENROLLMENT": "Board Enrollment", - "BOARD": "Board", - "BOARD_NAME": "Board Name", - "BOARD_CODE": "Board Code", - "BOARD_TYPE": "Board Type", - "BOARD_TYPE_NAME": "Board Type Name", - "BOARD_TYPE_CODE": "Board Type Code", - "BOARD_TYPE_DESCRIPTION": "Board Type Description", - "BOARD_TYPE_STATUS": "Board Type Status", - "BOARD_TYPE_CREATED_BY": "Board Type Created By", - "BOARD_TYPE_CREATED_ON": "Board Type Created On", - "BOARD_TYPE_UPDATED_BY": "Board Type Updated By", - "BOARD_TYPE_UPDATED_ON": "Board Type Updated On", - "BOARD_TYPE_ACTION": "Board Type Action", - "BOARD_TYPE_ADD": "Add Board Type", - "BOARD_TYPE_EDIT": "Edit Board Type", - "BOARD_TYPE_DELETE": "Delete Board Type", - "BOARD_TYPE_CONFIRM_DELETE": "Are you sure you want to delete this board type?", - "BOARD_TYPE_CONFIRM_DELETE_SUCCESS": "Board type deleted successfully", - "BOARD_TYPE_CONFIRM_DELETE_FAILURE": "Failed to delete board type", - "BOARD_TYPE_CONFIRM_UPDATE_SUCCESS": "Board type updated successfully", - "BOARD_TYPE_CONFIRM_UPDATE_FAILURE": "Failed to update board type", - "BOARD_TYPE_CONFIRM_ADD_SUCCESS": "Board type added successfully", - "BOARD_TYPE_CONFIRM_ADD_FAILURE": "Failed to add board type", - "BOARD_TYPE_CONFIRM_STATUS_SUCCESS": "Board type status updated successfully", - "BOARD_TYPE_CONFIRM_STATUS_FAILURE": "Failed to update board type status", - "BOARD_TYPE_CONFIRM_STATUS": "Are you sure you want to update the status of this board type?", - "BOARD_TYPE_CONFIRM_STATUS_ACTIVE": "Are you sure you want to activate this board type?", - "BOARD_TYPE_CONFIRM_STATUS_INACTIVE": "Are you sure you want to deactivate this board type?", - "BOARD_TYPE_CONFIRM_STATUS_DISABLED": "Are you sure you want to disable this board type?", - "BOARD_TYPE_CONFIRM_STATUS_ENABLED": "Are you sure you want to enable this board type?", - "BOARD_TYPE_CONFIRM_STATUS_PENDING": "Are you sure you want to set this board type to pending?", - "BOARD_TYPE_CONFIRM_STATUS_REJECTED": "Are you sure you want to reject this board type?", - "BOARD_TYPE_CONFIRM_STATUS_APPROVED": "Are you sure you want to approve this board type?", - "BOARD_TYPE_CONFIRM_STATUS_CANCELLED": "Are you sure you want to cancel this board type?", - "BOARD_TYPE_CONFIRM_STATUS_DELETED": "Are you sure you want to delete this board type?", - "BOARD_TYPE_CONFIRM_STATUS_ARCHIVED": "Are you sure you want to archive this board type?", - "BOARD_TYPE_CONFIRM_STATUS_UNARCHIVED": "Are you sure you want to unarchive this board type?" - } + "BOARD_SELECTION":"Board Selection", + "SUBJECTS_SELECTION": "Subjects Selection", + "REGISTRATION_COMPLETED":"Registration Completed" + } } diff --git a/src/components/Stepper.tsx b/src/components/HorizontalLinearStepper.tsx similarity index 76% rename from src/components/Stepper.tsx rename to src/components/HorizontalLinearStepper.tsx index b52c4476..7fb95b3e 100644 --- a/src/components/Stepper.tsx +++ b/src/components/HorizontalLinearStepper.tsx @@ -8,19 +8,23 @@ import RadioButtonCheckedIcon from '@mui/icons-material/RadioButtonChecked'; import RadioButtonUncheckedIcon from '@mui/icons-material/RadioButtonUnchecked'; import CheckCircleIcon from '@mui/icons-material/CheckCircle'; +import { useTranslation } from 'react-i18next'; +import { useTheme } from '@mui/material/styles'; const steps: string[] = ['Board', 'Subjects', 'Registration']; export default function HorizontalLinearStepper() { const [activeStep, setActiveStep] = React.useState(1); - // Custom StepIcon to switch between CheckCircleIcon, RadioButtonCheckedIcon, and RadioButtonUncheckedIcon + const { t } = useTranslation(); + const theme = useTheme(); + const CustomStepIcon = (props: any) => { const { icon, active, completed } = props; if (completed) { - return ; + return ; } else if (active) { - return ; + return ; } else { return ; } @@ -31,18 +35,18 @@ export default function HorizontalLinearStepper() { }> {steps.map((label, index) => ( - {label} diff --git a/src/components/MenuDrawer.tsx b/src/components/MenuDrawer.tsx index 0e439b61..53984b62 100644 --- a/src/components/MenuDrawer.tsx +++ b/src/components/MenuDrawer.tsx @@ -94,9 +94,6 @@ const MenuDrawer: React.FC = ({ const isCoursePlanner = router.pathname === '/course-planner'; const isAssessments = router.pathname === '/assessments'; const isBoard = router.pathname === '/board-enrollment'; - - - // const isManageUser = router.pathname === '/manageUser'; return ( diff --git a/src/components/PieChartGraph.tsx b/src/components/PieChartGraph.tsx index 31da63ae..7b1122a5 100644 --- a/src/components/PieChartGraph.tsx +++ b/src/components/PieChartGraph.tsx @@ -1,5 +1,7 @@ import { Box } from '@mui/material' import React, { useEffect, useState } from 'react' +import { useTranslation } from 'react-i18next'; +import { useTheme } from '@mui/material/styles'; import { PieChart, Pie, Cell, ResponsiveContainer, Legend } from 'recharts'; interface DataItem { @@ -8,16 +10,17 @@ interface DataItem { } const PieChartGraph = () => { - + const { t } = useTranslation(); + const theme = useTheme(); const data: DataItem[] = [ - { name: 'Not Started', value: 4 }, - { name: 'Board Selection', value: 5 }, - { name: 'Subjects Selection', value: 10 }, - { name: 'Registration Completed', value: 5 }, + { name: t('ASSESSMENTS.NOT_STARTED'), value: 4 }, + { name: t('BOARD_ENROOLMENT.BOARD_SELECTION'), value: 5 }, + { name: t('BOARD_ENROOLMENT.SUBJECTS_SELECTION'), value: 10 }, + { name: t('BOARD_ENROOLMENT.REGISTRATION_COMPLETED'), value: 5 }, ]; - const COLORS = ['#C0C0C0', '#8000FE', '#FF8042', '#FFBB28']; + const COLORS = ['#C0C0C0', '#8000FE', '#FF8042', '#FFBB28']; //colors not in custom theme const [isMobile, setIsMobile] = useState(false); @@ -40,14 +43,14 @@ const PieChartGraph = () => { ); }; - return ( - <> - + - + Stages and Number of Students @@ -101,8 +104,8 @@ const PieChartGraph = () => { - - ) + + ) } export default PieChartGraph \ No newline at end of file diff --git a/src/pages/board-enrollment/index.tsx b/src/pages/board-enrollment/index.tsx index 930a7902..7898511b 100644 --- a/src/pages/board-enrollment/index.tsx +++ b/src/pages/board-enrollment/index.tsx @@ -8,7 +8,7 @@ import React, { useEffect, useState } from 'react'; import SearchIcon from '@mui/icons-material/Search'; import { PieChart, Pie, Cell, ResponsiveContainer, Legend } from 'recharts'; import EastIcon from '@mui/icons-material/East'; -import HorizontalLinearStepper from '@/components/Stepper'; +import HorizontalLinearStepper from '@/components/HorizontalLinearStepper'; import PieChartGraph from '@/components/PieChartGraph'; @@ -21,8 +21,8 @@ const BoardEnrollment = () => { <>
- - Board Enrollment + + {t('BOARD_ENROOLMENT.BOARD_ENROLLMENT')} @@ -41,7 +41,7 @@ const BoardEnrollment = () => { @@ -66,7 +66,7 @@ const BoardEnrollment = () => { }} > - All Centers + All Centers {/*will come form API */} @@ -94,7 +94,7 @@ const BoardEnrollment = () => { - + Aanya Gupta From 06bb7920e7a53b563bdfd3b625f3e34703ec6600 Mon Sep 17 00:00:00 2001 From: ttpl-rt-214 Date: Tue, 27 Aug 2024 15:53:52 +0530 Subject: [PATCH 15/34] #PS-1769 Course Planner bottom drawer desktop view UI --- src/pages/board-enrollment/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/board-enrollment/index.tsx b/src/pages/board-enrollment/index.tsx index 7898511b..f4a7a327 100644 --- a/src/pages/board-enrollment/index.tsx +++ b/src/pages/board-enrollment/index.tsx @@ -100,7 +100,7 @@ const BoardEnrollment = () => { - Khapari Dharmu (Chimur, Chandrapur) + Khapari Dharmu (Chimur, Chandrapur) {/*will come from API*/} From 218636de9eaacf71bc87c56208815386169491a1 Mon Sep 17 00:00:00 2001 From: vivek kasture Date: Tue, 27 Aug 2024 15:58:18 +0530 Subject: [PATCH 16/34] Issue #PS-000 feat: Bug fixes --- src/components/center/CreateCenterModal.tsx | 3 +- src/pages/centers/index.tsx | 42 ++++++++++----------- src/pages/learner/[userId].tsx | 3 +- src/pages/user-profile/[userId].tsx | 3 +- src/utils/app.constant.ts | 2 + 5 files changed, 27 insertions(+), 26 deletions(-) diff --git a/src/components/center/CreateCenterModal.tsx b/src/components/center/CreateCenterModal.tsx index 5e9d3c8c..7d5d7945 100644 --- a/src/components/center/CreateCenterModal.tsx +++ b/src/components/center/CreateCenterModal.tsx @@ -19,6 +19,7 @@ import { GenerateSchemaAndUiSchema } from '../GeneratedSchemas'; import { showToastMessage } from '../Toastify'; import FormButtons from '../FormButtons'; import useSubmittedButtonStore from '@/store/useSubmittedButtonStore'; +import { FormContext, FormContextType } from '@/utils/app.constant'; interface CreateBlockModalProps { open: boolean; @@ -63,7 +64,7 @@ const CreateCenterModal: React.FC = ({ useEffect(() => { const getForm = async () => { try { - const res = await getFormRead('cohorts', 'cohort'); + const res = await getFormRead(FormContext.COHORTS, FormContextType.COHORT); console.log(res); const { schema, uiSchema } = GenerateSchemaAndUiSchema(res, t); console.log(schema, uiSchema); diff --git a/src/pages/centers/index.tsx b/src/pages/centers/index.tsx index 373edd64..61877f11 100644 --- a/src/pages/centers/index.tsx +++ b/src/pages/centers/index.tsx @@ -1,6 +1,17 @@ +import CenterList from '@/components/center/centerList'; +import CreateCenterModal from '@/components/center/CreateCenterModal'; +import Header from '@/components/Header'; +import Loader from '@/components/Loader'; +import ManageUser from '@/components/ManageUser'; +import { showToastMessage } from '@/components/Toastify'; import { getCohortList } from '@/services/CohortServices'; +import useStore from '@/store/store'; +import { CenterType, Role } from '@/utils/app.constant'; import { accessGranted, toPascalCase } from '@/utils/Helper'; import { ICohort } from '@/utils/Interfaces'; +import { ArrowDropDown, Clear, Search } from '@mui/icons-material'; +import AddIcon from '@mui/icons-material/Add'; +import ChevronRightIcon from '@mui/icons-material/ChevronRight'; import { Box, Button, @@ -12,28 +23,16 @@ import { Tabs, TextField, } from '@mui/material'; -import React, { useEffect, useState } from 'react'; -import FilterModalCenter from '../blocks/components/FilterModalCenter'; -import CenterList from '@/components/center/centerList'; -import Header from '@/components/Header'; -import Loader from '@/components/Loader'; -import ManageUser from '@/components/ManageUser'; -import { showToastMessage } from '@/components/Toastify'; -import CreateCenterModal from '@/components/center/CreateCenterModal'; -import useStore from '@/store/store'; -import { CenterType, Role, Status } from '@/utils/app.constant'; -import { ArrowDropDown, Clear, Search } from '@mui/icons-material'; -import AddIcon from '@mui/icons-material/Add'; -import ChevronRightIcon from '@mui/icons-material/ChevronRight'; -import SmartDisplayOutlinedIcon from '@mui/icons-material/SmartDisplayOutlined'; import { useTheme } from '@mui/material/styles'; import { useTranslation } from 'next-i18next'; import { serverSideTranslations } from 'next-i18next/serverSideTranslations'; import Image from 'next/image'; import { useRouter } from 'next/router'; +import React, { useEffect, useState } from 'react'; import { setTimeout } from 'timers'; import { accessControl } from '../../../app.config'; import building from '../../assets/images/apartment.png'; +import FilterModalCenter from '../blocks/components/FilterModalCenter'; const CentersPage = () => { const [loading, setLoading] = useState(false); @@ -97,11 +96,10 @@ const CentersPage = () => { userId && accessGranted('showBlockLevelCohort', accessControl, userRole) ) { - let response = await getCohortList(userId, { + const response = await getCohortList(userId, { customField: 'true', }); - const blockData = response.map((block: any) => { const blockName = block.cohortName; const blockId = block.cohortId; @@ -391,11 +389,13 @@ const CentersPage = () => { )} - + {openCreateCenterModal && ( + + )} {accessGranted( 'showBlockLevelCenterData', diff --git a/src/pages/learner/[userId].tsx b/src/pages/learner/[userId].tsx index c1bdb75b..14025f07 100644 --- a/src/pages/learner/[userId].tsx +++ b/src/pages/learner/[userId].tsx @@ -216,9 +216,8 @@ const LearnerProfile: React.FC = ({ const fetchDataAndInitializeForm = async () => { try { - let formFields; const response = await getUserDetails(userId, true); - formFields = await getFormRead('USERS', 'STUDENT'); + const formFields = await getFormRead(FormContext.USERS, FormContextType.STUDENT); console.log('response', response); console.log('formFields', formFields); setFormData(mapFields(formFields, response?.result)); diff --git a/src/pages/user-profile/[userId].tsx b/src/pages/user-profile/[userId].tsx index 7abd317a..3f02ae2b 100644 --- a/src/pages/user-profile/[userId].tsx +++ b/src/pages/user-profile/[userId].tsx @@ -178,9 +178,8 @@ const TeacherProfile: React.FC = ({ const fetchDataAndInitializeForm = async () => { try { - let formFields; const response = await getUserDetails(userId, true); - formFields = await getFormRead('USERS', 'TEACHER'); + const formFields = await getFormRead(FormContext.USERS, FormContextType.TEACHER); console.log('response', response); console.log('formFields', formFields); setUserFormData(mapFields(formFields, response?.result)); diff --git a/src/utils/app.constant.ts b/src/utils/app.constant.ts index 88d6a1c9..353d94e3 100644 --- a/src/utils/app.constant.ts +++ b/src/utils/app.constant.ts @@ -72,12 +72,14 @@ export enum cohortPrivileges { export enum FormContext { USERS = 'USERS', + COHORTS = 'COHORTS', } export enum FormContextType { STUDENT = 'STUDENT', TEACHER = 'TEACHER', TEAM_LEADER = 'TEAM LEADER', + COHORT= 'COHORT', } export enum CenterType { From 863fed3cc84afa909a5e8a7a312991134aeccde4 Mon Sep 17 00:00:00 2001 From: ttpl-rt-214 Date: Tue, 27 Aug 2024 16:07:26 +0530 Subject: [PATCH 17/34] #PS-1769 Course Planner bottom drawer desktop view UI --- src/components/FormButtons.tsx | 3 ++- src/components/PieChartGraph.tsx | 4 ++-- src/components/SimpleModal.tsx | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/components/FormButtons.tsx b/src/components/FormButtons.tsx index f4dcc0c9..d8afbd5c 100644 --- a/src/components/FormButtons.tsx +++ b/src/components/FormButtons.tsx @@ -37,11 +37,12 @@ const FormButtons: React.FC = ({ {!isSingleButton && !isCreateCentered && !isCreatedFacilitator && ( diff --git a/src/components/PieChartGraph.tsx b/src/components/PieChartGraph.tsx index 7b1122a5..2ffb5c3d 100644 --- a/src/components/PieChartGraph.tsx +++ b/src/components/PieChartGraph.tsx @@ -89,7 +89,7 @@ const PieChartGraph = () => { align="right" verticalAlign="middle" formatter={renderLegendText} - iconType="circle" // Change this line to make the legend icon circular + iconType="circle" /> ) : ( { align="center" verticalAlign="bottom" formatter={renderLegendText} - iconType="circle" // Change this line to make the legend icon circular + iconType="circle" /> )} diff --git a/src/components/SimpleModal.tsx b/src/components/SimpleModal.tsx index 2bea3cc9..64f06bac 100644 --- a/src/components/SimpleModal.tsx +++ b/src/components/SimpleModal.tsx @@ -85,13 +85,13 @@ const SimpleModal: React.FC = ({ - + {children} {showFooter ? ( - + {secondaryText && ( diff --git a/src/components/PieChartGraph.tsx b/src/components/PieChartGraph.tsx index 2ffb5c3d..9d78ba98 100644 --- a/src/components/PieChartGraph.tsx +++ b/src/components/PieChartGraph.tsx @@ -14,9 +14,9 @@ const PieChartGraph = () => { const theme = useTheme(); const data: DataItem[] = [ { name: t('ASSESSMENTS.NOT_STARTED'), value: 4 }, - { name: t('BOARD_ENROOLMENT.BOARD_SELECTION'), value: 5 }, - { name: t('BOARD_ENROOLMENT.SUBJECTS_SELECTION'), value: 10 }, - { name: t('BOARD_ENROOLMENT.REGISTRATION_COMPLETED'), value: 5 }, + { name: t('BOARD_ENROLMENT.BOARD_SELECTION'), value: 5 }, + { name: t('BOARD_ENROLMENT.SUBJECTS_SELECTION'), value: 10 }, + { name: t('BOARD_ENROLMENT.REGISTRATION_COMPLETED'), value: 5 }, ]; diff --git a/src/components/center/DeleteCenterModal.tsx b/src/components/center/DeleteCenterModal.tsx index a90ae39c..4e97e9ef 100644 --- a/src/components/center/DeleteCenterModal.tsx +++ b/src/components/center/DeleteCenterModal.tsx @@ -1,15 +1,6 @@ -import { - Box, - Button, - Divider, - Fade, - Modal, - Radio, - Typography -} from '@mui/material'; -import { styled, useTheme } from '@mui/material/styles'; import { useTranslation } from 'next-i18next'; import React from 'react'; +import ConfirmationModal from '../ConfirmationModal'; import { showToastMessage } from '../Toastify'; interface CreateBlockModalProps { @@ -17,19 +8,11 @@ interface CreateBlockModalProps { handleClose: () => void; } -const CustomRadio = styled(Radio)(({ theme }) => ({ - color: theme.palette.text.primary, - '&.Mui-checked': { - color: theme.palette.text.primary, - }, -})); - const DeleteCenterModal: React.FC = ({ open, handleClose, }) => { const { t } = useTranslation(); - const theme = useTheme(); const handleDeleteButtonClick = () => { console.log('Delete request sent'); @@ -38,70 +21,16 @@ const DeleteCenterModal: React.FC = ({ }; return ( - - - - - {t('CENTERS.YOU_ARE_SENDING_REQUEST_TO_THE_STATE_ADMIN')} - - - - - - - - - + handleDeleteButtonClick} + modalOpen={open} + /> ); }; diff --git a/src/components/center/RenameCenterModal.tsx b/src/components/center/RenameCenterModal.tsx index 1bab7ca9..c5c93b03 100644 --- a/src/components/center/RenameCenterModal.tsx +++ b/src/components/center/RenameCenterModal.tsx @@ -5,12 +5,13 @@ import { Button, Divider, Fade, + FormHelperText, IconButton, Modal, TextField, - Typography + Typography, } from '@mui/material'; -import { styled, useTheme } from '@mui/material/styles'; +import { useTheme } from '@mui/material/styles'; import { useTranslation } from 'next-i18next'; import { useRouter } from 'next/router'; import React, { useState } from 'react'; @@ -18,9 +19,10 @@ import { showToastMessage } from '../Toastify'; interface CreateBlockModalProps { open: boolean; - handleClose: () => void; + handleClose: (name: string) => void; reloadState: boolean; setReloadState: React.Dispatch>; + name?: string; } const RenameCenterModal: React.FC = ({ @@ -28,15 +30,16 @@ const RenameCenterModal: React.FC = ({ handleClose, reloadState, setReloadState, + name, }) => { const router = useRouter(); const { t } = useTranslation(); const theme = useTheme(); - const { cohortId }: any = router.query; + const [centerName, setCenterName] = useState(name ?? ''); + const [error, setError] = useState(false); - const [centerName, setCenterName] = useState(''); - const [error, setError] = useState(''); + const pattern = /^[a-zA-Z ]*$/; React.useEffect(() => { if (reloadState) { @@ -48,29 +51,26 @@ const RenameCenterModal: React.FC = ({ event: React.ChangeEvent ) => { const value = event.target.value; - setCenterName(value); - if (!value.trim()) { - setError(t('CENTERS.ERROR_EMPTY')); - } else if (!isNaN(Number(value))) { - setError(t('CENTERS.ERROR_NUMBER')); + console.log('value', event); + // Validate against the pattern + if (!pattern.test(value.trim())) { + setError(true); } else { - setError(''); + setError(false); } + setCenterName(value); }; const handleCreateButtonClick = async () => { if (error) return; console.log('Entered Rename Name:', centerName); - - const name = centerName; - - const response = await renameFacilitator(cohortId, name); + const name = centerName.trim(); + await renameFacilitator(cohortId, name); setReloadState(true); showToastMessage(t('CENTERS.CENTER_RENAMED'), 'success'); - - handleClose(); + handleClose(name); }; return ( @@ -117,6 +117,7 @@ const RenameCenterModal: React.FC = ({ = ({ value={centerName} onChange={handleTextFieldChange} error={!!error} - helperText={error} + inputProps={{ pattern: pattern }} /> {t('CENTERS.NOTE')} + {error && ( + + {t('FORM_ERROR_MESSAGES.ENTER_VALID_CENTER_NAME')} + + )} */} - - - {/* { - router.push('/attendance-overview'); - }} - > - {t('COMMON.REVIEW_ATTENDANCE')} - */} - {/* */} - - - - + + )} From aa76a2df63a2b1e9d782d7765dfd31776f2caa8b Mon Sep 17 00:00:00 2001 From: vivek kasture Date: Tue, 27 Aug 2024 19:27:24 +0530 Subject: [PATCH 24/34] Issue #PS-000 feat: Bug fixes --- src/components/center/RenameCenterModal.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/center/RenameCenterModal.tsx b/src/components/center/RenameCenterModal.tsx index c5c93b03..e37c5df3 100644 --- a/src/components/center/RenameCenterModal.tsx +++ b/src/components/center/RenameCenterModal.tsx @@ -74,7 +74,7 @@ const RenameCenterModal: React.FC = ({ }; return ( - + handleClose('')} closeAfterTransition> = ({ {t('CENTERS.RENAME_CENTER')} handleClose('')} sx={{ color: theme?.palette?.text?.primary }} > From db7dd5164fd1ba4509c9469dc34e0da06ef44944 Mon Sep 17 00:00:00 2001 From: vivek kasture Date: Tue, 27 Aug 2024 20:50:28 +0530 Subject: [PATCH 25/34] Issue #PS-000 feat: Bug fixes --- app.config.ts | 8 + src/components/CohortSelectionSection.tsx | 12 - src/components/ConfirmationModal.tsx | 4 +- src/components/ManageUser.tsx | 828 ++++++++---------- src/pages/assessments/index.tsx | 5 +- src/pages/assessments/user/[userId]/index.tsx | 5 +- src/pages/dashboard.tsx | 5 +- src/pages/learner/[userId].tsx | 4 +- src/pages/user-profile/[userId].tsx | 262 ++---- 9 files changed, 463 insertions(+), 670 deletions(-) diff --git a/app.config.ts b/app.config.ts index aaeaff03..f9701776 100644 --- a/app.config.ts +++ b/app.config.ts @@ -63,3 +63,11 @@ export const DaysOfWeek = { Fri: 5, Sat: 6, }; + +export const Program = "Second chance"; + +export enum AssessmentType { + PRE_TEST = 'Pre Test', + POST_TEST = 'Post Test', +} + diff --git a/src/components/CohortSelectionSection.tsx b/src/components/CohortSelectionSection.tsx index c34536ae..3f752ae5 100644 --- a/src/components/CohortSelectionSection.tsx +++ b/src/components/CohortSelectionSection.tsx @@ -332,18 +332,6 @@ const CohortSelectionSection: React.FC = ({ // ---------- set cohortId and stateName----------- const cohort_id = event.target.value; localStorage.setItem('cohortId', cohort_id); - - const get_state_name: string | null = getStateByCohortId(cohort_id); - if (get_state_name) { - localStorage.setItem('stateName', get_state_name); - } else { - localStorage.setItem('stateName', ''); - console.log('NO State For Selected Cohort'); - } - function getStateByCohortId(cohortId: any) { - const cohort = cohortsData?.find((item) => item.cohortId === cohortId); - return cohort ? cohort?.state : null; - } }; const isAttendanceOverview = pathname === '/attendance-overview'; diff --git a/src/components/ConfirmationModal.tsx b/src/components/ConfirmationModal.tsx index 943e08b0..e227b5c1 100644 --- a/src/components/ConfirmationModal.tsx +++ b/src/components/ConfirmationModal.tsx @@ -26,7 +26,7 @@ const ConfirmationModal: React.FC = ({ buttonNames, handleCloseModal, }) => { - const theme = useTheme(); + const theme = useTheme(); const style = { position: 'absolute', @@ -50,7 +50,7 @@ const ConfirmationModal: React.FC = ({ aria-describedby="confirmation-modal-description" > - + {message} diff --git a/src/components/ManageUser.tsx b/src/components/ManageUser.tsx index 92013110..07ef186f 100644 --- a/src/components/ManageUser.tsx +++ b/src/components/ManageUser.tsx @@ -1,5 +1,5 @@ import { Button, Grid, Typography } from '@mui/material'; -import React, { useState, useEffect } from 'react'; +import React, { useEffect, useState } from 'react'; import BottomDrawer from '@/components/BottomDrawer'; import ConfirmationModal from '@/components/ConfirmationModal'; @@ -7,31 +7,29 @@ import ManageCentersModal from '@/components/ManageCentersModal'; import ManageUsersModal from '@/components/ManageUsersModal'; import { showToastMessage } from '@/components/Toastify'; import { cohortList, getCohortList } from '@/services/CohortServices'; +import { getMyUserList } from '@/services/MyClassDetailsService'; +import reassignLearnerStore from '@/store/reassignLearnerStore'; +import useStore from '@/store/store'; import { Role, Status } from '@/utils/app.constant'; import AddIcon from '@mui/icons-material/Add'; -import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline'; import ApartmentIcon from '@mui/icons-material/Apartment'; +import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline'; import LocationOnOutlinedIcon from '@mui/icons-material/LocationOnOutlined'; import MoreVertIcon from '@mui/icons-material/MoreVert'; +import { useMediaQuery } from '@mui/material'; import Box from '@mui/material/Box'; import { useTheme } from '@mui/material/styles'; import { styled } from '@mui/system'; import { useTranslation } from 'next-i18next'; import Link from 'next/link'; import { useRouter } from 'next/router'; +import { setTimeout } from 'timers'; import manageUserStore from '../store/manageUserStore'; -import useStore from '@/store/store'; -import { getMyUserList } from '@/services/MyClassDetailsService'; -import reassignLearnerStore from '@/store/reassignLearnerStore'; -import Image from 'next/image'; -import profileALT from '../assets/images/Profile.png'; import AddFacilitatorModal from './AddFacilitator'; import DeleteUserModal from './DeleteUserModal'; +import Loader from './Loader'; import ReassignModal from './ReassignModal'; import SimpleModal from './SimpleModal'; -import { setTimeout } from 'timers'; -import Loader from './Loader'; -import { useMediaQuery } from '@mui/material'; interface Cohort { cohortId: string; @@ -48,15 +46,6 @@ type CohortsData = { [userId: string]: Cohort[]; }; type Anchor = 'bottom'; -interface LearnerDataProps { - name: string; - userId: string; - memberStatus: string; - cohortMembershipId: string; - enrollmentNumber: string; - statusReason: string; - block: string; -} interface ManageUsersProps { reloadState: boolean; @@ -95,9 +84,7 @@ const ManageUser: React.FC = ({ const [selectedUserName, setSelectedUserName] = useState(null); const [centers, setCenters] = useState([]); const [centerList, setCenterList] = useState([]); - const handleChange = (event: React.SyntheticEvent, newValue: number) => { - setValue(newValue); - }; + const [state, setState] = React.useState({ bottom: false, }); @@ -105,9 +92,7 @@ const ManageUser: React.FC = ({ React.useState(false); const [reassignModalOpen, setReassignModalOpen] = React.useState(false); - const [learnerData, setLearnerData] = React.useState(); - const [reassignBlockRequestModalOpen, setReassignBlockRequestModalOpen] = - React.useState(false); + const [openDeleteUserModal, setOpenDeleteUserModal] = React.useState(false); const [isFacilitatorAdded, setIsFacilitatorAdded] = React.useState(false); const [openRemoveUserModal, setOpenRemoveUserModal] = React.useState(false); @@ -216,18 +201,6 @@ const ManageUser: React.FC = ({ getFacilitator(); }, [isFacilitatorAdded, reloadState]); - const handleModalToggle = (user: any) => { - setSelectedUser(user); - setSelectedUserName(user.name); - setCenters(cohortsData?.[user.userId]?.map((cohort) => cohort?.name) || []); - setOpen(true); - // logEvent({ - // action: 'mark/modify-attendance-button-clicked-dashboard', - // category: 'Dashboard Page', - // label: 'Mark/ Modify Attendance', - // }); - }; - const handleClose = () => { setOpen(false); setSelectedUser(null); @@ -249,27 +222,27 @@ const ManageUser: React.FC = ({ const toggleDrawer = (anchor: Anchor, open: boolean, user?: any, teacherUserId?: string) => - (event: React.KeyboardEvent | React.MouseEvent) => { - setCohortDeleteId(isFromFLProfile ? teacherUserId : user.userId); - if (!isFromFLProfile) { - const cohortNamesArray = user?.cohortNames?.split(', '); - const centerNames = cohortNamesArray?.map((cohortName: string) => - cohortName.trim() - ) || [t('ATTENDANCE.N/A')]; - setCenters(centerNames); - setSelectedUser(user); - } + (event: React.KeyboardEvent | React.MouseEvent) => { + setCohortDeleteId(isFromFLProfile ? teacherUserId : user.userId); + if (!isFromFLProfile) { + const cohortNamesArray = user?.cohortNames?.split(', '); + const centerNames = cohortNamesArray?.map((cohortName: string) => + cohortName.trim() + ) || [t('ATTENDANCE.N/A')]; + setCenters(centerNames); + setSelectedUser(user); + } - if ( - event.type === 'keydown' && - ((event as React.KeyboardEvent).key === 'Tab' || - (event as React.KeyboardEvent).key === 'Shift') - ) { - return; - } + if ( + event.type === 'keydown' && + ((event as React.KeyboardEvent).key === 'Tab' || + (event as React.KeyboardEvent).key === 'Shift') + ) { + return; + } - setState({ ...state, bottom: open }); - }; + setState({ ...state, bottom: open }); + }; const listItemClick = async (event: React.MouseEvent, name: string) => { if (name === 'delete-User') { @@ -300,23 +273,6 @@ const ManageUser: React.FC = ({ ); setOpenDeleteUserModal(true); } - - // const name = selectedUser?.name || ''; - // const userId = selectedUser?.userId || ''; - // console.log('user deleted', name, userId); - // try { - // if (userId) { - // const userData = { - // name: name, - // status: Status.ARCHIVED, - // }; - // const response = await editEditUser(userId, { userData }); - // console.log(response); - // } - // } catch (error) { - // console.log(error); - // showToastMessage(t('COMMON.SOMETHING_WENT_WRONG'), 'error'); - // } } if (name === 'reassign-block') { const reassignuserId = isFromFLProfile @@ -428,34 +384,12 @@ const ManageUser: React.FC = ({ ...matchedCohortIdsFromCentersData, ]) ); - - console.log('matchedCohortIds', matchedCohortIds); - console.log('selectedUserIds', selectedUserIds); - - // const response = await assignCentersToFacilitator({ - // userId: selectedUserIds, - // cohortId: matchedCohortIds, - // }); - // console.log(response); - // if (response) { - // centers; - // handleCloseCentersModal(); - // setState({ ...state, bottom: false }); - // } } catch (error) { console.error('Error assigning centers:', error); showToastMessage(t('COMMON.SOMETHING_WENT_WRONG'), 'error'); } }; - const handleReassignBlockRequest = () => { - showToastMessage('Request Send', 'success'); - }; - - const handleReassignBlockRequestCloseModal = () => { - setReassignBlockRequestModalOpen(false); - }; - const handleTeacherFullProfile = (userId: string) => { router.push(`/user-profile/${userId}`); }; @@ -473,7 +407,7 @@ const ManageUser: React.FC = ({ setOpenFacilitatorModal(false); }; - const handleDeleteUser = () => { }; + const handleDeleteUser = () => {}; const handleFacilitatorAdded = () => { setIsFacilitatorAdded((prev) => prev); @@ -483,402 +417,390 @@ const ManageUser: React.FC = ({ }; return (
- - <> - {/*
*/} - - - - - - {value === 1 && ( - <> - {!isFromFLProfile && ( - - - - - - )} - - - {isFromFLProfile ? ( - { - isMobile ? toggleDrawer('bottom', true, teacherUserId)(event) : handleMenuOpen(event) + + {value === 1 && ( + <> + {!isFromFLProfile && ( + + + + + + )} + + + {isFromFLProfile ? ( + { + isMobile + ? toggleDrawer('bottom', true, teacherUserId)(event) + : handleMenuOpen(event); + }} + sx={{ + fontSize: '24px', + marginTop: '1rem', + color: theme.palette.warning['300'], + }} + /> + ) : ( + + - ) : ( - + > - - {loading ? ( - - - - ) : ( - - {users && - users.length !== 0 && - [...users] - .sort((a, b) => a.name.localeCompare(b.name)) - .map((user) => ( - + + + ) : ( + + {users && + users.length !== 0 && + [...users] + .sort((a, b) => a.name.localeCompare(b.name)) + .map((user) => ( + + - - - e.preventDefault()} - > - { - handleTeacherFullProfile( - user.userId! - ); - // ReactGA.event('teacher-details-link-clicked', { - // userId: userId, - // }); - }} - sx={{ - textAlign: 'left', - fontSize: '16px', - fontWeight: '400', - marginTop: '5px', - color: - theme.palette.secondary.main, - }} - > - {user.name - .charAt(0) - .toUpperCase() + - user.name.slice(1)} - - - + e.preventDefault()} + > + { + handleTeacherFullProfile( + user?.userId + ); + }} sx={{ - backgroundColor: '#FFF8F2', - padding: '5px', - borderRadius: '5px', - fontSize: '12px', - fontWeight: '600', - color: 'black', - marginBottom: '10px', + textAlign: 'left', + fontSize: '16px', + fontWeight: '400', + marginTop: '5px', + color: + theme.palette.secondary.main, }} > - {user?.cohortNames - ? `${user.cohortNames - .charAt(0) - .toUpperCase() + - user.cohortNames.slice(1) + {user.name.charAt(0).toUpperCase() + + user.name.slice(1)} + + + + {user?.cohortNames + ? `${ + user.cohortNames + .charAt(0) + .toUpperCase() + + user.cohortNames.slice(1) }` - : t('ATTENDANCE.N/A')} - + : t('ATTENDANCE.N/A')} - - { - isMobile - ? toggleDrawer( + + + { + isMobile + ? toggleDrawer( 'bottom', true, user )(event) - : handleMenuOpen(event); - }} - sx={{ - fontSize: '24px', - marginTop: '1rem', - color: theme.palette.warning['300'], - }} - /> - + : handleMenuOpen(event); + }} + sx={{ + fontSize: '24px', + marginTop: '1rem', + color: theme.palette.warning['300'], + }} + /> - - ))} - {!users?.length && ( - + + ))} + {!users?.length && ( + + - - {t('COMMON.NO_DATA_FOUND')} - - - )} - - )} - + {t('COMMON.NO_DATA_FOUND')} + + + )} + + )} - )} + + )} - - - ), - name: 'reassign-block', - }, - { - label: t('COMMON.REASSIGN_BLOCKS_REQUEST'), - icon: ( - - ), - name: 'reassign-block-request', - }, - { - label: t('COMMON.DELETE_USER'), - icon: ( - - ), - name: 'delete-User', - }, - ].filter(option => !isFromFLProfile || (option.name !== 'reassign-block' && option.name !== 'reassign-block-request'))} + + + ), + name: 'reassign-block', + }, + { + label: t('COMMON.REASSIGN_BLOCKS_REQUEST'), + icon: ( + + ), + name: 'reassign-block-request', + }, + { + label: t('COMMON.DELETE_USER'), + icon: ( + + ), + name: 'delete-User', + }, + ].filter( + (option) => + !isFromFLProfile || + (option.name !== 'reassign-block' && + option.name !== 'reassign-block-request') + )} + > + + {selectedUser?.name + ? selectedUser.name.charAt(0).toUpperCase() + + selectedUser.name.slice(1) + : ''} + + - {selectedUser?.name - ? selectedUser.name.charAt(0).toUpperCase() + - selectedUser.name.slice(1) - : ''} + {t('COMMON.CENTERS_ASSIGNED', { + block: newStore.block, + })} - - - {t('COMMON.CENTERS_ASSIGNED', { - block: newStore.block, - })} - - - {centers.length > 0 && - centers.map( - ( - name: - | string - | number - | bigint - | boolean - | React.ReactElement< - any, - string | React.JSXElementConstructor - > - | Iterable - | React.ReactPortal - | Promise - | null - | undefined - ) => ( - - ) - )} - + + {centers.length > 0 && + centers.map((name: string) => ( + + ))} - - - - - - - + + + - - + + + + + + + {' '} + + + {t('CENTERS.THE_USER_BELONGS_TO_THE_FOLLOWING_COHORT')}{' '} + {removeCohortNames} +
+ {t('CENTERS.PLEASE_REMOVE_THE_USER_FROM_COHORT')} +
+
+
+ {openAddFacilitatorModal && ( + - - {' '} - - - {t('CENTERS.THE_USER_BELONGS_TO_THE_FOLLOWING_COHORT')}{' '} - {removeCohortNames} -
- {t('CENTERS.PLEASE_REMOVE_THE_USER_FROM_COHORT')} -
-
-
- {openAddFacilitatorModal && ( - - )} - - )} -
- - + )} + + )} +
); }; diff --git a/src/pages/assessments/index.tsx b/src/pages/assessments/index.tsx index 0841e0f9..deaeb8ef 100644 --- a/src/pages/assessments/index.tsx +++ b/src/pages/assessments/index.tsx @@ -32,6 +32,7 @@ import { useTranslation } from 'next-i18next'; import { serverSideTranslations } from 'next-i18next/serverSideTranslations'; import { useRouter } from 'next/router'; import React, { useEffect, useState } from 'react'; +import { AssessmentType, Program } from '../../../app.config'; const Assessments = () => { const theme = useTheme(); @@ -121,10 +122,10 @@ const Assessments = () => { const stateName = localStorage.getItem('stateName'); const filters = { - program: ['Second chance'], + program: [Program], se_boards: [stateName], // subject: [subjects || subject], - assessment1: assessmentType === 'pre' ? 'Pre Test' : 'Post Test', + assessment1: assessmentType === 'pre' ? AssessmentType.PRE_TEST : AssessmentType.POST_TEST, }; try { if (stateName) { diff --git a/src/pages/assessments/user/[userId]/index.tsx b/src/pages/assessments/user/[userId]/index.tsx index d9456561..11502365 100644 --- a/src/pages/assessments/user/[userId]/index.tsx +++ b/src/pages/assessments/user/[userId]/index.tsx @@ -33,6 +33,7 @@ import { useParams, useSearchParams } from 'next/navigation'; import { useRouter } from 'next/router'; import { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; +import { AssessmentType, Program } from '../../../../../app.config'; const statusKeyMap: any = { [AssessmentStatus.COMPLETED]: 'ASSESSMENTS.COMPLETED', @@ -79,10 +80,10 @@ function AssessmentsDetails() { const stateName = localStorage.getItem('stateName'); const filters = { - program: ['Second chance'], + program: [Program], se_boards: [stateName], // subject: [subjects || subject], - assessment1: assessmentType === 'pre' ? 'Pre Test' : 'Post Test', + assessment1: assessmentType === 'pre' ? AssessmentType.PRE_TEST : AssessmentType.POST_TEST, }; try { if (stateName) { diff --git a/src/pages/dashboard.tsx b/src/pages/dashboard.tsx index 9682d21b..c62da367 100644 --- a/src/pages/dashboard.tsx +++ b/src/pages/dashboard.tsx @@ -1041,10 +1041,11 @@ const Dashboard: React.FC = () => { {t('DASHBOARD.MY_TIMETABLE')} diff --git a/src/pages/learner/[userId].tsx b/src/pages/learner/[userId].tsx index 14025f07..97431152 100644 --- a/src/pages/learner/[userId].tsx +++ b/src/pages/learner/[userId].tsx @@ -66,7 +66,7 @@ import { getMenuItems, limit, } from '@/utils/app.constant'; -import { accessControl } from '../../../app.config'; +import { accessControl, Program } from '../../../app.config'; import LearnersListItem from '@/components/LearnersListItem'; import { getMyCohortMemberList } from '@/services/MyClassDetailsService'; import AssessmentReport from '@/components/AssessmentReport'; @@ -444,7 +444,7 @@ const LearnerProfile: React.FC = ({ const stateName: any = address?.split(',')[0]; const filters = { - program: ['Second chance'], + program: [Program], se_boards: [stateName ?? ''], subject: [subjects || subject], assessment1: tests || test, diff --git a/src/pages/user-profile/[userId].tsx b/src/pages/user-profile/[userId].tsx index 3f02ae2b..24c7074b 100644 --- a/src/pages/user-profile/[userId].tsx +++ b/src/pages/user-profile/[userId].tsx @@ -1,44 +1,33 @@ -import { Box, Grid, Typography, useMediaQuery } from '@mui/material'; -import { - ArrowBack as ArrowBackIcon, - East as EastIcon, -} from '@mui/icons-material'; -import { CustomField } from '@/utils/Interfaces'; -import React, { useEffect, useRef, useState } from 'react'; -import { getUserDetails } from '@/services/ProfileService'; -import { useTheme } from '@mui/material/styles'; -import { GetStaticPaths } from 'next'; -import Button from '@mui/material/Button'; -import CreateOutlinedIcon from '@mui/icons-material/CreateOutlined'; +import AddFacilitatorModal from '@/components/AddFacilitator'; import Header from '@/components/Header'; -import Image from 'next/image'; import Loader from '@/components/Loader'; -import PlaceOutlinedIcon from '@mui/icons-material/PlaceOutlined'; -import ReactGA from 'react-ga4'; -import { accessControl } from '../../../app.config'; +import ManageUser from '@/components/ManageUser'; +import { showToastMessage } from '@/components/Toastify'; +import { getFormRead } from '@/services/CreateUserService'; +import { getUserDetails } from '@/services/ProfileService'; +import { useProfileInfo } from '@/services/queries'; +import manageUserStore from '@/store/manageUserStore'; import { - toPascalCase, - mapFieldIdToValue, extractAddress, + mapFieldIdToValue, + toPascalCase, } from '@/utils/Helper'; +import { CustomField } from '@/utils/Interfaces'; +import { FormContext, FormContextType, Role } from '@/utils/app.constant'; import { logEvent } from '@/utils/googleAnalytics'; +import withAccessControl from '@/utils/hoc/withAccessControl'; +import { ArrowBack as ArrowBackIcon } from '@mui/icons-material'; +import CreateOutlinedIcon from '@mui/icons-material/CreateOutlined'; +import { Box, Grid, Typography } from '@mui/material'; +import Button from '@mui/material/Button'; +import { useTheme } from '@mui/material/styles'; +import { GetStaticPaths } from 'next'; +import { useTranslation } from 'next-i18next'; 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 user_placeholder from '../../assets/images/user_placeholder.png'; -import withAccessControl from '@/utils/hoc/withAccessControl'; -import { getFormRead } from '@/services/CreateUserService'; -import { FormContext, FormContextType, Role } from '@/utils/app.constant'; -import manageUserStore from '@/store/manageUserStore'; -// import useStore from '@/store/store'; -import AddFacilitatorModal from '@/components/AddFacilitator'; -import ManageUser from '@/components/ManageUser'; +import React, { useEffect, useState } from 'react'; +import { accessControl } from '../../../app.config'; -interface UserData { - name: string; -} interface TeacherProfileProp { reloadState?: boolean; setReloadState?: React.Dispatch>; @@ -48,28 +37,17 @@ const TeacherProfile: React.FC = ({ reloadState, setReloadState, }) => { - const user_placeholder_img: string = user_placeholder.src; - const { t } = useTranslation(); const router = useRouter(); const { userId }: any = router.query; - // const store = useStore(); - // const userRole = store?.userRole; const userStore = manageUserStore(); - const theme = useTheme(); - const [userData, setUserData] = useState(null); const [userName, setUserName] = useState(null); - const isDesktop = useMediaQuery(theme.breakpoints.up('md')); - const fileInputRef = useRef(null); const [customFieldsData, setCustomFieldsData] = useState([]); - const [loading, setLoading] = useState(false); - const [image, setImage] = useState(user_placeholder_img); const [isAuthenticated, setIsAuthenticated] = React.useState(false); const [address, setAddress] = useState(''); - const [isError, setIsError] = React.useState(false); const [isData, setIsData] = React.useState(false); const [userFormData, setUserFormData] = useState<{ [key: string]: any }>({}); const [openAddLearnerModal, setOpenAddLearnerModal] = React.useState(false); @@ -108,7 +86,7 @@ const TeacherProfile: React.FC = ({ }; const mapFields = (formFields: any, response: any) => { - let initialFormData: any = {}; + const initialFormData: any = {}; formFields.fields.forEach((item: any) => { const userData = response?.userData; const customFieldValue = userData?.customFields?.find( @@ -179,7 +157,10 @@ const TeacherProfile: React.FC = ({ const fetchDataAndInitializeForm = async () => { try { const response = await getUserDetails(userId, true); - const formFields = await getFormRead(FormContext.USERS, FormContextType.TEACHER); + const formFields = await getFormRead( + FormContext.USERS, + FormContextType.TEACHER + ); console.log('response', response); console.log('formFields', formFields); setUserFormData(mapFields(formFields, response?.result)); @@ -189,7 +170,8 @@ const TeacherProfile: React.FC = ({ }; useEffect(() => { - fetchDataAndInitializeForm(); + if (selfUserId && userId && selfUserId === userId) + fetchDataAndInitializeForm(); }, [userId, reload]); useEffect(() => { @@ -209,11 +191,8 @@ const TeacherProfile: React.FC = ({ 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) { @@ -276,9 +255,6 @@ const TeacherProfile: React.FC = ({ console.log(`mergedProfileData`, mergedProfileData); if (mergedProfileData) { setUserData(mergedProfileData?.fields); - // const nameField = mergedProfileData.fields.find( - // (field: { name: string }) => field.name === 'name' - // ); const customDataFields = mergedProfileData?.fields; setIsData(true); @@ -294,9 +270,12 @@ const TeacherProfile: React.FC = ({ console.error('Error fetching form data:', error); } }; - fetchFormData(); + + if (userRole) { + fetchFormData(); + } } - }, [data, error, isLoading]); + }, [data, error, isLoading, userRole]); // Find fields for "Subjects I Teach" and "My Main Subjects" const teachSubjectsField = customFieldsData?.find( @@ -314,15 +293,6 @@ const TeacherProfile: React.FC = ({ ? mainSubjectsField?.value?.split(',') : []; - // Find mutual and remaining subjects - // const mutualSubjects = teachSubjects?.filter((subject) => - // mainSubjects?.includes(subject) - // ); - - // const remainingSubjects = teachSubjects?.filter( - // (subject) => !mainSubjects?.includes(subject) - // ); - const mutualSubjects = teachSubjects && mainSubjects ? teachSubjects.filter((subject) => mainSubjects.includes(subject)) @@ -379,7 +349,7 @@ const TeacherProfile: React.FC = ({ {loading && ( )} - {isData && isData ? ( + {isData ? ( = ({ > = ({ { })} + setReloadState={setReloadState ?? (() => {})} isFromFLProfile={true} teacherUserId={userId} />
)} - - {/* - - user - - - - - {toPascalCase( - userData?.find( - (field: { name: string }) => field.name === 'name' - )?.value - )} - - - - - {address ? ( - - ) : ( - '' - )} - - - {address} - - - - - */} {userRole === Role.TEAM_LEADER && userId !== selfUserId ? ( @@ -604,7 +487,6 @@ const TeacherProfile: React.FC = ({ ) : null} {openAddLearnerModal && ( -
= ({ userId={userId} onReload={handleReload} /> -
)} = ({ border={'1px'} display="flex" flexDirection="row" - > - {filteredSortedForView?.map((item, index) => { + {filteredSortedForView?.map((item) => { if (String(item.order) === '7') { return ( - + = ({ > {orderedSubjects && orderedSubjects.length > 0 && - orderedSubjects.map( - (subject: any, index: number) => { - const isMutualSubject = - mutualSubjects?.includes(subject); - return ( - - ); - } - )} + orderedSubjects.map((subject: any) => { + const isMutualSubject = + mutualSubjects?.includes(subject); + return ( + + ); + })} ); } else if (item.order === 7) { return ( - + = ({ ); } else { return ( - + {/* Profile Field Labels */} = ({ {item?.value ? toPascalCase(getLabelForValue(item, item?.value)) : '-'}{' '} - {/* apply elipses/ truncating here */} ); From 80451f96be86aee85d9511e44ae21480771038c7 Mon Sep 17 00:00:00 2001 From: suvarnakale Date: Wed, 28 Aug 2024 12:37:41 +0530 Subject: [PATCH 26/34] Issue #PS-1625 chore: updatedBy key added --- src/components/PlannedSession.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/PlannedSession.tsx b/src/components/PlannedSession.tsx index ffa60846..d99b3dd3 100644 --- a/src/components/PlannedSession.tsx +++ b/src/components/PlannedSession.tsx @@ -764,6 +764,10 @@ const PlannedSession: React.FC = ({ if (updateEvent && eventData) { console.log('eventData', eventData); try { + const userId = + typeof window !== 'undefined' + ? localStorage.getItem('userId') || '' + : ''; let isMainEvent; if (eventData?.isRecurring === false) { isMainEvent = true; @@ -779,6 +783,7 @@ const PlannedSession: React.FC = ({ const apiBody: any = { isMainEvent: isMainEvent, status: 'live', + updatedBy: userId, }; let startDateTime = sessionBlocks?.[0]?.startDatetime; @@ -788,7 +793,7 @@ const PlannedSession: React.FC = ({ const eventDateTimeDate = new Date(eventData.startDateTime); if (startDateTimeDate.getTime() !== eventDateTimeDate.getTime()) { - apiBody['startDateTime'] = startDateTime; + apiBody['startDatetime'] = startDateTime; } } @@ -798,7 +803,7 @@ const PlannedSession: React.FC = ({ const eventDateTimeDate = new Date(eventData.endDateTime); if (endDateTimeDate.getTime() !== eventDateTimeDate.getTime()) { - apiBody['endDateTime'] = endDateTime; + apiBody['endDatetime'] = endDateTime; } } From c5197d56fb0ffc4eeff70e03a7681edc13b6bfe9 Mon Sep 17 00:00:00 2001 From: suvarnakale Date: Wed, 28 Aug 2024 12:47:38 +0530 Subject: [PATCH 27/34] Issue #PS-1625 chore: updatedBy key added --- src/components/PlannedSession.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/PlannedSession.tsx b/src/components/PlannedSession.tsx index d99b3dd3..385e0150 100644 --- a/src/components/PlannedSession.tsx +++ b/src/components/PlannedSession.tsx @@ -108,7 +108,7 @@ const PlannedSession: React.FC = ({ ); const [subjects, setSubjects] = useState(); const [initialEventData, setInitialEventData] = useState(null); - const [shortDescription, setShortDescription] = useState(); + const [shortDescription, setShortDescription] = useState(''); const [meetingPasscode, setMeetingPasscode] = useState(); const [selectedDays, setSelectedDays] = useState(); const [startDate, setStartDate] = useState(dayjs()); From ed63d72794d105d6abe9dab2a03dada166c0964e Mon Sep 17 00:00:00 2001 From: vivek kasture Date: Wed, 28 Aug 2024 12:49:49 +0530 Subject: [PATCH 28/34] Issue #PS-000 feat: Bug fixes --- src/components/AddLeanerModal.tsx | 166 +++++++++----------- src/components/SimpleModal.tsx | 2 +- src/components/center/CreateCenterModal.tsx | 64 ++++---- src/hooks/useFormRead.ts | 51 ++++++ src/pages/_app.tsx | 4 +- src/pages/user-profile/[userId].tsx | 1 - 6 files changed, 160 insertions(+), 128 deletions(-) create mode 100644 src/hooks/useFormRead.ts diff --git a/src/components/AddLeanerModal.tsx b/src/components/AddLeanerModal.tsx index ed020a5f..92609966 100644 --- a/src/components/AddLeanerModal.tsx +++ b/src/components/AddLeanerModal.tsx @@ -4,23 +4,30 @@ import { customFields, } from '@/components/GeneratedSchemas'; import SimpleModal from '@/components/SimpleModal'; -import { createUser, getFormRead } from '@/services/CreateUserService'; +import { useFormRead } from '@/hooks/useFormRead'; +import { createUser } from '@/services/CreateUserService'; +import { sendCredentialService } from '@/services/NotificationService'; +import { editEditUser } from '@/services/ProfileService'; +import useSubmittedButtonStore from '@/store/useSubmittedButtonStore'; import { generateUsernameAndPassword } from '@/utils/Helper'; -import { FormData } from '@/utils/Interfaces'; -import { FormContext, FormContextType, RoleId, Telemetry } from '@/utils/app.constant'; +import { + FormContext, + FormContextType, + RoleId, + Telemetry, +} from '@/utils/app.constant'; +import { telemetryFactory } from '@/utils/telemetry'; import { IChangeEvent } from '@rjsf/core'; import { RJSFSchema } from '@rjsf/utils'; import React, { useEffect } from 'react'; +import ReactGA from 'react-ga4'; import { useTranslation } from 'react-i18next'; -import { showToastMessage } from './Toastify'; -import { editEditUser } from '@/services/ProfileService'; import { tenantId } from '../../app.config'; -import SendCredentialModal from './SendCredentialModal'; import FormButtons from './FormButtons'; -import { sendCredentialService } from '@/services/NotificationService'; -import useSubmittedButtonStore from '@/store/useSubmittedButtonStore'; -import ReactGA from 'react-ga4'; -import { telemetryFactory } from '@/utils/telemetry'; +import SendCredentialModal from './SendCredentialModal'; +import { showToastMessage } from './Toastify'; +import Loader from './Loader'; +import { Box } from '@mui/material'; interface AddLearnerModalProps { open: boolean; @@ -47,34 +54,28 @@ const AddLearnerModal: React.FC = ({ const [learnerFormData, setLearnerFormData] = React.useState(); const [fullname, setFullname] = React.useState(); + const { + data: formResponse, + isPending, + } = useFormRead(FormContext.USERS, FormContextType.STUDENT); + const { t } = useTranslation(); const setSubmittedButtonStatus = useSubmittedButtonStore( (state: any) => state.setSubmittedButtonStatus ); let userEmail: string = ''; if (typeof window !== 'undefined' && window.localStorage) { - userEmail = localStorage.getItem('userEmail') || ''; + userEmail = localStorage.getItem('userEmail') ?? ''; } - useEffect(() => { - const getAddLearnerFormData = async () => { - try { - const response: FormData = await getFormRead( - FormContext.USERS, - FormContextType.STUDENT - ); - console.log('sortedFields', response); - if (response) { - const { schema, uiSchema } = GenerateSchemaAndUiSchema(response, t); - setSchema(schema); - setUiSchema(uiSchema); - } - } catch (error) { - console.error('Error fetching form data:', error); - } - }; - getAddLearnerFormData(); - }, []); + useEffect(() => { + if (formResponse) { + console.log('formResponse', formResponse); + const { schema, uiSchema } = GenerateSchemaAndUiSchema(formResponse, t); + setSchema(schema); + setUiSchema(uiSchema); + } + }, [formResponse]); const handleSubmit = async ( data: IChangeEvent, @@ -83,21 +84,7 @@ const AddLearnerModal: React.FC = ({ setTimeout(() => { setLearnerFormData(data.formData); }); - const target = event.target as HTMLFormElement; - const elementsArray = Array.from(target.elements); - // for (const element of elementsArray) { - // if ( - // (element instanceof HTMLInputElement || - // element instanceof HTMLSelectElement || - // element instanceof HTMLTextAreaElement) && - // (element.value === '' || - // (Array.isArray(element.value) && element.value.length === 0)) - // ) { - // element.focus(); - // return; - // } - // } console.log('Form data submitted:', data.formData); const formData = data.formData; @@ -154,8 +141,8 @@ const AddLearnerModal: React.FC = ({ } } else { if ( - fieldSchema?.hasOwnProperty('isDropdown') || - fieldSchema.hasOwnProperty('isCheckbox') + Object.hasOwn(fieldSchema, 'isDropdown') || + Object.hasOwn(fieldSchema, 'isCheckbox') ) { apiBody.customFields.push({ fieldId: fieldId, @@ -179,7 +166,6 @@ const AddLearnerModal: React.FC = ({ fieldId: fieldData?.state?.stateId, value: [fieldData?.state?.stateCode], }); - fieldData; apiBody.customFields.push({ fieldId: fieldData?.state?.districtId, value: [fieldData?.state?.districtCode], @@ -240,14 +226,14 @@ const AddLearnerModal: React.FC = ({ const isQueue = false; const context = 'USER'; - let createrName; + let creatorName; const key = 'onLearnerCreated'; if (typeof window !== 'undefined' && window.localStorage) { - createrName = localStorage.getItem('userName'); + creatorName = localStorage.getItem('userName'); } let replacements; - if (createrName) { - replacements = [createrName, apiBody['name'], username, password]; + if (creatorName) { + replacements = [creatorName, apiBody['name'], username, password]; } const sendTo = { receipients: [userEmail], @@ -277,14 +263,12 @@ const AddLearnerModal: React.FC = ({ } } } - // onClose(); } catch (error) { showToastMessage(t('COMMON.SOMETHING_WENT_WRONG'), 'error'); setReloadProfile(true); ReactGA.event('learner-creation-fail', { error: error, }); - } } }; @@ -315,47 +299,41 @@ const AddLearnerModal: React.FC = ({ isEditModal ? t('COMMON.EDIT_LEARNER') : t('COMMON.NEW_LEARNER') } > - {formData - ? schema && - uiSchema && ( - - - - ) - : schema && - uiSchema && ( - - - - )} + {isPending && ( + + + + )} + + {!isPending && schema && uiSchema && ( + + + + )} = ({ {showFooter ? ( - + {secondaryText && ( ) : null} {openAddLearnerModal && ( - + )} { + const replacements = { + '{FirstName}': name, + '{UserName}': username, + '{Password}': password, + }; + + const sendTo = { + receipients: [email], + }; + + return sendCredentialService({ + isQueue: false, + context: 'USER', + key: 'onFacilitatorCreated', + replacements, + email: sendTo, + }); +}; + +export const sendEmailOnLearnerCreation = async ( + name: string, + username: string, + password: string, + email: string, + learnerName: string +) => { + const replacements = { + '{FirstName}': name, + '{UserName}': username, + '{Password}': password, + "{LearnerName}" : learnerName + }; + + const sendTo = { + receipients: [email], + }; + + return sendCredentialService({ + isQueue: false, + context: 'USER', + key: 'onLearnerCreated', + replacements, + email: sendTo, + }); +} diff --git a/src/services/queries.ts b/src/services/queries.ts index 5b64c804..5604a6d8 100644 --- a/src/services/queries.ts +++ b/src/services/queries.ts @@ -6,13 +6,13 @@ import { refetchInterval, gcTime } from '@/utils/app.constant'; export function useProfileInfo( userId: string | string[], fieldValue: boolean, - reload: boolean + // reload: boolean ) { return useQuery({ - queryKey: ['profile', userId, reload], + queryKey: ['profile', userId], queryFn: () => getUserDetails(userId, fieldValue), - refetchInterval: refetchInterval, - gcTime: gcTime, + // refetchInterval: refetchInterval, + staleTime: 1000 * 60 * 60, // 1 hour }); } diff --git a/src/utils/Interfaces.ts b/src/utils/Interfaces.ts index 1dc98cd2..c4e2712e 100644 --- a/src/utils/Interfaces.ts +++ b/src/utils/Interfaces.ts @@ -486,7 +486,7 @@ export interface SendCredentialsRequest { isQueue: boolean; context: string; key: string; - replacements: any[]; + replacements: any; email: { receipients: any[]; }; From 1ba79bbb9b45340a6fb2c0ed8b1b8443c9293021 Mon Sep 17 00:00:00 2001 From: vivek kasture Date: Wed, 28 Aug 2024 20:10:37 +0530 Subject: [PATCH 33/34] Issue #PS-000 feat: Bug fixes --- src/pages/_app.tsx | 11 ++++++++++- src/services/queries.ts | 4 ++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index c45996ab..fddeed01 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -69,7 +69,16 @@ export function DarkTheme() { } function App({ Component, pageProps }: AppProps) { - const [client] = React.useState(new QueryClient()) + const [client] = React.useState(new QueryClient( + { + defaultOptions: { + queries: { + gcTime: 1000 * 60 * 60 * 24, // 24 hours + staleTime: 1000 * 60 * 60 * 24, // 24 hours + }, + }, + } + )) const router = useRouter(); const isFullWidthPage = fullWidthPages.includes(router.pathname); useEffect(() => { diff --git a/src/services/queries.ts b/src/services/queries.ts index 5604a6d8..2b373cc6 100644 --- a/src/services/queries.ts +++ b/src/services/queries.ts @@ -11,7 +11,6 @@ export function useProfileInfo( return useQuery({ queryKey: ['profile', userId], queryFn: () => getUserDetails(userId, fieldValue), - // refetchInterval: refetchInterval, staleTime: 1000 * 60 * 60, // 1 hour }); } @@ -21,6 +20,7 @@ export function useCohortList(limit: any, offset: any, filters: any) { queryKey: ['cohort'], queryFn: () => cohortList({ limit, offset, filters }), refetchInterval: refetchInterval, - gcTime: gcTime, + staleTime: 1000 * 60 * 60, // 1 hour + }); } From 678802c99cf14c0c35757f633abef78bb5220402 Mon Sep 17 00:00:00 2001 From: vivek kasture Date: Thu, 29 Aug 2024 01:53:00 +0530 Subject: [PATCH 34/34] Issue #PS-000 feat: Used tanstack query --- src/components/AddFacilitator.tsx | 6 +++++ src/components/CohortSelectionSection.tsx | 3 ++- src/components/ManageUser.tsx | 20 ++++++++++++--- src/pages/assessments/index.tsx | 25 +++++++++++-------- src/pages/assessments/user/[userId]/index.tsx | 12 ++++++--- src/services/queries.ts | 2 +- src/utils/app.constant.ts | 6 +++++ 7 files changed, 54 insertions(+), 20 deletions(-) diff --git a/src/components/AddFacilitator.tsx b/src/components/AddFacilitator.tsx index 8f68d0c9..16f8845e 100644 --- a/src/components/AddFacilitator.tsx +++ b/src/components/AddFacilitator.tsx @@ -5,6 +5,7 @@ import { import { FormContext, FormContextType, + QueryKeys, RoleId, Telemetry, } from '@/utils/app.constant'; @@ -38,6 +39,7 @@ import { useTranslation } from 'next-i18next'; import { tenantId } from '../../app.config'; import FormButtons from './FormButtons'; import { showToastMessage } from './Toastify'; +import { useQueryClient } from '@tanstack/react-query'; interface AddFacilitatorModalprops { open: boolean; onClose: () => void; @@ -61,6 +63,7 @@ const AddFacilitatorModal: React.FC = ({ const [createFacilitator, setCreateFacilitator] = React.useState(false); const [isVisible, setIsVisible] = React.useState(true); const [uiSchema, setUiSchema] = React.useState(); + const queryClient = useQueryClient(); const [reloadProfile, setReloadProfile] = React.useState(false); const [email, setEmail] = React.useState(''); const [formData, setFormData] = React.useState(); @@ -287,6 +290,7 @@ const AddFacilitatorModal: React.FC = ({ ); setReloadProfile(true); onReload?.(); + queryClient.invalidateQueries({ queryKey: [QueryKeys.GET_ACTIVE_FACILITATOR] }); } onClose(); } else { @@ -299,6 +303,8 @@ const AddFacilitatorModal: React.FC = ({ if (response) { onFacilitatorAdded?.(); onClose(); + queryClient.invalidateQueries({ queryKey: [QueryKeys.GET_ACTIVE_FACILITATOR] }); + queryClient.invalidateQueries({ queryKey: [QueryKeys.MY_COHORTS, userId] }); showToastMessage( t('COMMON.FACILITATOR_ADDED_SUCCESSFULLY'), 'success' diff --git a/src/components/CohortSelectionSection.tsx b/src/components/CohortSelectionSection.tsx index 3f752ae5..ff8a7a76 100644 --- a/src/components/CohortSelectionSection.tsx +++ b/src/components/CohortSelectionSection.tsx @@ -28,6 +28,7 @@ import { showToastMessage } from './Toastify'; import manageUserStore from '@/store/manageUserStore'; import { ArrowDropDownIcon } from '@mui/x-date-pickers/icons'; import { telemetryFactory } from '@/utils/telemetry'; +import { toPascalCase } from '@/utils/Helper'; interface CohortSelectionSectionProps { classId: string; @@ -424,7 +425,7 @@ const CohortSelectionSection: React.FC = ({ ) : ( - {cohortsData[0]?.name} + {toPascalCase(cohortsData[0]?.name)} )} diff --git a/src/components/ManageUser.tsx b/src/components/ManageUser.tsx index 07ef186f..22543ce9 100644 --- a/src/components/ManageUser.tsx +++ b/src/components/ManageUser.tsx @@ -10,7 +10,7 @@ import { cohortList, getCohortList } from '@/services/CohortServices'; import { getMyUserList } from '@/services/MyClassDetailsService'; import reassignLearnerStore from '@/store/reassignLearnerStore'; import useStore from '@/store/store'; -import { Role, Status } from '@/utils/app.constant'; +import { QueryKeys, Role, Status } from '@/utils/app.constant'; import AddIcon from '@mui/icons-material/Add'; import ApartmentIcon from '@mui/icons-material/Apartment'; import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline'; @@ -30,6 +30,7 @@ import DeleteUserModal from './DeleteUserModal'; import Loader from './Loader'; import ReassignModal from './ReassignModal'; import SimpleModal from './SimpleModal'; +import { useQueryClient } from '@tanstack/react-query'; interface Cohort { cohortId: string; @@ -67,6 +68,8 @@ const ManageUser: React.FC = ({ const router = useRouter(); const store = manageUserStore(); const newStore = useStore(); + const queryClient = useQueryClient(); + const [value, setValue] = React.useState(1); const [users, setUsers] = useState< { @@ -141,7 +144,12 @@ const ManageUser: React.FC = ({ }; const fields = ['age']; - const resp = await getMyUserList({ limit, page, filters, fields }); + // const resp = await getMyUserList({ limit, page, filters, fields }); + const resp = await queryClient.fetchQuery({ + queryKey: [QueryKeys.GET_ACTIVE_FACILITATOR, filters], + queryFn: () => getMyUserList({ limit, page, filters, fields }), + }); + const facilitatorList = resp.result?.getUserDetails; if (!facilitatorList || facilitatorList?.length === 0) { @@ -150,9 +158,13 @@ const ManageUser: React.FC = ({ } const userIds = facilitatorList?.map((user: any) => user.userId); - const cohortDetailsPromises = userIds?.map((userId: string) => - getCohortList(userId, { filter: 'true' }) + const cohortDetailsPromises = userIds.map((userId: string) => + queryClient.fetchQuery({ + queryKey: [QueryKeys.MY_COHORTS, userId], + queryFn: () => getCohortList(userId, { filter: 'true' }), + }) ); + const cohortDetailsResults = await Promise.allSettled( cohortDetailsPromises ); diff --git a/src/pages/assessments/index.tsx b/src/pages/assessments/index.tsx index deaeb8ef..f4586c9c 100644 --- a/src/pages/assessments/index.tsx +++ b/src/pages/assessments/index.tsx @@ -33,10 +33,12 @@ import { serverSideTranslations } from 'next-i18next/serverSideTranslations'; import { useRouter } from 'next/router'; import React, { useEffect, useState } from 'react'; import { AssessmentType, Program } from '../../../app.config'; +import { useQueryClient } from '@tanstack/react-query'; const Assessments = () => { const theme = useTheme(); const router = useRouter(); + const queryClient = useQueryClient(); const { t } = useTranslation(); const [modalOpen, setModalOpen] = useState(false); @@ -95,9 +97,6 @@ const Assessments = () => { ...user, name: toPascalCase(user.name), userId: user.userId, - // percentageString: '0%', - // percentage: 0, - // status: 'Not_Started', })); console.log(`userDetails`, userDetails); setCohortMembers(userDetails); @@ -125,7 +124,10 @@ const Assessments = () => { program: [Program], se_boards: [stateName], // subject: [subjects || subject], - assessment1: assessmentType === 'pre' ? AssessmentType.PRE_TEST : AssessmentType.POST_TEST, + assessment1: + assessmentType === 'pre' + ? AssessmentType.PRE_TEST + : AssessmentType.POST_TEST, }; try { if (stateName) { @@ -134,8 +136,10 @@ const Assessments = () => { setLearnerList([]); setFilteredLearnerList([]); setAssessmentList([]); - const searchResults = await getDoIdForAssessmentDetails({ - filters, + + const searchResults = await queryClient.fetchQuery({ + queryKey: ['contentSearch', { filters }], + queryFn: () => getDoIdForAssessmentDetails({ filters }), }); if (searchResults?.responseCode === 'OK') { @@ -317,7 +321,8 @@ const Assessments = () => { case AssessmentStatus.COMPLETED: return ( - {t('ASSESSMENTS.OVERALL_SCORE')}: {percentage}% + {t('ASSESSMENTS.OVERALL_SCORE')}:{' '} + {percentage}% ); default: @@ -595,9 +600,9 @@ const Assessments = () => {
)} - {!isLoading && !filteredLearnerList?.length && !!assessmentList?.length && ( - - )} + {!isLoading && + !filteredLearnerList?.length && + !!assessmentList?.length && } (); @@ -92,10 +94,12 @@ function AssessmentsDetails() { setAssessmentList([]); setSubject([]); setAssessmentInfo({}); - const searchResults = await getDoIdForAssessmentDetails({ - filters, - }); + + const searchResults = await queryClient.fetchQuery({ + queryKey: ['contentSearch', { filters }], + queryFn: () => getDoIdForAssessmentDetails({ filters }), + }); if (searchResults?.responseCode === 'OK') { const result = searchResults?.result; if (result) { @@ -203,7 +207,7 @@ function AssessmentsDetails() { useEffect(() => { const getUserInfo = async () => { try { - const response = await getUserDetails(params.userId); + const response = await queryClient.fetchQuery({ queryKey: ['userRead', params.userId], queryFn: () => getUserDetails(params.userId) }); console.log('response', response); if (response?.result?.userData) { setUserDetails(response?.result?.userData); diff --git a/src/services/queries.ts b/src/services/queries.ts index 2b373cc6..deae2426 100644 --- a/src/services/queries.ts +++ b/src/services/queries.ts @@ -1,7 +1,7 @@ import { useQuery } from '@tanstack/react-query'; import { getUserDetails } from './ProfileService'; import { cohortList } from './CohortServices'; -import { refetchInterval, gcTime } from '@/utils/app.constant'; +import { refetchInterval } from '@/utils/app.constant'; export function useProfileInfo( userId: string | string[], diff --git a/src/utils/app.constant.ts b/src/utils/app.constant.ts index 353d94e3..e8569272 100644 --- a/src/utils/app.constant.ts +++ b/src/utils/app.constant.ts @@ -111,4 +111,10 @@ export enum AssessmentStatus { NOT_STARTED = 'Not_Started', IN_PROGRESS = 'In_Progress', COMPLETED = 'Completed', +} + + +export enum QueryKeys { + GET_ACTIVE_FACILITATOR = 'getActiveFacilitatorList', + MY_COHORTS = 'myCohorts', } \ No newline at end of file