Browse Source

BUGS | Fix contacts

merge-requests/82/head
Vitalik 3 years ago
parent
commit
5e91369075
  1. 2
      android/app/build.gradle
  2. 5
      ios/Podfile
  3. 28
      ios/Podfile.lock
  4. 44
      ios/taskme.xcodeproj/project.pbxproj
  5. 5
      ios/taskme.xcworkspace/contents.xcworkspacedata
  6. 4
      ios/taskme/Info.plist
  7. 22
      package-lock.json
  8. 1
      package.json
  9. 7
      src/modules/account/hooks/use-account-editor.hook.ts
  10. 2
      src/modules/account/screens/account.screen.tsx
  11. 22
      src/modules/auth/hooks/use-authorization.hook.ts
  12. 79
      src/modules/auth/screens/confirm-code.screen.tsx
  13. 52
      src/modules/auth/screens/sign-in.screen.tsx
  14. 5
      src/modules/contacts/atoms/search-field-with-icon.component.tsx
  15. 26
      src/modules/contacts/components/contacts-list.component.tsx
  16. 28
      src/modules/contacts/hooks/use-fetch-contacts.hook.ts
  17. 9
      src/modules/contacts/screens/contacts.screen.tsx
  18. 15
      src/modules/contacts/smart-component/contacts-list.smart-component.tsx
  19. 8
      src/modules/root/atoms/icon-with-count-indicator.component.tsx
  20. 42
      src/modules/root/configs/tab-bar.config.ts
  21. 2
      src/modules/root/smart-components/tab-bar.smart-component.tsx
  22. 31
      src/modules/settings/screens/settings.screen.tsx
  23. 53
      src/services/system/media-permissions.service.ts
  24. 50
      src/services/system/media.service.ts
  25. 12
      src/services/system/real-time.service.ts
  26. 2
      src/shared/components/buttons/button.component.tsx
  27. 2
      src/shared/components/elements/index.ts
  28. 18
      src/shared/components/elements/loading.component.tsx
  29. 24
      src/shared/components/elements/not-found.component.tsx
  30. 16
      src/shared/components/forms/form-large-control-with-icon.component.tsx
  31. 2
      src/shared/components/forms/form-phone.component.tsx
  32. 4
      src/shared/helpers/exceptions.helpers.ts
  33. 5
      src/shared/hooks/use-flat-list.hook.ts
  34. 4
      src/shared/hooks/use-theme.hook.ts
  35. 2
      src/shared/themes/light/colors.ts
  36. 7
      src/shared/themes/light/navigation.ts
  37. 11
      yarn.lock

2
android/app/build.gradle

@ -134,7 +134,7 @@ android { @@ -134,7 +134,7 @@ android {
applicationId "com.taskme"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 3
versionCode 4
versionName "2.0"
vectorDrawables.useSupportLibrary true
}

5
ios/Podfile

@ -6,12 +6,17 @@ platform :ios, '10.0' @@ -6,12 +6,17 @@ platform :ios, '10.0'
target 'taskme' do
config = use_native_modules!
use_react_native!(
:path => config[:reactNativePath],
# to enable hermes on iOS, change `false` to `true` and then install pods
:hermes_enabled => false
)
permissions_path = '../node_modules/react-native-permissions/ios'
pod 'Permission-Camera', :path => "#{permissions_path}/Camera"
pod 'Permission-PhotoLibrary', :path => "#{permissions_path}/PhotoLibrary"
target 'taskmeTests' do
inherit! :complete

28
ios/Podfile.lock

@ -59,6 +59,10 @@ PODS: @@ -59,6 +59,10 @@ PODS:
- glog (0.3.5)
- libevent (2.1.12)
- OpenSSL-Universal (1.1.180)
- Permission-Camera (3.1.0):
- RNPermissions
- Permission-PhotoLibrary (3.1.0):
- RNPermissions
- RCT-Folly (2020.01.13.00):
- boost-for-react-native
- DoubleConversion
@ -345,6 +349,8 @@ PODS: @@ -345,6 +349,8 @@ PODS:
- React-Core
- React-RCTImage
- TOCropViewController
- RNPermissions (3.1.0):
- React-Core
- RNScreens (3.6.0):
- React-Core
- React-RCTImage
@ -379,6 +385,8 @@ DEPENDENCIES: @@ -379,6 +385,8 @@ DEPENDENCIES:
- FlipperKit/FlipperKitUserDefaultsPlugin (~> 0.75.1)
- FlipperKit/SKIOSNetworkPlugin (~> 0.75.1)
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
- Permission-Camera (from `../node_modules/react-native-permissions/ios/Camera`)
- Permission-PhotoLibrary (from `../node_modules/react-native-permissions/ios/PhotoLibrary`)
- RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
@ -415,6 +423,7 @@ DEPENDENCIES: @@ -415,6 +423,7 @@ DEPENDENCIES:
- RNDeviceInfo (from `../node_modules/react-native-device-info`)
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
- RNImageCropPicker (from `../node_modules/react-native-image-crop-picker`)
- RNPermissions (from `../node_modules/react-native-permissions`)
- RNScreens (from `../node_modules/react-native-screens`)
- RNVectorIcons (from `../node_modules/react-native-vector-icons`)
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
@ -444,6 +453,10 @@ EXTERNAL SOURCES: @@ -444,6 +453,10 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/React/FBReactNativeSpec"
glog:
:podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
Permission-Camera:
:path: "../node_modules/react-native-permissions/ios/Camera"
Permission-PhotoLibrary:
:path: "../node_modules/react-native-permissions/ios/PhotoLibrary"
RCT-Folly:
:podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec"
RCTRequired:
@ -512,6 +525,8 @@ EXTERNAL SOURCES: @@ -512,6 +525,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-gesture-handler"
RNImageCropPicker:
:path: "../node_modules/react-native-image-crop-picker"
RNPermissions:
:path: "../node_modules/react-native-permissions"
RNScreens:
:path: "../node_modules/react-native-screens"
RNVectorIcons:
@ -524,7 +539,7 @@ SPEC CHECKSUMS: @@ -524,7 +539,7 @@ SPEC CHECKSUMS:
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
DoubleConversion: cf9b38bf0b2d048436d9a82ad2abe1404f11e7de
FBLazyVector: e686045572151edef46010a6f819ade377dfeb4b
FBReactNativeSpec: fad958c172d538261d8afc7d05401008aace66e3
FBReactNativeSpec: fd8c7ca182f42221b54baa670a2c0a1cf425dc6f
Flipper: d3da1aa199aad94455ae725e9f3aa43f3ec17021
Flipper-DoubleConversion: 38631e41ef4f9b12861c67d17cb5518d06badc41
Flipper-Folly: 755929a4f851b2fb2c347d533a23f191b008554c
@ -535,6 +550,8 @@ SPEC CHECKSUMS: @@ -535,6 +550,8 @@ SPEC CHECKSUMS:
glog: 73c2498ac6884b13ede40eda8228cb1eee9d9d62
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
OpenSSL-Universal: 1aa4f6a6ee7256b83db99ec1ccdaa80d10f9af9b
Permission-Camera: 0db4fd6e1c556c1cf47f38b989a8084cea3ec3dd
Permission-PhotoLibrary: 9dcf80d1353d81b9f1e210c34291591236aaf2b6
RCT-Folly: ec7a233ccc97cc556cf7237f0db1ff65b986f27c
RCTRequired: 6d3e854f0e7260a648badd0d44fc364bc9da9728
RCTTypeSafety: c1f31d19349c6b53085766359caac425926fafaa
@ -547,10 +564,10 @@ SPEC CHECKSUMS: @@ -547,10 +564,10 @@ SPEC CHECKSUMS:
React-jsiexecutor: 80c46bd381fd06e418e0d4f53672dc1d1945c4c3
React-jsinspector: cc614ec18a9ca96fd275100c16d74d62ee11f0ae
react-native-date-picker: 201b481c94dcb7678f4712477ad026dd7793305b
react-native-netinfo: 7cb7877ff31ebeb3d03ce0b4fbb616f121ddd859
react-native-netinfo: 0f64266bbaa1989ebd51b43ee1723d582f6b3e47
react-native-orientation-locker: 998c0744e26624407dac068c04c605b4af7304a2
react-native-pager-view: 5ab4d0b4b44d89f77310cb3eb8129745f274ce55
react-native-safe-area-context: 61c8c484a3a9e7d1fda19f7b1794b35bbfd2262a
react-native-pager-view: f21658a2e12eced35ef998250375e4e4dc9b8487
react-native-safe-area-context: 8465df05de8106c584b117f0e027e17174d6e02e
react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865
React-perflogger: 25373e382fed75ce768a443822f07098a15ab737
React-RCTActionSheet: af7796ba49ffe4ca92e7277a5d992d37203f7da5
@ -569,12 +586,13 @@ SPEC CHECKSUMS: @@ -569,12 +586,13 @@ SPEC CHECKSUMS:
RNDeviceInfo: 0d6865ab0a57d9192bdd4e4f5894340b846c3e53
RNGestureHandler: a479ebd5ed4221a810967000735517df0d2db211
RNImageCropPicker: 35a3ceb837446fa11547704709bb22b5fac6d584
RNPermissions: 4b54095940aea8c03fa3e6c92d4ac3647b31ed4e
RNScreens: eb0dfb2d6b21d2d7f980ad46b14eb306d2f1062e
RNVectorIcons: f67a1abce2ec73e62fe4606e8110e95a832bc859
TOCropViewController: 3105367e808b7d3d886a74ff59bf4804e7d3ab38
Yoga: 575c581c63e0d35c9a83f4b46d01d63abc1100ac
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
PODFILE CHECKSUM: c73ef8efd63acc33c555dec2651103bc6355eb2c
PODFILE CHECKSUM: 465fefddb2adca7d66f342c9336387893ca73d38
COCOAPODS: 1.10.1

44
ios/taskme.xcodeproj/project.pbxproj

@ -167,8 +167,8 @@ @@ -167,8 +167,8 @@
00E356EA1AD99517003FC87E /* Sources */,
00E356EB1AD99517003FC87E /* Frameworks */,
00E356EC1AD99517003FC87E /* Resources */,
2FC4E8990FC32899F6E0043F /* [CP] Embed Pods Frameworks */,
BB0C9D47B84365A5F6D3E24E /* [CP] Copy Pods Resources */,
74B010BDD82A3A4D0704AE05 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
@ -190,8 +190,8 @@ @@ -190,8 +190,8 @@
13B07F8C1A680F5B00A75B9A /* Frameworks */,
13B07F8E1A680F5B00A75B9A /* Resources */,
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
E7C832199DD22C96F5336D00 /* [CP] Embed Pods Frameworks */,
05B6B7099CE8F919BEB18E0C /* [CP] Copy Pods Resources */,
41D2B570847BDD4DB7D87AE0 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
@ -290,7 +290,24 @@ @@ -290,7 +290,24 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-taskme/Pods-taskme-resources.sh\"\n";
showEnvVarsInLog = 0;
};
2FC4E8990FC32899F6E0043F /* [CP] Embed Pods Frameworks */ = {
41D2B570847BDD4DB7D87AE0 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-taskme/Pods-taskme-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-taskme/Pods-taskme-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-taskme/Pods-taskme-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
74B010BDD82A3A4D0704AE05 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@ -346,23 +363,6 @@ @@ -346,23 +363,6 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
E7C832199DD22C96F5336D00 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-taskme/Pods-taskme-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-taskme/Pods-taskme-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-taskme/Pods-taskme-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
F3DDDFEAAF0FFD1FC165FCCC /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@ -497,7 +497,7 @@ @@ -497,7 +497,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 4;
CURRENT_PROJECT_VERSION = 8;
DEVELOPMENT_TEAM = HQ3J3TDPR2;
ENABLE_BITCODE = NO;
"EXCLUDED_ARCHS[sdk=*]" = "";
@ -533,7 +533,7 @@ @@ -533,7 +533,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 4;
CURRENT_PROJECT_VERSION = 8;
DEVELOPMENT_TEAM = HQ3J3TDPR2;
ENABLE_BITCODE = NO;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";

5
ios/taskme.xcworkspace/contents.xcworkspacedata generated

@ -2,9 +2,12 @@ @@ -2,9 +2,12 @@
<Workspace
version = "1.0">
<FileRef
location = "group:taskme.xcodeproj">
location = "group:/Users/mac/work/rws/taskme/ios/taskme.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
<FileRef
location = "group:taskme.xcodeproj">
</FileRef>
</Workspace>

4
ios/taskme/Info.plist

@ -22,6 +22,8 @@ @@ -22,6 +22,8 @@
<string>????</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
@ -60,7 +62,5 @@ @@ -60,7 +62,5 @@
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
</dict>
</plist>

22
package-lock.json generated

@ -38,6 +38,7 @@ @@ -38,6 +38,7 @@
"react-native-masked-text": "^1.13.0",
"react-native-orientation-locker": "^1.3.1",
"react-native-pager-view": "^5.4.4",
"react-native-permissions": "^3.1.0",
"react-native-raw-bottom-sheet": "^2.2.0",
"react-native-safe-area-context": "^3.3.0",
"react-native-screens": "^3.6.0",
@ -11088,6 +11089,21 @@ @@ -11088,6 +11089,21 @@
"react-native": "*"
}
},
"node_modules/react-native-permissions": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/react-native-permissions/-/react-native-permissions-3.1.0.tgz",
"integrity": "sha512-Y/kAU8cUTNhX5CLxfAG96ItEjjmwvyqnVBie38Gj8HoomXQcKM+ToFmq/rPt+DOziCq7YFKinn9AIlnLBiV3AQ==",
"peerDependencies": {
"react": ">=16.13.1",
"react-native": ">=0.63.3",
"react-native-windows": ">=0.62.0"
},
"peerDependenciesMeta": {
"react-native-windows": {
"optional": true
}
}
},
"node_modules/react-native-raw-bottom-sheet": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/react-native-raw-bottom-sheet/-/react-native-raw-bottom-sheet-2.2.0.tgz",
@ -22713,6 +22729,12 @@ @@ -22713,6 +22729,12 @@
"integrity": "sha512-5zyol+FZ9X4N4OEz92IyaFFROR3KtgAgTmgqlUvG59Eigf+f6aWs5fvcbWwzuz/AlLZbrxIDrnLmSpMUOK57ww==",
"requires": {}
},
"react-native-permissions": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/react-native-permissions/-/react-native-permissions-3.1.0.tgz",
"integrity": "sha512-Y/kAU8cUTNhX5CLxfAG96ItEjjmwvyqnVBie38Gj8HoomXQcKM+ToFmq/rPt+DOziCq7YFKinn9AIlnLBiV3AQ==",
"requires": {}
},
"react-native-raw-bottom-sheet": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/react-native-raw-bottom-sheet/-/react-native-raw-bottom-sheet-2.2.0.tgz",

1
package.json

@ -42,6 +42,7 @@ @@ -42,6 +42,7 @@
"react-native-masked-text": "^1.13.0",
"react-native-orientation-locker": "^1.3.1",
"react-native-pager-view": "^5.4.4",
"react-native-permissions": "^3.1.0",
"react-native-raw-bottom-sheet": "^2.2.0",
"react-native-safe-area-context": "^3.3.0",
"react-native-screens": "^3.6.0",

7
src/modules/account/hooks/use-account-editor.hook.ts

@ -57,18 +57,17 @@ export const useAccountEditor = () => { @@ -57,18 +57,17 @@ export const useAccountEditor = () => {
try {
await updateAvatar()
await updateInfo()
appEvents.emit('openInfoModal', {
title: 'Успіх!',
message: 'Данні оновлені.',
onPressOk: () => {}
onPressOk: () => {},
})
} catch (e) {
console.log('AVATAR UPDATE: ', e)
console.log('AVATAR UPDATE 1: ', e)
appEvents.emit('openInfoModal', {
title: 'Сталась помилка!',
message: 'Спробуйте будь-ласка пізінше.',
onPressOk: () => {}
onPressOk: () => {},
})
}
setLoading(false)

2
src/modules/account/screens/account.screen.tsx

@ -22,7 +22,7 @@ export const AccountScreen: FC<IProps> = ({ navigation }) => { @@ -22,7 +22,7 @@ export const AccountScreen: FC<IProps> = ({ navigation }) => {
const { styles } = useTheme(createStyles)
const { form, submit, isLoading } = useAccountEditor()
const { logout } = useAuthorization()
const { logout } = useAuthorization({})
const showLogoutModal = () =>
appEvents.emit('openConfirmModal', {

22
src/modules/auth/hooks/use-authorization.hook.ts

@ -6,9 +6,12 @@ import { getErrorCode } from '@/shared/helpers' @@ -6,9 +6,12 @@ import { getErrorCode } from '@/shared/helpers'
import { selectRefreshToken } from '@/store/auth'
import { selectIsForbidden } from '@/store/shared'
export const useAuthorization = () => {
const [isSent, setIsSent] = useState(false)
const [isConfirmed, setIsConfirmed] = useState(false)
interface IParams {
onSentCode?: () => void
onConfirmCode?: () => void
}
export const useAuthorization = ({ onSentCode, onConfirmCode }: IParams) => {
const [isLoading, setLoading] = useState(false)
const [error, setError] = useState<any>(null)
const isForbidden = useSelector(selectIsForbidden)
const refreshToken = useSelector(selectRefreshToken)
@ -24,16 +27,15 @@ export const useAuthorization = () => { @@ -24,16 +27,15 @@ export const useAuthorization = () => {
}, [isForbidden])
const sendCode = async (phoneNumber: string) => {
setLoading(true)
try {
setIsSent(false)
if (!phoneNumber) {
setError("Обов'язкове поле")
return
}
await authService.sendConfirmationCode(phoneNumber)
setIsSent(true)
if (onSentCode) onSentCode()
clearError()
} catch (e: any) {
console.log(e)
@ -44,9 +46,11 @@ export const useAuthorization = () => { @@ -44,9 +46,11 @@ export const useAuthorization = () => {
setError(getMessageByExceptionKey(e.response?.data?.key))
}
setLoading(false)
}
const confirmLogin = async (code: string) => {
setLoading(true)
try {
if (!code) {
setError("Обов'язкове поле")
@ -54,7 +58,7 @@ export const useAuthorization = () => { @@ -54,7 +58,7 @@ export const useAuthorization = () => {
}
await authService.finishAuth(code)
setIsConfirmed(true)
if (onConfirmCode) onConfirmCode()
clearError()
} catch (e: any) {
if (getErrorCode(e) === 403) {
@ -63,6 +67,7 @@ export const useAuthorization = () => { @@ -63,6 +67,7 @@ export const useAuthorization = () => {
}
setError(getMessageByExceptionKey(e.response?.data?.key))
}
setLoading(false)
}
const logout = async () => {
@ -71,11 +76,10 @@ export const useAuthorization = () => { @@ -71,11 +76,10 @@ export const useAuthorization = () => {
return {
error,
isSent,
isConfirmed,
sendCode,
confirmLogin,
getPhoneNumber: authService.getPhoneNumber,
logout,
isLoading,
}
}

79
src/modules/auth/screens/confirm-code.screen.tsx

@ -10,7 +10,7 @@ import { @@ -10,7 +10,7 @@ import {
useCountdown,
} from '@/shared'
import { LargeFormControlWithIcon } from '@/shared/components/forms'
import React, { FC, useEffect, useState } from 'react'
import React, { ComponentRef, FC, useEffect, useRef, useState } from 'react'
import { StyleSheet, View, Text, TouchableOpacity } from 'react-native'
import { useAuthorization } from '../hooks'
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view'
@ -22,16 +22,21 @@ const initialCount = 120 @@ -22,16 +22,21 @@ const initialCount = 120
export const ConfirmCode: FC = () => {
const [isDisabledField, setField] = useState<boolean>(false)
const { styles, theme } = useTheme(createStyles)
const inputRef = useRef<any>()
const [confirmCode, setConfirmCode] = useState('')
const { confirmLogin, sendCode, getPhoneNumber, isConfirmed, error } =
useAuthorization()
const { confirmLogin, sendCode, getPhoneNumber, error } = useAuthorization({
onConfirmCode: () =>
NavigationService.setModule(NavigationModuleKey.User),
onSentCode: () => {},
})
const { startCountdown, getformattedTimer, restartCountDown, isTimeOver } =
useCountdown(initialCount)
useEffect(() => {
startCountdown()
focusInput()
}, [])
useEffect(() => {
@ -40,14 +45,17 @@ export const ConfirmCode: FC = () => { @@ -40,14 +45,17 @@ export const ConfirmCode: FC = () => {
}
}, [isTimeOver])
useEffect(() => {
if (isConfirmed) NavigationService.setModule(NavigationModuleKey.User)
}, [isConfirmed])
const resendCode = async () => {
restartCountDown()
setConfirmCode('')
await sendCode(getPhoneNumber())
setField(false)
focusInput()
}
const focusInput = () => {
if (!inputRef.current) return
inputRef.current.focus()
}
const renderTitle = () => {
@ -69,36 +77,41 @@ export const ConfirmCode: FC = () => { @@ -69,36 +77,41 @@ export const ConfirmCode: FC = () => {
)
}
const changeCode = (code: string) => {
if (code.length > 4) return
code = code.toUpperCase()
setConfirmCode(code)
}
return (
<AuthLayout>
<KeyboardAwareScrollView>
<View>
<ImgWithBgCircle
source={require('@/assets/images/auth_2.png')}
bgCircleTopPosition={'25%'}
/>
<View>
<ImgWithBgCircle
source={require('@/assets/images/auth_2.png')}
bgCircleTopPosition={'25%'}
/>
<Txt style={styles.label}>Вхід</Txt>
<Txt style={styles.label}>Вхід</Txt>
<LargeFormControlWithIcon
disabled={isDisabledField}
title={renderTitle()}
name={'verifyCode'}
onChange={v => setConfirmCode(v.toUpperCase())}
value={confirmCode}
placeHolder={'6342'}
beforeIcon={{
name: 'lock-1',
color: theme.iconComponent.$primaryColor,
}}
error={error}
/>
<Button
title="Підтвердити"
onPress={() => confirmLogin(confirmCode)}
/>
</View>
</KeyboardAwareScrollView>
<LargeFormControlWithIcon
disabled={isDisabledField}
title={renderTitle()}
name={'verifyCode'}
onChange={v => changeCode(v)}
value={confirmCode}
placeHolder={'6342'}
beforeIcon={{
name: 'lock-1',
color: theme.iconComponent.$primaryColor,
}}
error={error}
inputRef={inputRef}
/>
<Button
title="Підтвердити"
onPress={() => confirmLogin(confirmCode)}
/>
</View>
</AuthLayout>
)
}

52
src/modules/auth/screens/sign-in.screen.tsx

@ -16,39 +16,37 @@ export const SignInScreen: FC<IProps> = ({ navigation }) => { @@ -16,39 +16,37 @@ export const SignInScreen: FC<IProps> = ({ navigation }) => {
const { styles } = useTheme(createStyles)
const [phoneNumber, setPhoneNumber] = useState<string>('')
const { sendCode, isSent, error } = useAuthorization()
useEffect(() => {
if (isSent) navigation.navigate(RouteKey.ConfirmCode)
}, [isSent, navigation])
const { sendCode, isLoading, error } = useAuthorization({
onConfirmCode: () => {},
onSentCode: () => navigation.navigate(RouteKey.ConfirmCode),
})
return (
<AuthLayout>
<KeyboardAwareScrollView>
<View>
<ImgWithBgCircle
style={styles.img}
source={require('@/assets/images/auth_1.png')}
bgCircleTopPosition={'25%'}
/>
<View>
<ImgWithBgCircle
style={styles.img}
source={require('@/assets/images/auth_1.png')}
bgCircleTopPosition={'25%'}
/>
<Txt style={styles.label}>Вхід</Txt>
<Txt style={styles.label}>Вхід</Txt>
<FormPhone
label={'Номер телефону'}
name={'phoneNumber'}
onChange={v => setPhoneNumber(v)}
value={phoneNumber}
error={error}
/>
<FormPhone
label={'Номер телефону'}
name={'phoneNumber'}
onChange={v => setPhoneNumber(v)}
value={phoneNumber}
error={error}
/>
<Button
style={styles.btn}
title="Підтвердити"
onPress={() => sendCode(phoneNumber)}
/>
</View>
</KeyboardAwareScrollView>
<Button
style={styles.btn}
title="Підтвердити"
onPress={() => sendCode(phoneNumber)}
showLoadingIndicator={isLoading}
/>
</View>
</AuthLayout>
)
}

5
src/modules/contacts/atoms/search-field-with-icon.component.tsx

@ -27,7 +27,7 @@ export const SearchFieldWitchIcon: FC<IProps> = ({ @@ -27,7 +27,7 @@ export const SearchFieldWitchIcon: FC<IProps> = ({
return (
<SearchForm
containerStyle={style}
containerStyle={{ ...styles.container, ...style }}
searchValue={searchString}
placeholder={placeholder}
onChange={onChange}
@ -56,4 +56,7 @@ const createStyles = (theme: PartialTheme) => @@ -56,4 +56,7 @@ const createStyles = (theme: PartialTheme) =>
paddingHorizontal: $size(8),
borderRadius: 10,
},
container: {
paddingHorizontal: 0,
},
})

26
src/modules/contacts/components/contacts-list.component.tsx

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
import { IContact } from '@/shared'
import { IContact, Loading, NotFound } from '@/shared'
import _ from 'lodash'
import React, { FC, useCallback } from 'react'
import { FlatList, ViewStyle } from 'react-native'
import { FlatList, RefreshControl, Text, ViewStyle } from 'react-native'
import { ContactRowCard } from './contact-row-card.component'
interface IProps {
@ -10,6 +11,11 @@ interface IProps { @@ -10,6 +11,11 @@ interface IProps {
onPressCard: (id: number) => void
onPressInfo: (id: number) => void
loadMore: () => void
onRefresh: () => void
Header: JSX.Element
isLoading?: boolean
isLoadingMore?: boolean
}
export const ContactsList: FC<IProps> = ({
@ -19,6 +25,10 @@ export const ContactsList: FC<IProps> = ({ @@ -19,6 +25,10 @@ export const ContactsList: FC<IProps> = ({
onPressCard,
onPressInfo,
loadMore,
isLoading,
isLoadingMore,
onRefresh,
Header,
}) => {
const itemToRender = useCallback(
item => (
@ -39,6 +49,18 @@ export const ContactsList: FC<IProps> = ({ @@ -39,6 +49,18 @@ export const ContactsList: FC<IProps> = ({
style={style}
renderItem={({ item }) => itemToRender(item)}
onEndReached={() => loadMore()}
ListFooterComponent={() =>
!isLoading && isLoadingMore ? <Loading /> : null
}
showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator={false}
initialNumToRender={20}
keyExtractor={item => `${item.userId}${item.firstName}`}
// ListHeaderComponent={Header}
ListEmptyComponent={<NotFound text="Контакти не знайдені" />}
refreshControl={
<RefreshControl refreshing={isLoading} onRefresh={onRefresh} />
}
/>
)
}

28
src/modules/contacts/hooks/use-fetch-contacts.hook.ts

@ -5,16 +5,6 @@ import { contactsService } from '@/services/domain' @@ -5,16 +5,6 @@ import { contactsService } from '@/services/domain'
export const useFetchContacts = () => {
const [searchString, setSearchVal] = useState<string>()
const [onlyWithBirthday, setBirthday] = useState<boolean>(false)
const loadParams = useMemo(() => {
return {
sort: 'DESC',
sortField: 'id',
searchString,
soonBirthday: !onlyWithBirthday,
}
}, [onlyWithBirthday, searchString])
const {
items: contacts,
@ -22,6 +12,8 @@ export const useFetchContacts = () => { @@ -22,6 +12,8 @@ export const useFetchContacts = () => {
isLoadingNext,
loadMore,
resetFlatList,
setLoadParams,
loadParams,
} = useFlatList<IContact>({
fetchItems: params => contactsService.fetch({ ...params }),
needInit: true,
@ -35,20 +27,30 @@ export const useFetchContacts = () => { @@ -35,20 +27,30 @@ export const useFetchContacts = () => {
}
})
},
loadParams,
loadParams: {
sort: 'DESC',
sortField: 'id',
searchString,
soonBirthday: false,
},
limit: 20,
})
useEffect(() => resetFlatList(), [onlyWithBirthday, searchString])
const setBirthday = value => {
setLoadParams({ soonBirthday: value })
}
return {
contacts,
isLoading,
isLoadingNext,
searchString,
onlyWithBirthday,
onlyWithBirthday: loadParams.soonBirthday
? Boolean(loadParams.soonBirthday)
: false,
setBirthday,
loadMore,
setSearchVal,
resetFlatList,
}
}

9
src/modules/contacts/screens/contacts.screen.tsx

@ -7,7 +7,7 @@ import { CallSmartList } from '@/modules/calls/smart-components/calls-list.smart @@ -7,7 +7,7 @@ import { CallSmartList } from '@/modules/calls/smart-components/calls-list.smart
import { PartialTheme } from '@/shared/themes/interfaces'
import { useTheme } from '@/shared/hooks/use-theme.hook'
interface IProps extends IRouteParams { }
interface IProps extends IRouteParams {}
type TRoutes = {
key: string
@ -40,14 +40,17 @@ export const ContactScreen: FC<IProps> = ({ navigation }) => { @@ -40,14 +40,17 @@ export const ContactScreen: FC<IProps> = ({ navigation }) => {
{
label: 'Виклики',
key: 'calls',
onPress: () => setIndex(1)
onPress: () => setIndex(1),
},
]}
/>
)
return (
<ScreenLayout viewStyle={{ flex: 1, paddingTop: $size(15) }} horizontalPadding={0}>
<ScreenLayout
needScroll={false}
viewStyle={{ flex: 1, paddingTop: $size(15) }}
horizontalPadding={0}>
<TabView
swipeEnabled={false}
renderTabBar={renderTabBar}

15
src/modules/contacts/smart-component/contacts-list.smart-component.tsx

@ -21,11 +21,14 @@ export const ContactsSmartList: FC<IProps> = ({ navigate }) => { @@ -21,11 +21,14 @@ export const ContactsSmartList: FC<IProps> = ({ navigate }) => {
setSearchVal,
setBirthday,
loadMore,
isLoading,
isLoadingNext,
resetFlatList,
} = useFetchContacts()
return (
<>
<ScrollView style={styles.content}>
<View style={styles.content}>
<SearchFieldWitchIcon
searchString={searchString}
placeholder={'Знайти контакт'}
@ -39,11 +42,17 @@ export const ContactsSmartList: FC<IProps> = ({ navigate }) => { @@ -39,11 +42,17 @@ export const ContactsSmartList: FC<IProps> = ({ navigate }) => {
onPressCard={id =>
navigate(RouteKey.ContactDetail, { contactId: id })
}
onPressInfo={id => navigate(RouteKey.ContactDetail, { contactId: id })}
onPressInfo={id =>
navigate(RouteKey.ContactDetail, { contactId: id })
}
contentContainerStyle={styles.listContainer}
loadMore={loadMore}
isLoading={isLoading}
isLoadingMore={isLoadingNext}
onRefresh={resetFlatList}
Header={<View></View>}
/>
</ScrollView>
</View>
</>
)
}

8
src/modules/root/atoms/icon-with-count-indicator.component.tsx

@ -74,17 +74,19 @@ const createStyles = ({ tabBar }: PartialTheme) => @@ -74,17 +74,19 @@ const createStyles = ({ tabBar }: PartialTheme) =>
position: 'absolute',
alignItems: 'center',
justifyContent: 'center',
minWidth: $size(18, 16),
right: $size(20, 18),
bottom: 0,
bottom: -5,
borderRadius: 100,
borderWidth: 2,
borderColor: tabBar.indicator.$border,
backgroundColor: tabBar.indicator.$bg,
height: 20,
minWidth: 20,
},
indicatorCount: {
color: tabBar.indicator.$txt,
fontSize: $size(12, 10),
fontSize: $size(10, 8),
fontWeight: '500',
},
})

42
src/modules/root/configs/tab-bar.config.ts

@ -1,25 +1,25 @@ @@ -1,25 +1,25 @@
import { RouteKey } from "@/shared";
import { RouteKey } from '@/shared'
export const tabBarIconsConfig = {
[RouteKey.Home]: {
iconName: 'home',
indicatorCount: 0
},
[RouteKey.Chats]: {
iconName: 'chatcircledots-1',
indicatorCount: 13
},
[RouteKey.AddTask]: {
iconName: 'plus-2',
},
[RouteKey.Contacts]:{
iconName: 'users-1',
indicatorCount: 8
},
[RouteKey.Settings]: {
iconName: 'users-1',
indicatorCount: 0
},
[RouteKey.Home]: {
iconName: 'home',
indicatorCount: 0,
},
[RouteKey.Chats]: {
iconName: 'chatcircledots-1',
indicatorCount: 13,
},
[RouteKey.AddTask]: {
iconName: 'plus-2',
},
[RouteKey.Contacts]: {
iconName: 'users-1',
indicatorCount: 8,
},
[RouteKey.Settings]: {
iconName: 'gear-1',
indicatorCount: 0,
},
}
// export const tabBarIconsConfig = {
@ -28,4 +28,4 @@ export const tabBarIconsConfig = { @@ -28,4 +28,4 @@ export const tabBarIconsConfig = {
// [RouteKey.AddTask]: 'plus-2',
// [RouteKey.Contacts]: 'users-1',
// [RouteKey.Settings]: 'gear-1',
// }
// }

2
src/modules/root/smart-components/tab-bar.smart-component.tsx

@ -11,8 +11,6 @@ export const TabBarSmart: FC<IProps> = ({ state, navigate }) => { @@ -11,8 +11,6 @@ export const TabBarSmart: FC<IProps> = ({ state, navigate }) => {
if (state.index !== index) navigate(routeName)
}
console.log()
return (
<TabBarComponent
activeIndex={state.index}

31
src/modules/settings/screens/settings.screen.tsx

@ -1,13 +1,13 @@ @@ -1,13 +1,13 @@
import React, { FC } from 'react'
import { $size, ScreenLayout } from '@/shared'
import { StyleSheet, View, Text, Image } from 'react-native'
import { StyleSheet, View, Text, Image, Dimensions } from 'react-native'
import { SettingItem } from '../components/setting-item.component'
import { UseSettingNavigationList } from '../hooks'
import { IRouteParams } from '@/shared'
import { PartialTheme } from '@/shared/themes/interfaces'
import { useTheme } from '@/shared/hooks/use-theme.hook'
interface IProps extends IRouteParams { }
interface IProps extends IRouteParams {}
export const SettingsScreen: FC<IProps> = ({ navigation }) => {
const { styles } = useTheme(createStyles)
@ -22,10 +22,9 @@ export const SettingsScreen: FC<IProps> = ({ navigation }) => { @@ -22,10 +22,9 @@ export const SettingsScreen: FC<IProps> = ({ navigation }) => {
}}
scrollStyle={{
justifyContent: 'space-between',
flex: 1,
flexGrow: 1,
}}
needScroll={true}
>
needScroll={true}>
<View style={styles.wrapper}>
{settingListConfig.map(item => {
return (
@ -43,9 +42,10 @@ export const SettingsScreen: FC<IProps> = ({ navigation }) => { @@ -43,9 +42,10 @@ export const SettingsScreen: FC<IProps> = ({ navigation }) => {
<View style={styles.logoWrapper}>
<Image
style={styles.logo as any}
source={require('@/assets/images/small_logo.png')}
source={require('@/assets/images/logo.png')}
resizeMode="contain"
/>
<Text style={styles.version}>v 2.2.1</Text>
<Text style={styles.version}>v 2.0.0</Text>
</View>
</ScreenLayout>
)
@ -53,23 +53,30 @@ export const SettingsScreen: FC<IProps> = ({ navigation }) => { @@ -53,23 +53,30 @@ export const SettingsScreen: FC<IProps> = ({ navigation }) => {
const createStyles = (theme: PartialTheme) =>
StyleSheet.create({
container: {
flexGrow: 1,
backgroundColor: '#000',
justifyContent: 'space-between',
},
wrapper: {
flex: 1
flex: 1,
},
title: {
paddingTop: $size(10),
},
logoWrapper: {
alignItems: 'center',
paddingBottom: 36
paddingBottom: 36,
},
logo: {
marginBottom: 8,
opacity: 0.5
opacity: 0.5,
height: 20,
marginTop: 50,
},
version: {
color: theme.$textPrimary,
fontSize: 12,
fontWeight: '300'
}
fontWeight: '300',
},
})

53
src/services/system/media-permissions.service.ts

@ -0,0 +1,53 @@ @@ -0,0 +1,53 @@
import { Alert, PermissionsAndroid } from 'react-native'
import { request, check, RESULTS } from 'react-native-permissions'
const requestCameraPermission = async () => {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.CAMERA,
{
title: 'Cool Photo App Camera Permission',
message:
'Cool Photo App needs access to your camera ' +
'so you can take awesome pictures.',
buttonNegative: 'Cancel',
buttonPositive: 'OK',
},
)
console.log({ granted })
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log('You can use the camera')
} else {
console.log('Camera permission denied')
}
} catch (err) {
console.warn('requestCameraPermission: ', err)
}
}
const checkCameraPermissions = async (permission: any): Promise<boolean> => {
const perm = await check(permission)
console.log(permission, perm)
switch (perm) {
case RESULTS.GRANTED:
return true
case RESULTS.BLOCKED: {
// needMediaPermissions()
break
}
case RESULTS.UNAVAILABLE: {
Alert.alert('Your device does not support this function')
break
}
default: {
const requestRes = await request(permission)
if (requestRes === RESULTS.GRANTED) return true
else return false
}
}
}
export const mediaPermissionsService = {
checkCameraPermissions,
}

50
src/services/system/media.service.ts

@ -1,34 +1,24 @@ @@ -1,34 +1,24 @@
import { PermissionsAndroid } from 'react-native';
import { Alert, PermissionsAndroid, Platform } from 'react-native'
import ImagePicker from 'react-native-image-crop-picker'
const requestCameraPermission = async () => {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.CAMERA,
{
title: "Cool Photo App Camera Permission",
message:
"Cool Photo App needs access to your camera " +
"so you can take awesome pictures.",
buttonNegative: "Cancel",
buttonPositive: "OK"
}
);
console.log({granted})
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log("You can use the camera");
} else {
console.log("Camera permission denied");
}
} catch (err) {
console.warn('requestCameraPermission: ', err);
}
}
import { request, check, PERMISSIONS, RESULTS } from 'react-native-permissions'
import { mediaPermissionsService } from './media-permissions.service'
const permissions = Platform.select({
ios: {
camera: PERMISSIONS.IOS.CAMERA,
gallery: PERMISSIONS.IOS.PHOTO_LIBRARY,
},
android: {
camera: PERMISSIONS.ANDROID.CAMERA,
gallery: PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE,
},
})
const openCamera = async () => {
await requestCameraPermission()
const hasPermissions = await mediaPermissionsService.checkCameraPermissions(
permissions.camera,
)
if (!hasPermissions) return null
const image = await ImagePicker.openCamera({
width: 300,
@ -43,6 +33,10 @@ const openCamera = async () => { @@ -43,6 +33,10 @@ const openCamera = async () => {
}
const openPicker = async () => {
const hasPermissions = await mediaPermissionsService.checkCameraPermissions(
permissions.gallery,
)
if (!hasPermissions) return null
const image = await ImagePicker.openPicker({
width: 300,
height: 400,

12
src/services/system/real-time.service.ts

@ -17,12 +17,11 @@ export class SocketIo { @@ -17,12 +17,11 @@ export class SocketIo {
this.emit('join-user', store().getState().account.account)
this.initSockets()
})
this._on('websocket/test', (data: string) => {
Alert.alert(data)
})
// this._on('websocket/test', (data: string) => {
// Alert.alert(data)
// })
}
get header() {
return {
authorization: 'Bearer ' + store().getState().auth.accessToken,
@ -30,11 +29,11 @@ export class SocketIo { @@ -30,11 +29,11 @@ export class SocketIo {
}
_on(key, action) {
this.socket.on(key, (data) => action(data))
this.socket.on(key, data => action(data))
}
_onSocketSendEvent(key) {
this.socket.on(key, (data) => console.log('SOCKET EVENT', key))
this.socket.on(key, data => console.log('SOCKET EVENT', key))
}
_off(key) {
@ -58,7 +57,6 @@ export class SocketIo { @@ -58,7 +57,6 @@ export class SocketIo {
static instance: SocketIo = null
static get(): SocketIo {
if (this.instance) return this.instance
this.instance = new SocketIo()

2
src/shared/components/buttons/button.component.tsx

@ -64,7 +64,7 @@ export const Button: FC<ButtonProps> = ({ type = 'primary', ...props }) => { @@ -64,7 +64,7 @@ export const Button: FC<ButtonProps> = ({ type = 'primary', ...props }) => {
}
return (
<TouchableOpacity
disabled={props.isDisabled}
disabled={props.isDisabled || props.showLoadingIndicator}
style={[styles[`${type}Wrap`], styles.basicBtn, props.style]}
onPress={onPress}>
{renderContent()}

2
src/shared/components/elements/index.ts

@ -6,3 +6,5 @@ export * from './avatar.component' @@ -6,3 +6,5 @@ export * from './avatar.component'
export * from './picker.component'
export * from './circle-checkbox.component'
export * from './info-row-card.component'
export * from './not-found.component'
export * from './loading.component'

18
src/shared/components/elements/loading.component.tsx

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
import { useTheme } from '@/shared/hooks/use-theme.hook'
import React from 'react'
import { ActivityIndicator, StyleSheet, View } from 'react-native'
export const Loading = () => {
const { theme } = useTheme(() => {})
return (
<View style={styles.container}>
<ActivityIndicator color={theme.$secondaryText} />
</View>
)
}
const styles = StyleSheet.create({
container: {
marginTop: 20,
},
})

24
src/shared/components/elements/not-found.component.tsx

@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
import { Txt } from '@/shared'
import React from 'react'
import { StyleSheet, View } from 'react-native'
interface NotFoundParams {
text: string
}
export const NotFound = (params: NotFoundParams) => {
return (
<View>
<Txt style={styles.text}>{params.text}</Txt>
</View>
)
}
const styles = StyleSheet.create({
text: {
fontSize: 18,
textAlign: 'center',
flex: 1,
marginTop: 100,
},
})

16
src/shared/components/forms/form-large-control-with-icon.component.tsx

@ -1,7 +1,14 @@ @@ -1,7 +1,14 @@
import { IconComponent } from '../elements'
import { $size } from '@/shared/helpers'
import React from 'react'
import { StyleSheet, View, Text, TextInput, ColorValue, ViewStyle } from 'react-native'
import {
StyleSheet,
View,
Text,
TextInput,
ColorValue,
ViewStyle,
} from 'react-native'
import { PartialTheme } from '@/shared/themes/interfaces'
import { useTheme } from '@/shared/hooks/use-theme.hook'
@ -25,6 +32,7 @@ interface IProps { @@ -25,6 +32,7 @@ interface IProps {
placeHolder?: string
placeholderTextColor?: ColorValue
disabled?: boolean
inputRef?: any
}
export const LargeFormControlWithIcon = (props: IProps) => {
@ -51,12 +59,16 @@ export const LargeFormControlWithIcon = (props: IProps) => { @@ -51,12 +59,16 @@ export const LargeFormControlWithIcon = (props: IProps) => {
</View>
)}
<TextInput
ref={props.inputRef}
editable={!props.disabled}
value={props.value}
onChangeText={v => props.onChange(v)}
style={[styles.input, props.style]}
placeholder={props.placeHolder}
placeholderTextColor={props.placeholderTextColor || theme.input.$placeholder}
placeholderTextColor={
props.placeholderTextColor ||
theme.input.$placeholder
}
/>
</View>
</View>

2
src/shared/components/forms/form-phone.component.tsx

@ -107,7 +107,7 @@ const createStyles = (theme: PartialTheme) => @@ -107,7 +107,7 @@ const createStyles = (theme: PartialTheme) =>
minHeight: $size(32, 28),
},
error: {
color: 'red',
color: theme.$errorText,
marginBottom: $size(15),
fontSize: $size(12),
},

4
src/shared/helpers/exceptions.helpers.ts

@ -1,8 +1,8 @@ @@ -1,8 +1,8 @@
import { ExceptionKeys } from '../enums'
const exceptionsDictionary = {
[ExceptionKeys.WrongCode]: 'Неправильний код',
[ExceptionKeys.InvalidCredentials]: 'Невірно введено дані',
[ExceptionKeys.WrongCode]: 'Не дійсний код',
[ExceptionKeys.InvalidCredentials]: 'Невірно введені дані',
[ExceptionKeys.Forbidden]:
'Вашу IP-адресу заблоковано. Для розблокування зверніться до адміністратора',
}

5
src/shared/hooks/use-flat-list.hook.ts

@ -30,7 +30,7 @@ export const useFlatList = <T>(props: IProps<T>) => { @@ -30,7 +30,7 @@ export const useFlatList = <T>(props: IProps<T>) => {
props = Object.assign(getDefaultProps(), props)
const loadParams = useRef({
const loadParams = useRef<any>({
limit: props.limit,
page: props.page,
count: undefined,
@ -65,6 +65,7 @@ export const useFlatList = <T>(props: IProps<T>) => { @@ -65,6 +65,7 @@ export const useFlatList = <T>(props: IProps<T>) => {
loadParams.current = {
...props.loadParams,
...loadParams.current,
limit: loadParams.current.limit,
page: loadParams.current.page + 1,
count: response.data.count,
@ -111,7 +112,7 @@ export const useFlatList = <T>(props: IProps<T>) => { @@ -111,7 +112,7 @@ export const useFlatList = <T>(props: IProps<T>) => {
isEmpty: !items || !items.length,
isLoading,
isLoadingNext,
loadParams,
loadParams: loadParams.current,
resetFlatList,
loadMore,
setLoadParams,

4
src/shared/hooks/use-theme.hook.ts

@ -3,7 +3,7 @@ import { IStyles } from '../interfaces' @@ -3,7 +3,7 @@ import { IStyles } from '../interfaces'
import { ThemeContext } from '../themes'
import { PartialTheme } from '../themes/interfaces'
export type TStylesCreator = (theme?: PartialTheme) => IStyles
export type TStylesCreator = (theme?: PartialTheme) => any
export const useTheme = (stylesCreator: TStylesCreator) => {
const { theme, themeTitle } = useContext(ThemeContext)
@ -11,6 +11,6 @@ export const useTheme = (stylesCreator: TStylesCreator) => { @@ -11,6 +11,6 @@ export const useTheme = (stylesCreator: TStylesCreator) => {
return {
styles: stylesCreator(theme),
theme,
themeTitle
themeTitle,
}
}

2
src/shared/themes/light/colors.ts

@ -8,7 +8,7 @@ export const colors: Colors = { @@ -8,7 +8,7 @@ export const colors: Colors = {
$successText: '#186524',
$error: '#E4B9B9',
$errorText: '#870D0D',
$errorText: '#9F2843',
$warning: '#870D0D',

7
src/shared/themes/light/navigation.ts

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
import { NavigationColors } from '../interfaces/navigation.interface'
import { colors } from './colors'
export const navigation: NavigationColors = {
tabBar: {
@ -7,9 +8,9 @@ export const navigation: NavigationColors = { @@ -7,9 +8,9 @@ export const navigation: NavigationColors = {
$addTaskBtn: '#9F2843',
$shadowColor: 'rgba(221, 37, 59, 0.35)',
indicator: {
$bg: '#DE253B',
$bg: '#9E2743',
$txt: '#fff',
$border: '#fff'
}
$border: colors.$layoutBg,
},
},
}

11
yarn.lock

@ -6676,6 +6676,11 @@ @@ -6676,6 +6676,11 @@
"resolved" "https://registry.npmjs.org/react-native-pager-view/-/react-native-pager-view-5.4.4.tgz"
"version" "5.4.4"
"react-native-permissions@^3.1.0":
"integrity" "sha512-Y/kAU8cUTNhX5CLxfAG96ItEjjmwvyqnVBie38Gj8HoomXQcKM+ToFmq/rPt+DOziCq7YFKinn9AIlnLBiV3AQ=="
"resolved" "https://registry.npmjs.org/react-native-permissions/-/react-native-permissions-3.1.0.tgz"
"version" "3.1.0"
"react-native-raw-bottom-sheet@^2.2.0":
"integrity" "sha512-qL4JKIqvbcVxbkKzeh51hjV7suoJN3ouxzvLmOg0FBUV1yiJAfEbacjQdtRCI6+OU5pyGFBIifLsTXcFDwHggg=="
"resolved" "https://registry.npmjs.org/react-native-raw-bottom-sheet/-/react-native-raw-bottom-sheet-2.2.0.tgz"
@ -6717,7 +6722,7 @@ @@ -6717,7 +6722,7 @@
"prop-types" "^15.7.2"
"yargs" "^16.1.1"
"react-native-windows@^0.63.3":
"react-native-windows@^0.63.3", "react-native-windows@>=0.62.0":
"integrity" "sha512-AhLQP0dzX4jhtv9AsR5KF+BIlccKKPzTSmivg3ZUirqQxXwDDMjtIGwgFnp1WyH8cFoUEvpuyNnHsU3f7LxEyg=="
"resolved" "https://registry.npmjs.org/react-native-windows/-/react-native-windows-0.63.41.tgz"
"version" "0.63.41"
@ -6742,7 +6747,7 @@ @@ -6742,7 +6747,7 @@
"use-subscription" "^1.0.0"
"whatwg-fetch" "^3.0.0"
"react-native@*", "react-native@^0.0.0-0 || ^0.60.6 || ^0.61.5 || ^0.62.2 || ^0.63.2 || ^0.64.0 || ^0.65.0 || 1000.0.0", "react-native@^0.62.0", "react-native@^0.63.0-0", "react-native@>=0.40.0", "react-native@>=0.42.0", "react-native@>=0.48.4", "react-native@>=0.57", "react-native@>=0.57.0", "react-native@>=0.59", "react-native@>=0.61.5", "react-native@>=0.64.0-rc.0 || 0.0.0-*", "react-native@0.63.2", "react-native@0.64.2":
"react-native@*", "react-native@^0.0.0-0 || ^0.60.6 || ^0.61.5 || ^0.62.2 || ^0.63.2 || ^0.64.0 || ^0.65.0 || 1000.0.0", "react-native@^0.62.0", "react-native@^0.63.0-0", "react-native@>=0.40.0", "react-native@>=0.42.0", "react-native@>=0.48.4", "react-native@>=0.57", "react-native@>=0.57.0", "react-native@>=0.59", "react-native@>=0.61.5", "react-native@>=0.63.3", "react-native@>=0.64.0-rc.0 || 0.0.0-*", "react-native@0.63.2", "react-native@0.64.2":
"integrity" "sha512-Ty/fFHld9DcYsFZujXYdeVjEhvSeQcwuTGXezyoOkxfiGEGrpL/uwUZvMzwShnU4zbbTKDu2PAm/uwuOittRGA=="
"resolved" "https://registry.npmjs.org/react-native/-/react-native-0.64.2.tgz"
"version" "0.64.2"
@ -6815,7 +6820,7 @@ @@ -6815,7 +6820,7 @@
"react-shallow-renderer" "^16.13.1"
"scheduler" "^0.20.1"
"react@*", "react@^15.2.1 || 16.0.0-alpha.6 || 16.0.0-alpha.12 || 16.0.0-beta.5 || ^16.0.0", "react@^16.0.0 || ^17.0.0", "react@^16.8", "react@^16.8.0 || ^17.0.0", "react@^16.8.1", "react@^16.8.3 || ^17", "react@>=16.3.0", "react@>=16.9.0", "react@16 || 17", "react@16.13.1", "react@17.0.1":
"react@*", "react@^15.2.1 || 16.0.0-alpha.6 || 16.0.0-alpha.12 || 16.0.0-beta.5 || ^16.0.0", "react@^16.0.0 || ^17.0.0", "react@^16.8", "react@^16.8.0 || ^17.0.0", "react@^16.8.1", "react@^16.8.3 || ^17", "react@>=16.13.1", "react@>=16.3.0", "react@>=16.9.0", "react@16 || 17", "react@16.13.1", "react@17.0.1":
"integrity" "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w=="
"resolved" "https://registry.npmjs.org/react/-/react-17.0.1.tgz"
"version" "17.0.1"

Loading…
Cancel
Save