From 82e308bb6b9da4d2a90b735e0bac0a46379df4d0 Mon Sep 17 00:00:00 2001 From: Akshata Katwal Date: Tue, 5 Nov 2024 16:46:57 +0530 Subject: [PATCH 1/5] Issue feat: Add filtered and sorting for observations --- public/locales/en/common.json | 12 +- src/components/ObservationCard.tsx | 56 +++--- .../observations/ObservationComponent.tsx | 6 +- .../observation/[observationId]/index.tsx | 26 ++- src/pages/observation/index.tsx | 173 +++++++++++++++++- src/utils/Helper.ts | 6 +- 6 files changed, 232 insertions(+), 47 deletions(-) diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 915e8935..8517f55b 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -136,7 +136,9 @@ "CENTER": "Center", "AND_COUNT_MORE": "and {{count}} more", "RETURN_TO_LOGIN": "Return to Login", - "NO_CENTER_FOUND": "No Center found" + "NO_CENTER_FOUND": "No Center found", + "FILTER_BY":"Filter By", + "ALL":"All" }, "LOGIN_PAGE": { "USERNAME": "Username", @@ -600,7 +602,13 @@ "NOT_STARTED":"Not Started", "COMPLETED":"Completed", "INPROGRESS":"In-Progress", - "NO_DATA_FOUND":"No {{entity}} found" + "NO_DATA_FOUND":"No {{entity}} found", + "OBSERVATION_COMING_SOON":" Observations are coming soon for {{entity}}", + "NO_RESULT_FOUND":" No matching observation found for {{entity}}", + "NO_OBSERVATION_EXPIRED":"No observation expired for {{entity}}", + "DAYS_LEFT":"Days left" + + } } diff --git a/src/components/ObservationCard.tsx b/src/components/ObservationCard.tsx index 2f9acf00..ee3caa23 100644 --- a/src/components/ObservationCard.tsx +++ b/src/components/ObservationCard.tsx @@ -1,4 +1,4 @@ -import { Box, Typography, Card, CardContent } from '@mui/material'; +import { Box, Typography, Card, CardContent, Tooltip } from '@mui/material'; import React, { useEffect, useState } from 'react'; import AssignmentOutlinedIcon from '@mui/icons-material/AssignmentOutlined'; import { formatEndDate } from '@/utils/Helper'; @@ -26,28 +26,36 @@ const ObservationCard: React.FC = ({ useEffect(() => { const today = new Date(); - console.log("endDate", endDate) - if(endDate) - { + + if (endDate) { const targetDate = new Date(endDate.toString()); - console.log("targetDate", targetDate) - const diffTime = Math.abs(targetDate?.getTime() - today.getTime()); - const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); - - setRemainingTimes(diffDays) - if(diffDays) - { - - const remainingTime=formatEndDate({diffDays}) - setRemainingDays(remainingTime) - + + // Calculate the difference in time + const diffTime = (targetDate.getTime() - today.getTime()); + const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); + + // Update remaining times and days + setRemainingTimes(diffDays); + + if (diffDays > 0) { + const remainingTime = formatEndDate({ diffDays }); + setRemainingDays(remainingTime); + + } else { + // If diffDays is 0 or negative, set the status to 'expired' + setRemainingDays('0'); + setRemainingTimes(0) } - } - - }, [endDate]); + }, [endDate]); // Ensure to include endDate in the dependency array + return ( + = ({ }, width: '300px', cursor: 'pointer', - background: 'linear-gradient(135deg, #fff9e6 0%, #faf2d6 100%)', + background: "#FEF8F2", borderRadius: '16px', - border: '1px solid #f0e68c', + border: '1px solid #D0C5B4', height: '200px', // Fixed height for all cards display: 'flex', flexDirection: 'column', }} - onClick={() => onCardClick?.(id || '')} + onClick={remainingDays==="0"?()=>{}:() => onCardClick?.(id || '')} > - = ({ {remainingDays} left - + + )} = ({ + ); }; diff --git a/src/components/observations/ObservationComponent.tsx b/src/components/observations/ObservationComponent.tsx index 2c0c2abd..0fe4e67c 100644 --- a/src/components/observations/ObservationComponent.tsx +++ b/src/components/observations/ObservationComponent.tsx @@ -153,8 +153,9 @@ const ObservationComponent: React.FC = ({ observationQues const response= await updateSubmission({submissionId, submissionData}) if((event as CustomEvent).detail.status==="draft") { + showToastMessage( t('OBSERVATION.FORM_SAVED_SUCCESSFULLY'), 'success'); + t('OBSERVATION.FORM_SAVED_SUCCESSFULLY') - showToastMessage( t('OBSERVATION.FORM_SUBMIT_SUCCESSFULLY'), 'success'); // window.history.back(); // router.push( // `${localStorage.getItem('observationPath')}` @@ -163,7 +164,8 @@ const ObservationComponent: React.FC = ({ observationQues } else if((event as CustomEvent).detail.status==="submit") { - showToastMessage( t('OBSERVATION.FORM_SAVED_SUCCESSFULLY'), 'success'); + showToastMessage( t('OBSERVATION.FORM_SUBMIT_SUCCESSFULLY'), 'success'); + // window.history.back(); router.push( diff --git a/src/pages/observation/[observationId]/index.tsx b/src/pages/observation/[observationId]/index.tsx index 5c42b6e1..1e63b2b7 100644 --- a/src/pages/observation/[observationId]/index.tsx +++ b/src/pages/observation/[observationId]/index.tsx @@ -242,11 +242,11 @@ const ObservationDetails = () => { console.log("response.result.length",response.result.length) if(response.result.length!==0) { - if(response?.result[0]?.evidencesStatus[0]?.status==="draft") + if(response?.result[response.result.length-1]?.evidencesStatus[0]?.status==="draft") setFirstEntityStatus("draft") - else if(response?.result[0]?.evidencesStatus[0]?.status==="completed") + else if(response?.result[response.result.length-1]?.evidencesStatus[0]?.status==="completed") setFirstEntityStatus("completed") - else if(response?.result[0]?.evidencesStatus[0]?.status==="notstarted") + else if(response?.result[response.result.length-1]?.evidencesStatus[0]?.status==="notstarted") setFirstEntityStatus("notstarted") } @@ -320,6 +320,7 @@ const ObservationDetails = () => { } finally { } }; + if(selectedCohort && selectedCohort!=='') handleCohortChange(); }, [page, selectedCohort, searchInput]); @@ -466,7 +467,14 @@ const ObservationDetails = () => { : ''; setDescription(data) }, []); + const [endDate, setEndDate] = useState(''); + useEffect(() => { + const storedEndDate = localStorage.getItem("endDateForSelectedObservation"); + if (storedEndDate) { + setEndDate(storedEndDate); + } + }, []); return ( <>
@@ -498,12 +506,16 @@ const ObservationDetails = () => { {/* Increased the left side size */} - - {t('OBSERVATION.OBSERVATION_DETAILS')} + + {t('OBSERVATION.OBSERVATION_DETAILS')} - + + {description} + + {t('CENTER_SESSION.END_DATE')}: {endDate || "N/A"} + { }} > {entity !== ObservationEntityType?.CENTER && ( - + {t('ATTENDANCE.CENTER_NAME')} diff --git a/src/pages/observation/index.tsx b/src/pages/observation/index.tsx index bee7b1fe..f6776068 100644 --- a/src/pages/observation/index.tsx +++ b/src/pages/observation/index.tsx @@ -6,11 +6,13 @@ import { targetSolution } from '@/services/ObservationServices'; import { Box, Tab, Tabs, Typography } from '@mui/material'; import { serverSideTranslations } from 'next-i18next/serverSideTranslations'; import { useRouter } from 'next/router'; -import { FormContext, FormContextType, Role, Status } from '@/utils/app.constant'; +import { FormContext, FormContextType, Role, Status, Telemetry } from '@/utils/app.constant'; import { entityList } from '../../../app.config'; import { useTranslation } from 'react-i18next'; import SearchBar from '@/components/Searchbar'; import { toPascalCase } from '@/utils/Helper'; +import { telemetryFactory } from '@/utils/telemetry'; +import { FormControl, InputLabel, Select, MenuItem, SelectChangeEvent } from '@mui/material'; const ObservationForms: React.FC = () => { const [entityNames, setEntityNames] = useState(); @@ -18,7 +20,9 @@ const ObservationForms: React.FC = () => { const [filteredObservationData, setFilteredObservationData] = useState([]); const router = useRouter(); const { t } = useTranslation(); - + const [selectedOption, setSelectedOption] = useState('all'); + const [sortOrder, setSortOrder] = useState('lowToHigh'); + const currentDate = new Date(); useEffect(() => { const fetchEntityList = async () => { try { @@ -43,6 +47,11 @@ const ObservationForms: React.FC = () => { const response = await targetSolution(); setObservationData(response?.result?.data || []); setFilteredObservationData(response?.result?.data || []); + // const data=response?.result?.data; + // data[1].endDate = "2027-11-15T14:26:18.803Z"; + // setObservationData(data || []); + // setFilteredObservationData(data || []); + } catch (error) { console.error('Error fetching cohort list:', error); } @@ -56,7 +65,8 @@ const ObservationForms: React.FC = () => { entity: string, observationName: string, id: string, - description:string + description:string, + endDate:String ) => { const fullPath = router.asPath; const [basePath, queryString] = fullPath.split('?'); @@ -64,6 +74,8 @@ const ObservationForms: React.FC = () => { let newFullPath = `${basePath}${newRoute}`; const queryParams = { entity: entity, observationName: observationName, Id: id }; localStorage.setItem("observationDescription", description) + localStorage.setItem("endDateForSelectedObservation", endDate.toString()) + router.push({ pathname: newFullPath, query: queryParams, @@ -75,6 +87,22 @@ const ObservationForms: React.FC = () => { const handleChange = (event: React.SyntheticEvent, newValue: number) => { setValue(newValue); + + const windowUrl = window.location.pathname; + const cleanedUrl = windowUrl.replace(/^\//, ''); + const telemetryInteract = { + context: { + env: 'teaching-center', + cdata: [], + }, + edata: { + id: newValue==1?'change-tab-to-active-observations':'change-tab-to-expired-observations', + type: Telemetry.CLICK, + subtype: '', + pageid: cleanedUrl, + }, + }; + telemetryFactory.interact(telemetryInteract); // if(newValue===1) // { // setFilteredObservationData([]) @@ -83,13 +111,66 @@ const ObservationForms: React.FC = () => { }; const handleSearch = (searchTerm: string) => { + // setSearchInput(searchTerm); + // const filteredData = observationData.filter((item: any) => + // item.name.toLowerCase().includes(searchTerm.toLowerCase()) + // ); + // setFilteredObservationData(filteredData); + setSearchInput(searchTerm); + + // Filter observation data based on the search term const filteredData = observationData.filter((item: any) => item.name.toLowerCase().includes(searchTerm.toLowerCase()) ); setFilteredObservationData(filteredData); + const telemetryInteract = { + context: { + env: 'observation', + cdata: [], + }, + edata: { + id: 'search-observations', + type: Telemetry.SEARCH, + subtype: '', + pageid: 'observation', + }, + }; + telemetryFactory.interact(telemetryInteract); + + + }; + const handleFilterChange = (event: SelectChangeEvent) => { + setSelectedOption(event.target.value as string); + if(event.target.value==="all") + { + const role = localStorage.getItem('role'); + if (role) { + if (role === Role.TEAM_LEADER) { + setEntityNames(entityList.TEAM_LEADER); + } else if (role === Role.TEACHER) { + setEntityNames(entityList.TEACHER); + } + } + } + else{ + setEntityNames([event.target.value as string]) + } }; + + const handleSortChange = (event: SelectChangeEvent) => { + const selectedValue = event.target.value as string; + setSortOrder(selectedValue); + + const sortedData = [...filteredObservationData].sort((a, b) => { + const dateA = new Date(a.endDate); + const dateB = new Date(b.endDate); + return selectedValue === 'lowToHigh' ? dateA.getTime() - dateB.getTime() : dateB.getTime() - dateA.getTime(); + }); + + setFilteredObservationData(sortedData); + }; return (
@@ -99,12 +180,47 @@ const ObservationForms: React.FC = () => { - + - + {value===0 &&( + {t('OBSERVATION.DAYS_LEFT')} + + )} + {typeof window !== 'undefined' && window.localStorage&& localStorage.getItem('role')=== Role.TEAM_LEADER &&( + {t('COMMON.FILTER_BY')} + + + ) +} + {entityNames && entityNames.map((name, index) => ( { {filteredObservationData.filter((item: any) => item.entityType === name).length > 0 && value===0? ( filteredObservationData - .filter((item: any) => item.entityType === name) + .filter((item: any) => item.entityType === name && new Date(item.endDate) > currentDate) .map((item: any) => ( - onCardClick(item?.solutionId, item?.entityType, item?.name, item?._id, item?.description) + onCardClick(item?.solutionId, item?.entityType, item?.name, item?._id, item?.description, item?.endDate) } description={item?.description} endDate={item?.endDate} /> )) - ) : value===0 &&( - + ) :value === 1 ? ( + filteredObservationData.filter((item: any) => item.entityType === name && new Date(item.endDate) <= currentDate).length > 0 ? ( + filteredObservationData + .filter((item: any) => item.entityType === name && new Date(item.endDate) <= currentDate) + .map((item: any) => ( + + + // onCardClick(item?.solutionId, item?.entityType, item?.name, item?._id, item?.description) + // } + description={item?.description} + endDate={item?.endDate} + /> + + )) + ) : searchInput === "" ?( + + {t('OBSERVATION.NO_OBSERVATION_EXPIRED', { + entity: toPascalCase(name), + })} + + ):( + + {t('OBSERVATION.NO_RESULT_FOUND', { + entity: toPascalCase(name), + })} + + ) + ) : searchInput === "" && value === 0 ? ( - Observations are coming soon for {toPascalCase(name)} + {t('OBSERVATION.OBSERVATION_COMING_SOON', { + entity: toPascalCase(name), + })} + ) : ( + + {t('OBSERVATION.NO_RESULT_FOUND', { + entity: toPascalCase(name), + })} + )} + ))} diff --git a/src/utils/Helper.ts b/src/utils/Helper.ts index b42d0d07..4c645dfb 100644 --- a/src/utils/Helper.ts +++ b/src/utils/Helper.ts @@ -627,14 +627,14 @@ export function formatEndDate({diffDays}: any) { const months = Math.floor(remainingDays / 30.44); const days = Math.round(remainingDays % 30.44); - remainingTime = `${years} year(s)${months > 0 ? `, ${months} months` : ''}${days > 0 ? `, , ${days} days` : ''}`; + remainingTime = `${years} year(s)${months > 0 ? `, ${months} month(s)` : ''}${days > 0 ? `, ${days} day(s)` : ''}`; } else if (diffDays > 31) { const months = Math.floor(diffDays / 30.44); const days = Math.round(diffDays % 30.44); - remainingTime = `${months} months ${days > 0 ? ` , ${days} days` : ''}`; + remainingTime = `${months} month(s) ${days > 0 ? ` , ${days} day(s)` : ''}`; } else { - remainingTime = `${diffDays} days`; + remainingTime = `${diffDays} day(s0`; } return remainingTime; } From 3f68fce4d36a818f1d6cce5f022aa0013e459e95 Mon Sep 17 00:00:00 2001 From: Akshata Katwal Date: Tue, 5 Nov 2024 18:01:00 +0530 Subject: [PATCH 2/5] update pr: resolved comments --- public/locales/en/common.json | 3 ++- src/components/ObservationCard.tsx | 22 +++++++++++-------- .../observation/[observationId]/index.tsx | 10 ++++----- src/utils/app.constant.ts | 3 +++ 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 8517f55b..54db24c2 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -606,7 +606,8 @@ "OBSERVATION_COMING_SOON":" Observations are coming soon for {{entity}}", "NO_RESULT_FOUND":" No matching observation found for {{entity}}", "NO_OBSERVATION_EXPIRED":"No observation expired for {{entity}}", - "DAYS_LEFT":"Days left" + "DAYS_LEFT":"Days left", + "THIS_OBSERVATION_EXPIRED":"This observation is expired" } diff --git a/src/components/ObservationCard.tsx b/src/components/ObservationCard.tsx index ee3caa23..4a0e059b 100644 --- a/src/components/ObservationCard.tsx +++ b/src/components/ObservationCard.tsx @@ -2,6 +2,8 @@ import { Box, Typography, Card, CardContent, Tooltip } from '@mui/material'; import React, { useEffect, useState } from 'react'; import AssignmentOutlinedIcon from '@mui/icons-material/AssignmentOutlined'; import { formatEndDate } from '@/utils/Helper'; +import { useTranslation } from 'react-i18next'; +import { LeftDays } from '@/utils/app.constant'; interface ObservationCardProp { name?: string; @@ -20,8 +22,9 @@ const ObservationCard: React.FC = ({ startDate, endDate }) => { - const [remainingDays, setRemainingDays] = useState(""); + const [remainingDays, setRemainingDays] = useState(); const [remainingTimes, setRemainingTimes] = useState(); + const { t } = useTranslation(); useEffect(() => { @@ -33,28 +36,29 @@ const ObservationCard: React.FC = ({ // Calculate the difference in time const diffTime = (targetDate.getTime() - today.getTime()); - const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); + const diffDays = Math.ceil(diffTime / LeftDays.MILLISECOND_TO_DAYS); // Update remaining times and days setRemainingTimes(diffDays); if (diffDays > 0) { const remainingTime = formatEndDate({ diffDays }); + console.log("remainingTime",typeof remainingTime) setRemainingDays(remainingTime); } else { // If diffDays is 0 or negative, set the status to 'expired' - setRemainingDays('0'); + setRemainingDays(0); setRemainingTimes(0) } } - }, [endDate]); // Ensure to include endDate in the dependency array + }, [endDate]); return ( = ({ display: 'flex', flexDirection: 'column', }} - onClick={remainingDays==="0"?()=>{}:() => onCardClick?.(id || '')} + onClick={remainingDays===0?()=>{}:() => onCardClick?.(id || '')} > - {remainingDays!=='0' && ( { if(entityId) { const response = await checkEntityStatus({ observationId, entityId }); - console.log("response.result.length",response.result.length) - if(response.result.length!==0) + console.log("response.result.length",response?.result?.length) + if(response?.result?.length!==0) { - if(response?.result[response.result.length-1]?.evidencesStatus[0]?.status==="draft") + if(response?.result[response?.result?.length-1]?.evidencesStatus[0]?.status==="draft") setFirstEntityStatus("draft") - else if(response?.result[response.result.length-1]?.evidencesStatus[0]?.status==="completed") + else if(response?.result[response?.result?.length-1]?.evidencesStatus[0]?.status==="completed") setFirstEntityStatus("completed") - else if(response?.result[response.result.length-1]?.evidencesStatus[0]?.status==="notstarted") + else if(response?.result[response?.result?.length-1]?.evidencesStatus[0]?.status==="notstarted") setFirstEntityStatus("notstarted") } diff --git a/src/utils/app.constant.ts b/src/utils/app.constant.ts index 74e61654..887912d9 100644 --- a/src/utils/app.constant.ts +++ b/src/utils/app.constant.ts @@ -109,6 +109,9 @@ export enum Pagination { ITEMS_PER_PAGE = 10, MAX_ITEMS = 50, } +export enum LeftDays { + MILLISECOND_TO_DAYS=1000 * 60 * 60 * 24 +} export enum Telemetry { CLICK = 'CLICK', From a76d6efcacfc56715ecbc2dd891827a3210546b9 Mon Sep 17 00:00:00 2001 From: Akshata Katwal Date: Tue, 5 Nov 2024 18:06:18 +0530 Subject: [PATCH 3/5] update pr --- src/pages/observation/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/observation/index.tsx b/src/pages/observation/index.tsx index f6776068..c77b224f 100644 --- a/src/pages/observation/index.tsx +++ b/src/pages/observation/index.tsx @@ -210,7 +210,7 @@ const ObservationForms: React.FC = () => { labelId="filter-label" value={selectedOption} onChange={handleFilterChange} - label="Filter By" + label={t('COMMON.FILTER_BY')} > {t('COMMON.ALL')} {t('CENTERS.CENTERS')} From 6bcdf7ee630404aeda516d5312e051615a2b26cd Mon Sep 17 00:00:00 2001 From: Akshata Katwal Date: Wed, 6 Nov 2024 11:28:18 +0530 Subject: [PATCH 4/5] update pr: resolved comments --- src/components/FilterSelect.tsx | 38 +++++++++++++++ src/pages/centers/index.tsx | 2 +- .../observation/[observationId]/index.tsx | 47 ++++++++++++------- src/pages/observation/index.tsx | 32 ++++++------- 4 files changed, 84 insertions(+), 35 deletions(-) create mode 100644 src/components/FilterSelect.tsx diff --git a/src/components/FilterSelect.tsx b/src/components/FilterSelect.tsx new file mode 100644 index 00000000..f6509f07 --- /dev/null +++ b/src/components/FilterSelect.tsx @@ -0,0 +1,38 @@ +import React from 'react'; +import { FormControl, InputLabel, Select, MenuItem, SelectChangeEvent } from '@mui/material'; + +interface FilterSelectProps { + menuItems: { value: string; label: string }[]; + selectedOption: string; + handleFilterChange: (event: SelectChangeEvent) => void; + label: string; + sx?: object; +} + +const FilterSelect: React.FC = ({ + menuItems, + selectedOption, + handleFilterChange, + label, + sx = {} +}) => { + return ( + + {label} + + + ); +}; + +export default FilterSelect; diff --git a/src/pages/centers/index.tsx b/src/pages/centers/index.tsx index 6e37a41c..74e0e633 100644 --- a/src/pages/centers/index.tsx +++ b/src/pages/centers/index.tsx @@ -278,7 +278,7 @@ const CentersPage = () => { }, edata: { id:'apply-filter', - type: TelemetryEventType.Radio, + type: TelemetryEventType.RADIO, subtype: '', pageid: 'centers', }, diff --git a/src/pages/observation/[observationId]/index.tsx b/src/pages/observation/[observationId]/index.tsx index 19a6e843..12e3362b 100644 --- a/src/pages/observation/[observationId]/index.tsx +++ b/src/pages/observation/[observationId]/index.tsx @@ -34,6 +34,7 @@ import { addEntities, checkEntityStatus, fetchEntities, + targetSolution, } from '@/services/ObservationServices'; import { useTranslation } from 'react-i18next'; import { CheckBoxOutlineBlankRounded } from '@mui/icons-material'; @@ -75,9 +76,13 @@ const ObservationDetails = () => { const [limit, setLimit] = React.useState(pageLimit); const [searchInput, setSearchInput] = useState(''); - const [description, setDescription] = useState(''); const { t } = useTranslation(); + const [observationData, setObservationData] = useState([]); + const [observationDescription, setObservationDescription] = useState(); + const [observationEndDate, setObservationEndDate] = useState(); + + const theme = useTheme(); @@ -140,9 +145,26 @@ const ObservationDetails = () => { fetchCohorts(); }, [searchInput]); - + useEffect(() => { + const fetchObservationData = async () => { + try { + const response = await targetSolution(); + setObservationData(response?.result?.data || []); + + } catch (error) { + console.error('Error fetching cohort list:', error); + } + }; + fetchObservationData(); + }, []); + useEffect(() => { + const result = observationData?.find((item:any) => item._id === Id); + setObservationDescription(result?.description) + setObservationEndDate(result?.endDate) + + }, [Id, observationData]); useEffect(() => { const fetchEntityList = async () => { @@ -361,6 +383,8 @@ const ObservationDetails = () => { const basePath = router.asPath.split('?')[0]; const newFullPath = `${basePath}/questionary`; const { observationName } = router.query; + const { Id } = router.query; + const queryParams = { cohortId: cohortId, Id: Id , observationName: observationName }; router.push({ @@ -461,20 +485,7 @@ const ObservationDetails = () => { }; - useEffect(() => { - const data= typeof window !== 'undefined' - ? localStorage.getItem("observationDescription") || '' - : ''; - setDescription(data) - }, []); - const [endDate, setEndDate] = useState(''); - - useEffect(() => { - const storedEndDate = localStorage.getItem("endDateForSelectedObservation"); - if (storedEndDate) { - setEndDate(storedEndDate); - } - }, []); + return ( <>
@@ -511,10 +522,10 @@ const ObservationDetails = () => { - {description} + {observationDescription} - {t('CENTER_SESSION.END_DATE')}: {endDate || "N/A"} + {t('CENTER_SESSION.END_DATE')}: {observationEndDate || "N/A"} diff --git a/src/pages/observation/index.tsx b/src/pages/observation/index.tsx index c77b224f..72225e69 100644 --- a/src/pages/observation/index.tsx +++ b/src/pages/observation/index.tsx @@ -13,6 +13,7 @@ import SearchBar from '@/components/Searchbar'; import { toPascalCase } from '@/utils/Helper'; import { telemetryFactory } from '@/utils/telemetry'; import { FormControl, InputLabel, Select, MenuItem, SelectChangeEvent } from '@mui/material'; +import FilterSelect from '@/components/FilterSelect'; const ObservationForms: React.FC = () => { const [entityNames, setEntityNames] = useState(); @@ -23,6 +24,12 @@ const ObservationForms: React.FC = () => { const [selectedOption, setSelectedOption] = useState('all'); const [sortOrder, setSortOrder] = useState('lowToHigh'); const currentDate = new Date(); + const menuItems = [ + { value: 'all', label: t('COMMON.ALL') }, + { value: 'center', label: t('CENTERS.CENTERS') }, + { value: 'facilitator', label: t('COMMON.FACILITATORS') }, + { value: 'learner', label: t('COMMON.LEARNERS') } + ]; useEffect(() => { const fetchEntityList = async () => { try { @@ -204,22 +211,15 @@ const ObservationForms: React.FC = () => { {t('COMMON.HIGH_TO_LOW')} )} - {typeof window !== 'undefined' && window.localStorage&& localStorage.getItem('role')=== Role.TEAM_LEADER &&( - {t('COMMON.FILTER_BY')} - - - ) -} + {typeof window !== 'undefined' && window.localStorage&& localStorage.getItem('role')=== Role.TEAM_LEADER &&( + )} + + {entityNames && entityNames.map((name, index) => ( Date: Wed, 6 Nov 2024 15:52:49 +0530 Subject: [PATCH 5/5] update pr: resolved new comments and add telemetry events for observations --- public/locales/en/common.json | 3 +- src/components/ObservationCard.tsx | 2 +- src/components/Searchbar.tsx | 21 +++++++++++ .../observations/ObservationComponent.tsx | 37 +++++++++++++++++++ .../observation/[observationId]/index.tsx | 18 ++++++++- src/pages/observation/index.tsx | 32 +++++++++++++++- src/utils/Helper.ts | 2 +- src/utils/app.constant.ts | 2 +- 8 files changed, 109 insertions(+), 8 deletions(-) diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 54db24c2..f85bce90 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -603,8 +603,7 @@ "COMPLETED":"Completed", "INPROGRESS":"In-Progress", "NO_DATA_FOUND":"No {{entity}} found", - "OBSERVATION_COMING_SOON":" Observations are coming soon for {{entity}}", - "NO_RESULT_FOUND":" No matching observation found for {{entity}}", + "NO_RESULT_FOUND":"No Observations found for {{entity}}", "NO_OBSERVATION_EXPIRED":"No observation expired for {{entity}}", "DAYS_LEFT":"Days left", "THIS_OBSERVATION_EXPIRED":"This observation is expired" diff --git a/src/components/ObservationCard.tsx b/src/components/ObservationCard.tsx index 4a0e059b..df5d34a7 100644 --- a/src/components/ObservationCard.tsx +++ b/src/components/ObservationCard.tsx @@ -36,7 +36,7 @@ const ObservationCard: React.FC = ({ // Calculate the difference in time const diffTime = (targetDate.getTime() - today.getTime()); - const diffDays = Math.ceil(diffTime / LeftDays.MILLISECOND_TO_DAYS); + const diffDays = Math.ceil(diffTime / LeftDays.ONE_DAY_IN_MILLISECONDS); // Update remaining times and days setRemainingTimes(diffDays); diff --git a/src/components/Searchbar.tsx b/src/components/Searchbar.tsx index af7f90bd..5a29cac0 100644 --- a/src/components/Searchbar.tsx +++ b/src/components/Searchbar.tsx @@ -10,6 +10,8 @@ import { import SearchIcon from '@mui/icons-material/Search'; import ClearIcon from '@mui/icons-material/Clear'; import { debounce } from '@/utils/Helper'; +import { Telemetry } from '@/utils/app.constant'; +import { telemetryFactory } from '@/utils/telemetry'; export interface SearchBarProps { onSearch: (value: string) => void; @@ -50,6 +52,25 @@ const SearchBar: React.FC = ({ { handleSearch(searchTerm); + + + const windowUrl = window.location.pathname; + const cleanedUrl = windowUrl.replace(/^\//, ''); + const env = cleanedUrl.split("/")[0]; +console.log(env) + const telemetryInteract = { + context: { + env: env, + cdata: [], + }, + edata: { + id: 'search-value:'+searchTerm, + type: Telemetry.SEARCH, + subtype: '', + pageid: cleanedUrl, + }, + }; + telemetryFactory.interact(telemetryInteract); } }; diff --git a/src/components/observations/ObservationComponent.tsx b/src/components/observations/ObservationComponent.tsx index 0fe4e67c..6226af1b 100644 --- a/src/components/observations/ObservationComponent.tsx +++ b/src/components/observations/ObservationComponent.tsx @@ -9,6 +9,8 @@ import { mock } from 'node:test'; import { showToastMessage } from '../Toastify'; import { useTranslation } from 'react-i18next'; import { useRouter } from 'next/router'; +import { Telemetry } from '@/utils/app.constant'; +import { telemetryFactory } from '@/utils/telemetry'; @@ -160,6 +162,21 @@ const ObservationComponent: React.FC = ({ observationQues // router.push( // `${localStorage.getItem('observationPath')}` // ); + const windowUrl = window.location.pathname; + const cleanedUrl = windowUrl.replace(/^\//, ''); + const telemetryInteract = { + context: { + env: 'observation', + cdata: [], + }, + edata: { + id: 'save-observation-successfully', + type: Telemetry.CLICK, + subtype: '', + pageid: cleanedUrl, + }, + }; + telemetryFactory.interact(telemetryInteract); } else if((event as CustomEvent).detail.status==="submit") @@ -171,6 +188,26 @@ const ObservationComponent: React.FC = ({ observationQues router.push( `${localStorage.getItem('observationPath')}` ); + + + const windowUrl = window.location.pathname; + const cleanedUrl = windowUrl.replace(/^\//, ''); + const telemetryInteract = { + context: { + env: 'observation', + cdata: [], + }, + edata: { + id: 'submit-observation-successfully', + type: Telemetry.CLICK, + subtype: '', + pageid: cleanedUrl, + }, + }; + telemetryFactory.interact(telemetryInteract); + + + } }; diff --git a/src/pages/observation/[observationId]/index.tsx b/src/pages/observation/[observationId]/index.tsx index 12e3362b..11289b66 100644 --- a/src/pages/observation/[observationId]/index.tsx +++ b/src/pages/observation/[observationId]/index.tsx @@ -16,7 +16,7 @@ import React, { useEffect, useState, useMemo } from 'react'; import { useRouter } from 'next/router'; import Header from '@/components/Header'; // import AddEntityModal from '@/components/observations/AddEntityModal'; -import { ObservationEntityType, Role , ObservationStatus} from '@/utils/app.constant'; +import { ObservationEntityType, Role , ObservationStatus, Telemetry} from '@/utils/app.constant'; import { serverSideTranslations } from 'next-i18next/serverSideTranslations'; import { GetStaticPaths } from 'next'; import { toPascalCase } from '@/utils/Helper'; @@ -40,6 +40,7 @@ import { useTranslation } from 'react-i18next'; import { CheckBoxOutlineBlankRounded } from '@mui/icons-material'; import Entity from '@/components/observations/Entity'; import SearchBar from '@/components/Searchbar'; +import { telemetryFactory } from '@/utils/telemetry'; interface EntityData { cohortId?: string; name?: string; @@ -375,6 +376,21 @@ const ObservationDetails = () => { setPage(0); setSelectedCohort(event.target.value); localStorage.setItem("selectedCohort",event.target.value) + const windowUrl = window.location.pathname; + const cleanedUrl = windowUrl.replace(/^\//, ''); + const telemetryInteract = { + context: { + env: 'observation', + cdata: [], + }, + edata: { + id: 'filter-by-center:'+event.target.value, + type: Telemetry.CLICK, + subtype: '', + pageid: cleanedUrl, + }, + }; + telemetryFactory.interact(telemetryInteract); }; const onStartObservation = (cohortId: any) => { diff --git a/src/pages/observation/index.tsx b/src/pages/observation/index.tsx index 72225e69..959748a5 100644 --- a/src/pages/observation/index.tsx +++ b/src/pages/observation/index.tsx @@ -137,7 +137,7 @@ const ObservationForms: React.FC = () => { cdata: [], }, edata: { - id: 'search-observations', + id: 'search-observations-bysearchterm:'+searchTerm, type: Telemetry.SEARCH, subtype: '', pageid: 'observation', @@ -163,6 +163,20 @@ const ObservationForms: React.FC = () => { else{ setEntityNames([event.target.value as string]) } + + const telemetryInteract = { + context: { + env: 'observation', + cdata: [], + }, + edata: { + id: 'apply-entity-filter:'+event.target.value, + type: Telemetry.CLICK, + subtype: '', + pageid: 'observation', + }, + }; + telemetryFactory.interact(telemetryInteract); }; @@ -177,6 +191,20 @@ const ObservationForms: React.FC = () => { }); setFilteredObservationData(sortedData); + + const telemetryInteract = { + context: { + env: 'observation', + cdata: [], + }, + edata: { + id: 'apply-datewise-filter:'+selectedValue, + type: Telemetry.CLICK, + subtype: '', + pageid: 'observation', + }, + }; + telemetryFactory.interact(telemetryInteract); }; return (
@@ -283,7 +311,7 @@ const ObservationForms: React.FC = () => { ) ) : searchInput === "" && value === 0 ? ( - {t('OBSERVATION.OBSERVATION_COMING_SOON', { + {t('OBSERVATION.NO_RESULT_FOUND', { entity: toPascalCase(name), })} diff --git a/src/utils/Helper.ts b/src/utils/Helper.ts index 4c645dfb..e0b3c735 100644 --- a/src/utils/Helper.ts +++ b/src/utils/Helper.ts @@ -634,7 +634,7 @@ export function formatEndDate({diffDays}: any) { remainingTime = `${months} month(s) ${days > 0 ? ` , ${days} day(s)` : ''}`; } else { - remainingTime = `${diffDays} day(s0`; + remainingTime = `${diffDays} day(s)`; } return remainingTime; } diff --git a/src/utils/app.constant.ts b/src/utils/app.constant.ts index 887912d9..1216e661 100644 --- a/src/utils/app.constant.ts +++ b/src/utils/app.constant.ts @@ -110,7 +110,7 @@ export enum Pagination { MAX_ITEMS = 50, } export enum LeftDays { - MILLISECOND_TO_DAYS=1000 * 60 * 60 * 24 + ONE_DAY_IN_MILLISECONDS=1000 * 60 * 60 * 24 } export enum Telemetry {