@computools/react-native-template-controller 0.0.10 → 0.0.12

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.
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Workspace
3
+ version = "1.0">
4
+ <FileRef
5
+ location = "group:ReactNativeTemplate.xcodeproj">
6
+ </FileRef>
7
+ <FileRef
8
+ location = "group:Pods/Pods.xcodeproj">
9
+ </FileRef>
10
+ </Workspace>
@@ -1 +1 @@
1
- {"name":"React-Codegen","version":"0.72.0","summary":"Temp pod for generated files for React Native","homepage":"https://facebook.com/","license":"Unlicense","authors":"Facebook","compiler_flags":"-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32 -Wno-documentation -Wno-nullability-completeness -std=c++17","source":{"git":""},"header_mappings_dir":"./","platforms":{"ios":"12.4"},"source_files":"**/*.{h,mm,cpp}","pod_target_xcconfig":{"HEADER_SEARCH_PATHS":"\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"${PODS_ROOT}/Headers/Public/React-Codegen/react/renderer/components\" \"$(PODS_ROOT)/Headers/Private/React-Fabric\" \"$(PODS_ROOT)/Headers/Private/React-RCTFabric\"","FRAMEWORK_SEARCH_PATHS":[]},"dependencies":{"React-jsiexecutor":[],"RCT-Folly":[],"RCTRequired":[],"RCTTypeSafety":[],"React-Core":[],"React-jsi":[],"ReactCommon/turbomodule/bridging":[],"ReactCommon/turbomodule/core":[],"React-NativeModulesApple":[],"glog":[],"DoubleConversion":[],"hermes-engine":[],"React-rncore":[],"FBReactNativeSpec":[]}}
1
+ {"name":"React-Codegen","version":"0.72.1","summary":"Temp pod for generated files for React Native","homepage":"https://facebook.com/","license":"Unlicense","authors":"Facebook","compiler_flags":"-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32 -Wno-documentation -Wno-nullability-completeness -std=c++17","source":{"git":""},"header_mappings_dir":"./","platforms":{"ios":"12.4"},"source_files":"**/*.{h,mm,cpp}","pod_target_xcconfig":{"HEADER_SEARCH_PATHS":"\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"${PODS_ROOT}/Headers/Public/React-Codegen/react/renderer/components\" \"$(PODS_ROOT)/Headers/Private/React-Fabric\" \"$(PODS_ROOT)/Headers/Private/React-RCTFabric\"","FRAMEWORK_SEARCH_PATHS":[]},"dependencies":{"React-jsiexecutor":[],"RCT-Folly":[],"RCTRequired":[],"RCTTypeSafety":[],"React-Core":[],"React-jsi":[],"ReactCommon/turbomodule/bridging":[],"ReactCommon/turbomodule/core":[],"React-NativeModulesApple":[],"glog":[],"DoubleConversion":[],"hermes-engine":[],"React-rncore":[],"FBReactNativeSpec":[]}}
@@ -15,10 +15,12 @@
15
15
  "@react-navigation/native": "6.1.6",
16
16
  "@react-navigation/native-stack": "6.9.12",
17
17
  "axios": "1.3.4",
18
+ "i18next": "23.2.8",
18
19
  "mobx": "6.9.0",
19
20
  "mobx-react-lite": "3.4.3",
20
21
  "react": "18.2.0",
21
22
  "react-hook-form": "7.43.5",
23
+ "react-i18next": "13.0.1",
22
24
  "react-native": "0.72.1",
23
25
  "react-native-bootsplash": "4.5.3",
24
26
  "react-native-mmkv": "2.6.3",
@@ -31,12 +33,12 @@
31
33
  "@babel/core": "^7.20.0",
32
34
  "@babel/preset-env": "^7.20.0",
33
35
  "@babel/runtime": "^7.20.0",
34
- "@computools/eslint-config-react-native": "1.0.17",
36
+ "@computools/eslint-config-react-native": "1.0.3",
35
37
  "@react-native/eslint-config": "0.72.2",
36
38
  "@react-native/metro-config": "0.72.7",
37
39
  "@tsconfig/react-native": "^3.0.0",
38
- "@types/metro-config": "^0.76.3",
39
40
  "@types/jest": "^29.2.1",
41
+ "@types/metro-config": "^0.76.3",
40
42
  "@types/react": "^18.0.24",
41
43
  "@types/react-test-renderer": "^18.0.0",
42
44
  "@typescript-eslint/parser": "5.53.0",
@@ -11,6 +11,7 @@ import {MainStackParamsList, MainStackRoutes} from '@infra/MainStackRoutes.route
11
11
  import {Computools} from '@ui-kit/icons/computools/Computools.icon';
12
12
  import {InputField} from '@ui-kit/InputField.component';
13
13
  import {Button} from '@ui-kit/buttons/Button.component';
14
+ import {localization} from '@localization/localization';
14
15
  import {LoginController} from './login.controller';
15
16
 
16
17
  enum LoginField {
@@ -26,8 +27,11 @@ interface Form {
26
27
  const minPassLength = 8;
27
28
  const schema = yup
28
29
  .object({
29
- [LoginField.UserName]: yup.string().required('username is required'),
30
- [LoginField.Password]: yup.string().required('password is required').min(minPassLength, 'min 8 chars'),
30
+ [LoginField.UserName]: yup.string().required(localization.t('validation.usernameRequired')),
31
+ [LoginField.Password]: yup
32
+ .string()
33
+ .required(localization.t('validation.passRequired'))
34
+ .min(minPassLength, localization.t('validation.minChars', {min: minPassLength})),
31
35
  })
32
36
  .required();
33
37
 
@@ -60,11 +64,11 @@ export const Login: React.FC<NativeStackScreenProps<MainStackParamsList, MainSta
60
64
  };
61
65
 
62
66
  const renderUsername: ControllerProps<Form, LoginField.UserName>['render'] = ({fieldState, field}) => (
63
- <InputField {...field} error={fieldState.error} containerStyle={styles.row} placeholder="Username, Mobile Number" />
67
+ <InputField {...field} error={fieldState.error} containerStyle={styles.row} placeholder={localization.t('placeholders.username')} />
64
68
  );
65
69
 
66
70
  const renderPassword: ControllerProps<Form, LoginField.Password>['render'] = ({fieldState, field}) => (
67
- <InputField secureTextEntry {...field} error={fieldState.error} containerStyle={styles.row} placeholder="Password" />
71
+ <InputField secureTextEntry {...field} error={fieldState.error} containerStyle={styles.row} placeholder={localization.t('placeholders.pass')} />
68
72
  );
69
73
 
70
74
  return (
@@ -73,13 +77,13 @@ export const Login: React.FC<NativeStackScreenProps<MainStackParamsList, MainSta
73
77
  <View style={styles.iconWrapper}>
74
78
  <Computools />
75
79
  </View>
76
- <Text style={styles.headerText}>Welcome 🤩 we glad to see you in computools rn template</Text>
80
+ <Text style={styles.headerText}>{localization.t('greetings')}</Text>
77
81
  </View>
78
82
  <Controller name={LoginField.UserName} control={control} render={renderUsername} />
79
83
  <Controller name={LoginField.Password} control={control} render={renderPassword} />
80
- <Text style={[styles.forgetPassword, styles.row]}>Forget password?</Text>
81
- <Button style={styles.row} onPress={handleSubmit(onLogin)} text="Login" />
82
- <Button style={styles.row} onPress={onSignUp} text="Sign Up" />
84
+ <Text style={[styles.forgetPassword, styles.row]}>{localization.t('forgotPass')}</Text>
85
+ <Button style={styles.row} onPress={handleSubmit(onLogin)} text={localization.t('buttons.login')} />
86
+ <Button style={styles.row} onPress={onSignUp} text={localization.t('buttons.signup')} />
83
87
  </View>
84
88
  );
85
89
  };
@@ -8,14 +8,14 @@ export class LoginController {
8
8
 
9
9
  private loginProcessing: boolean = false;
10
10
 
11
- public constructor() {
12
- makeAutoObservable(this);
13
- }
14
-
15
11
  public get isProcessing() {
16
12
  return this.loginProcessing;
17
13
  }
18
14
 
15
+ public constructor() {
16
+ makeAutoObservable(this);
17
+ }
18
+
19
19
  public async login(username: string, password: string) {
20
20
  this.loginProcessing = true;
21
21
  try {
@@ -10,6 +10,7 @@ import {Computools} from '@ui-kit/icons/computools/Computools.icon';
10
10
  import {InputField} from '@ui-kit/InputField.component';
11
11
  import {Button} from '@ui-kit/buttons/Button.component';
12
12
  import {HeaderBack} from '@ui-kit/HeaderBack.component';
13
+ import {localization} from '@localization/localization';
13
14
 
14
15
  enum SignUpField {
15
16
  UserName = 'username',
@@ -26,13 +27,16 @@ interface Form {
26
27
  const minPassLength = 8;
27
28
  const schema = yup
28
29
  .object({
29
- [SignUpField.UserName]: yup.string().required('username is required'),
30
- [SignUpField.Password]: yup.string().required('password is required').min(minPassLength, 'min 8 chars'),
30
+ [SignUpField.UserName]: yup.string().required(localization.t('validation.usernameRequired')),
31
+ [SignUpField.Password]: yup
32
+ .string()
33
+ .required(localization.t('validation.passRequired'))
34
+ .min(minPassLength, localization.t('validation.minChars', {min: minPassLength})),
31
35
  [SignUpField.RepeatPassword]: yup
32
36
  .string()
33
- .required('password is required')
34
- .min(minPassLength, 'min 8 chars')
35
- .oneOf([yup.ref(SignUpField.Password)], 'Passwords do not match'),
37
+ .required(localization.t('validation.passRequired'))
38
+ .min(minPassLength, localization.t('validation.minChars', {min: minPassLength}))
39
+ .oneOf([yup.ref(SignUpField.Password)], localization.t('validation.passNotMatch')),
36
40
  })
37
41
  .required();
38
42
 
@@ -54,15 +58,21 @@ export const SignUp: React.FC<NativeStackScreenProps<MainStackParamsList, MainSt
54
58
  };
55
59
 
56
60
  const renderUsername: ControllerProps<Form, SignUpField.UserName>['render'] = ({fieldState, field}) => (
57
- <InputField {...field} error={fieldState.error} containerStyle={styles.row} placeholder="Username, Mobile Number" />
61
+ <InputField {...field} error={fieldState.error} containerStyle={styles.row} placeholder={localization.t('placeholders.username')} />
58
62
  );
59
63
 
60
64
  const renderPassword: ControllerProps<Form, SignUpField.Password>['render'] = ({fieldState, field}) => (
61
- <InputField secureTextEntry {...field} error={fieldState.error} containerStyle={styles.row} placeholder="Password" />
65
+ <InputField secureTextEntry {...field} error={fieldState.error} containerStyle={styles.row} placeholder={localization.t('placeholders.pass')} />
62
66
  );
63
67
 
64
68
  const renderRepeatPassword: ControllerProps<Form, SignUpField.RepeatPassword>['render'] = ({fieldState, field}) => (
65
- <InputField secureTextEntry {...field} error={fieldState.error} containerStyle={styles.row} placeholder="Repeat password" />
69
+ <InputField
70
+ secureTextEntry
71
+ {...field}
72
+ error={fieldState.error}
73
+ containerStyle={styles.row}
74
+ placeholder={localization.t('placeholders.repeatPass')}
75
+ />
66
76
  );
67
77
 
68
78
  return (
@@ -73,12 +83,12 @@ export const SignUp: React.FC<NativeStackScreenProps<MainStackParamsList, MainSt
73
83
  <View style={styles.iconWrapper}>
74
84
  <Computools />
75
85
  </View>
76
- <Text style={styles.headerText}>Welcome 🤩 we glad to see you in computools rn template</Text>
86
+ <Text style={styles.headerText}>{localization.t('greetings')}</Text>
77
87
  </View>
78
88
  <Controller name={SignUpField.UserName} control={control} render={renderUsername} />
79
89
  <Controller name={SignUpField.Password} control={control} render={renderPassword} />
80
90
  <Controller name={SignUpField.RepeatPassword} control={control} render={renderRepeatPassword} />
81
- <Button style={styles.row} onPress={handleSubmit(onSignUp)} text="Sign Up" />
91
+ <Button style={styles.row} onPress={handleSubmit(onSignUp)} text={localization.t('buttons.signup')} />
82
92
  </View>
83
93
  </SafeAreaView>
84
94
  );
@@ -4,6 +4,7 @@ import {type NativeStackScreenProps} from '@react-navigation/native-stack';
4
4
 
5
5
  import {MainStackParamsList, MainStackRoutes} from '@infra/MainStackRoutes.routes';
6
6
  import {Button} from '@ui-kit/buttons/Button.component';
7
+ import {localization} from '@localization/localization';
7
8
  import {Step} from './Step.component';
8
9
 
9
10
  const {width} = Dimensions.get('window');
@@ -20,12 +21,12 @@ export const Onboarding: React.FC<NativeStackScreenProps<MainStackParamsList, Ma
20
21
  decelerationRate="fast"
21
22
  style={styles.scroll}
22
23
  contentContainerStyle={styles.scrollContent}>
23
- <Step text="UNLOCK TOMORROW 1" />
24
- <Step text="UNLOCK TOMORROW 2" />
25
- <Step text="UNLOCK TOMORROW 3" />
24
+ <Step text={localization.t('brandPhrase', {count: 1}).toUpperCase()} />
25
+ <Step text={localization.t('brandPhrase', {count: 2}).toUpperCase()} />
26
+ <Step text={localization.t('brandPhrase', {count: 3}).toUpperCase()} />
26
27
  </ScrollView>
27
28
  <View style={styles.controllsWrapper}>
28
- <Button onPress={onSkip} text="Skip" />
29
+ <Button onPress={onSkip} text={localization.t('buttons.skip')} />
29
30
  </View>
30
31
  </View>
31
32
  );
@@ -0,0 +1,21 @@
1
+ {
2
+ "brandPhrase": "Unlock Tomorrow {{count}}",
3
+ "greetings": "Welcome 🤩 we glad to see you in computools rn template",
4
+ "forgotPass": "Forgot password?",
5
+ "buttons" : {
6
+ "skip": "Skip",
7
+ "login": "Login",
8
+ "signup": "Sign up"
9
+ },
10
+ "validation": {
11
+ "usernameRequired": "username is required",
12
+ "passRequired": "password is required",
13
+ "minChars": "min {{min}} chars",
14
+ "passNotMatch": "Passwords do not match"
15
+ },
16
+ "placeholders": {
17
+ "username": "Username, Mobile Number",
18
+ "pass": "Password",
19
+ "repeatPass": "Repeat password"
20
+ }
21
+ }
@@ -0,0 +1,53 @@
1
+ import * as i18n from 'i18next';
2
+ import {initReactI18next} from 'react-i18next';
3
+
4
+ import en from './en.json';
5
+ import uk from './uk.json';
6
+
7
+ export enum Languages {
8
+ EN = 'en',
9
+ UK = 'uk',
10
+ }
11
+
12
+ export type ResourceKey = string | {[key: string]: string};
13
+
14
+ export interface LangOptions {
15
+ fallbackLng: Languages;
16
+ resources: {[key in Languages]: {translation: Record<string, ResourceKey>}};
17
+ }
18
+
19
+ export interface Localization {
20
+ language: Languages;
21
+ t: (key: string, options?: {[key: string]: string | number}) => string;
22
+ selectLanguage: (langKey: Languages) => void;
23
+ }
24
+
25
+ export class NextLocalization implements Localization {
26
+ private currentLanguage: Languages;
27
+ public get language() {
28
+ return this.currentLanguage;
29
+ }
30
+
31
+ public constructor(options: LangOptions) {
32
+ this.currentLanguage = options.fallbackLng;
33
+ i18n.use(initReactI18next).init({
34
+ compatibilityJSON: 'v3',
35
+ ...options,
36
+ });
37
+ }
38
+
39
+ public t = (key: string, options?: {[key: string]: string | number}) => i18n.t(key, options);
40
+
41
+ public selectLanguage = (langKey: Languages) => {
42
+ this.currentLanguage = langKey;
43
+ i18n.changeLanguage(langKey);
44
+ };
45
+ }
46
+
47
+ export const localization: Localization = new NextLocalization({
48
+ fallbackLng: Languages.EN,
49
+ resources: {
50
+ [Languages.EN]: {translation: en},
51
+ [Languages.UK]: {translation: uk},
52
+ },
53
+ });
@@ -0,0 +1,21 @@
1
+ {
2
+ "brandPhrase": "Unlock Tomorrow {{count}}",
3
+ "greetings": "Ласкаво просимо 🤩 ми раді бачити вас у шаблоні computools rn",
4
+ "forgotPass": "Забули пароль?",
5
+ "buttons" : {
6
+ "skip": "Пропустити",
7
+ "login": "Логін",
8
+ "signup": "Зареєструватися"
9
+ },
10
+ "validation": {
11
+ "usernameRequired": "введіть ім'я користувача",
12
+ "passRequired": "потрібен пароль",
13
+ "minChars": "мінімум {{min}} символів",
14
+ "passNotMatch": "Паролі не збігаються"
15
+ },
16
+ "placeholders": {
17
+ "username": "Ім'я користувача, номер телефону",
18
+ "pass": "Пароль",
19
+ "repeatPass": "Повторіть пароль"
20
+ }
21
+ }
@@ -2,6 +2,8 @@
2
2
  "extends": "@tsconfig/react-native/tsconfig.json",
3
3
  "compilerOptions": {
4
4
  "useDefineForClassFields": true,
5
+ "resolveJsonModule": true,
6
+ "esModuleInterop": true,
5
7
 
6
8
  "baseUrl": ".",
7
9
  "paths": {
@@ -11,6 +13,7 @@
11
13
  "@infra/*": ["src/app/infrastructure/*"],
12
14
  "@types/*": ["src/app/types/*"],
13
15
  "@ui-kit/*": ["src/app/ui-kit/*"],
16
+ "@localization/*": ["src/localization/*"],
14
17
  }
15
18
  }
16
19
  }