From 00cf1d5029c7fed04ccd6073971202900b1669bb Mon Sep 17 00:00:00 2001 From: Rushikesh-Sonawane99 Date: Fri, 21 Jun 2024 01:11:52 +0530 Subject: [PATCH] Issue #PS-793 chore: Added dynamic reason for logout, callback functions, loaders and toast messages --- public/locales/en/common.json | 5 +- public/locales/hi/common.json | 5 +- public/locales/mr/common.json | 5 +- public/locales/or/common.json | 5 +- src/components/CohortLearnerList.tsx | 11 ++- src/components/DropOutModal.tsx | 70 ++++++++++----- src/components/LearnersList.tsx | 124 +++++++++++++++++---------- src/pages/centers/[cohortId].tsx | 3 +- src/utils/Interfaces.ts | 3 + 9 files changed, 158 insertions(+), 73 deletions(-) diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 1466edb0..1024386e 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -79,7 +79,10 @@ "SEARCH_FACILITATORS": "Search Facilitators..", "ADD_LEARNER":"Add Learners", "DESELECT_ALL":"Deselect All", - "SELECT_ALL":"Select All" + "SELECT_ALL":"Select All", + "LEARNER_MARKED_DROPOUT": "Learner marked as dropout", + "LEARNER_UNMARKED_DROPOUT": "Learner un-marked as dropout", + "LEARNER_REMOVED": "Learner has been removed" }, "LOGIN_PAGE": { "USERNAME": "Username", diff --git a/public/locales/hi/common.json b/public/locales/hi/common.json index a60104a9..15427467 100644 --- a/public/locales/hi/common.json +++ b/public/locales/hi/common.json @@ -79,7 +79,10 @@ "SEARCH_FACILITATORS": "खोज सुविधा प्रदाता..", "ADD_LEARNER": "शिक्षार्थियों को जोड़ें", "DESELECT_ALL": "सभी को अचयनित करें", - "SELECT_ALL": "सभी को चुनें" + "SELECT_ALL": "सभी को चुनें", + "LEARNER_MARKED_DROPOUT": "शिक्षार्थी को ड्रॉप आउट के रूप में चिह्नित किया गया", + "LEARNER_UNMARKED_DROPOUT": "शिक्षार्थी को ड्रॉपआउट के रूप में अनचिह्नित किया गया", + "LEARNER_REMOVED": "शिक्षार्थी को हटा दिया गया है" }, "LOGIN_PAGE": { "USERNAME": "उपयोगकर्ता नाम", diff --git a/public/locales/mr/common.json b/public/locales/mr/common.json index 0a6a1052..902f49b7 100644 --- a/public/locales/mr/common.json +++ b/public/locales/mr/common.json @@ -79,7 +79,10 @@ "SEARCH_FACILITATORS": "शोध सुविधा..", "ADD_LEARNER": "शिक्षार्थी जोडा", "DESELECT_ALL": "सर्व निवड रद्द करा", - "SELECT_ALL": "सर्व निवडा" + "SELECT_ALL": "सर्व निवडा", + "LEARNER_MARKED_DROPOUT": "शिकणाऱ्याला ड्रॉप आऊट म्हणून चिन्हांकित केले", + "LEARNER_UNMARKED_DROPOUT": "शिकणाऱ्याला ड्रॉपआउट म्हणून अनचिन्हांकित केले", + "LEARNER_REMOVED": "शिकणाऱ्याचे हटवले गेले आहे" }, "LOGIN_PAGE": { "USERNAME": "वापरकर्तानाव", diff --git a/public/locales/or/common.json b/public/locales/or/common.json index 003da2e2..aed80b49 100644 --- a/public/locales/or/common.json +++ b/public/locales/or/common.json @@ -56,7 +56,10 @@ "MARK_DROP_OUT": "ଡ୍ରପ୍ ଆଉଟ୍ ରୁପରେ ଚିହ୍ନିତ କରନ୍ତୁ", "UNMARK_DROP_OUT": " ଡ୍ରପ୍ ଆଉଟ୍ ଭାବରେ ଅପସାରଣ କରନ୍ତୁ", "SOMETHING_WENT_WRONG": "କିଛି ଭୁଲ ହେଇଗଲା।", - "SURE_REMOVE": "ଆପଣ ନିଶ୍ଚିତ ଏହି ଶିକ୍ଷାର୍ଥୀକୁ ହଟାଇବାକୁ ଚାହୁଁଛନ୍ତି କି?" + "SURE_REMOVE": "ଆପଣ ନିଶ୍ଚିତ ଏହି ଶିକ୍ଷାର୍ଥୀକୁ ହଟାଇବାକୁ ଚାହୁଁଛନ୍ତି କି?", + "LEARNER_MARKED_DROPOUT": "ଶିକ୍ଷାର୍ଥୀକୁ ଡ୍ରପ୍ ଆଉଟ୍ ଭାବେ ଚିହ୍ନିତ କରାଯାଇଛି", + "LEARNER_UNMARKED_DROPOUT": "ଶିକ୍ଷାର୍ଥୀକୁ ଡ୍ରପ୍ ଆଉଟ୍ ଭାବେ ଅଚିହ୍ନିତ କରାଯାଇଛି", + "LEARNER_REMOVED": "ଶିକ୍ଷାର୍ଥୀ କୁ ହଟାଇ ଦିଆଯାଇଛି" }, "LOGIN_PAGE": { "USERNAME": "ଉପଯୋଗକର୍ତା ନାମ", diff --git a/src/components/CohortLearnerList.tsx b/src/components/CohortLearnerList.tsx index cb284677..80c09ba5 100644 --- a/src/components/CohortLearnerList.tsx +++ b/src/components/CohortLearnerList.tsx @@ -19,8 +19,13 @@ interface UserDataProps { cohortMembershipId: string; enrollmentNumber: string; } +interface CohortLearnerListProp{ + cohortId: any, + reloadState: boolean; + setReloadState: React.Dispatch>; +} -const CohortLearnerList = (cohortId: any) => { +const CohortLearnerList : React.FC = ({cohortId, reloadState, setReloadState}) => { const [loading, setLoading] = React.useState(false); const [userData, setUserData] = React.useState(); @@ -45,6 +50,7 @@ const CohortLearnerList = (cohortId: any) => { name: toPascalCase(user.name), userId: user.userId, memberStatus: user.memberStatus, + statusReason: user.statusReason, cohortMembershipId: user.cohortMembershipId, enrollmentNumber: capitalizeEachWord( getFieldValue(user.customField, 'Enrollment Number') @@ -79,6 +85,9 @@ const CohortLearnerList = (cohortId: any) => { enrollmentId={data.enrollmentNumber} cohortMembershipId={data.cohortMembershipId} isDropout={data.memberStatus === 'dropout'} + statusReason = {data.statusReason} + reloadState={reloadState} + setReloadState={setReloadState} /> ); })} diff --git a/src/components/DropOutModal.tsx b/src/components/DropOutModal.tsx index 10582dba..4a8a1484 100644 --- a/src/components/DropOutModal.tsx +++ b/src/components/DropOutModal.tsx @@ -20,24 +20,37 @@ import { useTranslation } from 'next-i18next'; import { dropoutReasons } from '../../app.config'; import { updateCohortMemberStatus } from '@/services/MyClassDetailsService'; import ReactGA from 'react-ga4'; +import { showToastMessage } from './Toastify'; interface DropOutModalProps { open: boolean; onClose: (confirmed: boolean, reason?: string) => void; cohortMembershipId: string | number; + reloadState: boolean; + setReloadState: React.Dispatch>; } function DropOutModal({ open, onClose, cohortMembershipId, + reloadState, + setReloadState }: DropOutModalProps) { const [selectedReason, setSelectedReason] = React.useState(''); const [isButtonDisabled, setIsButtonDisabled] = React.useState(true); + const [loading, setLoading] = React.useState(false); const { t } = useTranslation(); const theme = useTheme(); + React.useEffect(() => { + if (reloadState) { + setReloadState(false); + window.location.reload(); + } + }, [reloadState, setReloadState]); + const style = { position: 'absolute', top: '50%', @@ -57,30 +70,41 @@ function DropOutModal({ setIsButtonDisabled(false); }; - const handleMarkDropout = () => { - onClose(true, selectedReason); - console.log('Dropout api called'); - if (selectedReason && cohortMembershipId) { - const memberStatus = 'dropout'; - const statusReason = selectedReason; - const membershipId = cohortMembershipId; - const response = updateCohortMemberStatus({ - memberStatus, - statusReason, - membershipId, - }); - // console.log('!!!!!!!!!!!!!!!!!!!!!', response); - ReactGA.event('dropout-student-successful', { - cohortMembershipId: membershipId, - }); - // if (response.responseCode !== 201 || response.params.err) { - // ReactGA.event('dropout-student-error', { cohortMembershipId: membershipId }); - throw new Error(); - // // response.params.errmsg || - // // 'An error occurred while updating the user.' + const handleMarkDropout = async () => { + try { + onClose(true, selectedReason); + setLoading(true); + + if (selectedReason && cohortMembershipId) { + const memberStatus = 'dropout'; + const statusReason = selectedReason; + const membershipId = cohortMembershipId; + + const response = await updateCohortMemberStatus({ + memberStatus, + statusReason, + membershipId, + }); + + if (response?.responseCode !== 200 || response?.params?.err) { + ReactGA.event('dropout-student-error', { cohortMembershipId: membershipId }); + // throw new Error(response.params?.errmsg || 'An error occurred while updating the user.'); + }else{ + ReactGA.event('dropout-student-successful', { + cohortMembershipId: membershipId, + }); + showToastMessage(t('COMMON.LEARNER_UNMARKED_DROPOUT'),'success'); + setReloadState(true) + } + setIsButtonDisabled(true); + } + } catch (error) { + console.log(error); + showToastMessage(t('COMMON.SOMETHING_WENT_WRONG'), 'error'); + } finally { + setLoading(false); } - setIsButtonDisabled(true); - }; + }; return ( diff --git a/src/components/LearnersList.tsx b/src/components/LearnersList.tsx index cfb378db..35b88dd5 100644 --- a/src/components/LearnersList.tsx +++ b/src/components/LearnersList.tsx @@ -14,6 +14,7 @@ import { LearnerListProps } from '@/utils/Interfaces'; import ConfirmationModal from './ConfirmationModal'; import { updateCohortMemberStatus } from '@/services/MyClassDetailsService'; import ReactGA from 'react-ga4'; +import { showToastMessage } from './Toastify'; type Anchor = 'bottom'; @@ -22,14 +23,27 @@ const LearnersList: React.FC = ({ isDropout, enrollmentId, cohortMembershipId, + statusReason, + reloadState, + setReloadState }) => { const [state, setState] = React.useState({ bottom: false, }); + const [showModal, setShowModal] = React.useState(false); + const [confirmationModalOpen, setConfirmationModalOpen] = + React.useState(false); + const [loading, setLoading] = React.useState(false); - // useEffect(()=>{ + const theme = useTheme(); + const { t } = useTranslation(); - // },[handleRemoveLearnerFromCohort, ]) //TODO: refresh page on mark/unmark dropout and remove learner + useEffect(()=>{ + if (reloadState) { + setReloadState(false); + window.location.reload(); + } + },[reloadState, setReloadState]) const toggleDrawer = (anchor: Anchor, open: boolean) => @@ -44,57 +58,78 @@ const LearnersList: React.FC = ({ setState({ ...state, bottom: open }); }; - const theme = useTheme(); - const { t } = useTranslation(); - const [showModal, setShowModal] = React.useState(false); - const [confirmationModalOpen, setConfirmationModalOpen] = - React.useState(false); + + + const handleUnmarkDropout = async () => { + try { + setLoading(true); + + if (cohortMembershipId) { + const memberStatus = 'active'; + const membershipId = cohortMembershipId; + + const response = await updateCohortMemberStatus({ + memberStatus, + membershipId, + }); + + if (response?.responseCode !== 200 || response?.params?.err) { + ReactGA.event('unmark-dropout-student-error', { cohortMembershipId: membershipId }); + throw new Error(response.params?.errmsg || 'An error occurred while updating the user.'); + } else { + ReactGA.event('unmark-dropout-student-successful', { + cohortMembershipId: membershipId, + }); + showToastMessage(t('COMMON.LEARNER_UNMARKED_DROPOUT'), 'success'); + setReloadState(true); + } + } + } catch (error) { + console.log(error); + showToastMessage(t('COMMON.SOMETHING_WENT_WRONG'), 'error'); + } finally { + setLoading(false); + } + }; const listItemClick = (event: React.MouseEvent, name: string) => { if (name === 'mark-drop-out') { setShowModal(true); } else if (name === 'unmark-drop-out') { + handleUnmarkDropout() + } else { + setConfirmationModalOpen(true); + } + }; + + const handleAction = async () => { + try { + setLoading(true); if (cohortMembershipId) { - const memberStatus = 'active'; + const memberStatus = 'archived'; const membershipId = cohortMembershipId; - const response = updateCohortMemberStatus({ + + const response = await updateCohortMemberStatus({ memberStatus, membershipId, }); - // console.log('!!!!!!!!!!!!!!!!!!!!!', response); - ReactGA.event('unmark-dropout-student-successful', { - cohortMembershipId: membershipId, - }); - // if (response.responseCode !== 201 || response.params.err) { - // ReactGA.event('unmark-dropout-student-error', { cohortMembershipId: membershipId }); - throw new Error(); - // // response.params.errmsg || - // // 'An error occurred while updating the user.' + + if (response?.responseCode !== 200 || response?.params?.err) { + ReactGA.event('remove-student-error', { cohortMembershipId: membershipId }); + throw new Error(response.params?.errmsg || 'An error occurred while updating the user.'); + } else { + ReactGA.event('remove-student-successful', { + cohortMembershipId: membershipId, + }); + showToastMessage(t('COMMON.LEARNER_REMOVED'), 'success'); + setReloadState(true) + } } - } else { - setConfirmationModalOpen(true); - } - }; - - const handleAction = () => { - //Close all modals - //add toast messages on success and failure - if (cohortMembershipId) { - const memberStatus = 'archived'; - const membershipId = cohortMembershipId; - const response = updateCohortMemberStatus({ - memberStatus, - membershipId, - }); - // console.log('!!!!!!!!!!!!!!!!!!!!!', response); - ReactGA.event('remove-student-successful', { - cohortMembershipId: membershipId, - }); - // if (response.responseCode !== 201 || response.params.err) { - // ReactGA.event('remove-student-error', { cohortMembershipId: membershipId }); - throw new Error(); - // // response.params.errmsg || - // // 'An error occurred while updating the user.' + } catch (error) { + console.log(error); + showToastMessage(t('COMMON.SOMETHING_WENT_WRONG'), 'error'); + } finally { + setLoading(false); } setConfirmationModalOpen(false); handleCloseBottomDrawer(); @@ -135,9 +170,8 @@ const LearnersList: React.FC = ({ color={theme.palette.warning[300]} fontWeight="500" > - {t('COMMON.REASON_FOR_DROPOUT')} + {statusReason} - {/* TODO: Add reason dynamically from api */} ); } @@ -266,6 +300,8 @@ const LearnersList: React.FC = ({ open={showModal} onClose={() => setShowModal(false)} cohortMembershipId={cohortMembershipId} + reloadState={reloadState} + setReloadState={setReloadState} /> { const theme = useTheme(); const [cohortDetails, setCohortDetails] = React.useState({}); + const [reloadState, setReloadState] = React.useState(false); useEffect(() => { const getCohortData = async () => { @@ -149,7 +150,7 @@ const TeachingCenterDetails = () => { /> - + )} diff --git a/src/utils/Interfaces.ts b/src/utils/Interfaces.ts index 79654887..1a5bbddf 100644 --- a/src/utils/Interfaces.ts +++ b/src/utils/Interfaces.ts @@ -237,6 +237,9 @@ export interface LearnerListProps { enrollmentId?: string | number; cohortMembershipId: string | number; learnerName: string; + statusReason: string; + reloadState: boolean; + setReloadState: React.Dispatch>; } export interface FacilitatorListParam { limit: number;