@brightlayer-ui/react-native-template-authentication-typescript 2.1.0 → 3.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -17
- package/package.json +3 -3
- package/template/.bundle/config +2 -0
- package/template/.eslintrc.js +57 -0
- package/template/.prettierrc.js +7 -0
- package/template/.watchmanconfig +1 -0
- package/template/App.tsx +85 -47
- package/template/Gemfile +9 -0
- package/template/Gemfile.lock +107 -0
- package/template/README.md +79 -0
- package/template/__tests__/App.test.tsx +17 -0
- package/template/_gitignore +74 -0
- package/template/android/app/build.gradle +120 -0
- package/template/android/app/debug.keystore +0 -0
- package/template/android/app/proguard-rules.pro +10 -0
- package/template/android/app/src/debug/AndroidManifest.xml +9 -0
- package/template/android/app/src/main/AndroidManifest.xml +25 -0
- package/template/android/app/src/main/java/com/workflow/MainActivity.kt +28 -0
- package/template/android/app/src/main/java/com/workflow/MainApplication.kt +43 -0
- package/template/android/app/src/main/res/drawable/rn_edit_text_material.xml +37 -0
- package/template/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
- package/template/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
- package/template/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
- package/template/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
- package/template/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
- package/template/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
- package/template/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/template/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
- package/template/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/template/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
- package/template/android/app/src/main/res/values/strings.xml +3 -0
- package/template/android/app/src/main/res/values/styles.xml +9 -0
- package/template/android/build.gradle +21 -0
- package/template/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/template/android/gradle/wrapper/gradle-wrapper.properties +7 -0
- package/template/android/gradle.properties +41 -0
- package/template/android/gradlew +249 -0
- package/template/android/gradlew.bat +92 -0
- package/template/android/link-assets-manifest.json +25 -0
- package/template/android/settings.gradle +4 -0
- package/template/app.json +4 -0
- package/template/assets/fonts/OpenSans-Bold.ttf +0 -0
- package/template/assets/fonts/OpenSans-ExtraBold.ttf +0 -0
- package/template/assets/fonts/OpenSans-Light.ttf +0 -0
- package/template/assets/fonts/OpenSans-Regular.ttf +0 -0
- package/template/assets/fonts/OpenSans-SemiBold.ttf +0 -0
- package/template/assets/images/Logo.png +0 -0
- package/template/babel.config.js +1 -2
- package/template/eslint.config.mjs +10 -0
- package/template/index.js +11 -0
- package/template/ios/.xcode.env +11 -0
- package/template/ios/Podfile +40 -0
- package/template/ios/Podfile.lock +1496 -0
- package/template/ios/blankTemplate/AppDelegate.h +6 -0
- package/template/ios/blankTemplate/AppDelegate.mm +31 -0
- package/template/ios/blankTemplate/Images.xcassets/AppIcon.appiconset/Contents.json +53 -0
- package/template/ios/blankTemplate/Images.xcassets/Contents.json +6 -0
- package/template/ios/blankTemplate/Info.plist +75 -0
- package/template/ios/blankTemplate/LaunchScreen.storyboard +47 -0
- package/template/ios/blankTemplate/PrivacyInfo.xcprivacy +37 -0
- package/template/ios/blankTemplate/main.m +10 -0
- package/template/ios/blankTemplate.xcodeproj/project.pbxproj +741 -0
- package/template/ios/blankTemplate.xcodeproj/xcshareddata/xcschemes/blankTemplate.xcscheme +88 -0
- package/template/ios/blankTemplate.xcworkspace/contents.xcworkspacedata +10 -0
- package/template/ios/blankTemplate.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/template/ios/blankTemplateTests/Info.plist +24 -0
- package/template/ios/blankTemplateTests/blankTemplateTests.m +66 -0
- package/template/ios/link-assets-manifest.json +25 -0
- package/template/jest.config.js +12 -0
- package/template/jestSetupFile.js +31 -10
- package/template/metro.config.js +7 -25
- package/template/package.json +71 -0
- package/template/src/actions/AuthUIActions.tsx +10 -11
- package/template/src/actions/RegistrationUIActions.tsx +37 -30
- package/template/src/assets/images/eaton_stacked_logo.png +0 -0
- package/template/src/components/AuthCustomScreen.tsx +50 -0
- package/template/src/components/CustomScreen.tsx +77 -0
- package/template/src/components/DebugComponent.tsx +49 -0
- package/template/src/components/ForgotPasswordScreenBaseExample.tsx +42 -0
- package/template/src/components/ResetPasswordScreenBaseExample.tsx +41 -0
- package/template/src/components/UserMenuExample.tsx +117 -0
- package/template/src/contexts/AppContextProvider.tsx +28 -0
- package/template/src/contexts/ThemeContext.ts +15 -0
- package/template/src/navigation/index.tsx +205 -22
- package/template/src/navigation/navigation-drawer.tsx +44 -26
- package/template/src/screens/ChangePassword.tsx +15 -0
- package/template/src/screens/Dashboard.tsx +137 -0
- package/template/src/screens/Homepage.tsx +135 -0
- package/template/src/screens/Locations.tsx +137 -0
- package/template/src/screens/Login.tsx +17 -0
- package/template/src/screens/Registration.tsx +4 -0
- package/template/src/screens/RegistrationInvite.tsx +5 -0
- package/template/src/screens/index.ts +12 -0
- package/template/src/store/local-storage.ts +4 -4
- package/template/translations/dictionary/chinese.ts +29 -0
- package/template/translations/dictionary/english.ts +29 -0
- package/template/translations/dictionary/french.ts +29 -0
- package/template/translations/dictionary/index.ts +19 -0
- package/template/translations/dictionary/portuguese.ts +29 -0
- package/template/translations/dictionary/spanish.ts +29 -0
- package/template/translations/dictionary/types.ts +27 -0
- package/template/translations/i18n.ts +58 -0
- package/template/tsconfig.json +60 -0
- package/template/yarn.lock +7346 -0
- package/template.config.js +4 -0
- package/CHANGELOG.md +0 -69
- package/dependencies.json +0 -31
- package/images/Logo.svg +0 -11
- package/template/__mocks__/svgMock.js +0 -8
- package/template/react-native.config.js +0 -3
- package/template/src/navigation/DeepLinking.ts +0 -62
- package/template/src/screens/home.tsx +0 -198
- package/template/src/screens/index.tsx +0 -3
- package/template/src/screens/pageOne.tsx +0 -91
- package/template/src/screens/pageTwo.tsx +0 -92
- /package/{fonts → template/android/app/src/main/assets/fonts}/OpenSans-Bold.ttf +0 -0
- /package/{fonts → template/android/app/src/main/assets/fonts}/OpenSans-ExtraBold.ttf +0 -0
- /package/{fonts → template/android/app/src/main/assets/fonts}/OpenSans-Light.ttf +0 -0
- /package/{fonts → template/android/app/src/main/assets/fonts}/OpenSans-Regular.ttf +0 -0
- /package/{fonts → template/android/app/src/main/assets/fonts}/OpenSans-SemiBold.ttf +0 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import React, { useCallback, useState } from 'react';
|
|
2
|
+
// import { useRegistrationWorkflowContext } from '../../contexts';
|
|
3
|
+
import {
|
|
4
|
+
WorkflowCard,
|
|
5
|
+
WorkflowCardActions,
|
|
6
|
+
WorkflowCardBody,
|
|
7
|
+
WorkflowCardHeader,
|
|
8
|
+
useRegistrationWorkflowContext,
|
|
9
|
+
useRegistrationContext,
|
|
10
|
+
} from '@brightlayer-ui/react-native-auth-workflow';
|
|
11
|
+
import { TextInput } from 'react-native-paper';
|
|
12
|
+
import { useTranslation } from 'react-i18next';
|
|
13
|
+
|
|
14
|
+
type CustomScreenProps = {
|
|
15
|
+
/**
|
|
16
|
+
* Used to pre-populate the data when the screen loads
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
organisationName?: any;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const CustomScreen: React.FC<CustomScreenProps> = (props) => {
|
|
23
|
+
const regWorkflow = useRegistrationWorkflowContext();
|
|
24
|
+
const { navigate } = useRegistrationContext();
|
|
25
|
+
const { nextScreen, screenData, currentScreen, totalScreens, resetScreenData, previousScreen } = regWorkflow;
|
|
26
|
+
const { organisationName } = props;
|
|
27
|
+
const { t } = useTranslation();
|
|
28
|
+
|
|
29
|
+
const [organisationNameInput, setOrganisationNameInput] = useState(
|
|
30
|
+
organisationName ? organisationName : screenData.Other?.organisationName
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
const onNext = useCallback(() => {
|
|
34
|
+
void nextScreen({
|
|
35
|
+
screenId: 'Custom',
|
|
36
|
+
values: { organisationName: organisationNameInput },
|
|
37
|
+
// isAccountExist: true,
|
|
38
|
+
});
|
|
39
|
+
}, [organisationNameInput, nextScreen]);
|
|
40
|
+
|
|
41
|
+
const onIconPress = useCallback(() => {
|
|
42
|
+
navigate(-1);
|
|
43
|
+
resetScreenData();
|
|
44
|
+
}, [navigate, resetScreenData]);
|
|
45
|
+
|
|
46
|
+
const onPrevious = useCallback(() => {
|
|
47
|
+
void previousScreen({
|
|
48
|
+
screenId: 'Custom',
|
|
49
|
+
values: { organisationName: organisationNameInput },
|
|
50
|
+
// isAccountExist: true,
|
|
51
|
+
});
|
|
52
|
+
}, [organisationNameInput, previousScreen]);
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<WorkflowCard>
|
|
56
|
+
<WorkflowCardHeader title="Custom Screen" onIconPress={onIconPress} icon={{ name: 'arrow-back' }} />
|
|
57
|
+
<WorkflowCardBody>
|
|
58
|
+
<TextInput
|
|
59
|
+
label={t('app:ORGANAIZATION_DETAILS.NAME')}
|
|
60
|
+
mode="flat"
|
|
61
|
+
value={organisationNameInput}
|
|
62
|
+
onChangeText={(value) => setOrganisationNameInput(value)}
|
|
63
|
+
/>
|
|
64
|
+
</WorkflowCardBody>
|
|
65
|
+
<WorkflowCardActions
|
|
66
|
+
showPrevious
|
|
67
|
+
showNext
|
|
68
|
+
previousLabel={t('bluiCommon:ACTIONS.BACK')}
|
|
69
|
+
nextLabel={t('bluiCommon:ACTIONS.OKAY')}
|
|
70
|
+
currentStep={currentScreen}
|
|
71
|
+
totalSteps={totalScreens}
|
|
72
|
+
onNext={onNext}
|
|
73
|
+
onPrevious={onPrevious}
|
|
74
|
+
/>
|
|
75
|
+
</WorkflowCard>
|
|
76
|
+
);
|
|
77
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Spacer } from '@brightlayer-ui/react-native-components';
|
|
2
|
+
import { useNavigation } from '@react-navigation/native';
|
|
3
|
+
import React, { useState } from 'react';
|
|
4
|
+
import { View } from 'react-native';
|
|
5
|
+
import { Button, Text } from 'react-native-paper';
|
|
6
|
+
|
|
7
|
+
export const DebugComponent = (): JSX.Element => {
|
|
8
|
+
const [debugMode, setDebugMode] = useState(false);
|
|
9
|
+
const navigation = useNavigation();
|
|
10
|
+
return (
|
|
11
|
+
<>
|
|
12
|
+
<View style={{ flexDirection: 'row' }}>
|
|
13
|
+
{debugMode && <Text variant="headlineSmall">DEBUG MODE</Text>}
|
|
14
|
+
<Spacer />
|
|
15
|
+
<Button
|
|
16
|
+
mode="contained"
|
|
17
|
+
onPress={(): void => {
|
|
18
|
+
setDebugMode(!debugMode);
|
|
19
|
+
}}
|
|
20
|
+
>
|
|
21
|
+
DEBUG
|
|
22
|
+
</Button>
|
|
23
|
+
</View>
|
|
24
|
+
{debugMode && (
|
|
25
|
+
<View style={{ paddingBottom: 2 }}>
|
|
26
|
+
<Button
|
|
27
|
+
mode={'text'}
|
|
28
|
+
labelStyle={{ fontSize: 16 }}
|
|
29
|
+
uppercase={false}
|
|
30
|
+
onPress={(): void => {
|
|
31
|
+
navigation.navigate('RegistrationProviderExample', { screen: 'RegisterInvite' });
|
|
32
|
+
}}
|
|
33
|
+
>
|
|
34
|
+
[Test Invite Register]
|
|
35
|
+
</Button>
|
|
36
|
+
|
|
37
|
+
<Button
|
|
38
|
+
mode={'text'}
|
|
39
|
+
labelStyle={{ fontSize: 16 }}
|
|
40
|
+
uppercase={false}
|
|
41
|
+
onPress={(): void => navigation.navigate('ResetPassword')}
|
|
42
|
+
>
|
|
43
|
+
[Test Reset Password]
|
|
44
|
+
</Button>
|
|
45
|
+
</View>
|
|
46
|
+
)}
|
|
47
|
+
</>
|
|
48
|
+
);
|
|
49
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
ForgotPasswordScreen,
|
|
4
|
+
AuthContextProvider,
|
|
5
|
+
ErrorContextProvider,
|
|
6
|
+
} from '@brightlayer-ui/react-native-auth-workflow';
|
|
7
|
+
import { useNavigation } from '@react-navigation/native';
|
|
8
|
+
import { useApp } from '../contexts/AppContextProvider';
|
|
9
|
+
import { ProjectAuthUIActions } from '../actions/AuthUIActions';
|
|
10
|
+
import i18nAppInstance from '../../translations/i18n';
|
|
11
|
+
|
|
12
|
+
export const ForgotPasswordScreenBaseExample: React.FC = () => {
|
|
13
|
+
const app = useApp();
|
|
14
|
+
const navigation = useNavigation();
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<AuthContextProvider
|
|
18
|
+
language={app.language}
|
|
19
|
+
actions={ProjectAuthUIActions(app)}
|
|
20
|
+
i18n={i18nAppInstance}
|
|
21
|
+
navigate={(destination: -1 | string) => {
|
|
22
|
+
if (typeof destination === 'string') {
|
|
23
|
+
navigation.navigate(destination);
|
|
24
|
+
} else {
|
|
25
|
+
navigation.goBack();
|
|
26
|
+
}
|
|
27
|
+
}}
|
|
28
|
+
routeConfig={{
|
|
29
|
+
LOGIN: 'Home',
|
|
30
|
+
FORGOT_PASSWORD: undefined,
|
|
31
|
+
RESET_PASSWORD: undefined,
|
|
32
|
+
REGISTER_INVITE: undefined,
|
|
33
|
+
REGISTER_SELF: undefined,
|
|
34
|
+
SUPPORT: undefined,
|
|
35
|
+
}}
|
|
36
|
+
>
|
|
37
|
+
<ErrorContextProvider>
|
|
38
|
+
<ForgotPasswordScreen />
|
|
39
|
+
</ErrorContextProvider>
|
|
40
|
+
</AuthContextProvider>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { AuthContextProvider, ResetPasswordScreen } from '@brightlayer-ui/react-native-auth-workflow';
|
|
3
|
+
import { useApp } from '../contexts/AppContextProvider';
|
|
4
|
+
import { useNavigation } from '@react-navigation/native';
|
|
5
|
+
import { ProjectAuthUIActions } from '../actions/AuthUIActions';
|
|
6
|
+
import i18nAppInstance from '../../translations/i18n';
|
|
7
|
+
|
|
8
|
+
export const ResetPasswordScreenBaseExample: React.FC = () => {
|
|
9
|
+
const app = useApp();
|
|
10
|
+
const navigation = useNavigation();
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<AuthContextProvider
|
|
14
|
+
language={app.language}
|
|
15
|
+
actions={ProjectAuthUIActions(app)}
|
|
16
|
+
i18n={i18nAppInstance}
|
|
17
|
+
navigate={(destination: -1 | string) => {
|
|
18
|
+
if (typeof destination === 'string') {
|
|
19
|
+
navigation.navigate(destination);
|
|
20
|
+
} else {
|
|
21
|
+
navigation.goBack();
|
|
22
|
+
}
|
|
23
|
+
}}
|
|
24
|
+
routeConfig={{
|
|
25
|
+
LOGIN: 'Home',
|
|
26
|
+
FORGOT_PASSWORD: undefined,
|
|
27
|
+
RESET_PASSWORD: undefined,
|
|
28
|
+
REGISTER_INVITE: undefined,
|
|
29
|
+
REGISTER_SELF: undefined,
|
|
30
|
+
SUPPORT: undefined,
|
|
31
|
+
}}
|
|
32
|
+
>
|
|
33
|
+
<ResetPasswordScreen
|
|
34
|
+
accountParams={{
|
|
35
|
+
code: '123',
|
|
36
|
+
email: 'test@eaton.com',
|
|
37
|
+
}}
|
|
38
|
+
/>
|
|
39
|
+
</AuthContextProvider>
|
|
40
|
+
);
|
|
41
|
+
};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { InfoListItemProps, UserMenu } from '@brightlayer-ui/react-native-components';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Avatar } from 'react-native-paper';
|
|
4
|
+
import * as BLUIColors from '@brightlayer-ui/colors';
|
|
5
|
+
import { IconFamily } from '@brightlayer-ui/react-native-components/core/__types__';
|
|
6
|
+
import SelectDropdown from 'react-native-select-dropdown';
|
|
7
|
+
import { useTranslation } from 'react-i18next';
|
|
8
|
+
import { useExtendedTheme } from '@brightlayer-ui/react-native-themes';
|
|
9
|
+
import { useApp } from '../contexts/AppContextProvider';
|
|
10
|
+
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
11
|
+
import { LocalStorage } from '../store/local-storage';
|
|
12
|
+
import { useNavigation } from '@react-navigation/native';
|
|
13
|
+
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
|
14
|
+
|
|
15
|
+
const SwapIcon: IconFamily = {
|
|
16
|
+
family: 'material',
|
|
17
|
+
name: 'swap-horiz',
|
|
18
|
+
direction: 'ltr',
|
|
19
|
+
};
|
|
20
|
+
const InvertColorsIcon: IconFamily = {
|
|
21
|
+
family: 'material',
|
|
22
|
+
name: 'invert-colors',
|
|
23
|
+
direction: 'ltr',
|
|
24
|
+
};
|
|
25
|
+
const ExitToAppIcon: IconFamily = {
|
|
26
|
+
family: 'material',
|
|
27
|
+
name: 'exit-to-app',
|
|
28
|
+
direction: 'ltr',
|
|
29
|
+
};
|
|
30
|
+
const LockIcon: IconFamily = {
|
|
31
|
+
family: 'material',
|
|
32
|
+
name: 'lock',
|
|
33
|
+
direction: 'ltr',
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
type UserMenuExampleProps = {
|
|
37
|
+
onToggleRTL: () => void;
|
|
38
|
+
onToggleTheme: () => void;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const UserMenuExample: React.FC<UserMenuExampleProps> = (props) => {
|
|
42
|
+
const { onToggleRTL, onToggleTheme } = props;
|
|
43
|
+
const theme = useExtendedTheme();
|
|
44
|
+
const { i18n, t } = useTranslation();
|
|
45
|
+
const navigation = useNavigation<NativeStackNavigationProp<any>>();
|
|
46
|
+
const app = useApp();
|
|
47
|
+
const handleLanguageChange = async (newLanguage: string): Promise<any> => {
|
|
48
|
+
app.setLanguage(newLanguage);
|
|
49
|
+
void i18n.changeLanguage(newLanguage);
|
|
50
|
+
try {
|
|
51
|
+
await AsyncStorage.setItem('userLanguage', newLanguage);
|
|
52
|
+
} catch (error) {
|
|
53
|
+
// eslint-disable-next-line no-console
|
|
54
|
+
console.error('Error setting new language:', error);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
const logout = (): void => {
|
|
58
|
+
LocalStorage.clearAuthCredentials();
|
|
59
|
+
app.onUserNotAuthenticated();
|
|
60
|
+
};
|
|
61
|
+
const changePassword = (): void => {
|
|
62
|
+
navigation.navigate('ChangePassword');
|
|
63
|
+
};
|
|
64
|
+
const languageOptions = [
|
|
65
|
+
{ label: 'English', value: 'en' },
|
|
66
|
+
{ label: 'Spanish', value: 'es' },
|
|
67
|
+
{ label: 'French', value: 'fr' },
|
|
68
|
+
{ label: 'Chinese', value: 'zh' },
|
|
69
|
+
{ label: 'Portuguese', value: 'pt' },
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
const menuItems: InfoListItemProps[] = [
|
|
73
|
+
{ title: t('USER_MENU.TOGGLE_RTL'), icon: SwapIcon, onPress: (): void => onToggleRTL() },
|
|
74
|
+
{
|
|
75
|
+
title: t('USER_MENU.TOGGLE_THEME'),
|
|
76
|
+
icon: InvertColorsIcon,
|
|
77
|
+
onPress: (): void => onToggleTheme(),
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
title: t('USER_MENU.LANGUAGE'),
|
|
81
|
+
icon: { name: 'translate' },
|
|
82
|
+
rightComponent: (
|
|
83
|
+
<SelectDropdown
|
|
84
|
+
defaultValue={languageOptions.find((option) => option.value === i18n.language)}
|
|
85
|
+
// eslint-disable-next-line
|
|
86
|
+
onSelect={(item) => handleLanguageChange(item.value)}
|
|
87
|
+
data={languageOptions}
|
|
88
|
+
buttonStyle={{ backgroundColor: theme.colors.background }}
|
|
89
|
+
buttonTextStyle={{ color: theme.colors.primary }}
|
|
90
|
+
rowTextForSelection={(item) => item.label}
|
|
91
|
+
buttonTextAfterSelection={() => {
|
|
92
|
+
const selectedLabel = languageOptions.find((option) => option.value === i18n.language)?.label;
|
|
93
|
+
return selectedLabel || 'Select Language';
|
|
94
|
+
}}
|
|
95
|
+
/>
|
|
96
|
+
),
|
|
97
|
+
},
|
|
98
|
+
{ title: t('USER_MENU.CHANGE_PASSWORD'), icon: LockIcon, onPress: (): void => changePassword() },
|
|
99
|
+
{ title: t('USER_MENU.LOG_OUT'), icon: ExitToAppIcon, onPress: (): void => logout() },
|
|
100
|
+
];
|
|
101
|
+
|
|
102
|
+
return (
|
|
103
|
+
<UserMenu
|
|
104
|
+
menuTitle={'John Smith'}
|
|
105
|
+
menuSubtitle={'Account Manager'}
|
|
106
|
+
menuItems={menuItems}
|
|
107
|
+
avatar={
|
|
108
|
+
<Avatar.Icon
|
|
109
|
+
icon="account-circle"
|
|
110
|
+
size={40}
|
|
111
|
+
color={BLUIColors.primary[50]}
|
|
112
|
+
style={{ backgroundColor: BLUIColors.primary[80] }}
|
|
113
|
+
/>
|
|
114
|
+
}
|
|
115
|
+
/>
|
|
116
|
+
);
|
|
117
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
|
|
3
|
+
export type LoginData = {
|
|
4
|
+
email: string;
|
|
5
|
+
rememberMe: boolean;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export type AppContextType = {
|
|
9
|
+
isAuthenticated: boolean;
|
|
10
|
+
loginData: LoginData;
|
|
11
|
+
onUserAuthenticated: (args: { email: string; userId: string; rememberMe: boolean }) => void;
|
|
12
|
+
onUserNotAuthenticated: (clearRememberMe?: boolean, overrideRememberMeEmail?: string) => void;
|
|
13
|
+
language: string;
|
|
14
|
+
setLanguage: (language: string) => void;
|
|
15
|
+
setLoginData: (args: LoginData) => void;
|
|
16
|
+
setAuthenticated: (isAuthenticated: boolean) => void;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const AppContext = createContext<AppContextType | null>(null);
|
|
20
|
+
|
|
21
|
+
export const useApp = (): AppContextType => {
|
|
22
|
+
const context = useContext(AppContext);
|
|
23
|
+
|
|
24
|
+
if (context === null) {
|
|
25
|
+
throw new Error('useApp must be used within a AppContextProvider');
|
|
26
|
+
}
|
|
27
|
+
return context;
|
|
28
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
|
|
3
|
+
export type ThemeType = 'light' | 'dark';
|
|
4
|
+
|
|
5
|
+
type ThemeContextType = {
|
|
6
|
+
theme: ThemeType;
|
|
7
|
+
setTheme: (themeName: ThemeType) => void;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const ThemeContext = createContext<ThemeContextType>({
|
|
11
|
+
theme: 'light',
|
|
12
|
+
setTheme: () => {},
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export const useThemeContext = (): ThemeContextType => useContext(ThemeContext);
|
|
@@ -1,37 +1,220 @@
|
|
|
1
1
|
import React, { ReactNode } from 'react';
|
|
2
|
+
import { NavigationContainer, createNavigationContainerRef, useNavigation } from '@react-navigation/native';
|
|
3
|
+
import { useApp } from '../contexts/AppContextProvider';
|
|
4
|
+
import {
|
|
5
|
+
AuthContextProvider,
|
|
6
|
+
ContactSupportScreen,
|
|
7
|
+
ResetPasswordScreen,
|
|
8
|
+
RegistrationContextProvider,
|
|
9
|
+
ForgotPasswordScreen,
|
|
10
|
+
} from '@brightlayer-ui/react-native-auth-workflow';
|
|
11
|
+
import i18nAppInstance from '../../translations/i18n';
|
|
12
|
+
import { NavigationDrawer } from './navigation-drawer';
|
|
2
13
|
import { createDrawerNavigator } from '@react-navigation/drawer';
|
|
3
|
-
import { View } from 'react-native';
|
|
4
|
-
import { NavDrawerProps, NavigationDrawer } from './navigation-drawer';
|
|
5
|
-
import { createStackNavigator } from '@react-navigation/stack';
|
|
6
|
-
import Home from '../screens/home';
|
|
7
|
-
import PageOne from '../screens/pageOne';
|
|
8
|
-
import PageTwo from '../screens/pageTwo';
|
|
14
|
+
import { Dimensions, View } from 'react-native';
|
|
9
15
|
|
|
16
|
+
import { ProjectAuthUIActions } from '../actions/AuthUIActions';
|
|
17
|
+
import { ProjectRegistrationUIActions } from '../actions/RegistrationUIActions';
|
|
18
|
+
|
|
19
|
+
import { Login } from '../screens/Login';
|
|
20
|
+
import { ChangePassword } from '../screens/ChangePassword';
|
|
21
|
+
import { Registration } from '../screens/Registration';
|
|
22
|
+
import { RegistrationInvite } from '../screens/RegistrationInvite';
|
|
23
|
+
|
|
24
|
+
import { Homepage } from '../screens/Homepage';
|
|
25
|
+
import Locations from '../screens/Locations';
|
|
26
|
+
import Dashboard from '../screens/Dashboard';
|
|
27
|
+
import { NativeStackNavigationProp, createNativeStackNavigator } from '@react-navigation/native-stack';
|
|
28
|
+
|
|
29
|
+
const Stack = createNativeStackNavigator();
|
|
10
30
|
const Drawer = createDrawerNavigator();
|
|
31
|
+
const navigationRef = createNavigationContainerRef();
|
|
11
32
|
|
|
12
33
|
export type RootStackParamList = {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
34
|
+
Homepage: undefined;
|
|
35
|
+
Dashboard: undefined;
|
|
36
|
+
Locations: undefined;
|
|
16
37
|
NavigationDrawer: undefined;
|
|
17
38
|
};
|
|
18
39
|
|
|
19
|
-
const RootStack = createStackNavigator<RootStackParamList>();
|
|
20
|
-
|
|
21
40
|
const CustomDrawerContent = (props: any): any => (
|
|
22
41
|
<View style={{ height: '100%' }}>
|
|
23
42
|
<NavigationDrawer {...props} />
|
|
24
43
|
</View>
|
|
25
44
|
);
|
|
26
45
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
46
|
+
const AuthRouter = (): any => {
|
|
47
|
+
const app = useApp();
|
|
48
|
+
const { email, rememberMe } = app.loginData;
|
|
49
|
+
const navigation = useNavigation<NativeStackNavigationProp<any>>();
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<>
|
|
53
|
+
<AuthContextProvider
|
|
54
|
+
language={app.language}
|
|
55
|
+
actions={ProjectAuthUIActions(app)}
|
|
56
|
+
i18n={i18nAppInstance}
|
|
57
|
+
navigate={(destination: -1 | string) => {
|
|
58
|
+
if (typeof destination === 'string') {
|
|
59
|
+
switch (destination) {
|
|
60
|
+
case 'SelfRegister':
|
|
61
|
+
case 'RegisterInvite':
|
|
62
|
+
navigation.navigate('RegistrationProviderExample', { screen: destination });
|
|
63
|
+
break;
|
|
64
|
+
default:
|
|
65
|
+
navigation.navigate(destination);
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
} else if (destination === -1) {
|
|
69
|
+
navigation.goBack();
|
|
70
|
+
}
|
|
71
|
+
}}
|
|
72
|
+
routeConfig={{
|
|
73
|
+
LOGIN: 'Login',
|
|
74
|
+
FORGOT_PASSWORD: 'ForgotPassword',
|
|
75
|
+
RESET_PASSWORD: 'ResetPassword',
|
|
76
|
+
REGISTER_INVITE: 'RegisterInvite',
|
|
77
|
+
REGISTER_SELF: 'SelfRegister',
|
|
78
|
+
SUPPORT: 'ContactSupport',
|
|
79
|
+
}}
|
|
80
|
+
rememberMeDetails={{ email: rememberMe ? email : '', rememberMe: rememberMe }}
|
|
81
|
+
>
|
|
82
|
+
<Drawer.Navigator
|
|
83
|
+
screenOptions={{
|
|
84
|
+
headerShown: false,
|
|
85
|
+
drawerType: 'front',
|
|
86
|
+
drawerStyle: { backgroundColor: 'transparent' },
|
|
87
|
+
}}
|
|
88
|
+
drawerContent={(props: any): ReactNode => <CustomDrawerContent {...props} />}
|
|
89
|
+
backBehavior="history"
|
|
90
|
+
initialRouteName="Login"
|
|
91
|
+
>
|
|
92
|
+
{!app.isAuthenticated && (
|
|
93
|
+
<Drawer.Screen
|
|
94
|
+
options={{
|
|
95
|
+
swipeEnabled: false,
|
|
96
|
+
}}
|
|
97
|
+
name="Login"
|
|
98
|
+
component={Login}
|
|
99
|
+
/>
|
|
100
|
+
)}
|
|
101
|
+
{!app.isAuthenticated && (
|
|
102
|
+
<Drawer.Screen
|
|
103
|
+
options={{
|
|
104
|
+
swipeEnabled: false,
|
|
105
|
+
}}
|
|
106
|
+
name="ForgotPassword"
|
|
107
|
+
component={ForgotPasswordScreen}
|
|
108
|
+
/>
|
|
109
|
+
)}
|
|
110
|
+
{!app.isAuthenticated && (
|
|
111
|
+
<Drawer.Screen
|
|
112
|
+
options={{
|
|
113
|
+
swipeEnabled: false,
|
|
114
|
+
}}
|
|
115
|
+
name="ResetPassword"
|
|
116
|
+
component={ResetPasswordScreen}
|
|
117
|
+
/>
|
|
118
|
+
)}
|
|
119
|
+
|
|
120
|
+
{app.isAuthenticated && <Drawer.Screen name="Homepage" component={Homepage} />}
|
|
121
|
+
{app.isAuthenticated && <Drawer.Screen name="Dashboard" component={Dashboard} />}
|
|
122
|
+
{app.isAuthenticated && <Drawer.Screen name="Locations" component={Locations} />}
|
|
123
|
+
|
|
124
|
+
<Drawer.Screen
|
|
125
|
+
name="ContactSupport"
|
|
126
|
+
options={{
|
|
127
|
+
swipeEnabled: false,
|
|
128
|
+
}}
|
|
129
|
+
component={ContactSupportScreen}
|
|
130
|
+
/>
|
|
131
|
+
{app.isAuthenticated && (
|
|
132
|
+
<Drawer.Screen
|
|
133
|
+
name="ChangePassword"
|
|
134
|
+
options={{
|
|
135
|
+
swipeEnabled: false,
|
|
136
|
+
}}
|
|
137
|
+
component={ChangePassword}
|
|
138
|
+
/>
|
|
139
|
+
)}
|
|
140
|
+
</Drawer.Navigator>
|
|
141
|
+
</AuthContextProvider>
|
|
142
|
+
</>
|
|
143
|
+
);
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
const RegistrationRouter = (): any => {
|
|
147
|
+
const app = useApp();
|
|
148
|
+
const navigation = useNavigation<NativeStackNavigationProp<any>>();
|
|
149
|
+
const RegistrationStack = createNativeStackNavigator();
|
|
150
|
+
|
|
151
|
+
return (
|
|
152
|
+
<>
|
|
153
|
+
<RegistrationContextProvider
|
|
154
|
+
language={app.language}
|
|
155
|
+
actions={ProjectRegistrationUIActions()}
|
|
156
|
+
i18n={i18nAppInstance}
|
|
157
|
+
routeConfig={{
|
|
158
|
+
LOGIN: 'Login',
|
|
159
|
+
FORGOT_PASSWORD: 'ForgotPassword',
|
|
160
|
+
RESET_PASSWORD: 'ResetPassword',
|
|
161
|
+
REGISTER_INVITE: 'RegisterInvite',
|
|
162
|
+
REGISTER_SELF: 'SelfRegister',
|
|
163
|
+
SUPPORT: 'ContactSupport',
|
|
164
|
+
}}
|
|
165
|
+
navigate={(destination: -1 | string) => {
|
|
166
|
+
if (typeof destination === 'string') {
|
|
167
|
+
switch (destination) {
|
|
168
|
+
case 'SelfRegister':
|
|
169
|
+
case 'RegisterInvite':
|
|
170
|
+
navigation.navigate('RegistrationProviderExample', { screen: destination });
|
|
171
|
+
break;
|
|
172
|
+
default:
|
|
173
|
+
navigation.navigate(destination);
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
} else if (destination === -1) {
|
|
177
|
+
navigation.goBack();
|
|
178
|
+
}
|
|
179
|
+
}}
|
|
180
|
+
>
|
|
181
|
+
<RegistrationStack.Navigator
|
|
182
|
+
screenOptions={{
|
|
183
|
+
headerShown: false,
|
|
184
|
+
}}
|
|
185
|
+
initialRouteName="SelfRegister"
|
|
186
|
+
>
|
|
187
|
+
{!app.isAuthenticated && (
|
|
188
|
+
<RegistrationStack.Screen
|
|
189
|
+
name="SelfRegister"
|
|
190
|
+
component={Registration}
|
|
191
|
+
></RegistrationStack.Screen>
|
|
192
|
+
)}
|
|
193
|
+
{!app.isAuthenticated && (
|
|
194
|
+
<RegistrationStack.Screen
|
|
195
|
+
name="RegisterInvite"
|
|
196
|
+
component={RegistrationInvite}
|
|
197
|
+
></RegistrationStack.Screen>
|
|
198
|
+
)}
|
|
199
|
+
</RegistrationStack.Navigator>
|
|
200
|
+
</RegistrationContextProvider>
|
|
201
|
+
</>
|
|
202
|
+
);
|
|
203
|
+
};
|
|
204
|
+
export const MainRouter = (): any => {
|
|
205
|
+
const { height, width } = Dimensions.get('screen');
|
|
206
|
+
return (
|
|
207
|
+
<NavigationContainer ref={navigationRef}>
|
|
208
|
+
<Stack.Navigator
|
|
209
|
+
initialRouteName={'AuthProviderExample'}
|
|
210
|
+
screenOptions={{
|
|
211
|
+
headerShown: false,
|
|
212
|
+
orientation: width >= 768 && height >= 768 ? 'all' : 'portrait',
|
|
213
|
+
}}
|
|
214
|
+
>
|
|
215
|
+
<Stack.Screen name="AuthProviderExample" component={AuthRouter} />
|
|
216
|
+
<Stack.Screen name="RegistrationProviderExample" component={RegistrationRouter} />
|
|
217
|
+
</Stack.Navigator>
|
|
218
|
+
</NavigationContainer>
|
|
219
|
+
);
|
|
220
|
+
};
|