From 6e8cc8860786bea1b19ea7595650f90bd41ac80c Mon Sep 17 00:00:00 2001 From: Rushikesh-Sonawane99 Date: Thu, 13 Jun 2024 18:57:16 +0530 Subject: [PATCH] PS-Issue #PS-906 feat: Added user events to track in google Analytics --- .env | 1 - src/components/DateRangePopup.tsx | 19 ++++++++--- src/components/Header.tsx | 11 +++++++ .../LearnerAttendanceStatsListView.tsx | 5 ++- src/components/SortingModal.tsx | 9 ++++++ src/components/UpDownButton.tsx | 19 +++++++++++ src/pages/attendance-history.tsx | 11 ++++++- src/pages/attendance-overview.tsx | 9 ++++++ src/pages/dashboard.tsx | 20 +++++++++++- src/pages/learner-attendance-history.tsx | 11 +++++++ src/pages/learner/[userId].tsx | 32 +++++++++++++++++-- src/pages/login.tsx | 32 +++++++++++++++++-- src/pages/profile.tsx | 23 +++++++++++-- 13 files changed, 188 insertions(+), 14 deletions(-) diff --git a/.env b/.env index accab3c1..725ab0b3 100644 --- a/.env +++ b/.env @@ -1,3 +1,2 @@ NEXT_PUBLIC_BASE_URL=https://qa.prathamteacherapp.tekdinext.com/user/v1 -NEXT_PUBLIC_ANALYTICS_ID=abcdefghijk NEXT_PUBLIC_MEASUREMENT_ID= G-GNMQZ8Z65Z \ No newline at end of file diff --git a/src/components/DateRangePopup.tsx b/src/components/DateRangePopup.tsx index 27e9bcd1..7db122b9 100644 --- a/src/components/DateRangePopup.tsx +++ b/src/components/DateRangePopup.tsx @@ -12,6 +12,7 @@ import { useStepContext, } from '@mui/material'; import React, { useState } from 'react'; +import ReactGA from 'react-ga4'; import { getDayAndMonthName, getTodayDate } from '@/utils/Helper'; import checkMark from '../assets/images/checkMark.svg'; @@ -86,8 +87,15 @@ const DateRangePopup: React.FC = ({ getDayAndMonthName(getTodayDate()) ); const [cancelClicked, setCancelClicked] = React.useState(false); + const [appliedOption, setAppliedOption] = React.useState(''); + const [appliedIndex, setAppliedIndex] = React.useState(0); const toggleModal = () => setIsModalOpen(!isModalOpen); + const handleModalClose = () =>{ + setIsModalOpen(false) + setSelectedValue(appliedOption) + setSelectedIndex(appliedIndex) + } const toggleCalendarModal = () => setIsCalenderModalOpen(!isCalendarModalOpen); const { t } = useTranslation(); @@ -113,10 +121,13 @@ const DateRangePopup: React.FC = ({ setSelectedValue(''); setCancelClicked(false); } else { - console.log('applied', selectedIndex, selectedValue); + // console.log('applied', selectedIndex, selectedValue); + setAppliedOption(selectedValue) + setAppliedIndex(selectedIndex) + ReactGA.event("date-range-pop-up-clicked", { dateRangeType: selectedValue}); const values = getDateRange(selectedIndex); const { toDate, fromDate } = values; - console.log(toDate, fromDate); + // console.log(toDate, fromDate); onDateRangeSelected({ fromDate, toDate }); toggleModal(); } @@ -225,7 +236,7 @@ const DateRangePopup: React.FC = ({ @@ -244,7 +255,7 @@ const DateRangePopup: React.FC = ({ - + diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 2528e202..a16e94b0 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -16,6 +16,7 @@ import Image from 'next/image'; import logoLight from '../../public/images/logo-light.png'; import menuIcon from '../assets/images/menuIcon.svg'; import accountIcon from './../assets/images/account.svg'; +import { logEvent } from '@/utils/googleAnalytics'; const Header: React.FC = () => { const router = useRouter(); @@ -69,10 +70,20 @@ const Header: React.FC = () => { const handleProfileClick = () => { if (pathname !== '/profile') { router.push('/profile'); + logEvent({ + action: 'my-profile-clicked-header', + category: 'Dashboard', + label: 'Profile Clicked', + }); } }; const handleLogoutClick = () => { router.replace('/logout'); + logEvent({ + action: 'logout-clicked-header', + category: 'Dashboard', + label: 'Logout Clicked', + }); }; const [openDrawer, setOpenDrawer] = useState(false); diff --git a/src/components/LearnerAttendanceStatsListView.tsx b/src/components/LearnerAttendanceStatsListView.tsx index 83b06f6c..7ae0c0e2 100644 --- a/src/components/LearnerAttendanceStatsListView.tsx +++ b/src/components/LearnerAttendanceStatsListView.tsx @@ -1,5 +1,6 @@ import { Box, Grid, Stack, Typography, useMediaQuery } from '@mui/material'; import React, { useState } from 'react'; +import ReactGA from 'react-ga4'; import { UserData, updateCustomField } from '@/utils/Interfaces'; import LearnerModal from './LearnerModal'; @@ -130,7 +131,9 @@ const StudentsStatsList: React.FC = ({ handleOpenModalLearner(userId!)} + onClick={() => {handleOpenModalLearner(userId!) + ReactGA.event("learner-details-link-clicked", { userId: userId}); + }} sx={{ textAlign: 'left', fontSize: '14px', diff --git a/src/components/SortingModal.tsx b/src/components/SortingModal.tsx index d2109277..9176eeb6 100644 --- a/src/components/SortingModal.tsx +++ b/src/components/SortingModal.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import ReactGA from 'react-ga4'; import { FormControl, @@ -88,6 +89,14 @@ const SortingModal: React.FC = ({ sortByClassesMissed, sortByAttendanceNumber ); + ReactGA.event('sort-by-applied', { + sortingBasis: [ + sortByName, + sortByAttendance, + sortByClassesMissed, + sortByAttendanceNumber, + ], + }); handleCloseModal(); }; diff --git a/src/components/UpDownButton.tsx b/src/components/UpDownButton.tsx index 133a7217..9487a893 100644 --- a/src/components/UpDownButton.tsx +++ b/src/components/UpDownButton.tsx @@ -5,6 +5,7 @@ import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward'; import { Box } from '@mui/material'; import { usePathname } from 'next/navigation'; import { useTranslation } from 'next-i18next'; +import { logEvent } from '@/utils/googleAnalytics'; const UpDownButton = () => { const [isVisible, setIsVisible] = useState(false); @@ -49,6 +50,22 @@ const UpDownButton = () => { } }, [pathname]); + const handleBackToTopButtonClicked = () =>{ + logEvent({ + action: 'back-to-top-button-clicked', + category: 'Attendance Overview/ History Page', + label: 'Back To Top Clicked', + }); + } + + const handleLearnerButtonClicked = () =>{ + logEvent({ + action: 'learners-button-clicked', + category: 'Attendance Overview/ History Page', + label: 'Learners Button Clicked', + }); + } + return (
{isVisible && ( @@ -61,6 +78,7 @@ const UpDownButton = () => { {t('DASHBOARD.BACK_TO_TOP')} @@ -69,6 +87,7 @@ const UpDownButton = () => { {t('COMMON.LEARNERS')} diff --git a/src/pages/attendance-history.tsx b/src/pages/attendance-history.tsx index aa7da4b9..aed666cd 100644 --- a/src/pages/attendance-history.tsx +++ b/src/pages/attendance-history.tsx @@ -19,6 +19,7 @@ import { Typography, } from '@mui/material'; import React, { useEffect, useRef, useState } from 'react'; +import ReactGA from 'react-ga4'; import { debounce, getTodayDate, @@ -49,6 +50,7 @@ import { useRouter } from 'next/router'; import { useTheme } from '@mui/material/styles'; import { useTranslation } from 'next-i18next'; import ToastMessage from '@/components/ToastMessage'; +import { logEvent } from '@/utils/googleAnalytics'; interface user { userId: string; @@ -404,6 +406,7 @@ const UserAttendanceHistory = () => { const handleCohortSelection = (event: SelectChangeEvent) => { setClassId(event.target.value as string); + ReactGA.event("cohort-selection-attendance-history-page", { selectedCohortID: event.target.value }); setHandleSaveHasRun(!handleSaveHasRun); // ---------- set cohortId and stateName----------- @@ -440,6 +443,7 @@ const UserAttendanceHistory = () => { // handle search student data const handleSearch = (event: React.ChangeEvent) => { setSearchWord(event.target.value); + ReactGA.event("search-by-keyword-attendance-history-age", { keyword: event.target.value}); if (event.target.value.length >= 3) { debouncedSearch(event.target.value); } else { @@ -570,7 +574,12 @@ const UserAttendanceHistory = () => { width={'100%'} paddingTop={'10px'} > - window.history.back()}> + {window.history.back() + logEvent({ + action: 'back-button-clicked-attendance-history-page', + category: 'Attendance History Page', + label: 'Back Button Clicked', + });}}> = () => { const handleCohortSelection = (event: SelectChangeEvent) => { setClassId(event.target.value as string); + ReactGA.event("cohort-selection-attendance-overview-page", { selectedCohortID: event.target.value }); // ---------- set cohortId and stateName----------- const cohort_id = event.target.value; @@ -491,6 +494,7 @@ const AttendanceOverview: React.FC = () => { setSearchWord(event.target.value); if (event.target.value.length >= 1) { debouncedSearch(event.target.value); + ReactGA.event("search-by-keyword-attendance-overview-page", { keyword: event.target.value}); } else { setDisplayStudentList(learnerData); } @@ -585,6 +589,11 @@ const AttendanceOverview: React.FC = () => { }; const handleBackEvent = () => { window.history.back(); + logEvent({ + action: 'back-button-clicked-attendance-overview', + category: 'Attendance Overview Page', + label: 'Back Button Clicked', + }); }; const truncate = (str: string, length: number) => { if (str.length <= length) return str; diff --git a/src/pages/dashboard.tsx b/src/pages/dashboard.tsx index 7d6d5fc3..04dfd5d4 100644 --- a/src/pages/dashboard.tsx +++ b/src/pages/dashboard.tsx @@ -19,6 +19,7 @@ import { } from '@mui/material'; import { CircularProgressbar, buildStyles } from 'react-circular-progressbar'; import React, { useEffect, useState } from 'react'; +import ReactGA from 'react-ga4'; // import Snackbar, { SnackbarOrigin } from '@mui/material/Snackbar'; import { classesMissedAttendancePercentList, @@ -56,6 +57,7 @@ import useDeterminePathColor from '../hooks/useDeterminePathColor'; import { useRouter } from 'next/navigation'; import { useTheme } from '@mui/material/styles'; import { useTranslation } from 'next-i18next'; +import { logEvent } from '@/utils/googleAnalytics'; // interface State extends SnackbarOrigin { // openModal: boolean; @@ -398,10 +400,16 @@ const Dashboard: React.FC = () => { setShowDetails(true); }; - const handleModalToggle = () => setOpen(!open); + const handleModalToggle = () => {setOpen(!open) + logEvent({ + action: 'mark/modify-attendance-button-clicked-dashboard', + category: 'Dashboard Page', + label: 'Mark/ Modify Attendance', + })}; const handleCohortSelection = (event: SelectChangeEvent) => { setClassId(event.target.value as string); + ReactGA.event("cohort-selection-dashboard", { selectedCohortID: event.target.value }); localStorage.setItem('classId', event.target.value); setHandleSaveHasRun(!handleSaveHasRun); }; @@ -470,6 +478,7 @@ const Dashboard: React.FC = () => { const viewAttendanceHistory = () => { if (classId !== 'all') { router.push('/attendance-history'); + ReactGA.event("month-name-clicked", { selectedCohortID: classId }); } }; @@ -502,6 +511,14 @@ const Dashboard: React.FC = () => { return str.slice(0, length) + '...'; }; + const handleMoreDetailsClicked = () => { + logEvent({ + action: 'more-details-button-clicked', + category: 'Dashboard Page', + label: 'More Details Link Clicked', + }); + }; + return ( <> {!isAuthenticated && ( @@ -834,6 +851,7 @@ const Dashboard: React.FC = () => { color: theme.palette.secondary.main, fontWeight: '500', }} + onClick={handleMoreDetailsClicked} > {t('DASHBOARD.MORE_DETAILS')} diff --git a/src/pages/learner-attendance-history.tsx b/src/pages/learner-attendance-history.tsx index 2abc0469..9450dedd 100644 --- a/src/pages/learner-attendance-history.tsx +++ b/src/pages/learner-attendance-history.tsx @@ -15,6 +15,7 @@ import { useTheme } from '@mui/material/styles'; import { useTranslation } from 'next-i18next'; import { useRouter } from 'next/router'; import ToastMessage from '@/components/ToastMessage'; +import { logEvent } from '@/utils/googleAnalytics'; type LearnerAttendanceData = { [date: string]: { @@ -69,6 +70,11 @@ const LearnerAttendanceHistory = () => { const handleOpen = () => { setOpen(true); + logEvent({ + action: 'individual-learner-attendance-modal-open', + category: 'Learner Attendance History Page', + label: 'Mark Individual Learner Modal Open', + }); }; const handleModalOpen = () => { @@ -77,6 +83,11 @@ const LearnerAttendanceHistory = () => { const handleModalClose = () => { setOpen(false); + logEvent({ + action: 'individual-learner-attendance-modal-close', + category: 'Learner Attendance History Page', + label: 'Mark Individual Learner Modal Close', + }); }; useEffect(() => { diff --git a/src/pages/learner/[userId].tsx b/src/pages/learner/[userId].tsx index b3705c02..a1102c49 100644 --- a/src/pages/learner/[userId].tsx +++ b/src/pages/learner/[userId].tsx @@ -38,6 +38,7 @@ import { } from '@/utils/Interfaces'; import Menu, { MenuProps } from '@mui/material/Menu'; import React, { useEffect, useState } from 'react'; +import ReactGA from 'react-ga4'; import { alpha, styled, useTheme } from '@mui/material/styles'; import { classesMissedAttendancePercentList, @@ -62,6 +63,7 @@ import { format } from 'date-fns'; import { serverSideTranslations } from 'next-i18next/serverSideTranslations'; import { useRouter } from 'next/router'; import { useTranslation } from 'next-i18next'; +import { logEvent } from '@/utils/googleAnalytics'; // import { UserData, updateCustomField } from '../utils/Interfaces'; @@ -329,12 +331,14 @@ const LearnerProfile: React.FC = () => { const handleChangeTest = (event: SelectChangeEvent) => { const test = event.target.value; setTest(test); + ReactGA.event("pre-post-test-selected", { testTypeSelected: test}); getDoIdForAssesmentReport(test, subject); }; const handleChangeSubject = (event: SelectChangeEvent) => { const subject = event.target.value; setSubject(event.target.value); + ReactGA.event("select-subject-learner-details-page", { subjectSelected: subject}); getDoIdForAssesmentReport(test, subject); }; @@ -497,8 +501,19 @@ const LearnerProfile: React.FC = () => { const [contactNumber, setContactNumber] = useState(null); const [openEdit, setOpenEdit] = React.useState(false); const [loading, setLoading] = useState(false); - const handleOpen = () => setOpenEdit(true); + const handleOpen = () => {setOpenEdit(true) + logEvent({ + action: 'edit-learner-profile-modal-open', + category: 'Learner Detail Page', + label: 'Edit Learner Profile Modal Open', + }); + }; const handleClose = () => { + logEvent({ + action: 'edit-learner-profile-modal-close', + category: 'Learner Detail Page', + label: 'Edit Learner Profile Modal Close', + }); setOpenEdit(false); initialFormData(); setHasInputChanged(false); @@ -619,6 +634,11 @@ const LearnerProfile: React.FC = () => { e: React.MouseEvent ) => { e.preventDefault(); + logEvent({ + action: 'save-button-clicked-edit-learner-profile', + category: 'Learner Detail Page', + label: 'Learner Profile Save Button Clicked', + }); setLoading(true); const user_id = userId; const data = { @@ -637,8 +657,10 @@ const LearnerProfile: React.FC = () => { try { if (userId) { const response = await editEditUser(user_id, userDetails); + ReactGA.event("edit-learner-profile-successful", { userId: userId}); if (response.responseCode !== 200 || response.params.err) { + ReactGA.event("edit-learner-profile-failed", { userId: userId}); throw new Error( response.params.errmsg || 'An error occurred while updating the user.' @@ -809,7 +831,13 @@ const LearnerProfile: React.FC = () => { - window.history.back()}> + { + window.history.back() + logEvent({ + action: 'back-button-clicked-learner-detail-page', + category: 'Learner Detail Page', + label: 'Back Button Clicked', + });}}> { setPassword(value); }; - const handleClickShowPassword = () => setShowPassword((show) => !show); + const handleClickShowPassword = () => {setShowPassword((show) => !show); + logEvent({ + action: 'show-password-icon-clicked', + category: 'Login Page', + label: 'Show Password', + })}; const handleMouseDownPassword = ( event: React.MouseEvent @@ -101,6 +108,11 @@ const LoginPage = () => { const handleFormSubmit = async (event: React.FormEvent) => { event.preventDefault(); + logEvent({ + action: 'login-button-clicked', + category: 'Login Page', + label: 'Login Button Clicked', + }); if (!usernameError && !passwordError) { setLoading(true); try { @@ -152,6 +164,7 @@ const LoginPage = () => { if (typeof window !== 'undefined' && window.localStorage) { localStorage.setItem('preferredLanguage', newLocale); setLanguage(event.target.value); + ReactGA.event("select-language-login-page", { selectedLanguage: event.target.value}); router.push('/login', undefined, { locale: newLocale }); } }; @@ -184,6 +197,14 @@ const LoginPage = () => { } }, []); + const handleForgotPasswordClick = () => { + logEvent({ + action: 'forgot-password-link-clicked', + category: 'Login Page', + label: 'Forgot Password Link Clicked', + }); + }; + return (
@@ -316,6 +337,7 @@ const LoginPage = () => { sx={{ color: theme.palette.secondary.main }} href="https://qa.prathamteacherapp.tekdinext.com/auth/realms/pratham/login-actions/reset-credentials?client_id=security-admin-console&tab_id=rPJFHSFv50M" underline="none" + onClick={handleForgotPasswordClick} > {t('LOGIN_PAGE.FORGOT_PASSWORD')} @@ -331,7 +353,13 @@ const LoginPage = () => { color: theme.palette.warning['300'], }} className="fw-400" - onClick={() => setRememberMe(!rememberMe)} + onClick={() => {setRememberMe(!rememberMe) + logEvent({ + action: 'remember-me-button-clicked', + category: 'Login Page', + label: `Remember Me ${rememberMe ? 'Checked' : 'Unchecked'}`, + }) + }} > {t('LOGIN_PAGE.REMEMBER_ME')} diff --git a/src/pages/profile.tsx b/src/pages/profile.tsx index 8864d54f..3ffcaba3 100644 --- a/src/pages/profile.tsx +++ b/src/pages/profile.tsx @@ -20,6 +20,7 @@ import { } from '@mui/material'; import { CustomField, UserDatas, updateCustomField } from '@/utils/Interfaces'; import React, { ChangeEvent, useEffect, useRef, useState } from 'react'; +import ReactGA from 'react-ga4'; import { editEditUser, getUserDetails } from '@/services/ProfileService'; import { useTheme, withStyles } from '@mui/material/styles'; @@ -39,6 +40,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 { logEvent } from '@/utils/googleAnalytics'; interface FieldOption { name: string; @@ -64,7 +66,13 @@ const TeacherProfile = () => { const router = useRouter(); const theme = useTheme(); const [open, setOpen] = React.useState(false); - const handleOpen = () => setOpen(true); + const handleOpen = () => {setOpen(true) + logEvent({ + action: 'edit-teacher-profile-modal-open', + category: 'Profile Page', + label: 'Edit Teacher Profile Modal Open', + }); + }; const [errors, setErrors] = useState<{ [key: string]: boolean }>({}); const handleClose = () => { @@ -73,6 +81,11 @@ const TeacherProfile = () => { setHasInputChanged(false); setHasErrors(false); setErrors({}); + logEvent({ + action: 'edit-teacher-profile-modal-close', + category: 'Profile Page', + label: 'Edit Teacher Profile Modal Close', + }); }; const [userData, setUserData] = useState(null); const [userName, setUserName] = useState(null); @@ -404,6 +417,11 @@ const TeacherProfile = () => { e: React.MouseEvent ) => { e.preventDefault(); + logEvent({ + action: 'save-button-clicked-edit-teacher-profile', + category: 'Profile Page', + label: 'Teacher Profile Save Button Clicked', + }); setLoading(true); const userId = localStorage.getItem('userId'); const data = { @@ -422,8 +440,9 @@ const TeacherProfile = () => { try { if (userId) { const response = await editEditUser(userId, userDetails); - + ReactGA.event("edit-teacher-profile-successful", { userId: userId}); if (response.responseCode !== 200 || response.params.err) { + ReactGA.event("edit-teacher-profile-error", { userId: userId}); throw new Error( response.params.errmsg || 'An error occurred while updating the user.'