From 12ac94c6541e71b1e238fa44509c99ef917c2763 Mon Sep 17 00:00:00 2001 From: suvarnakale Date: Tue, 27 Aug 2024 17:54:03 +0530 Subject: [PATCH 01/17] Issue #PS-1625 chore: solved build issues --- src/components/PlannedSession.tsx | 25 +++++++++++++++---------- src/components/SessionCard.tsx | 1 + 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/components/PlannedSession.tsx b/src/components/PlannedSession.tsx index 60aa6324..bf5a39f3 100644 --- a/src/components/PlannedSession.tsx +++ b/src/components/PlannedSession.tsx @@ -768,19 +768,24 @@ const PlannedSession: React.FC = ({ }; let startDateTime = sessionBlocks?.[0]?.startDatetime; - if ( - new Date(eventData?.startDateTime).getTime() !== - new Date(startDateTime).getTime() - ) { - apiBody['startDateTime'] = startDateTime; + + if (startDateTime && eventData?.startDateTime) { + const startDateTimeDate = new Date(startDateTime); + const eventDateTimeDate = new Date(eventData.startDateTime); + + if (startDateTimeDate.getTime() !== eventDateTimeDate.getTime()) { + apiBody['startDateTime'] = startDateTime; + } } let endDateTime = sessionBlocks?.[0]?.endDatetime; - if ( - new Date(eventData?.endDateTime).getTime() !== - new Date(endDateTime).getTime() - ) { - apiBody['endDateTime'] = endDateTime; + if (endDateTime && eventData?.endDateTime) { + const endDateTimeDate = new Date(endDateTime); + const eventDateTimeDate = new Date(eventData.endDateTime); + + if (endDateTimeDate.getTime() !== eventDateTimeDate.getTime()) { + apiBody['endDateTime'] = endDateTime; + } } const metadata = { diff --git a/src/components/SessionCard.tsx b/src/components/SessionCard.tsx index f0bdc1c9..e24780ed 100644 --- a/src/components/SessionCard.tsx +++ b/src/components/SessionCard.tsx @@ -10,6 +10,7 @@ import { useTranslation } from 'next-i18next'; import React, { useEffect } from 'react'; import CenterSessionModal from './CenterSessionModal'; import PlannedSession from './PlannedSession'; +import ConfirmationModal from './ConfirmationModal'; const SessionsCard: React.FC = ({ data, From 69c4f29e7b3e99853b8f865742e3bb9a85f826a0 Mon Sep 17 00:00:00 2001 From: suvarnakale Date: Tue, 27 Aug 2024 19:03:35 +0530 Subject: [PATCH 02/17] Issue #PS-1625 chore: list api called on event edit --- public/locales/en/common.json | 8 +++++--- src/components/PlannedSession.tsx | 25 +++++++++++++++++++++---- src/components/SessionCard.tsx | 9 +++++++++ src/pages/centers/[cohortId]/index.tsx | 22 +++++++++++++++++----- 4 files changed, 52 insertions(+), 12 deletions(-) diff --git a/public/locales/en/common.json b/public/locales/en/common.json index eea9c919..889dbd4e 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -379,7 +379,9 @@ "DELETE_ALL_SESSION_MSG": "Are you sure you want to delete all sessions in this series?", "DELETE_THIS_SESSION": "Delete this session", "DELETE_FOLLOWING_SESSION": "Delete this and following sessions", - "UPDATE_CHANGES": "Are you sure you want to update the changes?" + "UPDATE_CHANGES": "Are you sure you want to update the changes?", + "SESSION_DELETED_SUCCESSFULLY": "Session deleted successfully", + "SESSION_EDITED_SUCCESSFULLY": "Session updated successfully" }, "MANAGE_USERS": { "CENTERS_REQUESTED_SUCCESSFULLY": "Center Requested Successfully", @@ -514,8 +516,8 @@ }, "BOARD_ENROOLMENT": { "BOARD_ENROLLMENT": "Board Enrollment", - "BOARD_SELECTION":"Board Selection", + "BOARD_SELECTION": "Board Selection", "SUBJECTS_SELECTION": "Subjects Selection", - "REGISTRATION_COMPLETED":"Registration Completed" + "REGISTRATION_COMPLETED": "Registration Completed" } } diff --git a/src/components/PlannedSession.tsx b/src/components/PlannedSession.tsx index bf5a39f3..ffa60846 100644 --- a/src/components/PlannedSession.tsx +++ b/src/components/PlannedSession.tsx @@ -90,6 +90,7 @@ const PlannedSession: React.FC = ({ onEventDeleted, eventData, updateEvent, + onEventUpdated, }) => { const { t } = useTranslation(); const theme = useTheme(); @@ -743,7 +744,10 @@ const PlannedSession: React.FC = ({ }; const response = await editEvent(eventRepetitionId, apiBody); if (response?.responseCode === 'OK') { - showToastMessage(t('COMMON.SESSION_DELETED_SUCCESSFULLY'), 'success'); + showToastMessage( + t('CENTER_SESSION.SESSION_DELETED_SUCCESSFULLY'), + 'success' + ); } else { showToastMessage(t('COMMON.SOMETHING_WENT_WRONG'), 'error'); } @@ -760,7 +764,17 @@ const PlannedSession: React.FC = ({ if (updateEvent && eventData) { console.log('eventData', eventData); try { - const isMainEvent = true; + let isMainEvent; + if (eventData?.isRecurring === false) { + isMainEvent = true; + } + if (eventData?.isRecurring === true) { + if (editSelection === t('CENTER_SESSION.EDIT_THIS_SESSION')) { + isMainEvent = false; + } else { + isMainEvent = true; + } + } const eventRepetitionId = eventData?.eventRepetitionId; const apiBody: any = { isMainEvent: isMainEvent, @@ -860,9 +874,12 @@ const PlannedSession: React.FC = ({ const response = await editEvent(eventRepetitionId, apiBody); if (response?.responseCode === 'OK') { showToastMessage( - t('COMMON.SESSION_EDITED_SUCCESSFULLY'), + t('CENTER_SESSION.SESSION_EDITED_SUCCESSFULLY'), 'success' ); + if (onEventUpdated) { + onEventUpdated(); + } } else { showToastMessage(t('COMMON.SOMETHING_WENT_WRONG'), 'error'); } @@ -872,7 +889,7 @@ const PlannedSession: React.FC = ({ } }; onUpdateEvent(); - }, [updateEvent, eventData, sessionBlocks]); + }, [updateEvent]); return ( diff --git a/src/components/SessionCard.tsx b/src/components/SessionCard.tsx index e24780ed..bed87f54 100644 --- a/src/components/SessionCard.tsx +++ b/src/components/SessionCard.tsx @@ -50,6 +50,14 @@ const SessionsCard: React.FC = ({ } }; + const onEventUpdated = () => { + setOpen(false); + if (isEventUpdated) { + isEventUpdated(); + } + setUpdateEvent(false); + }; + const handleSnackbarClose = () => setSnackbarOpen(false); const handleCopyUrl = () => { @@ -189,6 +197,7 @@ const SessionsCard: React.FC = ({ editSession={editSession} handleEditSelection={handleEditSelection} onEventDeleted={onEventDeleted} + onEventUpdated={onEventUpdated} eventDeleted={eventDeleted} eventData={data} updateEvent={updateEvent} diff --git a/src/pages/centers/[cohortId]/index.tsx b/src/pages/centers/[cohortId]/index.tsx index 057d2040..2ce61afc 100644 --- a/src/pages/centers/[cohortId]/index.tsx +++ b/src/pages/centers/[cohortId]/index.tsx @@ -111,7 +111,7 @@ const CohortPage = () => { const [openAddLearnerModal, setOpenAddLearnerModal] = React.useState(false); const [openSchedule, setOpenSchedule] = React.useState(false); const [eventDeleted, setEventDeleted] = React.useState(false); - + const [eventUpdated, setEventUpdated] = React.useState(false); const [deleteModal, setDeleteModal] = React.useState(false); const [cohortName, setCohortName] = React.useState(); const [clickedBox, setClickedBox] = useState(null); @@ -228,13 +228,15 @@ const CohortPage = () => { }); } setSessions(sessionArray); + setEventUpdated(false); + setEventDeleted(false); } catch (error) { setSessions([]); } }; getSessionsData(); - }, [selectedDate, eventCreated, eventDeleted]); + }, [selectedDate, eventCreated, eventDeleted, eventUpdated]); useEffect(() => { const getExtraSessionsData = async () => { @@ -273,14 +275,19 @@ const CohortPage = () => { setExtraSessions([]); } }; - + setEventUpdated(false); + setEventDeleted(false); getExtraSessionsData(); - }, [eventCreated, eventDeleted]); + }, [eventCreated, eventDeleted, eventUpdated]); const handleEventDeleted = () => { setEventDeleted(true); }; + const handleEventUpdated = () => { + setEventUpdated(true); + }; + const handleChange = (event: React.SyntheticEvent, newValue: number) => { setValue(newValue); }; @@ -575,6 +582,7 @@ const CohortPage = () => { @@ -643,7 +651,11 @@ const CohortPage = () => { {sessions?.map((item) => ( - + From 2283ae1ecede76e6e0d80c4d5d92ff5f9e1be25b Mon Sep 17 00:00:00 2001 From: suvarnakale Date: Tue, 27 Aug 2024 19:07:20 +0530 Subject: [PATCH 03/17] Issue #PS-1625 chore: interface added --- src/utils/Interfaces.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/utils/Interfaces.ts b/src/utils/Interfaces.ts index 3bb9716e..90191976 100644 --- a/src/utils/Interfaces.ts +++ b/src/utils/Interfaces.ts @@ -156,6 +156,7 @@ export interface PlannedModalProps { editSelection?: string; handleEditSelection?: (selection: string) => void; onEventDeleted?: () => void; + onEventUpdated?: () => void; updateEvent?: boolean; editSession?: any; eventData?: any; @@ -446,7 +447,6 @@ export interface FacilitatorDrawerProps { } export interface CoursePlannerCardsProps { resources: any; - } export interface scheduleEventParam { @@ -501,11 +501,10 @@ export interface Assessment { export interface BoardEnrollment { userId: number; studentName: string; - center:string; - isDropout:boolean + center: string; + isDropout: boolean; } - export interface AssessmentSubject { userId: number; subject: string; From 211b57981c9299a9cdcc110020e5b69b0ca24612 Mon Sep 17 00:00:00 2001 From: vivek kasture Date: Tue, 27 Aug 2024 19:16:59 +0530 Subject: [PATCH 04/17] Issue #PS-000 feat: Bug fixes --- public/locales/en/common.json | 29 ++--- src/components/CohortFacilitatorList.tsx | 88 +++++++-------- src/components/CohortLearnerList.tsx | 87 +++++++-------- src/components/ConfirmationModal.tsx | 2 +- src/components/MenuDrawer.tsx | 2 +- src/components/PieChartGraph.tsx | 6 +- src/components/center/DeleteCenterModal.tsx | 93 ++-------------- src/components/center/RenameCenterModal.tsx | 44 ++++---- src/components/common/NoDataFound.tsx | 27 +++++ src/pages/board-enrollment/index.tsx | 4 +- src/pages/centers/[cohortId]/index.tsx | 116 ++++++++------------ 11 files changed, 206 insertions(+), 292 deletions(-) create mode 100644 src/components/common/NoDataFound.tsx diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 77b34f3e..8d94a99c 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -72,7 +72,7 @@ "SURE_LOGOUT": "Are you sure you want to Logout?", "SURE_UPDATE": "Are you sure you want to update this attendance?", "SURE_REMOVE": "Are you sure you want to remove this learner?", - "SURE_REASSIGN_CENTER": "Are you sure you want to re-assign Center to this user?", + "SURE_REASSIGN_CENTER": "Are you sure you want to re-assign center to this user?", "SURE_CLOSE": "Are you sure you want to close without saving?", "LEARNER_LIST": "Learners List", "FACILITATOR_LIST": "Facilitators List", @@ -94,7 +94,7 @@ "DROPPED_OUT": "Dropped Out", "DELETE_USER": "Delete User Permanently", "DELETE_USER_WITH_REASON": "Delete User", - "USER_DELETED_PERMANENTLY": "User Successfully Deleted!", + "USER_DELETED_PERMANENTLY": "User successfully deleted!", "OBSERVATIONS_FORMS": "Observations and Forms", "OTHER_REASON": "Other Reason", "OTHER_REASON_PLACEHOLDER": "Enter Other Reason", @@ -103,7 +103,7 @@ "CREDENTIALS_EMAILED": "The login credentials will be emailed to the Facilitator at ", "CREDENTIALS_EMAILED_OF_LEARNER": "The login credentials have been send to your email ", "NEW": "New {{role}}", - "USER_CREDENTIAL_SEND_SUCCESSFULLY": "User Credentials Sent Successfully!", + "USER_CREDENTIAL_SEND_SUCCESSFULLY": "User credentials sent successfully!", "CENTER_SESSIONS": "Center Sessions", "SCHEDULE_NEW": "Schedule New", "UPCOMING_EXTRA_SESSION": "Upcoming Extra Sessions (Next {{days}} days)", @@ -118,7 +118,7 @@ "NEW_FACILITATOR": "New Facilitator", "EDIT_FACILITATOR": "Edit Facilitator", "SUBMIT": "Submit", - "LEARNER_CREATED_SUCCESSFULLY": "Leaner has been Successfully Created!", + "LEARNER_CREATED_SUCCESSFULLY": "Leaner has been successfully created!", "FACILITATOR_ADDED_SUCCESSFULLY": "Facilitator added successfully!", "LEARNER_UPDATED_SUCCESSFULLY": "Learner profile updated successfully!", "FACILITATOR_UPDATED_SUCCESSFULLY": "Facilitator profile updated successfully!", @@ -319,14 +319,14 @@ "CENTER_TYPE": "Center Type", "UNIT_NAME": "Unit Name", "NOTE": "Note: This will be the center name", - "CENTER_CREATED": "Center Created Successfully!", + "CENTER_CREATED": "Center created successfully!", "RENAME_CENTER": "Rename Center", "REQUEST_TO_DELETE": "Request to Delete", "RENAME": "Rename", - "CENTER_RENAMED": "Center Renamed Successfully!", + "CENTER_RENAMED": "Center renamed successfully!", "SEND_REQUEST": "Send Request", "REQUEST_TO_DELETE_HAS_BEEN_SENT": "Request to Delete has been sent", - "YOU_ARE_SENDING_REQUEST_TO_THE_STATE_ADMIN": "You are sending a request to the State Admin to delete this Center", + "YOU_ARE_SENDING_REQUEST_TO_THE_STATE_ADMIN": "You are sending a request to the State Admin to delete this center", "THE_USER_BELONGS_TO_THE_FOLLOWING_COHORT": "The user belongs to the following cohort: ", "PLEASE_REMOVE_THE_USER_FROM_COHORT": "Please remove the user from these cohorts before proceeding with deletion.", "ERROR_EMPTY": "Center name cannot be empty", @@ -352,7 +352,7 @@ "DOUBT_CLEARING": "For doubt clearing, webinars, etc", "TOPIC": "Topic", "SUBTOPIC": "Sub Topic", - "FACILITATORS": " Facilitators Pre-requisites", + "FACILITATORS": "Facilitators Pre-requisites", "TITLE": "Title", "DELETE_SESSION": "Delete Session", "SCHEDULE": "Schedule", @@ -371,7 +371,7 @@ "EXTRA_OFFLINE": "Extra offline", "ENTER_VALID_MEETING_LINK": "Please enter a valid Zoom or Google Meet link.", "ZOOM": "Zoom", - "GOOGLEMEET": "GoogleMeet", + "GOOGLE_MEET": "GOOGLE_MEET", "SET_UP": "Set-Up", "EDIT_THIS_SESSION": "Edit this session", "EDIT_FOLLOWING_SESSIONS": "Edit this and following sessions", @@ -382,8 +382,8 @@ "UPDATE_CHANGES": "Are you sure you want to update the changes?" }, "MANAGE_USERS": { - "CENTERS_REQUESTED_SUCCESSFULLY": "Center Requested Successfully", - "CENTERS_REQUEST_FAILED": "Center Requested Failed" + "CENTERS_REQUESTED_SUCCESSFULLY": "Center requested successfully", + "CENTERS_REQUEST_FAILED": "Center Request Failed" }, "FORM": { "FULL_NAME": "Full Name", @@ -408,7 +408,7 @@ "ENTER_YOUR_FATHER_NAME": "Enter Your Father Name", "CLASS_OR_LAST_PASSED_GRADE": "Class (Last passed grade)", "NO_SCHOOLING": "No Schooling", - "REASON_FOR_DROPOUT_FROM_SCHOOL": "Reason for Drop Out From School", + "REASON_FOR_DROPOUT_FROM_SCHOOL": "Reason for dropout from school", "SCHOOL_INACCESSIBLE": "School inaccessible", "FINANCIAL_CONSTRAINTS": "Financial Constraints", "LACK_OF_INTEREST": "Lack of Interest", @@ -483,7 +483,8 @@ "ENTER_VALID_EMAIL": "Enter valid Email", "ENTER_VALID_YEAR": "Enter valid Year", "MUST_BE_LESS_THAN": "{{fieldname}} must be less than {{maxLength}}", - "MUST_BE_GREATER_THAN": "{{fieldname}} must be greater than {{minLength}}" + "MUST_BE_GREATER_THAN": "{{fieldname}} must be greater than {{minLength}}", + "ENTER_VALID_CENTER_NAME": "Enter valid center name" }, "COURSE_PLANNER": { "COURSE_PLANNER": "Course Plan", @@ -512,7 +513,7 @@ "ASSESSMENT_NOT_STARTED_YET": "Assessment not started yet", "NUMBER_OUT_OF_COMPLETED": "{{completedCount}} out of {{totalCount}} completed" }, - "BOARD_ENROOLMENT": { + "BOARD_ENROLMENT": { "BOARD_ENROLLMENT": "Board Enrollment", "BOARD_SELECTION":"Board Selection", "SUBJECTS_SELECTION": "Subjects Selection", diff --git a/src/components/CohortFacilitatorList.tsx b/src/components/CohortFacilitatorList.tsx index ba45159c..3b04b9dd 100644 --- a/src/components/CohortFacilitatorList.tsx +++ b/src/components/CohortFacilitatorList.tsx @@ -1,20 +1,20 @@ -import React, { useEffect } from 'react'; +import LearnersList from '@/components/LearnersListItem'; import { - getMyCohortFacilitatorList, - getMyCohortMemberList, + getMyCohortFacilitatorList } from '@/services/MyClassDetailsService'; +import { Status, limit } from '@/utils/app.constant'; import { capitalizeEachWord, getFieldValue, toPascalCase, } from '@/utils/Helper'; -import LearnersList from '@/components/LearnersListItem'; -import { Status, limit } from '@/utils/app.constant'; -import { showToastMessage } from './Toastify'; +import { Box, Grid } from '@mui/material'; +import { useTheme } from '@mui/material/styles'; import { useTranslation } from 'next-i18next'; -import { Box, Grid, Typography } from '@mui/material'; +import React, { useEffect } from 'react'; +import NoDataFound from './common/NoDataFound'; import Loader from './Loader'; -import { useTheme } from '@mui/material/styles'; +import { showToastMessage } from './Toastify'; interface UserDataProps { name: string; @@ -88,7 +88,7 @@ const CohortLearnerList: React.FC = ({ getCohortMemberList(); }, [cohortId, reloadState]); - const onDelete = () => { }; + const onDelete = () => {}; console.log('userData', userData); const theme = useTheme(); @@ -97,50 +97,38 @@ const CohortLearnerList: React.FC = ({ {loading ? ( ) : ( - <> - - - {userData?.map((data: any) => { - return ( - - - - ); - })} - {!userData?.length && ( - - - {t('COMMON.NO_DATA_FOUND')} - - - )} - - - + }} + > + + {userData?.map((data: any) => { + return ( + + + + ); + })} + {!userData?.length && ( + + )} + + )} ); diff --git a/src/components/CohortLearnerList.tsx b/src/components/CohortLearnerList.tsx index 36893709..7d703283 100644 --- a/src/components/CohortLearnerList.tsx +++ b/src/components/CohortLearnerList.tsx @@ -1,18 +1,18 @@ -import React, { useEffect } from 'react'; +import LearnersListItem from '@/components/LearnersListItem'; import { getMyCohortMemberList } from '@/services/MyClassDetailsService'; +import { Role, Status, limit } from '@/utils/app.constant'; import { capitalizeEachWord, getFieldValue, toPascalCase, } from '@/utils/Helper'; -import LearnersListItem from '@/components/LearnersListItem'; -import { Role, Status, limit } from '@/utils/app.constant'; -import { showToastMessage } from './Toastify'; -import { useTranslation } from 'next-i18next'; import { Box, Grid, Typography } from '@mui/material'; -import Loader from './Loader'; import { useTheme } from '@mui/material/styles'; - +import { useTranslation } from 'next-i18next'; +import React, { useEffect } from 'react'; +import Loader from './Loader'; +import { showToastMessage } from './Toastify'; +import NoDataFound from './common/NoDataFound'; interface UserDataProps { name: string; @@ -99,53 +99,40 @@ const CohortLearnerList: React.FC = ({ {loading ? ( ) : ( - <> - - - - {userData?.map((data: any) => { - return ( - - - - ); - })} - {!userData?.length && ( - - - {t('COMMON.NO_DATA_FOUND')} - - - )} - - - + }} + > + + {userData?.map((data: any) => { + return ( + + + + ); + })} + {!userData?.length && ( + + )} + + )} ); diff --git a/src/components/ConfirmationModal.tsx b/src/components/ConfirmationModal.tsx index 10972715..943e08b0 100644 --- a/src/components/ConfirmationModal.tsx +++ b/src/components/ConfirmationModal.tsx @@ -57,7 +57,7 @@ const ConfirmationModal: React.FC = ({ = ({ router.push(`/board-enrollment`); }} > - {t('BOARD_ENROOLMENT.BOARD_ENROLLMENT')} + {t('BOARD_ENROLMENT.BOARD_ENROLLMENT')} 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 05/17] 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 06/17] 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 ae4b71534fa9fe81fbcc7b48365267f5921bc1f8 Mon Sep 17 00:00:00 2001 From: Arif Date: Wed, 28 Aug 2024 11:36:18 +0530 Subject: [PATCH 07/17] Issue #PS-1775 feat: Course planner API integration to View list of Topics and Sub-Topics --- .env | 4 +++- public/locales/en/common.json | 1 + src/pages/course-planner-detail.tsx | 26 ++++++++++++++------------ src/pages/topic-detail-view.tsx | 2 +- src/services/CoursePlannerService.ts | 10 +++++++--- src/utils/Interfaces.ts | 4 +++- 6 files changed, 29 insertions(+), 18 deletions(-) diff --git a/.env b/.env index 840b1f00..0d396ebc 100644 --- a/.env +++ b/.env @@ -4,4 +4,6 @@ NEXT_PUBLIC_EVENT_BASE_URL=https://event-pratham.tekdinext.com/event-service/eve NEXT_PUBLIC_NOTIFICATION_BASE_URL=https://notification.prathamdigital.org NEXT_PUBLIC_TELEMETRY_URL=https://qa.prathamteacherapp.tekdinext.com 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_SHIKSHALOKAM_API_URL=https://dev.elevate-apis.shikshalokam.org/project/v1 +NEXT_PUBLIC_SHIKSHALOKAM_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7ImlkIjoyNjIsIm5hbWUiOiJ0ZWtkaVRlc3RVc2VyIiwic2Vzc2lvbl9pZCI6NjExNiwib3JnYW5pemF0aW9uX2lkIjoxLCJyb2xlcyI6W3siaWQiOjEyLCJ0aXRsZSI6InByb2dyYW1fZGVzaWduZXIiLCJsYWJlbCI6IlByb2dyYW0gRGVzaWduZXIiLCJ1c2VyX3R5cGUiOjAsInN0YXR1cyI6IkFDVElWRSIsIm9yZ2FuaXphdGlvbl9pZCI6MSwidmlzaWJpbGl0eSI6IlBVQkxJQyJ9LHsiaWQiOjIxLCJ0aXRsZSI6ImRpc3RyaWN0X3Jlc291cmNlX3BlcnNvbiIsImxhYmVsIjoiRGlzdHJpY3QgUmVzb3VyY2UgUGVyc29uIiwidXNlcl90eXBlIjowLCJzdGF0dXMiOiJBQ1RJVkUiLCJvcmdhbml6YXRpb25faWQiOjI0LCJ2aXNpYmlsaXR5IjoiUFVCTElDIn1dfSwiaWF0IjoxNzI0ODI1MDM5LCJleHAiOjE3MjQ5MTE0Mzl9.HAK4_MAo-8tqxcVoLNDRuyNj_S_hqM8X5Pya1gKPXKg \ No newline at end of file diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 85a15e17..f67574f6 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -353,6 +353,7 @@ "TOPIC": "Topic", "SUBTOPIC": "Sub Topic", "FACILITATORS": " Facilitators Pre-requisites", + "LEARNERS": " Learners Pre-requisites", "TITLE": "Title", "DELETE_SESSION": "Delete Session", "SCHEDULE": "Schedule", diff --git a/src/pages/course-planner-detail.tsx b/src/pages/course-planner-detail.tsx index f8a1a6d9..014f4ec6 100644 --- a/src/pages/course-planner-detail.tsx +++ b/src/pages/course-planner-detail.tsx @@ -37,7 +37,7 @@ const CoursePlannerDetail = () => { const [expandedPanels, setExpandedPanels] = useState<{ [key: string]: boolean; }>({ - 'panel1-header': false, + 'panel1-header': true, 'panel2-header': false, // || example for multiple accordions do this dynamically // Add more panels if needed }); @@ -50,16 +50,18 @@ const CoursePlannerDetail = () => { const fetchCourseDetails = useCallback(() => { getTargetedSolutions({ - state: 'Maharashtra', - role: 'Learner,Teacher', - class: '10', - board: 'cbse', - courseType: 'foundationCourse', + subject: "Marathi", + class: "10", + state: "Maharasthra", + board: "NIOS", + type: "foundationCourse", + role: "Teacher", + medium: "English" }).then((response) => { const courseId = response.result.data[0]._id; setCourseDetails(response.result.data); - return getUserProjectDetails({ id: '66c8313f6cf0bfa90315ff2e' }); + return getUserProjectDetails({ id: '66cdb0c86a33880d1f4d60d7' }); }).then((userProjectDetailsResponse) => { setUserProjectDetails(userProjectDetailsResponse.result.tasks); }).catch((error) => { @@ -235,11 +237,11 @@ const CoursePlannerDetail = () => { {userProjectDetails.map((topic:any, index) => ( setExpandedPanels((prev) => ({ ...prev, - [`panel${index}-header`]: !prev[`panel${index}-header`], + [`panel1-header`]: !prev[`panel1-header`], })) } sx={{ @@ -293,7 +295,7 @@ const CoursePlannerDetail = () => {
- {getAbbreviatedMonth(topic?.metaInformation.startDate)}, {getAbbreviatedMonth(topic?.metaInformation.endDate)} + {getAbbreviatedMonth(topic?.metaInformation?.startDate)}, {getAbbreviatedMonth(topic?.metaInformation?.endDate)}
@@ -354,7 +356,7 @@ const CoursePlannerDetail = () => { borderRadius: '8px', }} > - {getAbbreviatedMonth(subTopic.metaInformation.startDate)} + {getAbbreviatedMonth(subTopic?.metaInformation?.startDate)}
{ setResources(subTopic); router.push(`/topic-detail-view`); }}> - {`${subTopic.learningResources.length} ${t('COURSE_PLANNER.RESOURCES')}`} + {`${subTopic?.learningResources?.length} ${t('COURSE_PLANNER.RESOURCES')}`} diff --git a/src/pages/topic-detail-view.tsx b/src/pages/topic-detail-view.tsx index b13d4402..ddb8bdf5 100644 --- a/src/pages/topic-detail-view.tsx +++ b/src/pages/topic-detail-view.tsx @@ -151,7 +151,7 @@ const TopicDetailView = () => { fontSize="14px" sx={{ color: theme?.palette?.warning['300'] }} > - {t('CENTER_SESSION.FACILITATORS')} + {t('CENTER_SESSION.LEARNERS')} { export const getTargetedSolutions = async ({ + subject, state, role, + medium, class: className, board, - courseType, + type, }: GetTargetedSolutionsParams): Promise => { - const apiUrl: string = `${process.env.NEXT_PUBLIC_SHIKSHALOKAM_API_URL}/solutions/targetedSolutions?type=improvementProject`; + const apiUrl: string = `${process.env.NEXT_PUBLIC_SHIKSHALOKAM_API_URL}/solutions/targetedSolutions?type=improvementProject¤tScopeOnly=true`; const headers = { 'X-auth-token': process.env.NEXT_PUBLIC_SHIKSHALOKAM_TOKEN, @@ -33,11 +35,13 @@ export const getTargetedSolutions = async ({ }; const data = { + subject, state, role, + medium, class: className, board, - courseType, + type, }; try { diff --git a/src/utils/Interfaces.ts b/src/utils/Interfaces.ts index 0dd921d0..47f6f927 100644 --- a/src/utils/Interfaces.ts +++ b/src/utils/Interfaces.ts @@ -595,11 +595,13 @@ export interface IAssessmentStatusOptions { } export interface GetTargetedSolutionsParams { + subject:string, state: string; role: string; + medium: string class: string; board: string; - courseType: string; + type: string; } export interface GetUserProjectDetailsParams { From 80451f96be86aee85d9511e44ae21480771038c7 Mon Sep 17 00:00:00 2001 From: suvarnakale Date: Wed, 28 Aug 2024 12:37:41 +0530 Subject: [PATCH 08/17] 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 09/17] 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 10/17] 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 15/17] 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 16/17] 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 From 6fdcd9cbce2eb64c77d51e8845d1b977411bee43 Mon Sep 17 00:00:00 2001 From: Arif Date: Thu, 29 Aug 2024 11:47:04 +0530 Subject: [PATCH 17/17] Issue #PS-1775 feat: Course planner API integration to View list of Topics and Sub-Topics --- .env | 2 +- src/pages/course-planner-detail.tsx | 377 ++++++++++++++++----------- src/services/CoursePlannerService.ts | 51 +++- src/utils/Interfaces.ts | 11 + 4 files changed, 279 insertions(+), 162 deletions(-) diff --git a/.env b/.env index 0d396ebc..ff6eea2b 100644 --- a/.env +++ b/.env @@ -6,4 +6,4 @@ NEXT_PUBLIC_TELEMETRY_URL=https://qa.prathamteacherapp.tekdinext.com NEXT_PUBLIC_MEASUREMENT_ID= G-GNMQZ8Z65Z NEXT_PUBLIC_TRACKING_API_URL=https://tracking-pratham.tekdinext.com NEXT_PUBLIC_SHIKSHALOKAM_API_URL=https://dev.elevate-apis.shikshalokam.org/project/v1 -NEXT_PUBLIC_SHIKSHALOKAM_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7ImlkIjoyNjIsIm5hbWUiOiJ0ZWtkaVRlc3RVc2VyIiwic2Vzc2lvbl9pZCI6NjExNiwib3JnYW5pemF0aW9uX2lkIjoxLCJyb2xlcyI6W3siaWQiOjEyLCJ0aXRsZSI6InByb2dyYW1fZGVzaWduZXIiLCJsYWJlbCI6IlByb2dyYW0gRGVzaWduZXIiLCJ1c2VyX3R5cGUiOjAsInN0YXR1cyI6IkFDVElWRSIsIm9yZ2FuaXphdGlvbl9pZCI6MSwidmlzaWJpbGl0eSI6IlBVQkxJQyJ9LHsiaWQiOjIxLCJ0aXRsZSI6ImRpc3RyaWN0X3Jlc291cmNlX3BlcnNvbiIsImxhYmVsIjoiRGlzdHJpY3QgUmVzb3VyY2UgUGVyc29uIiwidXNlcl90eXBlIjowLCJzdGF0dXMiOiJBQ1RJVkUiLCJvcmdhbml6YXRpb25faWQiOjI0LCJ2aXNpYmlsaXR5IjoiUFVCTElDIn1dfSwiaWF0IjoxNzI0ODI1MDM5LCJleHAiOjE3MjQ5MTE0Mzl9.HAK4_MAo-8tqxcVoLNDRuyNj_S_hqM8X5Pya1gKPXKg \ No newline at end of file +NEXT_PUBLIC_SHIKSHALOKAM_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7ImlkIjoxNjIsIm5hbWUiOiJQcml5YW5rYSIsInNlc3Npb25faWQiOjYxNTAsIm9yZ2FuaXphdGlvbl9pZCI6MjQsInJvbGVzIjpbeyJpZCI6MywidGl0bGUiOiJtZW50ZWUiLCJsYWJlbCI6Ik1lbnRlZSIsInVzZXJfdHlwZSI6MCwic3RhdHVzIjoiQUNUSVZFIiwib3JnYW5pemF0aW9uX2lkIjoxLCJ2aXNpYmlsaXR5IjoiUFVCTElDIn0seyJpZCI6NCwidGl0bGUiOiJhZG1pbiIsImxhYmVsIjoiQWRtaW4iLCJ1c2VyX3R5cGUiOjEsInN0YXR1cyI6IkFDVElWRSIsIm9yZ2FuaXphdGlvbl9pZCI6MSwidmlzaWJpbGl0eSI6IlBVQkxJQyJ9LHsiaWQiOjgsInRpdGxlIjoicHVibGljIiwibGFiZWwiOiJQdWJsaWMiLCJ1c2VyX3R5cGUiOjAsInN0YXR1cyI6IkFDVElWRSIsIm9yZ2FuaXphdGlvbl9pZCI6MSwidmlzaWJpbGl0eSI6IlBVQkxJQyJ9LHsiaWQiOjUsInRpdGxlIjoib3JnX2FkbWluIiwibGFiZWwiOiJPcmcgQWRtaW4iLCJ1c2VyX3R5cGUiOjEsInN0YXR1cyI6IkFDVElWRSIsIm9yZ2FuaXphdGlvbl9pZCI6MSwidmlzaWJpbGl0eSI6IlBVQkxJQyJ9LHsiaWQiOjEwLCJ0aXRsZSI6InJldmlld2VyIiwibGFiZWwiOiJSZXZpZXdlciIsInVzZXJfdHlwZSI6MCwic3RhdHVzIjoiQUNUSVZFIiwib3JnYW5pemF0aW9uX2lkIjoxLCJ2aXNpYmlsaXR5IjoiUFVCTElDIn0seyJpZCI6MjAsInRpdGxlIjoiZGlzdHJpY3RfZWR1Y2F0aW9uX29mZmljZXIiLCJsYWJlbCI6IkRpc3RyaWN0IEVkdWNhdGlvbiBPZmZpY2VyIiwidXNlcl90eXBlIjowLCJzdGF0dXMiOiJBQ1RJVkUiLCJvcmdhbml6YXRpb25faWQiOjI0LCJ2aXNpYmlsaXR5IjoiUFVCTElDIn1dfSwiaWF0IjoxNzI0ODM3NzEyLCJleHAiOjE3MjQ5MjQxMTJ9.5rBJlIC0wN-6zpISQfa-cNCLRvSSe6uI87W2JKBt4Yk \ No newline at end of file diff --git a/src/pages/course-planner-detail.tsx b/src/pages/course-planner-detail.tsx index 014f4ec6..cc43999f 100644 --- a/src/pages/course-planner-detail.tsx +++ b/src/pages/course-planner-detail.tsx @@ -21,9 +21,15 @@ import { useTranslation } from 'next-i18next'; import { serverSideTranslations } from 'next-i18next/serverSideTranslations'; import React, { useState, useEffect, useMemo, useCallback } from 'react'; import { buildStyles, CircularProgressbar } from 'react-circular-progressbar'; -import { getTargetedSolutions, getUserProjectDetails } from '@/services/CoursePlannerService'; +import { + getSolutionDetails, + getTargetedSolutions, + getUserProjectDetails, + getUserProjectTemplate, +} from '@/services/CoursePlannerService'; import useCourseStore from '@/store/coursePlannerStore'; import dayjs from 'dayjs'; +import { Role } from '@/utils/app.constant'; const CoursePlannerDetail = () => { const theme = useTheme(); @@ -32,14 +38,14 @@ const CoursePlannerDetail = () => { const setResources = useCourseStore((state) => state.setResources); const store = useCourseStore(); - // Initialize the panels' state, assuming you have a known set of panel IDs const [expandedPanels, setExpandedPanels] = useState<{ [key: string]: boolean; }>({ + 'panel0-header': true, 'panel1-header': true, - 'panel2-header': false, // || example for multiple accordions do this dynamically - // Add more panels if needed + 'panel2-header': true, + 'panel3-header': true, }); const [drawerState, setDrawerState] = React.useState({ bottom: false }); const [isDrawerOpen, setIsDrawerOpen] = useState(false); @@ -48,31 +54,80 @@ const CoursePlannerDetail = () => { const [courseDetails, setCourseDetails] = useState(null); const [userProjectDetails, setUserProjectDetails] = useState([]); - const fetchCourseDetails = useCallback(() => { - getTargetedSolutions({ - subject: "Marathi", - class: "10", - state: "Maharasthra", - board: "NIOS", - type: "foundationCourse", - role: "Teacher", - medium: "English" - }).then((response) => { - const courseId = response.result.data[0]._id; - setCourseDetails(response.result.data); - - return getUserProjectDetails({ id: '66cdb0c86a33880d1f4d60d7' }); - }).then((userProjectDetailsResponse) => { - setUserProjectDetails(userProjectDetailsResponse.result.tasks); - }).catch((error) => { - console.error('Error fetching course planner:', error); + const fetchCourseDetails = useCallback(async () => { + try { + const response = await getTargetedSolutions({ + subject: 'Marathi', + class: '10', + state: 'Assam', + board: 'ASEB', + type: 'mainCourse', + role: 'Teacher', + medium: 'Hindi', }); + + const courseData = response.result.data[0]; + let courseId = courseData._id; + + if (!courseId) { + courseId = await fetchCourseIdFromSolution(courseData.solutionId); + } + + await fetchAndSetUserProjectDetails(courseId); + + } catch (error) { + console.error('Error fetching course planner:', error); + } }, []); + const fetchCourseIdFromSolution = async (solutionId: string): Promise => { + try { + const solutionResponse = await getSolutionDetails({ + id: solutionId, + role: 'Teacher', + }); + + const externalId = solutionResponse?.result?.externalId; + + const templateResponse = await getUserProjectTemplate({ + templateId: externalId, + solutionId, + role: Role.TEACHER, + }); + + const updatedResponse = await getTargetedSolutions({ + subject: 'Marathi', + class: '10', + state: 'Kerala', + board: 'KSEB', + type: 'mainCourse', + role: 'Teacher', + medium: 'Hindi', + }); + + return updatedResponse.result.data[0]._id; + } catch (error) { + console.error('Error fetching solution details:', error); + throw error; + } + }; + + const fetchAndSetUserProjectDetails = async (courseId: string) => { + try { + const userProjectDetailsResponse = await getUserProjectDetails({ + id: courseId, + }); + setUserProjectDetails(userProjectDetailsResponse.result.tasks); + } catch (error) { + console.error('Error fetching user project details:', error); + } + }; + + + useEffect(() => { fetchCourseDetails(); }, [fetchCourseDetails]); - const handleBackEvent = () => { window.history.back(); @@ -115,8 +170,6 @@ const CoursePlannerDetail = () => { // setModalOpen(true); // }; - - const getAbbreviatedMonth = (dateString: string | number | Date) => { const date = new Date(dateString); const months = Array.from({ length: 12 }, (_, i) => @@ -234,169 +287,175 @@ const CoursePlannerDetail = () => { - {userProjectDetails.map((topic:any, index) => ( - - - setExpandedPanels((prev) => ({ - ...prev, - [`panel1-header`]: !prev[`panel1-header`], - })) - } - sx={{ - boxShadow: 'none', - background: '#F1E7D9', - border: 'none', - transition: '0.3s', - }} - > - - } - aria-controls={`panel${index}-content`} - id={`panel${index}-header`} - className="accordion-summary" - sx={{ - px: '16px', - m: 0, - '&.Mui-expanded': { - minHeight: '48px', - }, - }} - > - - - - - {`Topic ${index + 1} - ${topic.name}`} - - - - {getAbbreviatedMonth(topic?.metaInformation?.startDate)}, {getAbbreviatedMonth(topic?.metaInformation?.endDate)} - - - - - {topic.children.map((subTopic:any) => ( - ( + + + setExpandedPanels((prev) => ({ + ...prev, + [`panel${index}-header`]: !prev[`panel${index}-header`], + })) + } sx={{ - borderBottom: `1px solid ${theme.palette.warning['A100']}`, + boxShadow: 'none', + background: '#F1E7D9', + border: 'none', + transition: '0.3s', }} > - + } + aria-controls={`panel${index}-content`} + id={`panel${index}-header`} + className="accordion-summary" sx={{ - py: '10px', px: '16px', - background: theme.palette.warning['A400'], + m: 0, + '&.Mui-expanded': { + minHeight: '48px', + }, }} > { - setResources(subTopic); - router.push(`/topic-detail-view`); + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + gap: '5px', }} > - {subTopic.name} + + + {`Topic ${index + 1} - ${topic.name}`} + + + {getAbbreviatedMonth(topic?.metaInformation?.startDate)},{' '} + {getAbbreviatedMonth(topic?.metaInformation?.endDate)} + + + + + {topic.children.map((subTopic: any) => ( - {getAbbreviatedMonth(subTopic?.metaInformation?.startDate)} + + { + setResources(subTopic); + router.push(`/topic-detail-view`); + }} + > + {subTopic.name} + + + + {getAbbreviatedMonth( + subTopic?.metaInformation?.startDate + )} + + + + + { + router.push(`/topic-detail-view`); + }} + > + { + setResources(subTopic); + router.push(`/topic-detail-view`); + }} + > + {`${subTopic?.learningResources?.length} ${t('COURSE_PLANNER.RESOURCES')}`} + + + - - - - { - router.push(`/topic-detail-view`); - }} - > - { - setResources(subTopic); - router.push(`/topic-detail-view`); - }}> - {`${subTopic?.learningResources?.length} ${t('COURSE_PLANNER.RESOURCES')}`} - - - - - ))} - - - - ))} - + ))} + + + + ))} + { @@ -10,7 +10,7 @@ export const getCoursePlanner = (): CoursePlanner[] => { // { id: 3, subject: 'History', circular: 30 }, // { id: 4, subject: 'Geography', circular: 60 }, // { id: 5, subject: 'Marathi', circular: 90 }, - { id: 6, subject: 'Hindi', circular: 70 }, + { id: 6, subject: 'Marathi', circular: 0 }, // { id: 7, subject: 'Social Science', circular: 80 }, ]; @@ -76,4 +76,51 @@ export const getUserProjectDetails = async ({ id }: GetUserProjectDetailsParams) }; +export const getSolutionDetails = async ({ id, role }: GetSolutionDetailsParams): Promise => { + const apiUrl: string = `${process.env.NEXT_PUBLIC_SHIKSHALOKAM_API_URL}/solutions/details/${id}`; + + const headers = { + 'X-auth-token': process.env.NEXT_PUBLIC_SHIKSHALOKAM_TOKEN, + 'Content-Type': 'application/json', + }; + + const data = { + role, + }; + + try { + const response = await axios.post(apiUrl, data, { headers }); + return response?.data; + } catch (error) { + console.error('Error in getting Solution Details', error); + return error; + } +}; + +export const getUserProjectTemplate = async ({ + templateId, + solutionId, + role, +}: GetUserProjectTemplateParams): Promise => { + const apiUrl: string = `${process.env.NEXT_PUBLIC_SHIKSHALOKAM_API_URL}/userProjects/details?templateId=${templateId}&solutionId=${solutionId}`; + + const headers = { + 'X-auth-token': process.env.NEXT_PUBLIC_SHIKSHALOKAM_TOKEN, + 'Content-Type': 'application/json', + }; + + const data = { + role, + }; + + try { + const response = await axios.post(apiUrl, data, { headers }); + return response?.data; + } catch (error) { + console.error('Error in getting User Project Details', error); + throw error; + } +}; + + diff --git a/src/utils/Interfaces.ts b/src/utils/Interfaces.ts index 47f6f927..a74f16e6 100644 --- a/src/utils/Interfaces.ts +++ b/src/utils/Interfaces.ts @@ -632,3 +632,14 @@ export interface IQuestion { score: number; sectionId: string; } + +export interface GetSolutionDetailsParams { + id: string; + role: string; +} + +export interface GetUserProjectTemplateParams { + templateId: string; + solutionId: string; + role: string; +}