Skip to content

Commit

Permalink
fix(preference): add icon and able to expand
Browse files Browse the repository at this point in the history
- add icons on preference settings
- redirect the login activities preference

[issueid: #104]
  • Loading branch information
niyibi250 committed Nov 21, 2024
1 parent 0d3869b commit 5b771da
Show file tree
Hide file tree
Showing 11 changed files with 233 additions and 110 deletions.
Binary file added assets/Preference_icons/down_arrow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Preference_icons/forward-pref-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions assets/Preference_icons/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
declare module '*.png' {
const content: any;
export default content;
}


7 changes: 7 additions & 0 deletions assets/Preference_icons/preference_icons.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import forward_pref_icon from '@/assets/Preference_icons/forward-pref-icon.png'
import down_arrow from '@/assets/Preference_icons/down_arrow.png'

export {
forward_pref_icon,
down_arrow
}
183 changes: 146 additions & 37 deletions components/settingPreference/SettingPreference.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,35 @@
import React, { useState } from 'react';
import { View, Switch, Text, useColorScheme, TouchableOpacity, StyleSheet } from 'react-native';
import { useEffect, useState } from 'react';
import { View, Switch, Text, useColorScheme, TouchableOpacity, StyleSheet, Image } from 'react-native';
import { router } from 'expo-router';
import LanguagePicker from '../LanguagePicker';
import { Dropdown } from 'react-native-element-dropdown';
import { useTranslation } from 'react-i18next';
import { useMutation, useQuery } from '@apollo/client';
import { EnableTwoFactorAuth,DisableTwoFactorAuth } from '@/graphql/mutations/two-factor.mutation';
import {updatePushNotifications,updateEmailNotifications} from '@/graphql/mutations/notificationMutation';
import { useToast } from 'react-native-toast-notifications';
import {
forward_pref_icon,
down_arrow
} from '@/assets/Preference_icons/preference_icons'
import AsyncStorage from '@react-native-async-storage/async-storage';
import { GET_PROFILE } from '@/graphql/queries/user';

const settings = () => {
const [emailNotifications, setEmailNotifications] = useState(false);
const [pushNotifications, setPushNotifications] = useState(false);
const toast = useToast();
const [isTwoFactorEnabled, setIsTwoFactorEnabled] = useState(false);
const [pushEnabled, setPushEnabled] = useState(false);
const [emailEnabled, setEmailEnabled] = useState(false);
const [enableTwoFactorAuth] = useMutation(EnableTwoFactorAuth);
const [disableTwoFactorAuth] = useMutation(DisableTwoFactorAuth);
const [updateEmailNotificationsMutation] = useMutation(updateEmailNotifications);
const [updatePushNotificationsMutation] = useMutation(updatePushNotifications);
const [userToken, setUserToken] = useState<string | null>(null);
const [selectedTheme, setSelectedTheme] = useState('system');
const { t } = useTranslation();

const [isProfileExpanded, setIsProfileExpanded] = useState(false);

const colorScheme = selectedTheme === 'system' ? useColorScheme() : selectedTheme;
const textStyle = colorScheme === 'dark' ? 'text-gray-100' : 'text-gray-800';
const borderColor = colorScheme === 'dark' ? 'border-gray-700' : 'border-gray-300';
Expand All @@ -22,23 +41,108 @@ const settings = () => {
{ label: 'Dark', value: 'dark' },
];

useEffect(() => {
(async () => {
const token = await AsyncStorage.getItem('authToken');
if (token) {
setUserToken(token);
}
})();
}, []);

const { data, error } = useQuery(GET_PROFILE, {
context: {
headers: {
Authorization: `Bearer ${userToken}`,
},
},
skip: !userToken,
});

const handleEnableTwoFactor = async () => {
try {
setIsTwoFactorEnabled(true);
await enableTwoFactorAuth({ variables: { email: data.getProfile.user?.email } });
toast.show(t('toasts.preferences.enableTwo-way'), { type: 'success', placement: 'top', duration: 3000 });

} catch (error) {
setIsTwoFactorEnabled(false);
toast.show(t('toasts.preferences.failEnableTwoway'), { type: 'danger', placement: 'top', duration: 3000 });
}
};

const handleDisableTwoFactor = async () => {
try {
setIsTwoFactorEnabled(false);
await disableTwoFactorAuth({ variables: { email: data.getProfile.user?.email } });
toast.show(t('toasts.preferences.desableTwo-way'), { type: 'success', placement: 'top', duration: 3000 });

} catch (error) {
setIsTwoFactorEnabled(true);
toast.show(t('toasts.preferences.failDesableTwoway'), { type: 'danger', placement: 'top', duration: 3000 });
}
};

const handleEmailNotificationChange = async () => {
try {
await updateEmailNotificationsMutation({
variables: { updateEmailNotificationsId: data.getProfile.user.id },
});
setEmailEnabled((prevEmailEnabled) => !prevEmailEnabled);
toast.show(t('toasts.preferences.updateEmailNotification'), { type: 'success', placement: 'top', duration: 3000 });

} catch (error) {
toast.show(t('toasts.preferences.failUpdatingeEmail'), { type: 'danger', placement: 'top', duration: 3000 });
}
};

const handlePushNotificationChange = async () => {
try {
await updatePushNotificationsMutation({
variables: { updatePushNotificationsId: data.getProfile.user?.id },
});
setPushEnabled((prevPushEnabled) => !prevPushEnabled);
toast.show(t('toasts.preferences.updatePushNotification'), { type: 'success', placement: 'top', duration: 3000 });

} catch (error) {
toast.show(t('toasts.preferences.failUpdatingPush'), { type: 'danger', placement: 'top', duration: 3000 });
}
};

return (
<View className={`p-4 mb-8 ${containerStyle}`}>
<Text className={`text-2xl font-extrabold ml-4 mb-4 ${textStyle}`}>{t('settings.title')}</Text>
{/* Profile Section */}
<View className="mb-6 p-4 rounded-lg flex flex-row justify-center">
<View className="flex-1 mr-4">
<Text className={`text-xl font-bold ${textStyle}`}>{t('settings.profile')}</Text>
<Text className={`text-lg mt-2 ${textStyle}`}>{t('settings.editProfile')}</Text>
</View>
<TouchableOpacity className="flex items-end">
<Text
className={`${textStyle} mt-2`}
onPress={() => router.push('/dashboard/trainee/profile')}
>
{t('settings.change')}
</Text>
<View className={`rounded-lg`}>
<TouchableOpacity
className="p-4 flex-row items-center justify-between"
onPress={() => setIsProfileExpanded(!isProfileExpanded)}
>
<View className="flex-row items-center gap-2">
<Text className={`text-xl font-bold ${textStyle}`}>{t('settings.profile')}</Text>
</View>
<Image
source={isProfileExpanded ? down_arrow : forward_pref_icon}
style={{
height: 24,
width: 24,
tintColor: colorScheme === 'dark' ? '#ffffff' : '#000000',
}}
/>
</TouchableOpacity>
{isProfileExpanded && (
<View className="p-4 flex flex-row justify-between">
<Text className={`text-lg mt-2 w-56 ${textStyle}`}>{t('settings.editProfile')}</Text>
<TouchableOpacity>
<Text
className={`mt-2 font-Inter-Bold ${colorScheme === 'light' ? 'text-black' : 'text-white'}`}
onPress={() => router.push('/dashboard/trainee/profile')}
>
{t('settings.change')}
</Text>
</TouchableOpacity>
</View>
)}
</View>

{/* Theme Picker */}
Expand Down Expand Up @@ -82,11 +186,11 @@ const settings = () => {
</Text>
</View>
<Switch
value={emailNotifications}
onValueChange={() => setEmailNotifications((prev) => !prev)}
thumbColor={emailNotifications ? '#6200ee' : '#f4f3f4'}
trackColor={{ false: '#767577', true: '#81b0ff' }}
/>
value={emailEnabled}
onValueChange={handleEmailNotificationChange}
thumbColor={emailEnabled ? '#6200ee' : '#f4f3f4'}
trackColor={{ false: '#767577', true: '#81b0ff' }}
/>
</View>

{/* Push Notifications */}
Expand All @@ -98,30 +202,31 @@ const settings = () => {
</Text>
</View>
<Switch
value={pushNotifications}
onValueChange={() => setPushNotifications((prev) => !prev)}
thumbColor={pushNotifications ? '#6200ee' : '#f4f3f4'}
trackColor={{ false: '#767577', true: '#81b0ff' }}
/>
value={pushEnabled}
onValueChange={handlePushNotificationChange}
thumbColor={pushEnabled ? '#6200ee' : '#f4f3f4'}
trackColor={{ false: '#767577', true: '#81b0ff' }}
/>
</View>

{/* Privacy and Security */}
<View className={`mb-6 p-4 border-t ${borderColor} rounded-lg flex-row justify-center`}>
<View className={`mb-6 p-4 border-t ${borderColor} rounded-lg flex-row justify-between`}>
<View className="flex-1 mr-4">
<Text className={`text-xl font-bold ${textStyle}`}>{t('settings.privacy')}</Text>
<Text className={`text-lg mt-2 ${textStyle}`}>{t('settings.privacy')}</Text>
<Text className={`text-xl font-bold ${textStyle}`}>{t('settings.Two-factor')}</Text>
<Text className={`text-lg mt-2 ${textStyle}`}>
{t('settings.Two-factor-Preference')}
</Text>
</View>
<Text className={`mt-2 ${textStyle}`}>{t('settings.change')}</Text>
<Switch
value={isTwoFactorEnabled}
onValueChange={isTwoFactorEnabled ? handleDisableTwoFactor : handleEnableTwoFactor}
thumbColor={isTwoFactorEnabled ? '#6200ee' : '#f4f3f4'}
trackColor={{ false: '#767577', true: '#81b0ff' }}
/>
</View>

{/* Login Activity */}
<View className={`p-4 mb-7 border-t ${borderColor} rounded-lg flex flex-row justify-center`}>
<View className="flex-1 mr-4">
<Text className={`text-xl font-bold ${textStyle}`}>{t('settings.login')}</Text>
<Text className={`text-lg ${textStyle}`}>{t('settings.loginHistory')}</Text>
</View>
<Text className={`mt-2 ${textStyle}`}>{t('settings.view')}</Text>
</View>

</View>
);
};
Expand All @@ -140,4 +245,8 @@ const styles = StyleSheet.create({
}),
});


export default settings;



13 changes: 13 additions & 0 deletions graphql/mutations/two-factor.mutation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { gql } from '@apollo/client';

export const EnableTwoFactorAuth = gql`
mutation EnableTwoFactorAuth($email: String!) {
enableTwoFactorAuth(email: $email)
}
`;

export const DisableTwoFactorAuth = gql`
mutation DisableTwoFactorAuth($email: String!) {
disableTwoFactorAuth(email: $email)
}
`;
1 change: 1 addition & 0 deletions graphql/queries/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const GET_PROFILE = gql`
biography
githubUsername
user {
id
organizations
email
role
Expand Down
14 changes: 13 additions & 1 deletion internationalization/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,8 @@
"emailFeeds": "Feedback emails, reminder emails, news emails",
"pushNotify": "Push Notifications",
"pushUpdates": "Grade updates, session reminders, performance comments",
"privacy": "Privacy and Security",
"Two-factor": "Two-factor authentication",
"Two-factor-Preference":"Get extra security by receiving a code on your email",
"login": "Login Activity" ,
"loginHistory": "History of Your login session",
"view": "View"
Expand Down Expand Up @@ -260,7 +261,18 @@
"avatarUpdated": "Profile picture updated successfully",
"avatarError": "Failed to update profile picture",
"imagePickerError": "Error selecting image"
},
"preferences":{
"enableTwo-way":"Two-factor authentication Enabled",
"failEnableTwoway":"Error enabling two-factor authentication",
"desableTwo-way":"Two-factor authentication Disabled",
"failDesableTwoway":"Error Desabling two-factor authentication",
"updateEmailNotification":"Email notifications updated successfull",
"failUpdatingeEmail":"Error updating Email Notifications",
"updatePushNotification":"Push Notifications updated successfull",
"failUpdatingPush":"Error enabling Push Notifications"
}

},
"notifications":{
"deleteSuccess": "Notification deleted successfully",
Expand Down
13 changes: 12 additions & 1 deletion internationalization/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,8 @@
"emailFeeds": "E-mails de retour, rappels, actualités",
"pushNotify": "Notifications poussées",
"pushUpdates": "Mises à jour des notes, rappels de session, commentaires de performance",
"privacy": "Confidentialité et Sécurité",
"Two-factor": "Two-factor authentication",
"Two-factor-Preference":"Bénéficiez d'une sécurité supplémentaire en recevant un code sur votre email",
"login": "Activité de connexion",
"loginHistory": "Historique de vos sessions de connexion",
"view": "Voir"
Expand Down Expand Up @@ -261,6 +262,16 @@
"avatarUpdated": "Photo de profil mise à jour avec succès",
"avatarError": "Erreur lors de la mise à jour de la photo de profil",
"imagePickerError": "Erreur lors de la sélection de l'image"
},
"preferences":{
"enableTwo-way":"authentification à deux facteurs activée",
"failEnableTwoway":"Erreur lors de l'activation de l'authentification à deux facteurs",
"desableTwo-way":"Authentification à deux facteurs désactivée",
"failDesableTwoway":"Erreur lors de la désactivation de l'authentification à deux facteurs",
"updateEmailNotification":"Notifications par e-mail mises à jour avec succès",
"failUpdatingeEmail":"Erreur lors de la mise à jour des notifications par e-mail",
"updatePushNotification":"Notifications push mises à jour avec succès",
"failUpdatingPush":"Erreur lors de la mise à jour des notifications push"
}
},
"notifications": {
Expand Down
13 changes: 12 additions & 1 deletion internationalization/locales/kin.json
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,8 @@
"emailFeeds": "Imeyili z'ibitekerezo, kwibutsa, amakuru",
"pushNotify": "Gutanga amatangazo",
"pushUpdates": "Amakuru ku manota, kwibutsa amasomo, ibisobanuro ku myitwarire",
"privacy": "Ubuzima bwite n'Umutekano",
"Two-factor": "Two-factor authentication",
"Two-factor-Preference":"Shaka umutekano wongeyeho wakiriye kode kuri imeri yawe",
"login": "Ibikorwa byo kwinjira",
"loginHistory": "Amateka y'ibihe wakoresheje winjira",
"view": "Reba"
Expand Down Expand Up @@ -261,6 +262,16 @@
"avatarUpdated": "Foto ya umwirondoro yashyizweho neza",
"avatarError": "Ikosa mu kuvugurura foto ya umwirondoro",
"imagePickerError": "Ikosa mu kuvugurura foto ya umwirondoro"
},
"preferences":{
"enableTwo-way":"Kwemeza ibintu bibiri",
"failEnableTwoway":"Ikosa rishobora kwemeza ibintu bibiri",
"desableTwo-way":"Kwemeza ibintu bibiri byahagaritswe",
"failDesableTwoway":"Ikosa Gusiba ibintu bibiri byemewe",
"updateEmailNotification":"Imenyesha rya imeri ryagezweho neza",
"failUpdatingeEmail":"Ikosa ryo kuvugurura imenyesha rya imeri",
"updatePushNotification":"Gusunika Kumenyesha bigezweho",
"failUpdatingPush":"Ikosa ryo kuvugurura Amatangazo"
}
},
"notifications": {
Expand Down
Loading

0 comments on commit 5b771da

Please sign in to comment.