diff --git a/src/containers/DashRoutes.tsx b/src/containers/DashRoutes.tsx
index c057430b..423da373 100644
--- a/src/containers/DashRoutes.tsx
+++ b/src/containers/DashRoutes.tsx
@@ -42,6 +42,9 @@ const ViewTraineeRatings = React.lazy(
const TtlTraineeDashboard = React.lazy(
() => import('../pages/ttlTraineeDashboard'),
);
+const LoginWith2fa = React.lazy(
+ () => import('../pages/LoginWith2fa'),
+);
const TraineeRatingDashboard = React.lazy(
() => import('../pages/TraineeRatingDashboard'),
diff --git a/src/containers/Routes.tsx b/src/containers/Routes.tsx
index c7193430..6d655e50 100644
--- a/src/containers/Routes.tsx
+++ b/src/containers/Routes.tsx
@@ -43,6 +43,7 @@ import RemoveTokenPage from '../utils/RemoveTokenPage';
import PrivateRoute from '../utils/PrivateRoute';
import CalendarConfirmation from '../components/CalendarConfirmation';
import NotFound from '../components/NotFoundPage';
+import TwoFactorPage from '../pages/LoginWith2fa';
function MainRoutes() {
return (
@@ -123,13 +124,14 @@ function MainRoutes() {
+
}>
-
+
}
/>
+ }/>
{
+ const [input, setInput] = useState(Array(6).fill(''));
+ const [error, setError] = useState('');
+ const [loading, setLoading] = useState(false);
+ const [isDark, setIsDark] = useState(false);
+ const { login } = useContext(UserContext);
+ const client = useApolloClient();
+ const { t } = useTranslation();
+
+ const location = useLocation();
+ const navigate = useNavigate();
+ const { email, TwoWayVerificationToken } = location.state || {};
+ useEffect(() => {
+ // Update document class and localStorage when theme changes
+ if (isDark) {
+ document.documentElement.classList.add('dark');
+ localStorage.setItem('theme', 'dark');
+ } else {
+ document.documentElement.classList.remove('dark');
+ localStorage.setItem('theme', 'light');
+ }
+ }, [isDark]);
+
+ useEffect(() => {
+ if (!email || !TwoWayVerificationToken) {
+ navigate('/login');
+ }
+ }, [email, TwoWayVerificationToken, navigate]);
+
+ const [loginWithTwoFactorAuthentication] = useMutation(
+ LOGIN_WITH_2FA,
+ {
+ onCompleted: async (data) => {
+ const response = data.loginWithTwoFactorAuthentication;
+ try {
+ localStorage.setItem('authToken', response.token);
+ localStorage.setItem('user', JSON.stringify(response.user));
+ await login(response);
+ await client.resetStore();
+ toast.success(response.message);
+
+ const rolePaths: Record = {
+ superAdmin: '/organizations',
+ admin: '/trainees',
+ coordinator: '/trainees',
+ manager: '/dashboard',
+ ttl: '/ttl-trainees',
+ trainee: '/performance',
+ };
+
+ const redirectPath = rolePaths[response.user.role] || '/dashboard';
+ navigate(redirectPath, { replace: true });
+ } catch (error) {
+ toast.error('Login Error');
+ }
+ },
+ onError: (error) => {
+ const errorMessage = error.message || 'Verification Failed';
+ setError(errorMessage);
+ toast.error(errorMessage);
+ setInput(Array(6).fill(''));
+ },
+ },
+ );
+
+ const verifyOtp = async (currentInput = input) => {
+ if (currentInput.some((val) => !val)) {
+ setError('Please Enter All Digits');
+ return;
+ }
+
+ setLoading(true);
+ setError('');
+
+ try {
+ await loginWithTwoFactorAuthentication({
+ variables: {
+ email,
+ otp: currentInput.join(''),
+ TwoWayVerificationToken,
+ },
+ });
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ const handleInput = useCallback(
+ (index: number, value: string) => {
+ if (!/^\d*$/.test(value)) return;
+
+ const newInput = [...input];
+ newInput[index] = value;
+ setInput(newInput);
+
+ if (value && index < input.length - 1) {
+ const nextInput = document.getElementById(
+ `otp-input-${index + 1}`,
+ ) as HTMLInputElement;
+ nextInput?.focus();
+ }
+
+ if (value && index === input.length - 1) {
+ const allFilled = newInput.every((val) => val !== '');
+ if (allFilled) {
+ verifyOtp(newInput);
+ }
+ }
+ },
+ [input],
+ );
+
+ const handleKeyDown = (
+ index: number,
+ e: React.KeyboardEvent,
+ ) => {
+ if (e.key === 'Backspace' && !input[index] && index > 0) {
+ const prevInput = document.getElementById(
+ `otp-input-${index - 1}`,
+ ) as HTMLInputElement;
+ prevInput?.focus();
+ }
+ };
+
+ const handlePaste = (e: React.ClipboardEvent) => {
+ e.preventDefault();
+ const pastedData = e.clipboardData.getData('text').trim();
+
+ if (!/^\d+$/.test(pastedData)) {
+ setError('Only Numbers Can Be Pasted');
+ return;
+ }
+
+ const digits = pastedData.slice(0, 6).split('');
+ const newInput = [...digits, ...Array(6 - digits.length).fill('')];
+
+ setInput(newInput);
+
+ if (digits.length < 6) {
+ const nextEmptyIndex = digits.length;
+ const nextInput = document.getElementById(
+ `otp-input-${nextEmptyIndex}`,
+ ) as HTMLInputElement;
+ nextInput?.focus();
+ } else {
+ verifyOtp(newInput);
+ }
+ };
+
+ const toggleTheme = () => {
+ setIsDark(!isDark);
+ };
+
+ return (
+
+
+
+ {'Verification Required'}
+
+
+
+ {'Enter Verification Code'}
+
+ {email}
+
+
+ {error && (
+
+ {error}
+
+ )}
+
+
+
+
+ );
+};
+
+export default TwoFactorPage;
diff --git a/src/pages/Organization/2faMutation.tsx b/src/pages/Organization/2faMutation.tsx
new file mode 100644
index 00000000..db253ac3
--- /dev/null
+++ b/src/pages/Organization/2faMutation.tsx
@@ -0,0 +1,26 @@
+import { gql } from '@apollo/client';
+
+export const EnableTwoFactorAuth = gql`
+ mutation EnableTwoFactorAuth($email: String!) {
+ enableTwoFactorAuth(email: $email)
+ }
+`;
+
+
+export const LoginWithTwoFactorAuthentication= gql`
+mutation LoginWithTwoFactorAuthentication($email: String!, $otp: String!, $twoWayVerificationToken: String!) {
+ loginWithTwoFactorAuthentication(email: $email, otp: $otp, TwoWayVerificationToken: $twoWayVerificationToken) {
+ message
+ token
+ user {
+ email
+ }
+ }
+}
+`;
+
+export const DisableTwoFactorAuth = gql`
+ mutation DisableTwoFactorAuth($email: String!) {
+ disableTwoFactorAuth(email: $email)
+ }
+`;
diff --git a/src/pages/Organization/AdminLogin.tsx b/src/pages/Organization/AdminLogin.tsx
index f0c25fbe..a3a37788 100644
--- a/src/pages/Organization/AdminLogin.tsx
+++ b/src/pages/Organization/AdminLogin.tsx
@@ -1,337 +1,348 @@
-/* eslint-disable */
-'use client';
-import { useApolloClient, useMutation } from '@apollo/client';
-import React, { useContext, useEffect, useState } from 'react';
-import { useForm } from 'react-hook-form';
-import { useTranslation } from 'react-i18next';
-import { FaRegEnvelope, FaRegEye } from 'react-icons/fa';
-import { FiEyeOff } from 'react-icons/fi';
-import { MdLockOutline } from 'react-icons/md';
-import {
- Link,
- useLocation,
- useNavigate,
- useSearchParams,
-} from 'react-router-dom';
-import { toast, ToastContent } from 'react-toastify';
-import ButtonLoading from '../../components/ButtonLoading';
-import Button from '../../components/Buttons';
-import { UserContext } from '../../hook/useAuth';
-import useDocumentTitle from '../../hook/useDocumentTitle';
-import LOGIN_MUTATION from './LoginMutation';
-import functionTree from '../../assets/Functionality_Tree.svg';
-import pulseStars from '../../assets/Property 1=Logo_flie (1).svg';
-
-function AdminLogin() {
- const orgToken: any = localStorage.getItem('orgToken');
- const orgName: any = localStorage.getItem('orgName');
- const [loading, setLoading] = useState(false);
-
- useDocumentTitle('Login');
- const { t } = useTranslation();
- const [passwordShown, setPasswordShown] = useState(false);
- /* istanbul ignore next */
- const tooglePassword = () => {
- setPasswordShown(!passwordShown);
- };
- const {
- register,
- handleSubmit,
- formState: { errors },
- setError,
- }: any = useForm();
- const { login } = useContext(UserContext);
- const navigate = useNavigate();
- const { state } = useLocation();
- const [LoginUser] = useMutation(LOGIN_MUTATION);
- const client = useApolloClient();
- const [searchParams] = useSearchParams();
-
- // Function to get the redirect_message from the URL and toast it
- const showRedirectMessage = () => {
- const redirectMessage = searchParams.get('redirect_message');
- if (redirectMessage) {
- toast.error(redirectMessage);
- }
- };
-
- // Call showRedirectMessage when the component mounts
- useEffect(() => {
- showRedirectMessage();
- }, [searchParams]);
-
- const onSubmit = async (userInput: any) => {
- userInput.orgToken = orgToken;
- try {
- setLoading(true);
- const redirect = searchParams.get('redirect');
- // const activity = await getLocation();
- await LoginUser({
- variables: {
- loginInput: {
- ...userInput,
- // activity, //disable geolocation
- },
- },
-
- /* istanbul ignore next */
- onCompleted: async (data) => {
- /* istanbul ignore next */
- toast.success(data.addMemberToCohort);
- /* istanbul ignore next */
- login(data.loginUser);
- /* istanbul ignore next */
- await client.resetStore();
- /* istanbul ignore next */
- toast.success(t(`Welcome`) as ToastContent);
- /* istanbul ignore next */
-
- const redirectParams=sessionStorage.getItem("redirectParams")||''
- if (data.loginUser) {
- redirect
- ? navigate(`${redirect}`)
- : data.loginUser.user.role === 'superAdmin'
- ? navigate(`/dashboard`)
- : data.loginUser.user.role === 'admin'
- ? navigate(`/trainees`)
- : data.loginUser.user.role === 'coordinator'
- ? navigate(`/trainees`)
- : data.loginUser.user.role === 'manager'
- ? navigate(`/dashboard`)
- : data.loginUser.user.role === 'ttl'
- ? navigate('/ttl-trainees')
- : navigate('/performance');
- sessionStorage.removeItem("redirectParams")
- } else {
- navigate('/dashboard');
- }
- },
- onError: (err) => {
- console.log(err)
- if (err.networkError)
- toast.error('There was a problem contacting the server');
- else if (err.message.toLowerCase() !== 'invalid credential') {
- const translateError = t(
- 'Please wait to be added to a program or cohort',
- );
- toast.error(translateError);
- } else {
- /* istanbul ignore next */
- setError('password', {
- type: 'custom',
- message: t('Invalid credentials'),
- });
- }
- },
- });
- } catch (error: any) {
- /* istanbul ignore next */
- setError('password', {
- type: 'custom',
- message: t('Invalid credentials'),
- });
- } finally {
- setLoading(false);
- }
- };
-
- const getLocation = async () => {
- const location = await fetch('https://geolocation-db.com/json/')
- .then(async (res) => {
- const activityResponse = await res.json();
-
- const activityResponseActual = {
- IPv4: activityResponse.IPv4,
- city: activityResponse.city,
- country_code: activityResponse.country_code,
- country_name: activityResponse.country_name,
- latitude:
- activityResponse.latitude === 'Not found'
- ? null
- : activityResponse.latitude,
- longitude:
- activityResponse.longitude === 'Not found'
- ? null
- : activityResponse.longitude,
- postal: activityResponse.postal,
- state: activityResponse.state,
- };
- return activityResponseActual;
- })
- .then((data) => data);
- const date = new Date().toString();
- return { date, ...location } || null;
- };
-
- return (
-
-
-
-
-
-
- {t('Boost your organization')}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {t('Welcome to')}{' '}
- {orgName
- ? orgName.charAt(0).toUpperCase() +
- orgName.slice(1).toLowerCase()
- : ''}
-
-
-
-
-
-
- {t('Switch')} {t('your organization')}
-
-
-
-
-
-
- {t('First time here?')}
-
- {t('Register')}
-
- {t('your organization')}
-
-
-
-
-
- );
-}
-
-export default AdminLogin;
+/* eslint-disable */
+'use client';
+import { useApolloClient, useMutation } from '@apollo/client';
+import React, { useContext, useEffect, useState } from 'react';
+import { useForm } from 'react-hook-form';
+import { useTranslation } from 'react-i18next';
+import { FaRegEnvelope, FaRegEye } from 'react-icons/fa';
+import { FiEyeOff } from 'react-icons/fi';
+import { MdLockOutline } from 'react-icons/md';
+import {
+ Link,
+ useLocation,
+ useNavigate,
+ useSearchParams,
+} from 'react-router-dom';
+import { toast, ToastContent } from 'react-toastify';
+import ButtonLoading from '../../components/ButtonLoading';
+import Button from '../../components/Buttons';
+import { UserContext } from '../../hook/useAuth';
+import useDocumentTitle from '../../hook/useDocumentTitle';
+import LOGIN_MUTATION from './LoginMutation';
+import functionTree from '../../assets/Functionality_Tree.svg';
+import pulseStars from '../../assets/Property 1=Logo_flie (1).svg';
+
+function AdminLogin() {
+ const orgToken: any = localStorage.getItem('orgToken');
+ const orgName: any = localStorage.getItem('orgName');
+ const [loading, setLoading] = useState(false);
+ const [otpRequired, setOtpRequired] = useState(false);
+ const [TwoWayVerificationToken, setTwoWayVerificationToken] = useState('');
+ const [otp, setOtp] = useState('');
+
+ useDocumentTitle('Login');
+ const { t } = useTranslation();
+ const [passwordShown, setPasswordShown] = useState(false);
+ /* istanbul ignore next */
+ const tooglePassword = () => {
+ setPasswordShown(!passwordShown);
+ };
+ const {
+ register,
+ handleSubmit,
+ formState: { errors },
+ setError,
+ }: any = useForm();
+ const { login } = useContext(UserContext);
+ const navigate = useNavigate();
+ const [LoginUser] = useMutation(LOGIN_MUTATION);
+ const client = useApolloClient();
+ const [searchParams] = useSearchParams();
+ // Function to get the redirect_message from the URL and toast it
+ const showRedirectMessage = () => {
+ const redirectMessage = searchParams.get('redirect_message');
+ if (redirectMessage) {
+ toast.error(redirectMessage);
+ }
+ };
+
+ // Call showRedirectMessage when the component mounts
+ useEffect(() => {
+ showRedirectMessage();
+ }, [searchParams]);
+
+ const onSubmit = async (userInput: any) => {
+ userInput.orgToken = orgToken;
+ try {
+ setLoading(true);
+ const redirect = searchParams.get('redirect');
+ // const activity = await getLocation();
+ await LoginUser({
+ variables: {
+ loginInput: {
+ ...userInput,
+ // activity, //disable geolocation
+ },
+ },
+
+
+ /* istanbul ignore next */
+ onCompleted: async (data) => {
+ if (data.loginUser.otpRequired) {
+ setOtpRequired(true);
+ setTwoWayVerificationToken(data.loginUser.TwoWayVerificationToken);
+ navigate('/users/LoginWith2fa', {
+ state: {
+ email: userInput.email,
+ TwoWayVerificationToken: data.loginUser.TwoWayVerificationToken,
+ },})
+
+ }else{
+ /* istanbul ignore next */
+ toast.success(data.addMemberToCohort);
+ /* istanbul ignore next */
+ login(data.loginUser);
+ /* istanbul ignore next */
+ await client.resetStore();
+ /* istanbul ignore next */
+ toast.success(t(`Welcome`) as ToastContent);
+ /* istanbul ignore next */
+ if (data.loginUser) {
+ redirect
+ ? navigate(`${redirect}`)
+ : data.loginUser.user.role === 'superAdmin'
+ ? navigate(`/dashboard`)
+ : data.loginUser.user.role === 'admin'
+ ? navigate(`/trainees`)
+ : data.loginUser.user.role === 'coordinator'
+ ? navigate(`/trainees`)
+ : data.loginUser.user.role === 'manager'
+ ? navigate(`/dashboard`)
+ : data.loginUser.user.role === 'ttl'
+ ? navigate('/ttl-trainees')
+ : navigate('/performance');
+ } else {
+ navigate('/dashboard');
+ }
+ }},
+ onError: (err) => {
+ /* istanbul ignore next */
+ console.log(err.message);
+
+ if (err.networkError)
+ toast.error('There was a problem contacting the server');
+ else if (err.message.toLowerCase() !== 'invalid credential') {
+ const translateError = t(
+ 'Please wait to be added to a program or cohort',
+ );
+ toast.error(translateError);
+ } else {
+ /* istanbul ignore next */
+ setError('password', {
+ type: 'custom',
+ message: t('Invalid credentials'),
+ });
+ }
+ },
+ });
+ } catch (error: any) {
+ /* istanbul ignore next */
+ setError('password', {
+ type: 'custom',
+ message: t('Invalid credentials'),
+ });
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ const getLocation = async () => {
+ const location = await fetch('https://geolocation-db.com/json/')
+ .then(async (res) => {
+ const activityResponse = await res.json();
+
+ const activityResponseActual = {
+ IPv4: activityResponse.IPv4,
+ city: activityResponse.city,
+ country_code: activityResponse.country_code,
+ country_name: activityResponse.country_name,
+ latitude:
+ activityResponse.latitude === 'Not found'
+ ? null
+ : activityResponse.latitude,
+ longitude:
+ activityResponse.longitude === 'Not found'
+ ? null
+ : activityResponse.longitude,
+ postal: activityResponse.postal,
+ state: activityResponse.state,
+ };
+ return activityResponseActual;
+ })
+ .then((data) => data);
+ const date = new Date().toString();
+ return { date, ...location } || null;
+ };
+
+ return (
+
+
+
+
+
+
+ {t('Boost your organization')}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {t('Welcome to')}{' '}
+ {orgName
+ ? orgName.charAt(0).toUpperCase() +
+ orgName.slice(1).toLowerCase()
+ : ''}
+
+
+
+
+
+
+ {t('Switch')} {t('your organization')}
+
+
+
+
+
+
+ {t('First time here?')}
+
+ {t('Register')}
+
+ {t('your organization')}
+
+
+
+
+
+ );
+}
+
+export default AdminLogin;
diff --git a/src/pages/Organization/LoginMutation.tsx b/src/pages/Organization/LoginMutation.tsx
index 5c7eae76..ef97ad0c 100644
--- a/src/pages/Organization/LoginMutation.tsx
+++ b/src/pages/Organization/LoginMutation.tsx
@@ -4,6 +4,8 @@ const LOGIN_MUTATION = gql`
mutation Mutation($loginInput: LoginInput) {
loginUser(loginInput: $loginInput) {
token
+ otpRequired
+ TwoWayVerificationToken
user {
id
role
diff --git a/src/pages/Settings.tsx b/src/pages/Settings.tsx
index 74af41c7..96508e43 100644
--- a/src/pages/Settings.tsx
+++ b/src/pages/Settings.tsx
@@ -1,15 +1,17 @@
+/* eslint-disable */
import React, { useState, useEffect, useRef, useContext } from 'react';
import i18next from 'i18next';
import { Link } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { Switch } from '@headlessui/react';
-import { useMutation, useQuery } from '@apollo/client';
+import { gql, useMutation, useQuery } from '@apollo/client';
import getLanguage from '../utils/getLanguage';
import useDocumentTitle from '../hook/useDocumentTitle';
import {
updatePushNotifications,
updateEmailNotifications,
} from '../Mutations/notificationMutation';
+import { EnableTwoFactorAuth,DisableTwoFactorAuth } from './Organization/2faMutation';
import {
updatedEmailNotifications,
updatedPushNotifications,
@@ -17,6 +19,16 @@ import {
import { UserContext } from '../hook/useAuth';
import { ThemeContext } from '../hook/ThemeProvider';
+const GetProfile = gql`
+ query GetProfile {
+ getProfile {
+ user {
+ twoFactorAuth
+ }
+ }
+ }
+`;
+
function Settings() {
useDocumentTitle('Settings');
const { t } = useTranslation();
@@ -24,74 +36,82 @@ function Settings() {
const lan = getLanguage();
const { colorTheme, setTheme } = useContext(ThemeContext);
const { user } = useContext(UserContext);
- const [updateEmailNotificationsMutation] = useMutation(
- updateEmailNotifications,
- );
- const [updatePushNotificationsMutation] = useMutation(
- updatePushNotifications,
- );
+
+ const [isTwoFactorEnabled, setIsTwoFactorEnabled] = useState(false);
+ const [enableTwoFactorAuth] = useMutation(EnableTwoFactorAuth);
+ const [disableTwoFactorAuth] = useMutation(DisableTwoFactorAuth);
+ const [updateEmailNotificationsMutation] = useMutation(updateEmailNotifications);
+ const [updatePushNotificationsMutation] = useMutation(updatePushNotifications);
+
+ const { data: profileData } = useQuery(GetProfile, {
+ onCompleted: data => setIsTwoFactorEnabled(data.getProfile.user.twoFactorAuth),
+ });
const { data: pushData } = useQuery(updatedPushNotifications, {
variables: { getUpdatedPushNotificationsId: user?.userId },
+ onCompleted: data => setPushEnabled(data.getUpdatedPushNotifications),
});
- const [pushEnabled, setPushEnabled] = useState(
- pushData?.getUpdatedPushNotifications || false,
- );
- const { data } = useQuery(updatedEmailNotifications, {
+ const { data: emailData } = useQuery(updatedEmailNotifications, {
variables: { getUpdatedEmailNotificationsId: user?.userId },
+ onCompleted: data => setEmailEnabled(data.getUpdatedEmailNotifications),
});
- const [emailEnabled, setEmailEnabled] = useState(
- data?.getUpdatedEmailNotifications || false,
- );
- const handleThemeChange = (e: { target: { value: any } }) => {
+ const [pushEnabled, setPushEnabled] = useState(false);
+ const [emailEnabled, setEmailEnabled] = useState(false);
+
+ const handleEnableTwoFactor = async () => {
+ try {
+ await enableTwoFactorAuth({ variables: { email: user?.email } });
+ setIsTwoFactorEnabled(true);
+ } catch (error) {
+ console.error("Error enabling two-factor authentication:", error);
+ }
+ };
+
+ const handleDisableTwoFactor = async () => {
+ try {
+ await disableTwoFactorAuth({ variables: { email: user?.email } });
+ setIsTwoFactorEnabled(false);
+ } catch (error) {
+ console.error("Error disabling two-factor authentication:", error);
+ }
+ };
+
+ const handleThemeChange = (e: React.ChangeEvent) => {
const { value } = e.target;
setTheme(value);
- localStorage.setItem('color-theme', colorTheme);
+ localStorage.setItem('color-theme', value);
};
- const defaultTheme: any = colorTheme;
- const userLang = window.navigator.language;
- const handleLanChange = (e: { target: { value: any } }) => {
+ const userLang = window.navigator.language;
+ const handleLanChange = (e: React.ChangeEvent) => {
const { value } = e.target;
- i18next.changeLanguage(value);
+ i18next.changeLanguage(value).catch((error) => {
+ console.error("Error changing language:", error);
+ });
};
const handleEmailNotificationChange = async () => {
try {
- const { data } = await updateEmailNotificationsMutation({
+ await updateEmailNotificationsMutation({
variables: { updateEmailNotificationsId: user?.userId },
});
- setEmailEnabled((prevEmailEnabled: any) => !prevEmailEnabled);
- return data;
- } catch (error: any) {
- return `Error updating email notifications:${error}`;
+ setEmailEnabled((prevEmailEnabled) => !prevEmailEnabled);
+ } catch (error) {
+ console.error("Error updating email notifications:", error);
}
};
const handlePushNotificationChange = async () => {
try {
- const { data: pushData } = await updatePushNotificationsMutation({
+ await updatePushNotificationsMutation({
variables: { updatePushNotificationsId: user?.userId },
});
- setPushEnabled((prevPushEnabled: any) => !prevPushEnabled);
- return pushData;
- } catch (error: any) {
- return `Error updating push notifications: ${error}`;
+ setPushEnabled((prevPushEnabled) => !prevPushEnabled);
+ } catch (error) {
+ console.error("Error updating push notifications:", error);
}
};
- useEffect(() => {
- if (data?.getUpdatedEmailNotifications !== undefined) {
- setEmailEnabled(data.getUpdatedEmailNotifications);
- }
- }, [data]);
-
- useEffect(() => {
- if (pushData?.getUpdatedPushNotifications !== undefined) {
- setPushEnabled(pushData.getUpdatedPushNotifications);
- }
- }, [pushData]);
-
useEffect(() => {
if (lanRef.current) {
lanRef.current.value = lan;
@@ -132,9 +152,9 @@ function Settings() {