@fadyshawky/react-native-magic 2.0.5 → 2.0.7

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.
Files changed (77) hide show
  1. package/package.json +1 -1
  2. package/template/App.tsx +21 -16
  3. package/template/ios/reactnativemagic/AppDelegate.mm +5 -0
  4. package/template/src/common/ImageResources.g.ts +1 -33
  5. package/template/src/common/components/Background.tsx +7 -7
  6. package/template/src/common/components/Container.tsx +7 -10
  7. package/template/src/common/localization/LocalizationProvider.tsx +14 -17
  8. package/template/src/common/localization/RTLInitializer.tsx +90 -0
  9. package/template/src/common/localization/intlFormatter.ts +37 -0
  10. package/template/src/common/localization/localization.ts +1 -3
  11. package/template/src/common/localization/translations/commonLocalization.ts +11 -81
  12. package/template/src/common/localization/translations/emptyLocalization.ts +6 -2
  13. package/template/src/common/localization/translations/errorsLocalization.ts +33 -13
  14. package/template/src/common/localization/translations/homeLocalization.ts +4 -24
  15. package/template/src/common/localization/translations/loginLocalization.ts +26 -29
  16. package/template/src/common/localization/translations/mainNavigationLocalization.ts +2 -2
  17. package/template/src/common/localization/translations/onboardingLocalization.ts +40 -9
  18. package/template/src/common/localization/translations/otpLocalization.ts +8 -8
  19. package/template/src/common/localization/translations/pagesLocalization.ts +13 -1
  20. package/template/src/common/localization/translations/passwordLocalization.ts +3 -3
  21. package/template/src/common/localization/translations/profileLocalization.ts +4 -4
  22. package/template/src/core/store/app/appSlice.ts +2 -2
  23. package/template/src/core/store/app/appState.ts +1 -1
  24. package/template/src/core/theme/colors.ts +106 -70
  25. package/template/src/core/theme/commonConsts.ts +1 -1
  26. package/template/src/core/theme/commonSizes.ts +119 -94
  27. package/template/src/core/theme/commonStyles.ts +22 -22
  28. package/template/src/core/theme/fonts.ts +13 -14
  29. package/template/src/core/theme/shadows.ts +135 -0
  30. package/template/src/core/theme/themes.ts +386 -75
  31. package/template/src/core/theme/types.ts +201 -15
  32. package/template/src/navigation/HeaderComponents.tsx +6 -30
  33. package/template/src/navigation/MainNavigation.tsx +2 -3
  34. package/template/src/navigation/MainStack.tsx +6 -97
  35. package/template/src/screens/Login/Login.tsx +5 -7
  36. package/template/src/screens/OTP/OTPScreen.tsx +12 -13
  37. package/template/src/screens/home/HomeScreen.tsx +2 -295
  38. package/template/src/screens/profile/Profile.tsx +2 -290
  39. package/template/src/common/localization/translations/posLocalization.ts +0 -196
  40. package/template/src/components/PrinterExample.js +0 -226
  41. package/template/src/core/store/Categories/categoryActions.ts +0 -33
  42. package/template/src/core/store/Categories/categorySlice.ts +0 -75
  43. package/template/src/core/store/Categories/categoryState.ts +0 -41
  44. package/template/src/core/store/Providers/providersActions.ts +0 -102
  45. package/template/src/core/store/Providers/providersSlice.ts +0 -136
  46. package/template/src/core/store/Providers/providersState.ts +0 -37
  47. package/template/src/core/store/Services/servicesActions.ts +0 -191
  48. package/template/src/core/store/Services/servicesSlice.ts +0 -205
  49. package/template/src/core/store/Services/servicesState.ts +0 -466
  50. package/template/src/modules/SunmiCard.js +0 -212
  51. package/template/src/modules/SunmiPrepaid.ts +0 -122
  52. package/template/src/screens/Categories/Categories.tsx +0 -141
  53. package/template/src/screens/Categories/hooks/useCategoriesData.ts +0 -33
  54. package/template/src/screens/Categories/types.ts +0 -7
  55. package/template/src/screens/Favorites/Favorites.tsx +0 -130
  56. package/template/src/screens/ForceChangePassword/ForceChangePasswordScreen.tsx +0 -155
  57. package/template/src/screens/History/History.tsx +0 -430
  58. package/template/src/screens/History/hooks/useHistoryData.ts +0 -49
  59. package/template/src/screens/History/types.ts +0 -7
  60. package/template/src/screens/InquiredBill/InquiredBill.tsx +0 -443
  61. package/template/src/screens/InquiredBill/hooks/useInquiredData.ts +0 -91
  62. package/template/src/screens/PaymentConfirmation/PaymentConfirmation.tsx +0 -326
  63. package/template/src/screens/Providers/Providers.tsx +0 -166
  64. package/template/src/screens/Providers/hooks/useProvidersData.ts +0 -33
  65. package/template/src/screens/Providers/types.ts +0 -7
  66. package/template/src/screens/ReceiptScreen/ReceiptScreen.tsx +0 -181
  67. package/template/src/screens/ReceiptScreen/hooks/useReceiptData.ts +0 -46
  68. package/template/src/screens/ReceiptScreen/utils/utils.tsx +0 -156
  69. package/template/src/screens/Services/Services.tsx +0 -144
  70. package/template/src/screens/Services/hooks/useServicesData.ts +0 -41
  71. package/template/src/screens/SingleService/Components/FawryInputs.tsx +0 -446
  72. package/template/src/screens/SingleService/SingleService.tsx +0 -229
  73. package/template/src/screens/SingleService/hooks/useServiceData.ts +0 -164
  74. package/template/src/services/SunmiPrinterInternal.js +0 -268
  75. package/template/src/types/sunmiPrepaid.d.ts +0 -20
  76. package/template/src/utils/SunmiPrinter.ts +0 -442
  77. package/template/src/utils/feesCalculator.ts +0 -92
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fadyshawky/react-native-magic",
3
- "version": "2.0.5",
3
+ "version": "2.0.7",
4
4
  "description": "react native template with ready components, hooks, react navigation, redux, typescript, etc.",
5
5
  "keywords": [
6
6
  "react-native-magic",
package/template/App.tsx CHANGED
@@ -11,7 +11,8 @@ import {SafeAreaProvider} from 'react-native-safe-area-context';
11
11
  import {Provider} from 'react-redux';
12
12
  import {PersistGate} from 'redux-persist/integration/react';
13
13
  import {LocalizationProvider} from './src/common/localization/LocalizationProvider';
14
- import {DEFAULT_LANGUAGE} from './src/common/localization/localization';
14
+ import {RTLInitializer} from './src/common/localization/RTLInitializer';
15
+ import {useAppSelector} from './src/core/store/reduxHelpers';
15
16
  import {persistor, store} from './src/core/store/store';
16
17
  import {ThemeProvider, useTheme} from './src/core/theme/ThemeProvider';
17
18
  import AppNavigator from './src/navigation/MainNavigation';
@@ -20,17 +21,23 @@ LogBox.ignoreAllLogs();
20
21
 
21
22
  const ThemedApp = () => {
22
23
  const {theme} = useTheme();
24
+ const {language} = useAppSelector(state => state.app);
25
+
23
26
  return (
24
- <SafeAreaProvider>
25
- <SafeAreaView style={{position: 'absolute'}} />
26
- <StatusBar
27
- barStyle={theme.mode === 'dark' ? 'light-content' : 'dark-content'}
28
- backgroundColor={theme.colors.background}
29
- />
30
- <SheetProvider>
31
- <AppNavigator />
32
- </SheetProvider>
33
- </SafeAreaProvider>
27
+ <RTLInitializer>
28
+ <LocalizationProvider initialLanguage={language}>
29
+ <SafeAreaProvider>
30
+ <SafeAreaView style={{position: 'absolute'}} />
31
+ <StatusBar
32
+ barStyle={theme.mode === 'dark' ? 'light-content' : 'dark-content'}
33
+ backgroundColor={theme.colors.background_2}
34
+ />
35
+ <SheetProvider>
36
+ <AppNavigator />
37
+ </SheetProvider>
38
+ </SafeAreaProvider>
39
+ </LocalizationProvider>
40
+ </RTLInitializer>
34
41
  );
35
42
  };
36
43
 
@@ -38,11 +45,9 @@ function App(): React.JSX.Element {
38
45
  return (
39
46
  <Provider store={store}>
40
47
  <PersistGate loading={null} persistor={persistor}>
41
- <LocalizationProvider initialLanguage={DEFAULT_LANGUAGE}>
42
- <ThemeProvider initialTheme="dark">
43
- <ThemedApp />
44
- </ThemeProvider>
45
- </LocalizationProvider>
48
+ <ThemeProvider initialTheme="dark">
49
+ <ThemedApp />
50
+ </ThemeProvider>
46
51
  </PersistGate>
47
52
  </Provider>
48
53
  );
@@ -1,11 +1,16 @@
1
1
  #import "AppDelegate.h"
2
2
 
3
3
  #import <React/RCTBundleURLProvider.h>
4
+ #import <React/RCTI18nUtil.h>
4
5
 
5
6
  @implementation AppDelegate
6
7
 
7
8
  - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
8
9
  {
10
+
11
+ [[RCTI18nUtil sharedInstance] allowRTL:YES];
12
+ [[RCTI18nUtil sharedInstance] forceRTL:YES];
13
+
9
14
  self.moduleName = @"reactnativemagic";
10
15
  // You can add your custom initial props in the dictionary below.
11
16
  // They will be passed down to the ViewController used by React Native.
@@ -9,36 +9,4 @@ import {ImageURISource} from 'react-native';
9
9
  * https://github.com/svbutko/react-native-image-resource-generator
10
10
  */
11
11
 
12
- export class ImageResources {
13
- static readonly account: ImageURISource = require('../../resources/images/Account.png');
14
- static readonly arrows: ImageURISource = require('../../resources/images/Arrows.png');
15
- static readonly background_2: ImageURISource = require('../../resources/images/Background_2.png');
16
- static readonly balance: ImageURISource = require('../../resources/images/Balance.png');
17
- static readonly commission: ImageURISource = require('../../resources/images/Commission.png');
18
- static readonly display: ImageURISource = require('../../resources/images/Display.png');
19
- static readonly en: ImageURISource = require('../../resources/images/EN.png');
20
- static readonly favourite_active: ImageURISource = require('../../resources/images/Favourite_Active.png');
21
- static readonly favourite_inactive: ImageURISource = require('../../resources/images/Favourite_Inactive.png');
22
- static readonly favourites: ImageURISource = require('../../resources/images/Favourites.png');
23
- static readonly financials: ImageURISource = require('../../resources/images/Financials.png');
24
- static readonly language: ImageURISource = require('../../resources/images/Language.png');
25
- static readonly neo_pay_plus_logo: ImageURISource = require('../../resources/images/Neo_Pay_Plus_Logo.png');
26
- static readonly services: ImageURISource = require('../../resources/images/Services.png');
27
- static readonly splash_screen: ImageURISource = require('../../resources/images/Splash_Screen.png');
28
- static readonly ar: ImageURISource = require('../../resources/images/ar.png');
29
- static readonly arrow_left: ImageURISource = require('../../resources/images/arrow_left.png');
30
- static readonly arrow_right: ImageURISource = require('../../resources/images/arrow_right.png');
31
- static readonly dark: ImageURISource = require('../../resources/images/dark.png');
32
- static readonly dark_background_1: ImageURISource = require('../../resources/images/dark_background_1.png');
33
- static readonly dark_splash_logo: ImageURISource = require('../../resources/images/dark_splash_logo.png');
34
- static readonly full_ammount: ImageURISource = require('../../resources/images/full_ammount.png');
35
- static readonly header_logo: ImageURISource = require('../../resources/images/header_logo.png');
36
- static readonly light: ImageURISource = require('../../resources/images/light.png');
37
- static readonly light_background_1: ImageURISource = require('../../resources/images/light_background_1.png');
38
- static readonly light_header_logo: ImageURISource = require('../../resources/images/light_header_logo.png');
39
- static readonly light_splash_logo: ImageURISource = require('../../resources/images/light_splash_logo.png');
40
- static readonly partial_ammount: ImageURISource = require('../../resources/images/partial_ammount.png');
41
- static readonly receipt_logo: ImageURISource = require('../../resources/images/receipt_logo.png');
42
- static readonly receipt_logo_transparent: ImageURISource = require('../../resources/images/receipt_logo_transparent.png');
43
- static readonly repeat: ImageURISource = require('../../resources/images/repeat.png');
44
- }
12
+ export class ImageResources {}
@@ -1,9 +1,8 @@
1
1
  import React, {FC, memo} from 'react';
2
2
  import {ImageBackground, StyleSheet, View, ViewStyle} from 'react-native';
3
+ import {KeyboardAwareScrollViewProps} from 'react-native-keyboard-aware-scroll-view';
3
4
  import {useTheme} from '../../core/theme/ThemeProvider';
4
- import {ImageResources} from '../ImageResources.g';
5
5
  import {Container} from './Container';
6
- import {KeyboardAwareScrollViewProps} from 'react-native-keyboard-aware-scroll-view';
7
6
 
8
7
  interface BackgroundProps
9
8
  extends Omit<KeyboardAwareScrollViewProps, 'contentContainerStyle'> {
@@ -46,7 +45,7 @@ export const Background: FC<BackgroundProps> = memo(
46
45
  <View
47
46
  style={[
48
47
  styles.container,
49
- {backgroundColor: theme.colors.background},
48
+ {backgroundColor: theme.colors.background_2},
50
49
  ]}>
51
50
  {content}
52
51
  </View>
@@ -55,10 +54,11 @@ export const Background: FC<BackgroundProps> = memo(
55
54
 
56
55
  return (
57
56
  <View
58
- style={[styles.container, {backgroundColor: theme.colors.background}]}>
59
- <ImageBackground
60
- source={ImageResources[`${theme.mode}_background_1`]}
61
- style={styles.container}>
57
+ style={[
58
+ styles.container,
59
+ {backgroundColor: theme.colors.background_2},
60
+ ]}>
61
+ <ImageBackground source={0} style={styles.container}>
62
62
  {content}
63
63
  </ImageBackground>
64
64
  </View>
@@ -1,21 +1,18 @@
1
1
  import React, {forwardRef} from 'react';
2
2
  import {
3
- StyleSheet,
4
- ViewStyle,
5
- Platform,
6
- KeyboardAvoidingView,
7
- ScrollView,
8
- View,
9
3
  ImageBackground,
10
4
  ImageSourcePropType,
5
+ KeyboardAvoidingView,
6
+ StyleSheet,
7
+ View,
8
+ ViewStyle,
11
9
  } from 'react-native';
12
10
  import {
13
11
  KeyboardAwareScrollView,
14
12
  KeyboardAwareScrollViewProps,
15
13
  } from 'react-native-keyboard-aware-scroll-view';
16
- import {useTheme} from '../../core/theme/ThemeProvider';
17
14
  import {SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context';
18
- import {ImageResources} from '../ImageResources.g';
15
+ import {useTheme} from '../../core/theme/ThemeProvider';
19
16
 
20
17
  interface ContainerProps extends Partial<KeyboardAwareScrollViewProps> {
21
18
  children: React.ReactNode;
@@ -41,7 +38,7 @@ export const Container = forwardRef<KeyboardAwareScrollView, ContainerProps>(
41
38
  withoutScroll = false,
42
39
  backgroundColor,
43
40
  withoutBackgroundImage = false,
44
- backgroundImage = ImageResources[`light_background_1`],
41
+ backgroundImage = 0,
45
42
  extendedBackground = false,
46
43
  ...scrollViewProps
47
44
  },
@@ -50,7 +47,7 @@ export const Container = forwardRef<KeyboardAwareScrollView, ContainerProps>(
50
47
  const {theme} = useTheme();
51
48
  const insets = useSafeAreaInsets();
52
49
  const Wrapper = useSafeArea ? SafeAreaView : View;
53
- const bgColor = backgroundColor || theme.colors.background;
50
+ const bgColor = backgroundColor || theme.colors.background_2;
54
51
 
55
52
  const content = (
56
53
  <Wrapper
@@ -46,41 +46,42 @@ export const LocalizationProvider: React.FC<LocalizationProviderProps> = ({
46
46
  storedIsRTL !== undefined ? storedIsRTL : currentLanguage === Languages.ar,
47
47
  );
48
48
 
49
+ // Update RTL state when stored values change
49
50
  useEffect(() => {
50
- setLanguageUtil(currentLanguage);
51
- setIsRTL(currentLanguage === Languages.ar);
51
+ if (storedIsRTL !== undefined) {
52
+ setIsRTL(storedIsRTL);
53
+ } else if (storedLanguage) {
54
+ setIsRTL(storedLanguage === Languages.ar);
55
+ }
56
+ }, [storedLanguage, storedIsRTL]);
52
57
 
53
- // Force app restart on Android when changing RTL/LTR
54
- if (Platform.OS === 'android') {
55
- const shouldBeRTL = currentLanguage === Languages.ar;
56
- if (I18nManager.isRTL !== shouldBeRTL) {
57
- I18nManager.allowRTL(shouldBeRTL);
58
- I18nManager.forceRTL(shouldBeRTL);
59
- }
58
+ // Set language utility when currentLanguage changes
59
+ useEffect(() => {
60
+ if (currentLanguage) {
61
+ setLanguageUtil(currentLanguage);
60
62
  }
61
63
  }, [currentLanguage]);
62
64
 
63
65
  const changeLanguage = (language: Languages) => {
64
- // Only restart if the language is actually changing
65
66
  if (language !== currentLanguage) {
67
+ console.log('Changing language from', currentLanguage, 'to', language);
68
+
66
69
  setCurrentLanguage(language);
67
70
  dispatch(setLanguageAction(language));
68
71
 
69
72
  // Set RTL configuration before restart
70
73
  const shouldBeRTL = language === Languages.ar;
71
74
  if (I18nManager.isRTL !== shouldBeRTL) {
75
+ console.log('Language change requires RTL update:', shouldBeRTL);
72
76
  I18nManager.allowRTL(shouldBeRTL);
73
77
  I18nManager.forceRTL(shouldBeRTL);
74
78
 
75
79
  // Restart the app to apply RTL/LTR changes properly
76
- // Small delay to ensure settings are applied
77
80
  setTimeout(() => {
78
81
  try {
79
- // Check if RNRestart is available
80
82
  if (RNRestart && typeof RNRestart.restart === 'function') {
81
83
  RNRestart.restart();
82
84
  } else if (Platform.OS === 'android') {
83
- // Fallback for Android using DevSettings
84
85
  const DevSettings = NativeModules.DevSettings;
85
86
  if (DevSettings && DevSettings.reload) {
86
87
  DevSettings.reload();
@@ -103,7 +104,6 @@ export const LocalizationProvider: React.FC<LocalizationProviderProps> = ({
103
104
  const keys = key.split('.');
104
105
  let result: any = localization[section];
105
106
 
106
- // If the key has dot notation (e.g., 'registration.title'), navigate through the object
107
107
  if (keys.length > 1) {
108
108
  for (const k of keys) {
109
109
  result = result[k];
@@ -111,7 +111,6 @@ export const LocalizationProvider: React.FC<LocalizationProviderProps> = ({
111
111
  return result || key;
112
112
  }
113
113
 
114
- // Simple key
115
114
  return result[key] || key;
116
115
  } catch (error) {
117
116
  console.warn(
@@ -139,13 +138,11 @@ export const useLocalization = () => {
139
138
  return context;
140
139
  };
141
140
 
142
- // Shorthand hook for translations
143
141
  export const useTranslation = () => {
144
142
  const {t} = useLocalization();
145
143
  return t;
146
144
  };
147
145
 
148
- // Hook to get RTL status
149
146
  export const useRTL = () => {
150
147
  const {isRTL} = useLocalization();
151
148
  return isRTL;
@@ -0,0 +1,90 @@
1
+ import React, {useEffect, useState} from 'react';
2
+ import {I18nManager, Platform, NativeModules} from 'react-native';
3
+ import {useAppSelector} from '../../core/store/reduxHelpers';
4
+ import {Languages} from './localization';
5
+
6
+ interface RTLInitializerProps {
7
+ children: React.ReactNode;
8
+ }
9
+
10
+ export const RTLInitializer: React.FC<RTLInitializerProps> = ({children}) => {
11
+ const [isInitialized, setIsInitialized] = useState(false);
12
+ const {language, isRTL} = useAppSelector(state => state.app);
13
+
14
+ useEffect(() => {
15
+ const initializeRTL = () => {
16
+ console.log('=== RTL Initializer - Starting initialization ===');
17
+ console.log('Stored language:', language);
18
+ console.log('Stored isRTL:', isRTL);
19
+ console.log('Current I18nManager.isRTL:', I18nManager.isRTL);
20
+ console.log('Current I18nManager.forceRTL:', I18nManager.forceRTL);
21
+
22
+ // Determine the correct RTL setting with better logic
23
+ let shouldBeRTL: boolean;
24
+
25
+ if (isRTL !== undefined) {
26
+ // Use stored RTL setting if available (highest priority)
27
+ shouldBeRTL = isRTL;
28
+ console.log('✅ Using stored isRTL setting:', shouldBeRTL);
29
+ } else if (language) {
30
+ // Use stored language to determine RTL
31
+ shouldBeRTL = language === Languages.ar;
32
+ console.log('✅ Using language-based RTL setting:', shouldBeRTL);
33
+ } else {
34
+ // Fall back to default (Arabic/RTL)
35
+ shouldBeRTL = true;
36
+ console.log('✅ Using default RTL setting:', shouldBeRTL);
37
+ }
38
+
39
+ // Apply RTL setting if it differs from current
40
+ if (I18nManager.isRTL !== shouldBeRTL) {
41
+ console.log(
42
+ '🔄 Updating I18nManager RTL from',
43
+ I18nManager.isRTL,
44
+ 'to',
45
+ shouldBeRTL,
46
+ );
47
+
48
+ // Force the RTL setting
49
+ I18nManager.allowRTL(shouldBeRTL);
50
+ I18nManager.forceRTL(shouldBeRTL);
51
+
52
+ // Double-check the setting was applied
53
+ setTimeout(() => {
54
+ console.log(
55
+ ' Verification - I18nManager.isRTL after update:',
56
+ I18nManager.isRTL,
57
+ );
58
+ if (I18nManager.isRTL !== shouldBeRTL) {
59
+ console.warn('⚠️ RTL setting was not applied correctly!');
60
+ } else {
61
+ console.log('✅ RTL setting applied successfully');
62
+ }
63
+ }, 100);
64
+ } else {
65
+ console.log(
66
+ '✅ I18nManager RTL setting is already correct:',
67
+ I18nManager.isRTL,
68
+ );
69
+ }
70
+
71
+ // Mark as initialized
72
+ setIsInitialized(true);
73
+ console.log('=== RTL Initializer - Initialization complete ===');
74
+ };
75
+
76
+ // Wait longer to ensure Redux state is fully hydrated
77
+ // Increased timeout to handle slower devices
78
+ const timer = setTimeout(initializeRTL, 800);
79
+ return () => clearTimeout(timer);
80
+ }, [language, isRTL]);
81
+
82
+ // Don't render children until RTL is initialized
83
+ if (!isInitialized) {
84
+ console.log('⏳ RTL Initializer: Waiting for initialization...');
85
+ return null; // or a loading screen
86
+ }
87
+
88
+ console.log('🚀 RTL Initializer: Rendering children');
89
+ return <>{children}</>;
90
+ };
@@ -0,0 +1,37 @@
1
+ import Intl from 'intl';
2
+ import {getLanguage} from './localization';
3
+ // eslint-disable-next-line import/no-unassigned-import
4
+ import 'intl/locale-data/jsonp/en';
5
+
6
+ export function formatPercent(percent: number | string): string {
7
+ const formatter = new Intl.NumberFormat(getLanguage(), {
8
+ style: 'percent',
9
+ minimumFractionDigits: 0,
10
+ maximumFractionDigits: 2,
11
+ });
12
+
13
+ return formatter.format(Number(percent) / 100);
14
+ }
15
+
16
+ export function formatCurrency(
17
+ price: number | string,
18
+ currency?: string,
19
+ ): string {
20
+ const formatter = new Intl.NumberFormat(getLanguage(), {
21
+ style: 'currency',
22
+ minimumFractionDigits: 0,
23
+ maximumFractionDigits: 2,
24
+ currency: currency || 'USD',
25
+ });
26
+
27
+ return formatter.format(Number(price));
28
+ }
29
+
30
+ export function formatDecimal(value: number | string): string {
31
+ const formatter = new Intl.NumberFormat(getLanguage(), {
32
+ style: 'decimal',
33
+ minimumFractionDigits: 0,
34
+ });
35
+
36
+ return formatter.format(Number(value));
37
+ }
@@ -8,12 +8,11 @@ import {setDateLocale} from './dateFormatter';
8
8
  import {loginLocalization} from './translations/loginLocalization';
9
9
  import {homeLocalization} from './translations/homeLocalization';
10
10
  import {profileLocalization} from './translations/profileLocalization';
11
+ import {I18nManager} from 'react-native';
11
12
  import {otpLocalization} from './translations/otpLocalization';
12
13
  import {passwordLocalization} from './translations/passwordLocalization';
13
14
  import {navigationLocalization} from './translations/navigationLocalization';
14
15
  import {mainNavigationLocalization} from './translations/mainNavigationLocalization';
15
- import {I18nManager} from 'react-native';
16
- import {posLocalization} from './translations/posLocalization';
17
16
 
18
17
  export enum Languages {
19
18
  en = 'en',
@@ -33,7 +32,6 @@ export const localization = {
33
32
  password: new LocalizedStrings(passwordLocalization),
34
33
  navigation: new LocalizedStrings(navigationLocalization),
35
34
  mainNavigation: new LocalizedStrings(mainNavigationLocalization),
36
- pos: new LocalizedStrings(posLocalization),
37
35
  };
38
36
 
39
37
  export function getLanguage(): string {
@@ -1,19 +1,19 @@
1
1
  export const commonLocalization = {
2
2
  en: {
3
3
  search: 'Search',
4
- selectPhoto: 'Select a photo',
5
- takePhoto: 'Take a photo',
6
- chooseFromLibrary: 'Choose from library',
4
+ selectPhoto: 'Select Photo',
5
+ takePhoto: 'Take Photo',
6
+ chooseFromLibrary: 'Choose from Library',
7
7
  cancel: 'Cancel',
8
8
  reject: 'Reject',
9
9
  delete: 'Delete',
10
10
  back: 'Back',
11
11
  next: 'Next',
12
12
  done: 'Done',
13
- ok: 'Ok',
13
+ ok: 'OK',
14
14
  continue: 'Continue',
15
15
  save: 'Save',
16
- loading: 'Loading',
16
+ loading: 'Loading...',
17
17
  photo: 'Photo',
18
18
  yes: 'Yes',
19
19
  no: 'No',
@@ -21,50 +21,15 @@ export const commonLocalization = {
21
21
  warning: 'Warning',
22
22
  success: 'Success',
23
23
  select: 'Select',
24
- dataSuccessfullyUpdated: 'Data has been successfully updated',
24
+ dataSuccessfullyUpdated: 'Data updated successfully',
25
25
  settings: 'Settings',
26
26
  required: ' (required)',
27
27
  optional: ' (optional)',
28
- currency: 'EGP',
29
- seeMore: 'See More',
30
- restartRequired: 'Restart Required',
31
- restartAppMessage: 'The app needs to restart to apply language changes.',
32
- restart: 'Restart',
33
- change: 'Change',
34
- submit: 'Submit',
35
- billAmount: 'Bill Amount',
36
- fullAmount: 'Full Amount',
37
- partialAmount: 'Other Amount',
38
- enterAmount: 'Enter Amount',
39
- paymentDetails: 'Payment Details',
40
- amount: 'Amount',
41
- fees: 'Fees',
42
- total: 'Total',
43
- favoriteCategories: 'Favorite Categories',
44
- favoriteProviders: 'Favorite Providers',
45
- noFavoriteCategories: 'No favorite categories yet',
46
- noFavoriteProviders: 'No favorite providers yet',
47
- commission: 'Commission',
48
- dueDate: 'Due Date',
49
- issueDate: 'Issue Date',
50
- print: 'Print',
51
- allServices: 'All Services',
52
- totalAfterFees: 'Total after service fees',
53
- quantity: 'Quantity',
54
- amountToPay: 'Amount to Pay',
55
- voucher: 'Voucher',
56
- invalidAccountNumber: 'Invalid account number',
57
- otherAmount: 'Other Amount',
58
- error: 'Error',
59
- invalid_format: 'Invalid format',
60
- otherAmountLabel: 'Other Amount',
61
- backToHome: 'Back to Home',
62
- confirm: 'Confirm',
63
28
  },
64
29
  ar: {
65
30
  search: 'بحث',
66
31
  selectPhoto: 'اختر صورة',
67
- takePhoto: 'التقط صورة',
32
+ takePhoto: 'التقاط صورة',
68
33
  chooseFromLibrary: 'اختر من المكتبة',
69
34
  cancel: 'إلغاء',
70
35
  reject: 'رفض',
@@ -73,54 +38,19 @@ export const commonLocalization = {
73
38
  next: 'التالي',
74
39
  done: 'تم',
75
40
  ok: 'موافق',
76
- continue: 'استمرار',
41
+ continue: 'متابعة',
77
42
  save: 'حفظ',
78
- loading: 'جاري التحميل',
43
+ loading: 'جاري التحميل...',
79
44
  photo: 'صورة',
80
45
  yes: 'نعم',
81
46
  no: 'لا',
82
47
  areYouSure: 'هل أنت متأكد؟',
83
48
  warning: 'تحذير',
84
- success: 'نجاح',
85
- select: 'اختر',
49
+ success: 'نجح',
50
+ select: 'اختيار',
86
51
  dataSuccessfullyUpdated: 'تم تحديث البيانات بنجاح',
87
52
  settings: 'الإعدادات',
88
53
  required: ' (مطلوب)',
89
54
  optional: ' (اختياري)',
90
- currency: 'ج.م',
91
- seeMore: 'عرض المزيد',
92
- restartRequired: 'إعادة التشغيل مطلوبة',
93
- restartAppMessage: 'يحتاج التطبيق إلى إعادة التشغيل لتطبيق تغييرات اللغة.',
94
- restart: 'إعادة تشغيل',
95
- change: 'تغيير',
96
- submit: 'إرسال',
97
- billAmount: 'مبلغ الفاتورة',
98
- fullAmount: 'المبلغ الكامل',
99
- partialAmount: 'مبلغ آخر',
100
- enterAmount: 'أدخل المبلغ',
101
- paymentDetails: 'تفاصيل الدفع',
102
- amount: 'المبلغ',
103
- fees: 'الرسوم',
104
- total: 'الإجمالي',
105
- favoriteCategories: 'الفئات المفضلة',
106
- favoriteProviders: 'مقدمي الخدمات المفضلين',
107
- noFavoriteCategories: 'لا توجد فئات مفضلة بعد',
108
- noFavoriteProviders: 'لا يوجد مقدمي خدمات مفضلين بعد',
109
- commission: 'العمولة',
110
- dueDate: 'الموعد المستحق',
111
- issueDate: 'التاريخ الصادر',
112
- print: 'طباعة',
113
- allServices: 'جميع الخدمات',
114
- totalAfterFees: 'بعد رسوم الخدمة',
115
- quantity: 'الكمية',
116
- amountToPay: 'قيمة الدفع',
117
- voucher: 'القسيمة',
118
- otherAmount: 'مبلغ آخر',
119
- invalidAccountNumber: 'رقم الحساب غير صالح',
120
- error: 'خطأ',
121
- invalid_format: 'صيغة غير صالحة',
122
- otherAmountLabel: 'مبلغ آخر',
123
- backToHome: 'العودة للرئيسية',
124
- confirm: 'تأكيد',
125
55
  },
126
56
  };
@@ -1,6 +1,10 @@
1
1
  export const emptyLocalization = {
2
2
  en: {
3
- noData: 'No data',
4
- checkThisPageLater: 'Check this page later',
3
+ noData: 'No data available',
4
+ checkThisPageLater: 'Check back later',
5
+ },
6
+ ar: {
7
+ noData: 'لا توجد بيانات',
8
+ checkThisPageLater: 'تحقق لاحقاً',
5
9
  },
6
10
  };
@@ -1,22 +1,42 @@
1
1
  export const errorsLocalization = {
2
2
  en: {
3
- listErrorTitle: 'Failed to load data.',
4
- tryAgain: 'Try again.',
5
- thisFieldIsRequired: 'This field is required.',
6
- unknownErrorHasOccurred: 'An unknown error has occurred.',
7
- failedToOpenUrl: 'Failed to open URL. Check that the app is installed.',
8
- pleaseCheckYourInternetConnection: 'Please check your Internet connection.',
9
- invalidEmail: 'Invalid Email',
3
+ listErrorTitle: 'Failed to load data',
4
+ tryAgain: 'Try again',
5
+ thisFieldIsRequired: 'This field is required',
6
+ unknownErrorHasOccurred: 'An error occurred',
7
+ failedToOpenUrl: 'Failed to open URL',
8
+ pleaseCheckYourInternetConnection: 'Please check your internet connection',
9
+ invalidEmail: 'Invalid email',
10
10
  invalidPhoneNumber: 'Invalid phone number',
11
- invalidFullName: 'Invalid full name',
11
+ invalidFullName: 'Invalid name',
12
12
  invalidFromDate: (fromField: string, toField: string) =>
13
- `${fromField} can't be later than ${toField.toLowerCase()}`,
13
+ `${fromField} cannot be later than ${toField.toLowerCase()}`,
14
14
  invalidToDate: (fromField: string, toField: string) =>
15
- `${toField} can't be earlier than ${fromField.toLowerCase()}`,
15
+ `${toField} cannot be earlier than ${fromField.toLowerCase()}`,
16
16
  datesCantBeEqual: (fromField: string, toField: string) =>
17
- `${fromField} and ${toField.toLowerCase()} can't be equal`,
18
- mobileDataIsTurnedOff: 'Mobile Data is Turned Off',
19
- turnOnMobileData: 'Turn on mobile data or use Wi-Fi to access data.',
17
+ `${fromField} and ${toField.toLowerCase()} cannot be equal`,
18
+ mobileDataIsTurnedOff: 'Mobile data is turned off',
19
+ turnOnMobileData: 'Turn on mobile data or use Wi-Fi',
20
20
  error: 'Error',
21
21
  },
22
+ ar: {
23
+ listErrorTitle: 'فشل تحميل البيانات',
24
+ tryAgain: 'حاول مرة أخرى',
25
+ thisFieldIsRequired: 'هذا الحقل مطلوب',
26
+ unknownErrorHasOccurred: 'حدث خطأ',
27
+ failedToOpenUrl: 'فشل فتح الرابط',
28
+ pleaseCheckYourInternetConnection: 'يرجى التحقق من اتصال الإنترنت',
29
+ invalidEmail: 'بريد إلكتروني غير صالح',
30
+ invalidPhoneNumber: 'رقم هاتف غير صالح',
31
+ invalidFullName: 'اسم غير صالح',
32
+ invalidFromDate: (fromField: string, toField: string) =>
33
+ `${fromField} لا يمكن أن يكون بعد ${toField.toLowerCase()}`,
34
+ invalidToDate: (fromField: string, toField: string) =>
35
+ `${toField} لا يمكن أن يكون قبل ${fromField.toLowerCase()}`,
36
+ datesCantBeEqual: (fromField: string, toField: string) =>
37
+ `${fromField} و ${toField.toLowerCase()} لا يمكن أن يكونا متساويين`,
38
+ mobileDataIsTurnedOff: 'بيانات الجوال مغلقة',
39
+ turnOnMobileData: 'قم بتشغيل بيانات الجوال أو استخدم Wi-Fi',
40
+ error: 'خطأ',
41
+ },
22
42
  };