From 69734d169f8c8cef1528af66b3db35b639d7c9fd Mon Sep 17 00:00:00 2001 From: Arif Date: Mon, 24 Jun 2024 11:24:37 +0530 Subject: [PATCH 1/2] Issue #PS-919 feat: [FRONTEND] Implementation of caching --- package-lock.json | 25 +++++++++++++++++++++ package.json | 1 + src/pages/_app.tsx | 5 +++++ src/pages/dashboard.tsx | 31 ++++++++++--------------- src/pages/profile.tsx | 50 ++++++++++++++++++----------------------- src/services/queries.ts | 23 +++++++++++++++++++ 6 files changed, 88 insertions(+), 47 deletions(-) create mode 100644 src/services/queries.ts diff --git a/package-lock.json b/package-lock.json index e46271a8..4a0ea7e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@mui/material": "^5.15.15", "@project-sunbird/client-services": "^7.0.6", "@project-sunbird/telemetry-sdk": "^1.3.0", + "@tanstack/react-query": "^5.45.1", "axios": "^1.6.8", "date-fns": "^3.6.0", "fingerprintjs2": "^2.1.4", @@ -3682,6 +3683,30 @@ "tslib": "^2.4.0" } }, + "node_modules/@tanstack/query-core": { + "version": "5.45.0", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.45.0.tgz", + "integrity": "sha512-RVfIZQmFUTdjhSAAblvueimfngYyfN6HlwaJUPK71PKd7yi43Vs1S/rdimmZedPWX/WGppcq/U1HOj7O7FwYxw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.45.1", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.45.1.tgz", + "integrity": "sha512-mYYfJujKg2kxmkRRjA6nn4YKG3ITsKuH22f1kteJ5IuVQqgKUgbaSQfYwVP0gBS05mhwxO03HVpD0t7BMN7WOA==", + "dependencies": { + "@tanstack/query-core": "5.45.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18.0.0" + } + }, "node_modules/@testing-library/dom": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.1.0.tgz", diff --git a/package.json b/package.json index 6ed77d59..d4037585 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "@mui/material": "^5.15.15", "@project-sunbird/client-services": "^7.0.6", "@project-sunbird/telemetry-sdk": "^1.3.0", + "@tanstack/react-query": "^5.45.1", "axios": "^1.6.8", "date-fns": "^3.6.0", "fingerprintjs2": "^2.1.4", diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 9b7f0d9d..c76edbf4 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -24,7 +24,10 @@ import { initGA, logPageView } from '../utils/googleAnalytics'; import { ToastContainer } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; import Head from 'next/head'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; + +const queryClient = new QueryClient(); const ColorModeContext = React.createContext({ toggleColorMode: () => {} }); const poppins = Poppins({ weight: ['100', '200', '300', '400', '500', '600', '700', '800', '900'], @@ -127,7 +130,9 @@ function App({ Component, pageProps }: AppProps) { {/* */} + + = () => { const sevenDaysAgo = new Date(); sevenDaysAgo.setDate(currentDate.getDate() - modifyAttendanceLimit); const formattedSevenDaysAgo = shortDateFormat(sevenDaysAgo); + const [userId, setUserId] = React.useState(null); useEffect(() => { setIsClient(true); @@ -128,29 +129,28 @@ const Dashboard: React.FC = () => { useEffect(() => { if (typeof window !== 'undefined' && window.localStorage) { const token = localStorage.getItem('token'); + const storedUserId = localStorage.getItem('userId'); setClassId(localStorage.getItem('classId') || ''); if (token) { setIsAuthenticated(true); } else { router.push('/login'); } + setUserId(storedUserId); } }, []); - // API call to get center list - useEffect(() => { - const fetchCohortList = async () => { - const userId = localStorage.getItem('userId'); - setLoading(true); - try { - if (userId) { + const limit = 0; const page = 0; const filters = { userId: userId }; - const resp = await cohortList({ limit, page, filters }); + const { data, error, isLoading } = useCohortList(limit, page, filters); + // API call to get center list + useEffect(() => { + if (data) { - const extractedNames = resp?.results?.cohortDetails; - localStorage.setItem('parentCohortId', extractedNames?.[0].parentId); + const extractedNames = data?.results?.cohortDetails; + localStorage.setItem('parentCohortId', extractedNames?.[0].cohortData?.parentId); const filteredData = extractedNames ?.map((item: any) => ({ @@ -176,14 +176,7 @@ const Dashboard: React.FC = () => { } setLoading(false); } - } catch (error) { - console.error('Error fetching cohort list:', error); - showToastMessage(t('COMMON.SOMETHING_WENT_WRONG'), 'error'); - setLoading(false); - } - }; - fetchCohortList(); - }, []); + }, [data]); //API for getting student list useEffect(() => { diff --git a/src/pages/profile.tsx b/src/pages/profile.tsx index acefb30e..ed4eacd3 100644 --- a/src/pages/profile.tsx +++ b/src/pages/profile.tsx @@ -41,6 +41,7 @@ import { useRouter } from 'next/router'; import { useTranslation } from 'next-i18next'; import userPicture from '@/assets/images/imageOne.jpg'; import user_placeholder from '../assets/images/user_placeholder.png'; +import { useProfileInfo } from '@/services/queries'; interface FieldOption { name: string; @@ -108,6 +109,7 @@ const TeacherProfile = () => { const [hasInputChanged, setHasInputChanged] = React.useState(false); const [isValidationTriggered, setIsValidationTriggered] = React.useState(false); + const [userId, setUserId] = useState(null); const handleNameFieldChange = (event: ChangeEvent) => { const { value } = event.target; @@ -131,12 +133,15 @@ const TeacherProfile = () => { useEffect(() => { if (typeof window !== 'undefined' && window.localStorage) { const token = localStorage.getItem('token'); + const storedUserId = localStorage.getItem('userId'); if (token) { setIsAuthenticated(true); } else { router.push('/login'); } + setUserId(storedUserId); } + }, []); // find Address @@ -145,20 +150,21 @@ const TeacherProfile = () => { return field ? field.value[0] : null; }; - const fetchUserDetails = async () => { - setLoading(true); - if (typeof window !== 'undefined' && window.localStorage) { - const userId = localStorage.getItem('userId'); + const { data, error, isLoading } = useProfileInfo(userId ?? '', true); - try { - if (userId) { - const response = await getUserDetails(userId, true); - console.log('response', response); + useEffect(() => { + setLoading(isLoading); - const data = response?.result; + if (error) { + setIsError(true); + showToastMessage(t('COMMON.SOMETHING_WENT_WRONG'), 'error'); + console.error('Error fetching user details:', error); + } else { + setIsError(false); + } if (data) { - const userData = data?.userData; + const userData = data?.result?.userData; setUserData(userData); setUserName(userData?.name); const customDataFields = userData?.customFields; @@ -170,27 +176,15 @@ const TeacherProfile = () => { setUnitName(unitName); const blockName = getFieldValue(customDataFields, 'Block Name'); setBlockName(blockName); - setLoading(false); + } } else { - setLoading(false); + setIsData(false); console.log('No data Found'); } - } - setIsError(false); - } catch (error) { - setLoading(false); - setIsError(true); - showToastMessage(t('COMMON.SOMETHING_WENT_WRONG'), 'error'); - console.error('Error fetching user details:', error); - } - } - }; - - useEffect(() => { - fetchUserDetails(); - }, []); + + }, [data, error, isLoading]); const handleClickImage = () => { fileInputRef.current && fileInputRef.current.click(); @@ -454,7 +448,7 @@ const TeacherProfile = () => { handleClose(); console.log(response.params.successmessage); - fetchUserDetails(); + setIsError(false); setLoading(false); } @@ -1142,7 +1136,7 @@ const TeacherProfile = () => { ) : ( - {t('COMMON.SOMETHING_WENT_WRONG')} + {t('COMMON.LOADING')} )}{' '} diff --git a/src/services/queries.ts b/src/services/queries.ts new file mode 100644 index 00000000..a1eb320d --- /dev/null +++ b/src/services/queries.ts @@ -0,0 +1,23 @@ +import { useQuery } from "@tanstack/react-query"; +import { getUserDetails } from "./ProfileService"; +import { cohortList } from "./CohortServices"; + +export function useProfileInfo(userId: string | string[], fieldValue: boolean) { + return useQuery({ + + queryKey: ['profile', userId], + queryFn: () => getUserDetails(userId, fieldValue), + refetchInterval: 5 * 60 * 1000, + gcTime: 10 * 60 * 1000 + }); +} + +export function useCohortList( limit: any, page: any, filters: any) { + return useQuery({ + queryKey: ['cohort'], + queryFn: () => cohortList({limit , page, filters}), + refetchInterval: 5 * 60 * 1000, + gcTime: 10 * 60 * 1000 + }); + } + From 46c621469e9ae1b76c9600e0ffdb8293d61fa0a4 Mon Sep 17 00:00:00 2001 From: Arif Date: Wed, 26 Jun 2024 13:33:01 +0530 Subject: [PATCH 2/2] Issue #PS-919 feat: [FRONTEND] Implementation of caching --- src/services/queries.ts | 9 +++++---- src/utils/app.constant.ts | 2 ++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/services/queries.ts b/src/services/queries.ts index a1eb320d..c15c2882 100644 --- a/src/services/queries.ts +++ b/src/services/queries.ts @@ -1,14 +1,15 @@ import { useQuery } from "@tanstack/react-query"; import { getUserDetails } from "./ProfileService"; import { cohortList } from "./CohortServices"; +import { refetchInterval, gcTime } from "@/utils/app.constant"; export function useProfileInfo(userId: string | string[], fieldValue: boolean) { return useQuery({ queryKey: ['profile', userId], queryFn: () => getUserDetails(userId, fieldValue), - refetchInterval: 5 * 60 * 1000, - gcTime: 10 * 60 * 1000 + refetchInterval: refetchInterval, + gcTime: gcTime }); } @@ -16,8 +17,8 @@ export function useCohortList( limit: any, page: any, filters: any) { return useQuery({ queryKey: ['cohort'], queryFn: () => cohortList({limit , page, filters}), - refetchInterval: 5 * 60 * 1000, - gcTime: 10 * 60 * 1000 + refetchInterval: refetchInterval, + gcTime: gcTime }); } diff --git a/src/utils/app.constant.ts b/src/utils/app.constant.ts index 478d8da5..df8e136f 100644 --- a/src/utils/app.constant.ts +++ b/src/utils/app.constant.ts @@ -1 +1,3 @@ export const limit: number = 300; +export const refetchInterval: number = 5 * 60 * 1000; +export const gcTime: number = 10 * 60 * 1000; \ No newline at end of file