Skip to content

Commit

Permalink
feat(#10): account password reset
Browse files Browse the repository at this point in the history
  • Loading branch information
fredshema committed Oct 16, 2024
1 parent 6ef8f24 commit 0ff6f38
Show file tree
Hide file tree
Showing 20 changed files with 6,308 additions and 1,359 deletions.
17 changes: 9 additions & 8 deletions __tests__/components/sidebar.test.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import React from 'react';
import { render, fireEvent, waitFor } from '@testing-library/react-native';
import { useRouter, usePathname } from 'expo-router';
import Sidebar from '@/components/sidebar'; // Adjust the import path as needed
import { fireEvent, render, waitFor } from '@testing-library/react-native';
import { usePathname, useRouter } from 'expo-router';

// Mock the expo-router hooks
jest.mock('expo-router', () => ({
useRouter: jest.fn(),
usePathname: jest.fn(),
}));

jest.mock('@react-native-async-storage/async-storage', () => ({
getItem: jest.fn(() => Promise.resolve('Test Organization')),
}));

// Mock the SvgXml component
jest.mock('react-native-svg', () => ({
SvgXml: 'SvgXml',
Expand Down Expand Up @@ -38,11 +41,9 @@ describe('Sidebar', () => {
it('highlights the active item based on current pathname', () => {
(usePathname as jest.Mock).mockReturnValue('/dashboard/trainee');
const { getByText } = render(<Sidebar onClose={mockOnClose} />);
const attendanceItem = getByText('Attendance').parent;
expect(attendanceItem?.props.style).toEqual(
expect.objectContaining({
backgroundColor: expect.stringContaining('indigo'),
})
const attendanceItem = getByText('Attendance').parent?.parent;
expect(attendanceItem?.props.className).toEqual(
expect.stringContaining('bg-indigo-300')
);
});

Expand Down
2 changes: 1 addition & 1 deletion __tests__/dashboard/trainee/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ describe('<TraineeDashboard />', () => {
test('Text renders correctly on Trainee', () => {
const { getByText } = render(<TraineeDashboard />);

getByText('Trainee Dashboard.');
getByText('Recent feedback');
});
});
13 changes: 12 additions & 1 deletion app/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import {
Inter_700Bold,
} from '@expo-google-fonts/inter';
import FontAwesome from '@expo/vector-icons/FontAwesome';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';
import { useFonts } from 'expo-font';
import { Stack } from 'expo-router';
import { Stack, useRouter } from 'expo-router';
import * as SplashScreen from 'expo-splash-screen';
import { useEffect } from 'react';
import 'react-native-reanimated';
Expand Down Expand Up @@ -52,9 +53,19 @@ export default function RootLayout() {
}

function RootLayoutNav() {
const router = useRouter();
const colorScheme = useColorScheme();
useApolloClientDevTools(client);

useEffect(() => {
(async function () {
const authToken = await AsyncStorage.getItem('authToken');
if (authToken !== null) {
router.push('/dashboard');
}
})();
});

return (
<ApolloProvider client={client}>
<ToastProvider placement="top" duration={5000}>
Expand Down
42 changes: 24 additions & 18 deletions app/auth/login/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import OrgLogin from '@/components/Login/OrgLogin';
import UserLogin from '@/components/Login/UserLogin';
import { LOGIN_MUTATION, ORG_LOGIN_MUTATION } from '@/graphql/mutations/login.mutation';
import { UserContext } from '@/hooks/useAuth';
import { useMutation, useApolloClient } from '@apollo/client';
import { useApolloClient, useMutation } from '@apollo/client';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { Href, useLocalSearchParams, useRouter } from 'expo-router';
import { useContext, useState } from 'react';
import { ToastAndroid, Alert } from 'react-native';
import { Alert, ToastAndroid } from 'react-native';
import { useToast } from 'react-native-toast-notifications';

class ErrorHandler {
Expand Down Expand Up @@ -48,16 +48,18 @@ export default function SignInOrganization() {
},
},
onCompleted({ loginOrg }) {
AsyncStorage.setItem('orgToken', loginOrg.token);
let value: string = String(values.organization);
AsyncStorage.setItem('orgName', value);
toast.show('Welcome! Sign in to Continue', {
type: 'success',
placement: 'top',
duration: 4000,
animationType: 'slide-in',
});
setOrgLoginSuccess(true);
(async function () {
await AsyncStorage.setItem('orgToken', loginOrg.token);
let value: string = String(values.organization);
await AsyncStorage.setItem('orgName', value);
toast.show('Welcome! Sign in to Continue', {
type: 'success',
placement: 'top',
duration: 4000,
animationType: 'slide-in',
});
setOrgLoginSuccess(true);
})();
},
onError(err: any) {
ErrorHandler.handleCustomError(`${err}`);
Expand All @@ -83,26 +85,30 @@ export default function SignInOrganization() {
ToastAndroid.show(`${data.addMemberToCohort}`, ToastAndroid.LONG);
}

if (login && data.loginUser) {
if (data.loginUser) {
const token = data.loginUser.token;

if (data.loginUser.user.role === 'trainee') {
params.redirect
? router.push(`${params.redirect}` as Href<string | object>)
: router.push('/dashboard' as Href<string | object>);
}
}

try {
await AsyncStorage.setItem('auth_token', token);
const storedToken = await AsyncStorage.getItem('auth_token');
await AsyncStorage.setItem('authToken', token);
const storedToken = await AsyncStorage.getItem('authToken');

if (storedToken !== token) {
console.error('Stored token does not match received token');
}
} catch (error) {
console.error('Error storing token:', error);
}
login(data.loginUser);

if (login !== undefined) {
login(data.loginUser);
}

try {
await client.resetStore();
} catch (error) {
Expand All @@ -111,7 +117,7 @@ export default function SignInOrganization() {

// Handle redirection
if (params.redirect) {
router.push(params.redirect);
router.push(params.redirect as Href);
return;
}

Expand Down
34 changes: 26 additions & 8 deletions app/dashboard/_layout.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,44 @@
import { lightLogoIcon, darkLogoIcon, menu, lightNotifyIcon, darkNotifyIcon } from '@/assets/Icons/dashboard/Icons';
import { router, Slot } from 'expo-router';
import {
darkLogoIcon,
darkNotifyIcon,
lightLogoIcon,
lightNotifyIcon,
menu,
} from '@/assets/Icons/dashboard/Icons';
import Sidebar from '@/components/sidebar';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { Slot, useRouter } from 'expo-router';
import { useEffect, useState } from 'react';
import {
Image,
KeyboardAvoidingView,
Platform,
ScrollView,
TouchableOpacity,
View,
useColorScheme,
Image,
} from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { SvgXml } from 'react-native-svg';
import Sidebar from '@/components/sidebar';

export default function AuthLayout() {
const router = useRouter();
const insets = useSafeAreaInsets();
const [isSidebarOpen, setIsSidebarOpen] = useState<boolean>(false);
const colorScheme = useColorScheme();

const toggleSidebar = () => setIsSidebarOpen(!isSidebarOpen);

useEffect(() => {
(async function () {
const authToken = await AsyncStorage.getItem('authToken');

if (authToken === null) {
router.push('/auth/login');
}
})();
}, []);

return (
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
Expand Down Expand Up @@ -54,13 +72,13 @@ export default function AuthLayout() {
</View>
<View className="flex-row gap-5">
<TouchableOpacity onPress={() => router.push('/')}>
<SvgXml
xml={colorScheme === 'dark' ? darkNotifyIcon : lightNotifyIcon}
width={25}
<SvgXml
xml={colorScheme === 'dark' ? darkNotifyIcon : lightNotifyIcon}
width={25}
height={40}
/>
</TouchableOpacity>
<TouchableOpacity onPress={() => router.push('/dashboard/profile/orgInfo')}>
<TouchableOpacity onPress={() => router.push('/dashboard/profile')}>
<Image
source={require('@/assets/images/profilePic.png')}
style={{ width: 40, height: 40 }}
Expand Down
18 changes: 4 additions & 14 deletions app/dashboard/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@
import { StyleSheet, Text, useColorScheme, View } from 'react-native';
import { PropsWithChildren } from 'react';
import TraineeRatings from '../../components/sprintRatings';
export const CustomText = ({ children }: PropsWithChildren) => <Text>{children}</Text>;
const Dashboard = () => {
return (
<View>
<TraineeRatings />
</View>
);
};
import { Redirect } from 'expo-router';

export default Dashboard;

const styles = StyleSheet.create({});
export default function Dashboard() {
return <Redirect href="/dashboard/trainee" />;
}
Loading

0 comments on commit 0ff6f38

Please sign in to comment.