From 0121613db617ac7497c544bbce6a10e0196e3b3f Mon Sep 17 00:00:00 2001 From: desperado1802 Date: Mon, 20 Nov 2023 13:00:36 +0200 Subject: [PATCH 01/13] aligned the navigation icons vertically in android devices --- .../app/navigators/AuthenticatedNavigator.tsx | 204 ++++++++---------- 1 file changed, 93 insertions(+), 111 deletions(-) diff --git a/apps/mobile/app/navigators/AuthenticatedNavigator.tsx b/apps/mobile/app/navigators/AuthenticatedNavigator.tsx index 1525078c1..e09413041 100644 --- a/apps/mobile/app/navigators/AuthenticatedNavigator.tsx +++ b/apps/mobile/app/navigators/AuthenticatedNavigator.tsx @@ -1,18 +1,14 @@ /* eslint-disable react-native/no-inline-styles */ -import React, { useEffect, useState } from "react" -import { Image, TextStyle, View, ViewStyle } from "react-native" -import { - BottomTabScreenProps, - createBottomTabNavigator, - BottomTabNavigationProp, -} from "@react-navigation/bottom-tabs" -import { createDrawerNavigator, DrawerScreenProps } from "@react-navigation/drawer" -import type { StackNavigationProp } from "@react-navigation/stack" -import { CompositeScreenProps, CompositeNavigationProp, RouteProp } from "@react-navigation/native" -import { useSafeAreaInsets } from "react-native-safe-area-context" +import React, { useEffect, useState } from 'react'; +import { Image, Platform, TextStyle, View, ViewStyle } from 'react-native'; +import { BottomTabScreenProps, createBottomTabNavigator, BottomTabNavigationProp } from '@react-navigation/bottom-tabs'; +import { createDrawerNavigator, DrawerScreenProps } from '@react-navigation/drawer'; +import type { StackNavigationProp } from '@react-navigation/stack'; +import { CompositeScreenProps, CompositeNavigationProp, RouteProp } from '@react-navigation/native'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; // COMPONENTS -import { AppStackParamList, AppStackScreenProps } from "./AppNavigator" +import { AppStackParamList, AppStackScreenProps } from './AppNavigator'; import { AuthenticatedProfileScreen, AuthenticatedTeamScreen, @@ -24,17 +20,17 @@ import { TaskPriorityScreen, MembersSettingsScreen, AuthenticatedTaskScreen, - TaskVersionScreen, -} from "../screens" + TaskVersionScreen +} from '../screens'; // HELPERS -import { translate } from "../i18n" -import { spacing, typography, useAppTheme } from "../theme" -import HamburgerMenu from "../components/HamburgerMenu" -import { Skeleton } from "react-native-skeletons" -import { useStores } from "../models" -import { observer } from "mobx-react-lite" -import { SvgXml } from "react-native-svg" +import { translate } from '../i18n'; +import { spacing, typography, useAppTheme } from '../theme'; +import HamburgerMenu from '../components/HamburgerMenu'; +import { Skeleton } from 'react-native-skeletons'; +import { useStores } from '../models'; +import { observer } from 'mobx-react-lite'; +import { SvgXml } from 'react-native-svg'; import { briefCaseNotFocusedDark, briefCaseNotFocusedLight, @@ -43,85 +39,75 @@ import { userFocusedDark, userFocusedLight, userNotFocusedDark, - userNotFocusedLight, -} from "../components/svgs/icons" + userNotFocusedLight +} from '../components/svgs/icons'; export type AuthenticatedTabParamList = { - Timer: undefined - Team: undefined - Setting: { activeTab: 1 | 2 } - Profile: { userId: string; activeTab: "worked" | "assigned" | "unassigned" } - TaskScreen: { taskId: string } -} + Timer: undefined; + Team: undefined; + Setting: { activeTab: 1 | 2 }; + Profile: { userId: string; activeTab: 'worked' | 'assigned' | 'unassigned' }; + TaskScreen: { taskId: string }; +}; export type AuthenticatedDrawerParamList = { - Setting: undefined - AuthenticatedTab: undefined - TaskLabelScreen: undefined - TaskSizeScreen: undefined - TaskStatus: undefined - TaskPriority: undefined - TaskVersion: undefined - MembersSettingsScreen: undefined - TaskScreen: { taskId: string } -} + Setting: undefined; + AuthenticatedTab: undefined; + TaskLabelScreen: undefined; + TaskSizeScreen: undefined; + TaskStatus: undefined; + TaskPriority: undefined; + TaskVersion: undefined; + MembersSettingsScreen: undefined; + TaskScreen: { taskId: string }; +}; /** * Helper for automatically generating navigation prop types for each route. * * More info: https://reactnavigation.org/docs/typescript/#organizing-types */ -export type AuthenticatedTabScreenProps = - CompositeScreenProps< - BottomTabScreenProps, - AppStackScreenProps - > +export type AuthenticatedTabScreenProps = CompositeScreenProps< + BottomTabScreenProps, + AppStackScreenProps +>; -export type AuthenticatedDrawerScreenProps = - CompositeScreenProps< - DrawerScreenProps, - AppStackScreenProps - > +export type AuthenticatedDrawerScreenProps = CompositeScreenProps< + DrawerScreenProps, + AppStackScreenProps +>; -export type SettingScreenNavigationProp = - CompositeNavigationProp< - BottomTabNavigationProp, - StackNavigationProp - > +export type SettingScreenNavigationProp = CompositeNavigationProp< + BottomTabNavigationProp, + StackNavigationProp +>; -export type DrawerNavigationProp = - CompositeNavigationProp< - BottomTabNavigationProp, - StackNavigationProp - > +export type DrawerNavigationProp = CompositeNavigationProp< + BottomTabNavigationProp, + StackNavigationProp +>; -export type SettingScreenRouteProp = RouteProp< - AuthenticatedTabParamList, - T -> +export type SettingScreenRouteProp = RouteProp; -const Tab = createBottomTabNavigator() +const Tab = createBottomTabNavigator(); const TabNavigator = observer(function TabNavigator() { - const { bottom } = useSafeAreaInsets() - const { colors, dark } = useAppTheme() + const { bottom } = useSafeAreaInsets(); + const { colors, dark } = useAppTheme(); const { - teamStore: { isTrackingEnabled }, - } = useStores() - const [isLoading, setIsLoading] = useState(true) + teamStore: { isTrackingEnabled } + } = useStores(); + const [isLoading, setIsLoading] = useState(true); useEffect(() => { - setTimeout(() => setIsLoading(false), 3000) - }, []) + setTimeout(() => setIsLoading(false), 3000); + }, []); return ( ( - + - + {isTrackingEnabled ? ( - + ) : null} - ), + ) } - : null), + : null) }} initialRouteName="Team" > @@ -179,22 +163,20 @@ const TabNavigator = observer(function TabNavigator() { name="Profile" component={AuthenticatedProfileScreen} options={{ - tabBarLabel: translate("tasksScreen.name"), + tabBarLabel: translate('tasksScreen.name'), tabBarIcon: ({ focused }) => focused ? ( ) : ( - + ), - tabBarActiveTintColor: dark ? "#8C7AE4" : "#3826A6", + tabBarActiveTintColor: dark ? '#8C7AE4' : '#3826A6' }} /> @@ -202,7 +184,7 @@ const TabNavigator = observer(function TabNavigator() { name="Team" component={AuthenticatedTeamScreen} options={{ - tabBarLabel: translate("teamScreen.name"), + tabBarLabel: translate('teamScreen.name'), tabBarIcon: ({ focused }) => !focused ? ( @@ -210,12 +192,12 @@ const TabNavigator = observer(function TabNavigator() { ), - tabBarActiveTintColor: dark ? "#8C7AE4" : "#3826A6", + tabBarActiveTintColor: dark ? '#8C7AE4' : '#3826A6' }} /> {isTrackingEnabled ? ( @@ -223,7 +205,7 @@ const TabNavigator = observer(function TabNavigator() { name="Timer" component={AuthenticatedTimerScreen} options={{ - tabBarLabel: translate("myWorkScreen.name"), + tabBarLabel: translate('myWorkScreen.name'), tabBarIcon: ({ focused }) => !focused ? ( @@ -231,15 +213,15 @@ const TabNavigator = observer(function TabNavigator() { ), - tabBarActiveTintColor: dark ? "#8C7AE4" : "#3826A6", + tabBarActiveTintColor: dark ? '#8C7AE4' : '#3826A6' }} /> ) : null} - ) -}) + ); +}); -const drawer = createDrawerNavigator() +const drawer = createDrawerNavigator(); export const AuthenticatedNavigator = observer(function AuthenticatedNavigator() { return ( @@ -247,8 +229,8 @@ export const AuthenticatedNavigator = observer(function AuthenticatedNavigator() drawerContent={(props) => } screenOptions={{ headerShown: false, - drawerPosition: "right", - drawerStyle: { width: "83%" }, + drawerPosition: 'right', + drawerStyle: { width: '83%' } }} > @@ -261,19 +243,19 @@ export const AuthenticatedNavigator = observer(function AuthenticatedNavigator() - ) -}) + ); +}); const $tabBarItem: ViewStyle = { - paddingTop: spacing.medium, -} + paddingTop: Platform.OS === 'ios' ? spacing.medium : spacing.extraSmall +}; const $tabBarLabel: TextStyle = { fontSize: 12, fontFamily: typography.fonts.PlusJakartaSans.semiBold, lineHeight: 16, - fontWeight: "500", - flex: 1, -} + fontWeight: '500', + flex: 1 +}; // @demo remove-file From df974ea04d376d8a1849bc9b674dbc5c1919ff71 Mon Sep 17 00:00:00 2001 From: desperado1802 Date: Mon, 20 Nov 2023 19:22:00 +0200 Subject: [PATCH 02/13] fixed teams dropdown responsiveness for android devices --- .../app/components/TeamDropdown/DropDown.tsx | 16 ++++++------ .../TeamDropdown/DropDownSection.tsx | 26 ++++++++++++------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/apps/mobile/app/components/TeamDropdown/DropDown.tsx b/apps/mobile/app/components/TeamDropdown/DropDown.tsx index 82733f7ff..c5cae7d93 100644 --- a/apps/mobile/app/components/TeamDropdown/DropDown.tsx +++ b/apps/mobile/app/components/TeamDropdown/DropDown.tsx @@ -2,7 +2,7 @@ /* eslint-disable react-native/no-inline-styles */ import { observer } from 'mobx-react-lite'; import React, { FC } from 'react'; -import { View, StyleSheet, TouchableOpacity, Text } from 'react-native'; +import { View, StyleSheet, TouchableOpacity, Text, Platform } from 'react-native'; import { Avatar } from 'react-native-paper'; import { AntDesign } from '@expo/vector-icons'; import { imgTitle } from '../../helpers/img-title'; @@ -53,7 +53,7 @@ const DropDown: FC = observer(function CreateTeamModal({ {activeTeam?.image?.thumbUrl || activeTeam?.logo || activeTeam?.image?.fullUrl ? ( = observer(function CreateTeamModal({ ) : ( @@ -69,14 +69,14 @@ const DropDown: FC = observer(function CreateTeamModal({ {`${limitTextCharaters({ text: activeTeam?.name, - numChars: resized ? 9 : 30 + numChars: resized ? (Platform.OS === 'android' ? 9 : 10) : 26 })} (${activeTeam?.members.length})`} {isOpen ? ( - + ) : ( - + )} @@ -97,7 +97,7 @@ const DropDown: FC = observer(function CreateTeamModal({ const styles = StyleSheet.create({ activeTeamTxt: { fontFamily: typography.fonts.PlusJakartaSans.semiBold, - fontSize: 14, + fontSize: 12, fontWeight: '600', left: 12 }, @@ -121,7 +121,7 @@ const styles = StyleSheet.create({ }, prefix: { fontFamily: typography.fonts.PlusJakartaSans.semiBold, - fontSize: 14, + fontSize: 12, fontWeight: '600' }, teamImage: { diff --git a/apps/mobile/app/components/TeamDropdown/DropDownSection.tsx b/apps/mobile/app/components/TeamDropdown/DropDownSection.tsx index ca36e9fc8..e6711ae90 100644 --- a/apps/mobile/app/components/TeamDropdown/DropDownSection.tsx +++ b/apps/mobile/app/components/TeamDropdown/DropDownSection.tsx @@ -1,7 +1,7 @@ /* eslint-disable react-native/no-color-literals */ /* eslint-disable react-native/no-inline-styles */ import React, { FC } from 'react'; -import { View, Text, StyleSheet, TouchableOpacity } from 'react-native'; +import { View, Text, StyleSheet, TouchableOpacity, Platform } from 'react-native'; import { Ionicons } from '@expo/vector-icons'; import { IOrganizationTeamList } from '../../services/interfaces/IOrganizationTeam'; import { SettingScreenNavigationProp } from '../../navigators/AuthenticatedNavigator'; @@ -16,7 +16,7 @@ import { Avatar } from 'react-native-paper'; import { observer } from 'mobx-react-lite'; import { limitTextCharaters } from '../../helpers/sub-text'; import { useNavigation } from '@react-navigation/native'; -import { FlatList } from 'react-native-gesture-handler'; +// import { FlatList } from 'react-native-gesture-handler'; export interface Props { teams: IOrganizationTeamList[]; @@ -32,8 +32,8 @@ const DropDownSection: FC = observer(function DropDownSection({ onCreateTeam, changeTeam, resized, - isAccountVerified, - isDrawer + isAccountVerified + // isDrawer }) { const { teamStore: { activeTeamId, activeTeam } @@ -74,7 +74,11 @@ const DropDownSection: FC = observer(function DropDownSection({ )} - ( + + ))} + + {/* ( @@ -95,7 +99,7 @@ const DropDownSection: FC = observer(function DropDownSection({ /> )} - /> + /> */} onCreateTeam()} @@ -161,15 +165,19 @@ const DropItem: FC = observer(function DropItem({ team, changeTeam, i style={{ color: colors.primary, paddingLeft: '5%', - fontSize: 16, + fontSize: 14, fontFamily: isActiveTeam ? typography.primary.semiBold : typography.primary.normal }} > - {limitTextCharaters({ text: team?.name, numChars: resized ? 12 : 20 })} ({team?.members.length}) + {limitTextCharaters({ + text: team?.name, + numChars: resized ? (Platform.OS === 'android' ? 10 : 12) : Platform.OS === 'android' ? 17 : 20 + })}{' '} + ({team?.members.length}) navigateToSettings(team)}> - + ); From 6995eebc8b93d0aec16c0983cce5c4ce585a4bad Mon Sep 17 00:00:00 2001 From: desperado1802 Date: Mon, 20 Nov 2023 23:57:37 +0200 Subject: [PATCH 03/13] added teams navigation icon --- apps/mobile/app/components/svgs/icons.tsx | 18 ++++++++++++++++++ .../app/navigators/AuthenticatedNavigator.tsx | 10 +++------- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/apps/mobile/app/components/svgs/icons.tsx b/apps/mobile/app/components/svgs/icons.tsx index d8ebc4ec5..2a68700bb 100644 --- a/apps/mobile/app/components/svgs/icons.tsx +++ b/apps/mobile/app/components/svgs/icons.tsx @@ -357,6 +357,24 @@ export const peopleNotFocusedLight = ` `; +export const peopleFocusedLight = ` + + + + + + + +`; +export const peopleFocusedDark = ` + + + + + + + +`; export const briefCaseNotFocusedLight = ` diff --git a/apps/mobile/app/navigators/AuthenticatedNavigator.tsx b/apps/mobile/app/navigators/AuthenticatedNavigator.tsx index e09413041..1ae12277b 100644 --- a/apps/mobile/app/navigators/AuthenticatedNavigator.tsx +++ b/apps/mobile/app/navigators/AuthenticatedNavigator.tsx @@ -34,6 +34,8 @@ import { SvgXml } from 'react-native-svg'; import { briefCaseNotFocusedDark, briefCaseNotFocusedLight, + peopleFocusedDark, + peopleFocusedLight, peopleNotFocusedDark, peopleNotFocusedLight, userFocusedDark, @@ -189,13 +191,7 @@ const TabNavigator = observer(function TabNavigator() { !focused ? ( ) : ( - + ), tabBarActiveTintColor: dark ? '#8C7AE4' : '#3826A6' }} From a4cc2b4e78b769b401d3f82237e24323ad9e68d9 Mon Sep 17 00:00:00 2001 From: desperado1802 Date: Tue, 21 Nov 2023 00:02:46 +0200 Subject: [PATCH 04/13] added profile navigator icon as svg --- apps/mobile/app/components/svgs/icons.tsx | 10 ++++++++++ .../mobile/app/navigators/AuthenticatedNavigator.tsx | 12 ++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/apps/mobile/app/components/svgs/icons.tsx b/apps/mobile/app/components/svgs/icons.tsx index 2a68700bb..1ca4c9764 100644 --- a/apps/mobile/app/components/svgs/icons.tsx +++ b/apps/mobile/app/components/svgs/icons.tsx @@ -399,6 +399,16 @@ export const briefCaseNotFocusedDark2 = ` `; +export const briefCaseFocusedLight = ` + + + +`; +export const briefCaseFocusedDark = ` + + + +`; export const userNotFocusedDark = ` diff --git a/apps/mobile/app/navigators/AuthenticatedNavigator.tsx b/apps/mobile/app/navigators/AuthenticatedNavigator.tsx index 1ae12277b..2bdbe0d6a 100644 --- a/apps/mobile/app/navigators/AuthenticatedNavigator.tsx +++ b/apps/mobile/app/navigators/AuthenticatedNavigator.tsx @@ -1,6 +1,6 @@ /* eslint-disable react-native/no-inline-styles */ import React, { useEffect, useState } from 'react'; -import { Image, Platform, TextStyle, View, ViewStyle } from 'react-native'; +import { Platform, TextStyle, View, ViewStyle } from 'react-native'; import { BottomTabScreenProps, createBottomTabNavigator, BottomTabNavigationProp } from '@react-navigation/bottom-tabs'; import { createDrawerNavigator, DrawerScreenProps } from '@react-navigation/drawer'; import type { StackNavigationProp } from '@react-navigation/stack'; @@ -32,6 +32,8 @@ import { useStores } from '../models'; import { observer } from 'mobx-react-lite'; import { SvgXml } from 'react-native-svg'; import { + briefCaseFocusedDark, + briefCaseFocusedLight, briefCaseNotFocusedDark, briefCaseNotFocusedLight, peopleFocusedDark, @@ -168,13 +170,7 @@ const TabNavigator = observer(function TabNavigator() { tabBarLabel: translate('tasksScreen.name'), tabBarIcon: ({ focused }) => focused ? ( - + ) : ( ), From 7c5936817565c6f5438da5776ab4ad1bc1703f94 Mon Sep 17 00:00:00 2001 From: desperado1802 Date: Tue, 21 Nov 2023 09:12:19 +0200 Subject: [PATCH 05/13] added invited user status icon as svg --- apps/mobile/app/components/svgs/icons.tsx | 4 ++++ .../TeamScreen/components/InviteCardItem.tsx | 17 ++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/apps/mobile/app/components/svgs/icons.tsx b/apps/mobile/app/components/svgs/icons.tsx index 1ca4c9764..5baa83907 100644 --- a/apps/mobile/app/components/svgs/icons.tsx +++ b/apps/mobile/app/components/svgs/icons.tsx @@ -497,6 +497,10 @@ export const pauseStatusIcon = ` `; +export const invitedStatusIcon = ` + + `; + export const suspendedStatusIconLarge = ` = observer(({ invite, onPr size={40} label={imgTitleProfileAvatar(invite.fullName)} /> - + + + {invite.fullName} {/* ENABLE ESTIMATE INPUTS */} @@ -298,7 +298,14 @@ const styles = StyleSheet.create({ opacity: 0.2 }, statusIcon: { + alignItems: 'center', + backgroundColor: '#DCD6D6', + borderColor: 'white', + borderRadius: 100, + borderWidth: 2, bottom: 0, + justifyContent: 'center', + padding: 2, position: 'absolute', right: -4 }, From 257afb4702757a0acb0ecdac569b74b7bb8c0339 Mon Sep 17 00:00:00 2001 From: desperado1802 <124465103+desperado1802@users.noreply.github.com> Date: Tue, 21 Nov 2023 18:47:57 +0200 Subject: [PATCH 06/13] fixed double letter insert and paste issue for android (#1844) * fixed double letter insert and paste issue for android * added a code input field using library --- apps/mobile/app/components/CodeField.tsx | 94 +++++++++++++++++++ apps/mobile/app/components/CodeInput.tsx | 6 +- .../LoginScreen/Components/PassCode.tsx | 5 +- apps/mobile/package.json | 1 + apps/mobile/yarn.lock | 5 + 5 files changed, 107 insertions(+), 4 deletions(-) create mode 100644 apps/mobile/app/components/CodeField.tsx diff --git a/apps/mobile/app/components/CodeField.tsx b/apps/mobile/app/components/CodeField.tsx new file mode 100644 index 000000000..f6a8bb23c --- /dev/null +++ b/apps/mobile/app/components/CodeField.tsx @@ -0,0 +1,94 @@ +/* eslint-disable react-native/no-inline-styles */ +/* eslint-disable react-native/no-color-literals */ +import React, { FC, useEffect, useState } from 'react'; +import { View, StyleSheet, Text } from 'react-native'; +import { colors, typography, useAppTheme } from '../theme'; +import { CodeField, Cursor, useBlurOnFulfill, useClearByFocusCell } from 'react-native-confirmation-code-field'; + +interface ICodeField { + onChange: (e: any) => void; + editable: boolean; + length?: number; + defaultValue?: string; +} + +export const CodeInputField: FC = (props) => { + const { onChange, editable, length = 6 } = props; + const { colors } = useAppTheme(); + + const [value, setValue] = useState(''); + + const [codeFieldProps, getCellOnLayoutHandler] = useClearByFocusCell({ + value, + setValue + }); + + useEffect(() => { + onChange(value); + }, [value]); + + const ref = useBlurOnFulfill({ value, cellCount: length }); + + return ( + ( + + + {symbol || (isFocused ? : null)} + + + )} + /> + ); +}; + +const styles = StyleSheet.create({ + container: { + flexDirection: 'row', + justifyContent: 'center', + width: '100%' + }, + inputContainer: { + backgroundColor: '#fff', + borderRadius: 10, + marginHorizontal: 4, + width: '14.6%' + }, + inputStyle: { + backgroundColor: '#fff', + borderColor: 'rgba(0, 0, 0, 0.1)', + borderRadius: 10, + borderWidth: 1, + color: colors.primary, + fontFamily: typography.primary.semiBold, + fontSize: 16, + height: 53, + textAlign: 'center', + width: '100%' + } +}); diff --git a/apps/mobile/app/components/CodeInput.tsx b/apps/mobile/app/components/CodeInput.tsx index 303e7be67..a56978f65 100644 --- a/apps/mobile/app/components/CodeInput.tsx +++ b/apps/mobile/app/components/CodeInput.tsx @@ -1,7 +1,7 @@ /* eslint-disable react-native/no-inline-styles */ /* eslint-disable react-native/no-color-literals */ import React, { FC, useRef, useState } from 'react'; -import { TextInput, View, StyleSheet, NativeSyntheticEvent, TextInputKeyPressEventData } from 'react-native'; +import { TextInput, View, StyleSheet, NativeSyntheticEvent, TextInputKeyPressEventData, Platform } from 'react-native'; import * as Clipboard from 'expo-clipboard'; import { colors, typography, useAppTheme } from '../theme'; @@ -38,7 +38,7 @@ export const CodeInput: FC = (props) => { onChange(updatedCode.join('')); } // Current input has value - if (inviteCode[active]) { + else if (inviteCode[active] && nativeEvent.key !== inviteCode[active]) { const updatedCode = [...inviteCode]; updatedCode[active + 1] = nativeEvent.key.toUpperCase(); setInviteCode(updatedCode); @@ -87,6 +87,8 @@ export const CodeInput: FC = (props) => { inputsRef.current[i].setNativeProps({ text: updatedCode[i] }); } } + + Platform.OS === 'android' && (await Clipboard.setStringAsync('')); }; for (let i = 0; i < length; i++) { diff --git a/apps/mobile/app/screens/LoginScreen/Components/PassCode.tsx b/apps/mobile/app/screens/LoginScreen/Components/PassCode.tsx index 49f9a5a03..5d029f985 100644 --- a/apps/mobile/app/screens/LoginScreen/Components/PassCode.tsx +++ b/apps/mobile/app/screens/LoginScreen/Components/PassCode.tsx @@ -12,11 +12,11 @@ import { translate } from '../../../i18n'; import { Button, TextField } from '../../../components'; import { spacing, typography, useAppTheme } from '../../../theme'; import { useStores } from '../../../models'; -import { CodeInput } from '../../../components/CodeInput'; import { GLOBAL_STYLE as GS } from '../../../../assets/ts/styles'; import { EMAIL_REGEX } from '../../../helpers/regex'; import UserTenants from './UserTenants'; import { IWorkspace, VerificationResponse } from '../../../services/interfaces/IAuthentication'; +import { CodeInputField } from '../../../components/CodeField'; interface Props { isLoading: boolean; @@ -139,6 +139,7 @@ const PassCode: FC = observer( const onChangeAuthCode = (text: string) => { setAuthInviteCode(text); + if (text.length === 6) { setIsValid({ ...isValid, @@ -213,7 +214,7 @@ const PassCode: FC = observer( {translate('loginScreen.inviteCodeFieldLabel')} - + {joinError ? {joinError} : null} getAuthCode()}> diff --git a/apps/mobile/package.json b/apps/mobile/package.json index 41875608c..87693b96c 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -88,6 +88,7 @@ "react-native-circular-progress": "^1.3.8", "react-native-click-outside": "^0.1.1", "react-native-cn-quill": "^0.7.18", + "react-native-confirmation-code-field": "^7.3.2", "react-native-dotenv": "^3.4.8", "react-native-dropdown-picker": "^5.4.6", "react-native-extended-stylesheet": "^0.12.0", diff --git a/apps/mobile/yarn.lock b/apps/mobile/yarn.lock index ca286d2ff..425a7cab0 100644 --- a/apps/mobile/yarn.lock +++ b/apps/mobile/yarn.lock @@ -12255,6 +12255,11 @@ react-native-codegen@^0.71.5: jscodeshift "^0.14.0" nullthrows "^1.1.1" +react-native-confirmation-code-field@^7.3.2: + version "7.3.2" + resolved "https://registry.yarnpkg.com/react-native-confirmation-code-field/-/react-native-confirmation-code-field-7.3.2.tgz#f0ee9e72f632aa2ae4dade4a1664a7a484885ea8" + integrity sha512-uuJKxR+pQrXSx8lmRpekA+Hlle/nkoQKppS8jH7ApqY00+c11nCJg9kuFM0++vdbXg1rKm2P6jPZoSEJK2EaKw== + react-native-dotenv@^3.4.8: version "3.4.8" resolved "https://registry.yarnpkg.com/react-native-dotenv/-/react-native-dotenv-3.4.8.tgz#42284070a9994076cd700805c2dd28051c9e1432" From 48b7ed1881747a4bbb3823de41a0ca56e2b1e234 Mon Sep 17 00:00:00 2001 From: desperado1802 <124465103+desperado1802@users.noreply.github.com> Date: Tue, 21 Nov 2023 18:49:59 +0200 Subject: [PATCH 07/13] Bug/expo doctor fixes (#1846) * removed dependencies that are added by default * updated react-native-webview * updated react native and fixed ts build errors --- .../app/screens/DemoPodcastListScreen.tsx | 189 ++++++++-------- .../DemoShowroomScreen/DrawerIconButton.tsx | 14 +- apps/mobile/package.json | 9 +- apps/mobile/yarn.lock | 203 +++--------------- 4 files changed, 143 insertions(+), 272 deletions(-) diff --git a/apps/mobile/app/screens/DemoPodcastListScreen.tsx b/apps/mobile/app/screens/DemoPodcastListScreen.tsx index ee8c5f7bd..e23f1e39b 100644 --- a/apps/mobile/app/screens/DemoPodcastListScreen.tsx +++ b/apps/mobile/app/screens/DemoPodcastListScreen.tsx @@ -13,6 +13,7 @@ import { ViewStyle } from 'react-native'; import Animated, { + AnimatedStyleProp, Extrapolate, interpolate, useAnimatedStyle, @@ -35,94 +36,94 @@ const rnrImage2 = require('../../assets/images/rnr-image-2.png'); const rnrImage3 = require('../../assets/images/rnr-image-3.png'); const rnrImages = [rnrImage1, rnrImage2, rnrImage3]; -export const DemoPodcastListScreen: FC> = observer( - function DemoPodcastListScreen(_props) { - const { episodeStore } = useStores(); +export const DemoPodcastListScreen: FC> = observer(function DemoPodcastListScreen( + _props +) { + const { episodeStore } = useStores(); - const [refreshing, setRefreshing] = React.useState(false); - const [isLoading, setIsLoading] = React.useState(false); + const [refreshing, setRefreshing] = React.useState(false); + const [isLoading, setIsLoading] = React.useState(false); - // initially, kick off a background refresh without the refreshing UI - useEffect(() => { - (async function load() { - setIsLoading(true); - await episodeStore.fetchEpisodes(); - setIsLoading(false); - })(); - }, [episodeStore]); + // initially, kick off a background refresh without the refreshing UI + useEffect(() => { + (async function load() { + setIsLoading(true); + await episodeStore.fetchEpisodes(); + setIsLoading(false); + })(); + }, [episodeStore]); - // simulate a longer refresh, if the refresh is too fast for UX - async function manualRefresh() { - setRefreshing(true); - await Promise.all([episodeStore.fetchEpisodes(), delay(750)]); - setRefreshing(false); - } + // simulate a longer refresh, if the refresh is too fast for UX + async function manualRefresh() { + setRefreshing(true); + await Promise.all([episodeStore.fetchEpisodes(), delay(750)]); + setRefreshing(false); + } - return ( - - - data={episodeStore.episodesForList} - extraData={episodeStore.favorites.length + episodeStore.episodes.length} - contentContainerStyle={$flatListContentContainer} - refreshing={refreshing} - onRefresh={manualRefresh} - ListEmptyComponent={ - isLoading ? ( - - ) : ( - - ) - } - ListHeaderComponent={ - - - {(episodeStore.favoritesOnly || episodeStore.episodesForList.length > 0) && ( - - - episodeStore.setProp('favoritesOnly', !episodeStore.favoritesOnly) - } - variant="switch" - labelTx="demoPodcastListScreen.onlyFavorites" - labelPosition="left" - labelStyle={$labelStyle} - accessibilityLabel={translate('demoPodcastListScreen.accessibility.switch')} - /> - - )} - - } - renderItem={({ item }) => ( - episodeStore.toggleFavorite(item)} + return ( + + + data={episodeStore.episodesForList} + extraData={episodeStore.favorites.length + episodeStore.episodes.length} + contentContainerStyle={$flatListContentContainer} + refreshing={refreshing} + onRefresh={manualRefresh} + ListEmptyComponent={ + isLoading ? ( + + ) : ( + - )} - /> - - ); - } -); + ) + } + ListHeaderComponent={ + + + {(episodeStore.favoritesOnly || episodeStore.episodesForList.length > 0) && ( + + + episodeStore.setProp('favoritesOnly', !episodeStore.favoritesOnly) + } + variant="switch" + labelTx="demoPodcastListScreen.onlyFavorites" + labelPosition="left" + labelStyle={$labelStyle} + accessibilityLabel={translate('demoPodcastListScreen.accessibility.switch')} + /> + + )} + + } + renderItem={({ item }) => ( + episodeStore.toggleFavorite(item)} + /> + )} + /> + + ); +}); const EpisodeCard = observer(function EpisodeCard({ episode, @@ -148,7 +149,7 @@ const EpisodeCard = observer(function EpisodeCard({ } ], opacity: interpolate(liked.value, [0, 1], [1, 0], Extrapolate.CLAMP) - }; + } as AnimatedStyleProp; }); // Pink heart @@ -160,7 +161,7 @@ const EpisodeCard = observer(function EpisodeCard({ } ], opacity: liked.value - }; + } as AnimatedStyleProp; }); /** @@ -207,14 +208,28 @@ const EpisodeCard = observer(function EpisodeCard({ function ButtonLeftAccessory() { return ( - + + } + > - + + } + > ; }); const animatedTopBarStyles = useAnimatedStyle(() => { @@ -36,7 +36,7 @@ export function DrawerIconButton(props: DrawerIconButtonProps) { marginBottom, width, transform: [{ rotate: `${rotate}deg` }] - }; + } as AnimateStyle; }); const animatedMiddleBarStyles = useAnimatedStyle(() => { @@ -62,7 +62,7 @@ export function DrawerIconButton(props: DrawerIconButtonProps) { width, marginTop, transform: [{ rotate: `${rotate}deg` }] - }; + } as AnimateStyle; }); useEffect(() => { @@ -71,11 +71,11 @@ export function DrawerIconButton(props: DrawerIconButtonProps) { return ( - + } /> - + } /> ); } diff --git a/apps/mobile/package.json b/apps/mobile/package.json index 87693b96c..4093b91a0 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -43,7 +43,7 @@ }, "dependencies": { "@expo-google-fonts/space-grotesk": "^0.2.3", - "@expo/config-plugins": "6.0.0", + "@expo/config-plugins": "~6.0.0", "@expo/webpack-config": "^18.0.1", "@react-native-async-storage/async-storage": "1.17.11", "@react-navigation/bottom-tabs": "^6.5.7", @@ -69,7 +69,6 @@ "expo-linear-gradient": "~12.1.2", "expo-localization": "~14.1.1", "expo-media-library": "~15.2.3", - "expo-modules-core": "~1.2.7", "expo-splash-screen": "~0.18.2", "expo-status-bar": "~1.4.4", "expo-updates": "~0.16.4", @@ -81,7 +80,7 @@ "mobx-state-tree": "5.1.8", "moment-timezone": "^0.5.42", "react": "18.2.0", - "react-native": "0.71.8", + "react-native": "0.71.14", "react-native-animatable": "^1.3.3", "react-native-bootsplash": "4.5.3", "react-native-calendars": "^1.1302.0", @@ -103,7 +102,7 @@ "react-native-svg": "13.4.0", "react-native-tab-view": "^3.5.2", "react-native-vector-icons": "^9.2.0", - "react-native-webview": "11.23.1", + "react-native-webview": "11.26.0", "react-query": "^3.39.3", "reactotron-mst": "3.1.4", "reactotron-react-js": "^3.3.7", @@ -125,7 +124,6 @@ "@types/i18n-js": "3.8.4", "@types/jest": "^29.5.0", "@types/react": "~18.0.27", - "@types/react-native": "0.71.5", "@typescript-eslint/eslint-plugin": "5.60.1", "@typescript-eslint/parser": "5.60.1", "babel-jest": "29.5.0", @@ -142,7 +140,6 @@ "eslint-plugin-react": "7.32.2", "eslint-plugin-react-native": "4.0.0", "expo-detox-hook": "1.0.10", - "expo-modules-autolinking": "~1.1.0", "fbjs-scripts": "3.0.1", "jest": "^29.2.1", "jest-circus": "29.5.0", diff --git a/apps/mobile/yarn.lock b/apps/mobile/yarn.lock index 425a7cab0..c526bc8ba 100644 --- a/apps/mobile/yarn.lock +++ b/apps/mobile/yarn.lock @@ -1344,27 +1344,6 @@ xcode "^3.0.1" xml2js "0.4.23" -"@expo/config-plugins@6.0.0": - version "6.0.0" - resolved "https://registry.yarnpkg.com/@expo/config-plugins/-/config-plugins-6.0.0.tgz#b17d633b708a547e229c981b95e23773fec7fa47" - integrity sha512-Hp9ZbAvonzPTJFcoBBfmxwLwxHFOQuj8YcbYzSW2UiXeco79Q0itsCEKenvfc16V+ZwMkcjpbahy5/8uVn6aiA== - dependencies: - "@expo/config-types" "^48.0.0" - "@expo/json-file" "~8.2.37" - "@expo/plist" "^0.0.20" - "@expo/sdk-runtime-versions" "^1.0.0" - "@react-native/normalize-color" "^2.0.0" - chalk "^4.1.2" - debug "^4.3.1" - find-up "~5.0.0" - getenv "^1.0.0" - glob "7.1.6" - resolve-from "^5.0.0" - semver "^7.3.5" - slash "^3.0.0" - xcode "^3.0.1" - xml2js "0.4.23" - "@expo/config-plugins@6.0.1", "@expo/config-plugins@~6.0.0": version "6.0.1" resolved "https://registry.yarnpkg.com/@expo/config-plugins/-/config-plugins-6.0.1.tgz#827cb34c51f725d8825b0768df6550c1cf81d457" @@ -2210,7 +2189,7 @@ dependencies: serve-static "^1.13.1" -"@react-native-community/cli-doctor@^10.2.2": +"@react-native-community/cli-doctor@^10.2.4": version "10.2.5" resolved "https://registry.yarnpkg.com/@react-native-community/cli-doctor/-/cli-doctor-10.2.5.tgz#e5e28c66c2373f05a94b296a8ec637f8df736707" integrity sha512-1YbzXvsldBmSw1MmBsXB74bKiHXKNCjlb2ByLgkfTiarpSvETYam3g5vex0N+qc0Cdkzkq+8NznE744LFhnUpw== @@ -2254,10 +2233,10 @@ glob "^7.1.3" logkitty "^0.7.1" -"@react-native-community/cli-platform-ios@10.2.1": - version "10.2.1" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-10.2.1.tgz#2e6bd2cb6d48cbb8720d7b7265bb1bab80745f72" - integrity sha512-hz4zu4Y6eyj7D0lnZx8Mf2c2si8y+zh/zUTgCTaPPLzQD8jSZNNBtUUiA1cARm2razpe8marCZ1QbTMAGbf3mg== +"@react-native-community/cli-platform-ios@10.2.4": + version "10.2.4" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-10.2.4.tgz#6af05cd4258438422a3a50d1c0cc757acd6be375" + integrity sha512-/6K+jeRhcGojFIJMWMXV2eY5n/In+YUzBr/DKWQOeHBOHkESRNheG310xSAIjgB46YniSSUKhSyeuhalTbm9OQ== dependencies: "@react-native-community/cli-tools" "^10.1.1" chalk "^4.1.2" @@ -2290,7 +2269,7 @@ glob "^7.1.3" ora "^5.4.1" -"@react-native-community/cli-plugin-metro@^10.2.2": +"@react-native-community/cli-plugin-metro@^10.2.3": version "10.2.3" resolved "https://registry.yarnpkg.com/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-10.2.3.tgz#419e0155a50951c3329818fba51cb5021a7294f1" integrity sha512-jHi2oDuTePmW4NEyVT8JEGNlIYcnFXCSV2ZMp4rnDrUk4TzzyvS3IMvDlESEmG8Kry8rvP0KSUx/hTpy37Sbkw== @@ -2359,17 +2338,17 @@ dependencies: joi "^17.2.1" -"@react-native-community/cli@10.2.2": - version "10.2.2" - resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-10.2.2.tgz#3fa438ba7f19f83e07bc337765fc1cabdcf2cac2" - integrity sha512-aZVcVIqj+OG6CrliR/Yn8wHxrvyzbFBY9cj7n0MvRw/P54QUru2nNqUTSSbqv0Qaa297yHJbe6kFDojDMSTM8Q== +"@react-native-community/cli@10.2.4": + version "10.2.4" + resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-10.2.4.tgz#c6afe723055d430061a32bd31644fc56eb9ba330" + integrity sha512-E9BUDHfLEsnjkjeJqECuCjl4E/1Ox9Nl6hkQBhEqjZm4AaQxgU7M6AyFfOgaXn5v3am16/R4ZOUTrJnGJWS3GA== dependencies: "@react-native-community/cli-clean" "^10.1.1" "@react-native-community/cli-config" "^10.1.1" "@react-native-community/cli-debugger-ui" "^10.0.0" - "@react-native-community/cli-doctor" "^10.2.2" + "@react-native-community/cli-doctor" "^10.2.4" "@react-native-community/cli-hermes" "^10.2.0" - "@react-native-community/cli-plugin-metro" "^10.2.2" + "@react-native-community/cli-plugin-metro" "^10.2.3" "@react-native-community/cli-server-api" "^10.1.1" "@react-native-community/cli-tools" "^10.1.1" "@react-native-community/cli-types" "^10.0.0" @@ -2994,13 +2973,6 @@ dependencies: "@types/react" "*" -"@types/react-native@0.71.5": - version "0.71.5" - resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.71.5.tgz#229bc670433f97fe1e03d62758d4fccf34a07714" - integrity sha512-Tp5druh7DGwNDvWYH09PCE++hbH4zYz0OOvGFb3/QFIFKXgfezaT/txJeKlBkbiqs45QJzllp9S0qo0WpWyijA== - dependencies: - "@types/react" "*" - "@types/react@*", "@types/react@18.0.0": version "18.0.0" resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.0.tgz#4be8aa3a2d04afc3ac2cc1ca43d39b0bd412890c" @@ -6461,7 +6433,7 @@ expo-media-library@~15.2.3: resolved "https://registry.yarnpkg.com/expo-media-library/-/expo-media-library-15.2.3.tgz#188f3c77f58b354f0ea6250f6756ac1e1a226291" integrity sha512-Oz8b8Xsvfj7YcutUBtI84NUIqSnt7iCM5HZ5DyKoWKKiDK/+aUuj3RXNQELG8jUw6pQPgEwgbZ1+J8SdH/y9jw== -expo-modules-autolinking@1.1.2, expo-modules-autolinking@~1.1.0: +expo-modules-autolinking@1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/expo-modules-autolinking/-/expo-modules-autolinking-1.1.2.tgz#a81c65c63bd281922410c6d8c3ad6255b6305246" integrity sha512-oOlkAccVnHwwR5ccvF/F/x4Omj9HWzSimMUlIVz0SVGdNBEqTPyn0L/d4uIufhyQbEWvrarqL8o5Yz11wEI0SQ== @@ -6480,14 +6452,6 @@ expo-modules-core@1.2.6: compare-versions "^3.4.0" invariant "^2.2.4" -expo-modules-core@~1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/expo-modules-core/-/expo-modules-core-1.2.7.tgz#c80627b13a8f1c94ae9da8eea41e1ef1df5788c8" - integrity sha512-sulqn2M8+tIdxi6QFkKppDEzbePAscgE2LEHocYoQOgHxJpeT7axE0Hkzc+81EeviQilZzGeFZMtNMGh3c9yJg== - dependencies: - compare-versions "^3.4.0" - invariant "^2.2.4" - expo-pwa@0.0.124: version "0.0.124" resolved "https://registry.yarnpkg.com/expo-pwa/-/expo-pwa-0.0.124.tgz#684e68aea6c7f95864a8cde17a57e223ed017199" @@ -9549,16 +9513,6 @@ metro-babel-transformer@0.73.10: metro-source-map "0.73.10" nullthrows "^1.1.1" -metro-babel-transformer@0.73.9: - version "0.73.9" - resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.73.9.tgz#bec8aaaf1bbdc2e469fde586fde455f8b2a83073" - integrity sha512-DlYwg9wwYIZTHtic7dyD4BP0SDftoltZ3clma76nHu43blMWsCnrImHeHsAVne3XsQ+RJaSRxhN5nkG2VyVHwA== - dependencies: - "@babel/core" "^7.20.0" - hermes-parser "0.8.0" - metro-source-map "0.73.9" - nullthrows "^1.1.1" - metro-babel-transformer@0.76.0: version "0.76.0" resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.76.0.tgz#cb3854ee74a1ecba40680af1b6625aa46928c3c0" @@ -9824,50 +9778,6 @@ metro-react-native-babel-preset@0.73.8: "@babel/template" "^7.0.0" react-refresh "^0.4.0" -metro-react-native-babel-preset@0.73.9: - version "0.73.9" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.73.9.tgz#ef54637dd20f025197beb49e71309a9c539e73e2" - integrity sha512-AoD7v132iYDV4K78yN2OLgTPwtAKn0XlD2pOhzyBxiI8PeXzozhbKyPV7zUOJUPETj+pcEVfuYj5ZN/8+bhbCw== - dependencies: - "@babel/core" "^7.20.0" - "@babel/plugin-proposal-async-generator-functions" "^7.0.0" - "@babel/plugin-proposal-class-properties" "^7.0.0" - "@babel/plugin-proposal-export-default-from" "^7.0.0" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.0.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" - "@babel/plugin-proposal-optional-chaining" "^7.0.0" - "@babel/plugin-syntax-dynamic-import" "^7.0.0" - "@babel/plugin-syntax-export-default-from" "^7.0.0" - "@babel/plugin-syntax-flow" "^7.18.0" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.0.0" - "@babel/plugin-syntax-optional-chaining" "^7.0.0" - "@babel/plugin-transform-arrow-functions" "^7.0.0" - "@babel/plugin-transform-async-to-generator" "^7.0.0" - "@babel/plugin-transform-block-scoping" "^7.0.0" - "@babel/plugin-transform-classes" "^7.0.0" - "@babel/plugin-transform-computed-properties" "^7.0.0" - "@babel/plugin-transform-destructuring" "^7.0.0" - "@babel/plugin-transform-flow-strip-types" "^7.0.0" - "@babel/plugin-transform-function-name" "^7.0.0" - "@babel/plugin-transform-literals" "^7.0.0" - "@babel/plugin-transform-modules-commonjs" "^7.0.0" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.0.0" - "@babel/plugin-transform-parameters" "^7.0.0" - "@babel/plugin-transform-react-display-name" "^7.0.0" - "@babel/plugin-transform-react-jsx" "^7.0.0" - "@babel/plugin-transform-react-jsx-self" "^7.0.0" - "@babel/plugin-transform-react-jsx-source" "^7.0.0" - "@babel/plugin-transform-runtime" "^7.0.0" - "@babel/plugin-transform-shorthand-properties" "^7.0.0" - "@babel/plugin-transform-spread" "^7.0.0" - "@babel/plugin-transform-sticky-regex" "^7.0.0" - "@babel/plugin-transform-template-literals" "^7.0.0" - "@babel/plugin-transform-typescript" "^7.5.0" - "@babel/plugin-transform-unicode-regex" "^7.0.0" - "@babel/template" "^7.0.0" - react-refresh "^0.4.0" - metro-react-native-babel-preset@0.76.0: version "0.76.0" resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.76.0.tgz#440a0e8965b2eb01afa391ef95575faeed67636b" @@ -9926,19 +9836,6 @@ metro-react-native-babel-transformer@0.73.10: metro-source-map "0.73.10" nullthrows "^1.1.1" -metro-react-native-babel-transformer@0.73.9: - version "0.73.9" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.73.9.tgz#4f4f0cfa5119bab8b53e722fabaf90687d0cbff0" - integrity sha512-DSdrEHuQ22ixY7DyipyKkIcqhOJrt5s6h6X7BYJCP9AMUfXOwLe2biY3BcgJz5GOXv8/Akry4vTCvQscVS1otQ== - dependencies: - "@babel/core" "^7.20.0" - babel-preset-fbjs "^3.4.0" - hermes-parser "0.8.0" - metro-babel-transformer "0.73.9" - metro-react-native-babel-preset "0.73.9" - metro-source-map "0.73.9" - nullthrows "^1.1.1" - metro-resolver@0.73.10: version "0.73.10" resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.73.10.tgz#c39a3bd8d33e5d78cb256110d29707d8d49ed0be" @@ -9959,14 +9856,6 @@ metro-runtime@0.73.10: "@babel/runtime" "^7.0.0" react-refresh "^0.4.0" -metro-runtime@0.73.9: - version "0.73.9" - resolved "https://registry.yarnpkg.com/metro-runtime/-/metro-runtime-0.73.9.tgz#0b24c0b066b8629ee855a6e5035b65061fef60d5" - integrity sha512-d5Hs83FpKB9r8q8Vb95+fa6ESpwysmPr4lL1I2rM2qXAFiO7OAPT9Bc23WmXgidkBtD0uUFdB2lG+H1ATz8rZg== - dependencies: - "@babel/runtime" "^7.0.0" - react-refresh "^0.4.0" - metro-runtime@0.76.0: version "0.76.0" resolved "https://registry.yarnpkg.com/metro-runtime/-/metro-runtime-0.76.0.tgz#ccc4721010a24d4919bf50e9146d06d28266efb3" @@ -9989,20 +9878,6 @@ metro-source-map@0.73.10: source-map "^0.5.6" vlq "^1.0.0" -metro-source-map@0.73.9: - version "0.73.9" - resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.73.9.tgz#89ca41f6346aeb12f7f23496fa363e520adafebe" - integrity sha512-l4VZKzdqafipriETYR6lsrwtavCF1+CMhCOY9XbyWeTrpGSNgJQgdeJpttzEZTHQQTLR0csQo0nD1ef3zEP6IQ== - dependencies: - "@babel/traverse" "^7.20.0" - "@babel/types" "^7.20.0" - invariant "^2.2.4" - metro-symbolicate "0.73.9" - nullthrows "^1.1.1" - ob1 "0.73.9" - source-map "^0.5.6" - vlq "^1.0.0" - metro-source-map@0.76.0: version "0.76.0" resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.76.0.tgz#0f05263dc4648f654feaab36dae799b7118b36c0" @@ -10029,18 +9904,6 @@ metro-symbolicate@0.73.10: through2 "^2.0.1" vlq "^1.0.0" -metro-symbolicate@0.73.9: - version "0.73.9" - resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.73.9.tgz#cb452299a36e5b86b2826e7426d51221635c48bf" - integrity sha512-4TUOwxRHHqbEHxRqRJ3wZY5TA8xq7AHMtXrXcjegMH9FscgYztsrIG9aNBUBS+VLB6g1qc6BYbfIgoAnLjCDyw== - dependencies: - invariant "^2.2.4" - metro-source-map "0.73.9" - nullthrows "^1.1.1" - source-map "^0.5.6" - through2 "^2.0.1" - vlq "^1.0.0" - metro-symbolicate@0.76.0: version "0.76.0" resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.76.0.tgz#3745875473d4fab544d054b90522df6779b41d37" @@ -10886,11 +10749,6 @@ ob1@0.73.10: resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.73.10.tgz#bf0a2e8922bb8687ddca82327c5cf209414a1bd4" integrity sha512-aO6EYC+QRRCkZxVJhCWhLKgVjhNuD6Gu1riGjxrIm89CqLsmKgxzYDDEsktmKsoDeRdWGQM5EdMzXDl5xcVfsw== -ob1@0.73.9: - version "0.73.9" - resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.73.9.tgz#d5677a0dd3e2f16ad84231278d79424436c38c59" - integrity sha512-kHOzCOFXmAM26fy7V/YuXNKne2TyRiXbFAvPBIbuedJCZZWQZHLdPzMeXJI4Egt6IcfDttRzN3jQ90wOwq1iNw== - ob1@0.76.0: version "0.76.0" resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.76.0.tgz#d36e1a2f2e7ff4534cf25aaf2ab27b48161a408f" @@ -12245,7 +12103,7 @@ react-native-cn-quill@^0.7.18: resolved "https://registry.yarnpkg.com/react-native-cn-quill/-/react-native-cn-quill-0.7.18.tgz#9006e5227eebc0b751aea6cb91490a22a1c286f2" integrity sha512-v8r6FEV3xFD+z/lEZrGIReZwmAnw7aTxyJSSmcv9O2PSHL994L4nW6nnDLXPKBG3PLfOKIkLbErQK9r6aQdXUQ== -react-native-codegen@^0.71.5: +react-native-codegen@^0.71.6: version "0.71.6" resolved "https://registry.yarnpkg.com/react-native-codegen/-/react-native-codegen-0.71.6.tgz#481a610c3af9135b09e1e031da032e7270e0cc1b" integrity sha512-e5pR4VldIhEaFctfSAEgxbng0uG4gjBQxAHes3EKLdosH/Av90pQfSe9IDVdFIngvNPzt8Y14pNjrtqov/yNIg== @@ -12304,7 +12162,7 @@ react-native-gesture-handler@~2.9.0: lodash "^4.17.21" prop-types "^15.7.2" -react-native-gradle-plugin@^0.71.18: +react-native-gradle-plugin@^0.71.19: version "0.71.19" resolved "https://registry.yarnpkg.com/react-native-gradle-plugin/-/react-native-gradle-plugin-0.71.19.tgz#3379e28341fcd189bc1f4691cefc84c1a4d7d232" integrity sha512-1dVk9NwhoyKHCSxcrM6vY6cxmojeATsBobDicX0ZKr7DgUF2cBQRTKsimQFvzH8XhOVXyH8p4HyDSZNIFI8OlQ== @@ -12400,28 +12258,29 @@ react-native-web@~0.18.11: postcss-value-parser "^4.2.0" styleq "^0.1.2" -react-native-webview@11.23.1: - version "11.23.1" - resolved "https://registry.yarnpkg.com/react-native-webview/-/react-native-webview-11.23.1.tgz#6a4bf2620e491dd4fecf4e6dc079005117fae12c" - integrity sha512-bmqsdg4RYOUYD37R9XTrQALm7eD62KbLNPRfgvpLGd1SjaurvAjjsLrLN4mt6yOtKOMKeZvlcAl3x6De6cCQsA== +react-native-webview@11.26.0: + version "11.26.0" + resolved "https://registry.yarnpkg.com/react-native-webview/-/react-native-webview-11.26.0.tgz#e524992876fe4a79e69905f0fab8949b470e9f16" + integrity sha512-4T4CKRm8xlaQDz9h/bCMPGAvtkesrhkRWqCX9FDJEzBToaVUIsV0ZOqtC4w/JSnCtFKKYiaC1ReJtCGv+4mFeQ== dependencies: escape-string-regexp "2.0.0" invariant "2.2.4" -react-native@0.71.8: - version "0.71.8" - resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.71.8.tgz#4314145341c49448cf7465b93ced52a433a5e191" - integrity sha512-ftMAuhpgTkbHU9brrqsEyxcNrpYvXKeATY+if22Nfhhg1zW+6wn95w9otwTnA3xHkljPCbng8mUhmmERjGEl7g== +react-native@0.71.14: + version "0.71.14" + resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.71.14.tgz#df12b405a7913b736de01b0347af14e4be7bf324" + integrity sha512-7uhzas8aKpU2EARhlONt7yiclh+7PXEOJk469ewpQyId8Owq5WNtZvQm/z3k4mHUriMeQ37vgSGkOInSKcCazw== dependencies: "@jest/create-cache-key-function" "^29.2.1" - "@react-native-community/cli" "10.2.2" + "@react-native-community/cli" "10.2.4" "@react-native-community/cli-platform-android" "10.2.0" - "@react-native-community/cli-platform-ios" "10.2.1" + "@react-native-community/cli-platform-ios" "10.2.4" "@react-native/assets" "1.0.0" "@react-native/normalize-color" "2.1.0" "@react-native/polyfills" "2.0.0" abort-controller "^3.0.0" anser "^1.4.9" + ansi-regex "^5.0.0" base64-js "^1.1.2" deprecated-react-native-prop-types "^3.0.1" event-target-shim "^5.0.1" @@ -12429,16 +12288,16 @@ react-native@0.71.8: jest-environment-node "^29.2.1" jsc-android "^250231.0.0" memoize-one "^5.0.0" - metro-react-native-babel-transformer "0.73.9" - metro-runtime "0.73.9" - metro-source-map "0.73.9" + metro-react-native-babel-transformer "0.73.10" + metro-runtime "0.73.10" + metro-source-map "0.73.10" mkdirp "^0.5.1" nullthrows "^1.1.1" pretty-format "^26.5.2" promise "^8.3.0" react-devtools-core "^4.26.1" - react-native-codegen "^0.71.5" - react-native-gradle-plugin "^0.71.18" + react-native-codegen "^0.71.6" + react-native-gradle-plugin "^0.71.19" react-refresh "^0.4.0" react-shallow-renderer "^16.15.0" regenerator-runtime "^0.13.2" From b7545520b7435a87c33c34777bb88932a5965bed Mon Sep 17 00:00:00 2001 From: desperado1802 <124465103+desperado1802@users.noreply.github.com> Date: Wed, 22 Nov 2023 00:49:50 +0200 Subject: [PATCH 08/13] added defaultTeamId to be saved in asyncStorage (#1839) * added defaultTeamId to be saved in asyncStorage, so next time when user logins it memorizes the team * added functionality when there are multi tenants * storing the userId and tenantId in asyncStorage too, in order to check default team * removed unnecessary else block --- .../LoginScreen/Components/PassCode.tsx | 14 +- .../LoginScreen/Components/UserTenants.tsx | 67 +++- .../hooks/features/useAuthenticationTeam.ts | 322 +++++++++--------- .../services/interfaces/IAuthentication.ts | 1 + 4 files changed, 236 insertions(+), 168 deletions(-) diff --git a/apps/mobile/app/screens/LoginScreen/Components/PassCode.tsx b/apps/mobile/app/screens/LoginScreen/Components/PassCode.tsx index 5d029f985..ec6968245 100644 --- a/apps/mobile/app/screens/LoginScreen/Components/PassCode.tsx +++ b/apps/mobile/app/screens/LoginScreen/Components/PassCode.tsx @@ -17,6 +17,7 @@ import { EMAIL_REGEX } from '../../../helpers/regex'; import UserTenants from './UserTenants'; import { IWorkspace, VerificationResponse } from '../../../services/interfaces/IAuthentication'; import { CodeInputField } from '../../../components/CodeField'; +import AsyncStorage from '@react-native-async-storage/async-storage'; interface Props { isLoading: boolean; @@ -29,6 +30,11 @@ interface Props { signInWorkspace: () => unknown; setIsWorkspaceScreen: React.Dispatch>; } +export type defaultUserInfoType = { + defaultUserId: string; + defaultUserTenantId: string; +}; + const { width } = Dimensions.get('window'); const PassCode: FC = observer( ({ @@ -55,8 +61,12 @@ const PassCode: FC = observer( step2: false, step3: false }); - const [selectedWorkspace, setSelectedWorkspace] = useState(0); + const [selectedWorkspace, setSelectedWorkspace] = useState(null); const [workspaceData, setWorkspaceData] = useState(null); + const [defaultUserInfo, setDefaultUserInfo] = useState({ + defaultUserId: '', + defaultUserTenantId: '' + }); const onNextStep = async () => { if (step === 'Email') { @@ -100,6 +110,7 @@ const PassCode: FC = observer( }, 1000); } if (step === 'Tenant') { + await AsyncStorage.setItem('defaultUserInfo', JSON.stringify(defaultUserInfo)); signInWorkspace(); } }; @@ -242,6 +253,7 @@ const PassCode: FC = observer( data={item} activeTeamId={activeTeamId} setActiveTeamId={setActiveTeamId} + setDefaultUserInfo={setDefaultUserInfo} selectedWorkspace={selectedWorkspace} setSelectedWorkspace={setSelectedWorkspace} isValid={isValid} diff --git a/apps/mobile/app/screens/LoginScreen/Components/UserTenants.tsx b/apps/mobile/app/screens/LoginScreen/Components/UserTenants.tsx index 8dff8703f..6db6cfc36 100644 --- a/apps/mobile/app/screens/LoginScreen/Components/UserTenants.tsx +++ b/apps/mobile/app/screens/LoginScreen/Components/UserTenants.tsx @@ -1,12 +1,14 @@ /* eslint-disable react-native/no-inline-styles */ /* eslint-disable react-native/no-color-literals */ /* eslint-disable react-native/no-unused-styles */ -import React, { FC } from 'react'; +import React, { FC, useEffect, useState } from 'react'; import { View, Text, StyleSheet, Image, FlatList } from 'react-native'; import { IWorkspace } from '../../../services/interfaces/IAuthentication'; import { SvgXml } from 'react-native-svg'; import { grayCircleIcon, greenCircleTickIcon } from '../../../components/svgs/icons'; import { useAppTheme } from '../../../theme'; +import AsyncStorage from '@react-native-async-storage/async-storage'; +import { defaultUserInfoType } from './PassCode'; interface IValid { step1: boolean; @@ -23,6 +25,7 @@ interface IUserTenants { isValid: IValid; setIsValid: React.Dispatch>; setTempAuthToken: (token: string) => void; + setDefaultUserInfo: React.Dispatch>; } const UserTenants: FC = ({ @@ -34,20 +37,67 @@ const UserTenants: FC = ({ selectedWorkspace, isValid, setIsValid, - setTempAuthToken + setTempAuthToken, + setDefaultUserInfo }) => { const { colors } = useAppTheme(); + + const [autoSetWorkspace, setAutoSetWorkspace] = useState(true); + + useEffect(() => { + const getDefaultTeamId = async () => { + try { + setAutoSetWorkspace(true); + const defaultTeamId = await AsyncStorage.getItem('defaultTeamId'); + const defaultUserInfoString = await AsyncStorage.getItem('defaultUserInfo'); + const defaultUserInfoObj: defaultUserInfoType = JSON.parse(defaultUserInfoString); + + if ( + defaultTeamId && + data?.user?.id === defaultUserInfoObj?.defaultUserId && + data?.user?.tenant?.id === defaultUserInfoObj?.defaultUserTenantId + ) { + setActiveTeamId(defaultTeamId); + } else { + index === 0 && setActiveTeamId(data?.current_teams[0]?.team_id); + } + + setIsValid({ ...isValid, step3: true }); + + setTempAuthToken(data?.token); + } catch (error) { + console.error(error); + } + }; + + getDefaultTeamId(); + }, [data.current_teams]); + + useEffect(() => { + if (autoSetWorkspace) { + const selectedIndex = data.current_teams.findIndex((team) => team.team_id === activeTeamId); + if (selectedIndex !== -1) { + setSelectedWorkspace(index); + } + } + }, [activeTeamId]); + return ( {data.user.tenant.name} { + autoSetWorkspace && setAutoSetWorkspace(false); + setDefaultUserInfo({ + defaultUserId: data?.user?.id, + defaultUserTenantId: data?.user?.tenant?.id + }); setSelectedWorkspace(index); - selectedWorkspace !== index && setActiveTeamId(data.current_teams[0].team_id); - data.current_teams.filter((team) => team.team_id === activeTeamId) && + selectedWorkspace !== index && setActiveTeamId(data?.current_teams[0].team_id); + data?.current_teams.filter((team) => team.team_id === activeTeamId) && setIsValid({ ...isValid, step3: true }); - setTempAuthToken(data.token); + setTempAuthToken(data?.token); }} > {selectedWorkspace === index ? ( @@ -74,10 +124,15 @@ const UserTenants: FC = ({ { + autoSetWorkspace && setAutoSetWorkspace(false); + setDefaultUserInfo({ + defaultUserId: data?.user?.id, + defaultUserTenantId: data?.user?.tenant?.id + }); setActiveTeamId(item.team_id); setSelectedWorkspace(index); setIsValid({ ...isValid, step3: true }); - setTempAuthToken(data.token); + setTempAuthToken(data?.token); }} > {activeTeamId === item.team_id ? ( diff --git a/apps/mobile/app/services/hooks/features/useAuthenticationTeam.ts b/apps/mobile/app/services/hooks/features/useAuthenticationTeam.ts index 48a5a92bb..e11505aea 100644 --- a/apps/mobile/app/services/hooks/features/useAuthenticationTeam.ts +++ b/apps/mobile/app/services/hooks/features/useAuthenticationTeam.ts @@ -1,30 +1,31 @@ -import { useCallback, useEffect, useRef, useState } from "react" -import { TextInput } from "react-native" -import { useStores } from "../../../models" -import { login } from "../../client/api/auth/login" -import { register } from "../../client/api/auth/register" -import sendAuthCode from "../../client/api/auth/sendAuthCode" +import { useCallback, useEffect, useRef, useState } from 'react'; +import { TextInput } from 'react-native'; +import { useStores } from '../../../models'; +import { login } from '../../client/api/auth/login'; +import { register } from '../../client/api/auth/register'; +import sendAuthCode from '../../client/api/auth/sendAuthCode'; import { resentVerifyUserLinkRequest, verifyAuthCodeRequest, - verifyUserEmailByCodeRequest, -} from "../../client/requests/auth" -import { useFirstLoad } from "../useFirstLoad" -import { signIn } from "../../client/api/auth/signin" -import { VerificationResponse } from "../../interfaces/IAuthentication" + verifyUserEmailByCodeRequest +} from '../../client/requests/auth'; +import { useFirstLoad } from '../useFirstLoad'; +import { signIn } from '../../client/api/auth/signin'; +import { VerificationResponse } from '../../interfaces/IAuthentication'; +import AsyncStorage from '@react-native-async-storage/async-storage'; export function useAuthenticationTeam() { - const authTeamInput = useRef() - const [isSubmitted, setIsSubmitted] = useState(false) - const [isLoading, setIsLoading] = useState(false) - const [joinError, setJoinError] = useState(null) - const [verificationError, setVerificationError] = useState(null) + const authTeamInput = useRef(); + const [isSubmitted, setIsSubmitted] = useState(false); + const [isLoading, setIsLoading] = useState(false); + const [joinError, setJoinError] = useState(null); + const [verificationError, setVerificationError] = useState(null); const [screenstatus, setScreenStatus] = useState<{ screen: number; animation: boolean }>({ screen: 1, - animation: false, - }) - const [withteam, setWithTeam] = useState(false) - const [attemptsCount, setAttemptsCount] = useState(0) + animation: false + }); + const [withteam, setWithTeam] = useState(false); + const [attemptsCount, setAttemptsCount] = useState(0); const { authenticationStore: { @@ -46,262 +47,261 @@ export function useAuthenticationTeam() { setUser, setTenantId, setEmployeeId, - setRefreshToken, + setRefreshToken }, - teamStore: { setActiveTeam, setActiveTeamId }, - } = useStores() + teamStore: { setActiveTeam, setActiveTeamId, activeTeamId } + } = useStores(); - const { firstLoadData } = useFirstLoad() + const { firstLoadData } = useFirstLoad(); - const errors: typeof validationErrors = isSubmitted ? validationErrors : ({} as any) + const errors: typeof validationErrors = isSubmitted ? validationErrors : ({} as any); const signInWorkspace = async ({ signinAuthToken }: { signinAuthToken?: string } = {}) => { - const token = signinAuthToken || tempAuthToken + const token = signinAuthToken || tempAuthToken; try { - setIsSubmitted(true) - setAttemptsCount(attemptsCount + 1) + setIsSubmitted(true); + setAttemptsCount(attemptsCount + 1); - setIsLoading(true) + setIsLoading(true); - const { response } = await signIn({ email: authEmail, token }) + const { response } = await signIn({ email: authEmail, token }); if (response) { - setUser(response.data.authStoreData.user) - setEmployeeId(response.data.authStoreData.user.employeeId) + setUser(response.data.authStoreData.user); + setEmployeeId(response.data.authStoreData.user.employeeId); // Save Auth Token - setTenantId(response.data.authStoreData.tenantId) - setOrganizationId(response.data.authStoreData.organizationId) - setAuthToken(response.data.authStoreData.access_token) - setRefreshToken(response.data.authStoreData.refresh_token) + setTenantId(response.data.authStoreData.tenantId); + setOrganizationId(response.data.authStoreData.organizationId); + setAuthToken(response.data.authStoreData.access_token); + setRefreshToken(response.data.authStoreData.refresh_token); + + await AsyncStorage.setItem('defaultTeamId', activeTeamId); // Reset all fields - setIsSubmitted(false) - setAuthTeamName("") - setAuthEmail("") - setAuthInviteCode("") - setAuthUsername("") - setAuthConfirmCode("") - setAuthTeamName("") - setAuthEmail("") - setAuthUsername("") - setAuthInviteCode("") - setAuthConfirmCode("") + setIsSubmitted(false); + setAuthTeamName(''); + setAuthEmail(''); + setAuthInviteCode(''); + setAuthUsername(''); + setAuthConfirmCode(''); + setAuthTeamName(''); + setAuthEmail(''); + setAuthUsername(''); + setAuthInviteCode(''); + setAuthConfirmCode(''); if (response.errors) { - setJoinError(response.errors.email) + setJoinError(response.errors.email); } } } catch (error) { - setIsSubmitted(false) - console.log(error) + setIsSubmitted(false); + console.log(error); } finally { - setIsLoading(false) + setIsLoading(false); } - } + }; /** * * Register or Create New Team */ const createNewTeam = async () => { - setIsSubmitted(true) - setAttemptsCount(attemptsCount + 1) + setIsSubmitted(true); + setAttemptsCount(attemptsCount + 1); - if (Object.values(validationErrors).some((v) => !!v)) return + if (Object.values(validationErrors).some((v) => !!v)) return; - setIsLoading(true) + setIsLoading(true); // Make a request to your server to get an authentication token. await register({ team: authTeamName, name: authUsername, - email: authEmail, + email: authEmail }) .then((res) => { - const { response } = res + const { response } = res; // If successful, reset the fields and set the token. if (response.status === 200) { - const data = response.data + const data = response.data; - const employee = data.employee - const loginRes = data.loginRes + const employee = data.employee; + const loginRes = data.loginRes; - setActiveTeamId(data.team.id) - setActiveTeam(data.team) - setOrganizationId(data.team.organizationId) - setUser(loginRes.user) - setTenantId(data.team.tenantId) - setEmployeeId(employee.id) + setActiveTeamId(data.team.id); + setActiveTeam(data.team); + setOrganizationId(data.team.organizationId); + setUser(loginRes.user); + setTenantId(data.team.tenantId); + setEmployeeId(employee.id); - firstLoadData() + firstLoadData(); // Save Auth Data // setTempAuthToken(loginRes.token) - setAuthToken(loginRes.token) - setRefreshToken(loginRes.refresh_token) + setAuthToken(loginRes.token); + setRefreshToken(loginRes.refresh_token); setScreenStatus({ screen: 3, - animation: true, - }) + animation: true + }); - setIsLoading(false) - setIsSubmitted(false) + setIsLoading(false); + setIsSubmitted(false); } }) .catch((e) => { - setIsLoading(false) - setIsSubmitted(false) - console.log(e) - }) - } + setIsLoading(false); + setIsSubmitted(false); + console.log(e); + }); + }; /** * Generate authentication code for login */ const getAuthCode = useCallback(async () => { - setIsSubmitted(true) - setIsLoading(true) + setIsSubmitted(true); + setIsLoading(true); await sendAuthCode(authEmail) .then((res) => { - res.status === 400 && setJoinError(res.error) + res.status === 400 && setJoinError(res.error); }) .catch((e) => { - console.log(e) - }) - setIsSubmitted(false) - setIsLoading(false) - }, [authEmail]) + console.log(e); + }); + setIsSubmitted(false); + setIsLoading(false); + }, [authEmail]); /** * Verify User Email by Verification Code */ const verifyEmailAndCodeOrAcceptInvite = async (): Promise => { - setIsLoading(true) - setJoinError("") + setIsLoading(true); + setJoinError(''); try { await login({ email: authEmail, code: authInviteCode }).then((res) => { - const { response, errors, status } = res + const { response, errors, status } = res; if (status === 200) { - const loginRes = response.data.authStoreData - const user = response.data.loginResponse.user - const noTeam = response.data.noTeam - setUser(user) - setEmployeeId(user.employee.id) - const team = response.data.team + const loginRes = response.data.authStoreData; + const user = response.data.loginResponse.user; + const noTeam = response.data.noTeam; + setUser(user); + setEmployeeId(user.employee.id); + const team = response.data.team; // Check if team is not null if (!noTeam) { - setActiveTeamId(team.id) - setActiveTeam(team) + setActiveTeamId(team.id); + setActiveTeam(team); } // Save Auth Token - setTenantId(user.tenantId) - setOrganizationId(user.employee.organizationId) - setAuthToken(loginRes.access_token) - setRefreshToken(loginRes.refresh_token.token) - setIsLoading(false) + setTenantId(user.tenantId); + setOrganizationId(user.employee.organizationId); + setAuthToken(loginRes.access_token); + setRefreshToken(loginRes.refresh_token.token); + setIsLoading(false); // Reset all fields - setIsSubmitted(false) - setAuthTeamName("") - setAuthEmail("") - setAuthInviteCode("") - setAuthUsername("") - setAuthConfirmCode("") - setAuthTeamName("") - setAuthEmail("") - setAuthUsername("") - setAuthInviteCode("") - setAuthConfirmCode("") + setIsSubmitted(false); + setAuthTeamName(''); + setAuthEmail(''); + setAuthInviteCode(''); + setAuthUsername(''); + setAuthConfirmCode(''); + setAuthTeamName(''); + setAuthEmail(''); + setAuthUsername(''); + setAuthInviteCode(''); + setAuthConfirmCode(''); } else { if (errors) { - setJoinError(errors.email) - setIsLoading(false) - setIsSubmitted(false) + setJoinError(errors.email); + setIsLoading(false); + setIsSubmitted(false); } } - }) + }); return { success: false, - data: null, - } + data: null + }; } catch (error) { - const response = await verifyAuthCodeRequest(authEmail, authInviteCode) + const response = await verifyAuthCodeRequest(authEmail, authInviteCode); - setIsLoading(false) + setIsLoading(false); return { response: response.response.status, success: response.response.status === 201, data: response.data, - error: - response.response.status === 401 - ? "Authentication code or email address invalid" - : null, - } + error: response.response.status === 401 ? 'Authentication code or email address invalid' : null + }; } - } + }; const verifyEmailByCode = async () => { - setIsLoading(true) + setIsLoading(true); await verifyUserEmailByCodeRequest({ bearer_token: tempAuthToken, code: authConfirmCode, email: authEmail, - tenantId, + tenantId }) .then((res) => { - const { data } = res + const { data } = res; if (data.status === 400) { - setVerificationError(data.message) - return + setVerificationError(data.message); + return; } if (data.status === 200) { - setAuthToken(tempAuthToken) - setAuthTeamName("") - setAuthEmail("") - setAuthUsername("") - setAuthInviteCode("") - setAuthConfirmCode("") + setAuthToken(tempAuthToken); + setAuthTeamName(''); + setAuthEmail(''); + setAuthUsername(''); + setAuthInviteCode(''); + setAuthConfirmCode(''); } - setIsLoading(false) + setIsLoading(false); }) .catch((e) => { - setIsLoading(false) - console.log(e) - }) - } + setIsLoading(false); + console.log(e); + }); + }; /** * Resend Email Verification Code */ const resendEmailVerificationCode = async () => { - setIsLoading(true) + setIsLoading(true); await resentVerifyUserLinkRequest({ bearer_token: tempAuthToken, email: authEmail, - tenantId, - }) - setIsLoading(false) - } + tenantId + }); + setIsLoading(false); + }; useEffect(() => { return () => { - setIsSubmitted(false) - setAuthTeamName("") - setAuthEmail("") - setAuthUsername("") - setAuthInviteCode("") - setAuthConfirmCode("") - setVerificationError(null) - setJoinError(null) - } - }, []) + setIsSubmitted(false); + setAuthTeamName(''); + setAuthEmail(''); + setAuthUsername(''); + setAuthInviteCode(''); + setAuthConfirmCode(''); + setVerificationError(null); + setJoinError(null); + }; + }, []); return { resendEmailVerificationCode, @@ -319,6 +319,6 @@ export function useAuthenticationTeam() { screenstatus, setScreenStatus, authTeamInput, - signInWorkspace, - } + signInWorkspace + }; } diff --git a/apps/mobile/app/services/interfaces/IAuthentication.ts b/apps/mobile/app/services/interfaces/IAuthentication.ts index f78d0355a..d3ab4e204 100644 --- a/apps/mobile/app/services/interfaces/IAuthentication.ts +++ b/apps/mobile/app/services/interfaces/IAuthentication.ts @@ -30,6 +30,7 @@ export interface IWorkspace { interface IUserMultiTenant { email: string; name: string; + id: string; imageUrl: string; tenant: ITenant; } From 1cb6fc83b28f10bbff43a6c70e180e4d1f09ec70 Mon Sep 17 00:00:00 2001 From: desperado1802 Date: Wed, 22 Nov 2023 12:04:03 +0200 Subject: [PATCH 09/13] fixed java errors with style types --- .../Task/DetailsBlock/blocks/TaskMainInfo.tsx | 201 ++++++-------- apps/mobile/app/components/TaskLabels.tsx | 261 ++++++++---------- .../components/UserProfileTasks.tsx | 4 +- 3 files changed, 210 insertions(+), 256 deletions(-) diff --git a/apps/mobile/app/components/Task/DetailsBlock/blocks/TaskMainInfo.tsx b/apps/mobile/app/components/Task/DetailsBlock/blocks/TaskMainInfo.tsx index 2261c9811..107dafe59 100644 --- a/apps/mobile/app/components/Task/DetailsBlock/blocks/TaskMainInfo.tsx +++ b/apps/mobile/app/components/Task/DetailsBlock/blocks/TaskMainInfo.tsx @@ -1,47 +1,41 @@ /* eslint-disable react-native/no-inline-styles */ /* eslint-disable react-native/no-color-literals */ -import { View, Text, StyleSheet } from "react-native" -import React from "react" -import { useStores } from "../../../../models" -import TaskRow from "../components/TaskRow" -import { SvgXml } from "react-native-svg" -import { - calendarIcon, - categoryIcon, - clipboardIcon, - peopleIconSmall, - profileIcon, -} from "../../../svgs/icons" -import ProfileInfo from "../components/ProfileInfo" -import ManageAssignees from "../components/ManageAssignees" -import { useOrganizationTeam } from "../../../../services/hooks/useOrganization" -import CalendarModal from "../components/CalendarModal" -import { useTeamTasks } from "../../../../services/hooks/features/useTeamTasks" -import moment from "moment-timezone" -import TaskStatus from "../../../TaskStatus" -import TaskSize from "../../../TaskSize" -import TaskPriority from "../../../TaskPriority" -import TaskLabels from "../../../TaskLabels" -import TaskVersion from "../../../TaskVersion" -import { useAppTheme } from "../../../../theme" -import { ITeamTask } from "../../../../services/interfaces/ITask" -import { TouchableOpacity } from "react-native-gesture-handler" -import { useNavigation } from "@react-navigation/native" -import { SettingScreenNavigationProp } from "../../../../navigators/AuthenticatedNavigator" -import TaskEpic from "../../../TaskEpic" -import IssuesModal from "../../../IssuesModal" -import { observer } from "mobx-react-lite" -import { translate } from "../../../../i18n" +import { View, Text, StyleSheet } from 'react-native'; +import React from 'react'; +import { useStores } from '../../../../models'; +import TaskRow from '../components/TaskRow'; +import { SvgXml } from 'react-native-svg'; +import { calendarIcon, categoryIcon, clipboardIcon, peopleIconSmall, profileIcon } from '../../../svgs/icons'; +import ProfileInfo from '../components/ProfileInfo'; +import ManageAssignees from '../components/ManageAssignees'; +import { useOrganizationTeam } from '../../../../services/hooks/useOrganization'; +import CalendarModal from '../components/CalendarModal'; +import { useTeamTasks } from '../../../../services/hooks/features/useTeamTasks'; +import moment from 'moment-timezone'; +import TaskStatus from '../../../TaskStatus'; +import TaskSize from '../../../TaskSize'; +import TaskPriority from '../../../TaskPriority'; +import TaskLabels from '../../../TaskLabels'; +import TaskVersion from '../../../TaskVersion'; +import { useAppTheme } from '../../../../theme'; +import { ITeamTask } from '../../../../services/interfaces/ITask'; +import { TouchableOpacity } from 'react-native-gesture-handler'; +import { useNavigation } from '@react-navigation/native'; +import { SettingScreenNavigationProp } from '../../../../navigators/AuthenticatedNavigator'; +import TaskEpic from '../../../TaskEpic'; +import IssuesModal from '../../../IssuesModal'; +import { observer } from 'mobx-react-lite'; +import { translate } from '../../../../i18n'; const TaskMainInfo = observer(() => { const { - TaskStore: { detailedTask: task }, - } = useStores() + TaskStore: { detailedTask: task } + } = useStores(); - const { currentTeam } = useOrganizationTeam() - const { updateTask } = useTeamTasks() + const { currentTeam } = useOrganizationTeam(); + const { updateTask } = useTeamTasks(); - const { colors } = useAppTheme() + const { colors } = useAppTheme(); return ( @@ -50,9 +44,7 @@ const TaskMainInfo = observer(() => { labelComponent={ - - {translate("taskDetailsScreen.typeIssue")} - + {translate('taskDetailsScreen.typeIssue')} } > @@ -63,16 +55,14 @@ const TaskMainInfo = observer(() => { labelComponent={ - - {translate("taskDetailsScreen.creator")} - + {translate('taskDetailsScreen.creator')} } > {/* Assignees */} @@ -80,9 +70,7 @@ const TaskMainInfo = observer(() => { labelComponent={ - - {translate("taskDetailsScreen.assignees")} - + {translate('taskDetailsScreen.assignees')} } > @@ -91,7 +79,7 @@ const TaskMainInfo = observer(() => { key={index} userId={member?.userId || member?.user?.id} profilePicSrc={member?.user?.imageUrl} - names={`${member?.user?.firstName || ""} ${member?.user?.lastName || ""}`} + names={`${member?.user?.firstName || ''} ${member?.user?.lastName || ''}`} /> ))} @@ -104,9 +92,7 @@ const TaskMainInfo = observer(() => { labelComponent={ - - {translate("taskDetailsScreen.startDate")} - + {translate('taskDetailsScreen.startDate')} } > @@ -120,9 +106,7 @@ const TaskMainInfo = observer(() => { - - {translate("taskDetailsScreen.dueDate")} - + {translate('taskDetailsScreen.dueDate')} } > @@ -138,16 +122,14 @@ const TaskMainInfo = observer(() => { - - {translate("taskDetailsScreen.daysRemaining")} - + {translate('taskDetailsScreen.daysRemaining')} } > - - {moment(task?.dueDate).diff(moment(), "days") < 0 + + {moment(task?.dueDate).diff(moment(), 'days') < 0 ? 0 - : moment(task?.dueDate).diff(moment(), "days")} + : moment(task?.dueDate).diff(moment(), 'days')} )} @@ -160,38 +142,34 @@ const TaskMainInfo = observer(() => { alignItems={true} labelComponent={ - - {translate("taskDetailsScreen.version")} - + {translate('taskDetailsScreen.version')} } > {/* Epic */} - {task && task.issueType === "Story" && ( + {task && task.issueType === 'Story' && ( - - {translate("taskDetailsScreen.epic")} - + {translate('taskDetailsScreen.epic')} } > @@ -203,18 +181,16 @@ const TaskMainInfo = observer(() => { alignItems={true} labelComponent={ - - {translate("taskDetailsScreen.status")} - + {translate('taskDetailsScreen.status')} } > @@ -223,9 +199,7 @@ const TaskMainInfo = observer(() => { - - {translate("taskDetailsScreen.labels")} - + {translate('taskDetailsScreen.labels')} } > @@ -234,9 +208,9 @@ const TaskMainInfo = observer(() => { taskScreenButton={true} noBorders={true} containerStyle={{ - width: "70%", + width: '70%', borderRadius: 3, - marginVertical: task?.tags.length ? 20 : 0, + marginVertical: task?.tags.length ? 20 : 0 }} /> @@ -246,16 +220,16 @@ const TaskMainInfo = observer(() => { alignItems={true} labelComponent={ - {translate("taskDetailsScreen.size")} + {translate('taskDetailsScreen.size')} } > @@ -265,46 +239,43 @@ const TaskMainInfo = observer(() => { alignItems={true} labelComponent={ - - {translate("taskDetailsScreen.priority")} - + {translate('taskDetailsScreen.priority')} } > - ) -}) + ); +}); -export default TaskMainInfo +export default TaskMainInfo; const EpicParent: React.FC<{ task: ITeamTask }> = ({ task }) => { - const { colors } = useAppTheme() + const { colors } = useAppTheme(); - const navigation = useNavigation>() + const navigation = useNavigation>(); const navigateToEpic = () => { - navigation.navigate("TaskScreen", { taskId: task?.rootEpic?.id }) - } + navigation.navigate('TaskScreen', { taskId: task?.rootEpic?.id }); + }; - if (task?.issueType === "Story") { - return <> + if (task?.issueType === 'Story') { + return <>; } - return (!task?.issueType || task?.issueType === "Task" || task?.issueType === "Bug") && - task?.rootEpic ? ( + return (!task?.issueType || task?.issueType === 'Task' || task?.issueType === 'Bug') && task?.rootEpic ? ( - {translate("taskDetailsScreen.epic")} + {translate('taskDetailsScreen.epic')} } > @@ -321,30 +292,30 @@ const EpicParent: React.FC<{ task: ITeamTask }> = ({ task }) => { ) : ( <> - ) -} + ); +}; const styles = StyleSheet.create({ - epicParentButton: { alignItems: "center", flexDirection: "row", gap: 4, width: "60%" }, + epicParentButton: { alignItems: 'center', flexDirection: 'row', gap: 4, width: '60%' }, epicParentIconWrapper: { - backgroundColor: "#8154BA", + backgroundColor: '#8154BA', borderRadius: 4, marginVertical: 5, - padding: 4, + padding: 4 }, horizontalSeparator: { - borderBottomColor: "#F2F2F2", + borderBottomColor: '#F2F2F2', borderBottomWidth: 1, marginVertical: 10, - width: "100%", + width: '100%' }, labelComponent: { - alignItems: "center", - flexDirection: "row", - gap: 7, + alignItems: 'center', + flexDirection: 'row', + gap: 7 }, labelText: { - color: "#A5A2B2", - fontSize: 12, - }, -}) + color: '#A5A2B2', + fontSize: 12 + } +}); diff --git a/apps/mobile/app/components/TaskLabels.tsx b/apps/mobile/app/components/TaskLabels.tsx index 374d05265..8ae0c8d01 100644 --- a/apps/mobile/app/components/TaskLabels.tsx +++ b/apps/mobile/app/components/TaskLabels.tsx @@ -1,134 +1,121 @@ /* eslint-disable react-native/no-color-literals */ /* eslint-disable react-native/no-inline-styles */ -import React, { FC, useEffect, useRef, useState } from "react" -import { - TouchableOpacity, - View, - Text, - StyleSheet, - ViewStyle, - FlatList, - Dimensions, -} from "react-native" -import { AntDesign, Entypo } from "@expo/vector-icons" -import { observer } from "mobx-react-lite" -import { ITeamTask } from "../services/interfaces/ITask" -import { useTeamTasks } from "../services/hooks/features/useTeamTasks" -import { useAppTheme, typography } from "../theme" -import TaskLabelPopup from "./TaskLabelPopup" -import { ITaskLabelItem } from "../services/interfaces/ITaskLabel" -import { translate } from "../i18n" -import { limitTextCharaters } from "../helpers/sub-text" -import { SvgUri } from "react-native-svg" -import { isEqual } from "lodash" +import React, { FC, useEffect, useRef, useState } from 'react'; +import { TouchableOpacity, View, Text, StyleSheet, ViewStyle, FlatList, Dimensions } from 'react-native'; +import { AntDesign, Entypo } from '@expo/vector-icons'; +import { observer } from 'mobx-react-lite'; +import { ITeamTask } from '../services/interfaces/ITask'; +import { useTeamTasks } from '../services/hooks/features/useTeamTasks'; +import { useAppTheme, typography } from '../theme'; +import TaskLabelPopup from './TaskLabelPopup'; +import { ITaskLabelItem } from '../services/interfaces/ITaskLabel'; +import { translate } from '../i18n'; +import { limitTextCharaters } from '../helpers/sub-text'; +import { SvgUri } from 'react-native-svg'; +import { isEqual } from 'lodash'; interface TaskLabelProps { - task?: ITeamTask - containerStyle?: ViewStyle - labels?: string - setLabels?: (label: ITaskLabelItem[]) => unknown - newTaskLabels?: ITaskLabelItem[] | undefined - taskScreenButton?: boolean - noBorders?: boolean + task?: ITeamTask; + containerStyle?: ViewStyle; + labels?: string; + setLabels?: (label: ITaskLabelItem[]) => unknown; + newTaskLabels?: ITaskLabelItem[] | undefined; + taskScreenButton?: boolean; + noBorders?: boolean; } interface IndividualTaskLabel { - color: string - createdAt: string - description: string | null - fullIconUrl: string - icon: string - id: string - isSystem: boolean - name: string - organizationId: string - organizationTeamId: string - tenantId: string - updatedAt: string + color: string; + createdAt: string; + description: string | null; + fullIconUrl: string; + icon: string; + id: string; + isSystem: boolean; + name: string; + organizationId: string; + organizationTeamId: string; + tenantId: string; + updatedAt: string; } const TaskLabels: FC = observer( ({ task, setLabels, newTaskLabels, taskScreenButton, noBorders, containerStyle }) => { - const { colors, dark } = useAppTheme() - const { updateTask } = useTeamTasks() - const [openModal, setOpenModal] = useState(false) - const flatListRef = useRef(null) - const [labelIndex, setLabelIndex] = useState(0) - const [tempLabels, setTempLabels] = useState( - task?.tags || newTaskLabels || [], - ) - const [arrayChanged, setArrayChanged] = useState(false) + const { colors, dark } = useAppTheme(); + const { updateTask } = useTeamTasks(); + const [openModal, setOpenModal] = useState(false); + const flatListRef = useRef(null); + const [labelIndex, setLabelIndex] = useState(0); + const [tempLabels, setTempLabels] = useState(task?.tags || newTaskLabels || []); + const [arrayChanged, setArrayChanged] = useState(false); const freshOpenModal = () => { - setOpenModal(true) - setTempLabels(task?.tags || newTaskLabels || []) - arraysHaveSameValues(tempLabels, task?.tags || newTaskLabels || []) - } + setOpenModal(true); + setTempLabels(task?.tags || newTaskLabels || []); + arraysHaveSameValues(tempLabels, task?.tags || newTaskLabels || []); + }; const saveLabels = async () => { if (task) { const taskEdit = { ...task, - tags: tempLabels, - } - await updateTask(taskEdit, task.id) + tags: tempLabels + }; + await updateTask(taskEdit, task.id); } else { - setLabels(tempLabels) + setLabels(tempLabels); } - setOpenModal(false) - } + setOpenModal(false); + }; const addOrRemoveLabelsInTempArray = (tag: ITaskLabelItem): void => { - const exist = tempLabels.find((label) => label.id === tag.id) + const exist = tempLabels.find((label) => label.id === tag.id); if (exist) { - setTempLabels(tempLabels.filter((label) => label.id !== tag.id)) + setTempLabels(tempLabels.filter((label) => label.id !== tag.id)); } else { - setTempLabels([...tempLabels, tag]) + setTempLabels([...tempLabels, tag]); } - } + }; - const arraysHaveSameValues = ( - array1: ITaskLabelItem[] | [], - array2: ITaskLabelItem[] | [], - ): void => { - const sortedArray1 = array1.slice().sort((a, b) => a.id.localeCompare(b.id)) - const sortedArray2 = array2.slice().sort((a, b) => a.id.localeCompare(b.id)) + const arraysHaveSameValues = (array1: ITaskLabelItem[] | [], array2: ITaskLabelItem[] | []): void => { + const sortedArray1 = array1.slice().sort((a, b) => a.id.localeCompare(b.id)); + const sortedArray2 = array2.slice().sort((a, b) => a.id.localeCompare(b.id)); - const areArraysEqual = isEqual(sortedArray1, sortedArray2) + const areArraysEqual = isEqual(sortedArray1, sortedArray2); - setArrayChanged(!areArraysEqual) - } + setArrayChanged(!areArraysEqual); + }; useEffect(() => { - arraysHaveSameValues(tempLabels, task?.tags || newTaskLabels || []) - }, [tempLabels]) + arraysHaveSameValues(tempLabels, task?.tags || newTaskLabels || []); + }, [tempLabels]); const scrollToIndexWithDelay = (index: number) => { flatListRef.current?.scrollToIndex({ animated: true, index: index < 0 ? 0 : index, - viewPosition: 0, - }) - } + viewPosition: 0 + }); + }; const onNextPressed = () => { if (labelIndex !== task?.tags?.length - 2) { - scrollToIndexWithDelay(labelIndex + 1) + scrollToIndexWithDelay(labelIndex + 1); } - } + }; const onPrevPressed = () => { if (labelIndex > 0) { - const newIndex = labelIndex - 2 - scrollToIndexWithDelay(newIndex) + const newIndex = labelIndex - 2; + scrollToIndexWithDelay(newIndex); } - } + }; const handleScrollEnd = (event: any) => { - const offsetX = event.nativeEvent.contentOffset.x - const currentIndex = Math.round(offsetX / 100) // Assuming 100 is the item width - setLabelIndex(currentIndex) - } + const offsetX = event.nativeEvent.contentOffset.x; + const currentIndex = Math.round(offsetX / 100); // Assuming 100 is the item width + setLabelIndex(currentIndex); + }; return ( <> @@ -148,14 +135,12 @@ const TaskLabels: FC = observer( ( - - )} + renderItem={({ item }) => } horizontal={true} keyExtractor={(_, index) => index.toString()} showsHorizontalScrollIndicator={false} ItemSeparatorComponent={() => ( - + )} onMomentumScrollEnd={handleScrollEnd} /> @@ -167,9 +152,9 @@ const TaskLabels: FC = observer( style={[ styles.scrollButtons, { - backgroundColor: dark ? "#1e2430" : colors.background, - right: 0, - }, + backgroundColor: dark ? '#1e2430' : colors.background, + right: 0 + } ]} onPress={() => onNextPressed()} > @@ -183,8 +168,8 @@ const TaskLabels: FC = observer( styles.scrollButtons, { left: 0, - backgroundColor: dark ? "#1e2430" : colors.background, - }, + backgroundColor: dark ? '#1e2430' : colors.background + } ]} onPress={() => onPrevPressed()} > @@ -204,7 +189,7 @@ const TaskLabels: FC = observer( borderColor: colors.border, borderWidth: 1, marginTop: 0, - marginBottom: 15, + marginBottom: 15 }} > @@ -213,10 +198,10 @@ const TaskLabels: FC = observer( style={{ ...styles.text, color: colors.primary, - marginLeft: 5, + marginLeft: 5 }} > - {translate("taskDetailsScreen.items")} ({task?.tags.length}) + {translate('taskDetailsScreen.items')} ({task?.tags.length}) @@ -251,16 +236,14 @@ const TaskLabels: FC = observer( ...styles.container, ...containerStyle, borderColor: colors.border, - borderWidth: 1, + borderWidth: 1 }} > - + - {translate("settingScreen.labelScreen.labels")} + {translate('settingScreen.labelScreen.labels')} @@ -269,96 +252,96 @@ const TaskLabels: FC = observer( )} - ) - }, -) + ); + } +); interface ILabel { - item: IndividualTaskLabel | null - freshOpenModal: () => void - taskScreenButton?: boolean - noBorders?: boolean + item: IndividualTaskLabel | null; + freshOpenModal: () => void; + taskScreenButton?: boolean; + noBorders?: boolean; } const Label: FC = ({ item, freshOpenModal, taskScreenButton, noBorders }) => { - const { colors } = useAppTheme() + const { colors } = useAppTheme(); - const { width } = Dimensions.get("screen") + const { width } = Dimensions.get('screen'); return ( {limitTextCharaters({ text: item?.name, - numChars: taskScreenButton && width > 420 ? 15 : 12, + numChars: taskScreenButton && width > 420 ? 15 : 12 })} - ) -} + ); +}; const styles = StyleSheet.create({ container: { - alignItems: "center", + alignItems: 'center', borderRadius: 10, borderWidth: 1, - flexDirection: "row", + flexDirection: 'row', height: 32, - justifyContent: "space-between", + justifyContent: 'space-between', marginVertical: 20, paddingHorizontal: 12, paddingVertical: 7, - width: 160, + width: 160 }, scrollButtons: { - alignItems: "center", - backgroundColor: "#fff", + alignItems: 'center', + backgroundColor: '#fff', borderRadius: 20, bottom: 23, elevation: 10, height: 27, - justifyContent: "center", + justifyContent: 'center', padding: 5, - position: "absolute", - shadowColor: "rgba(0,0,0,0.16)", + position: 'absolute', + shadowColor: 'rgba(0,0,0,0.16)', shadowOffset: { width: 0, height: 5 }, shadowOpacity: 1, shadowRadius: 15, - width: 28, + width: 28 }, text: { fontFamily: typography.fonts.PlusJakartaSans.semiBold, - fontSize: 10, + fontSize: 10 }, wrapStatus: { - alignItems: "center", - flexDirection: "row", - width: "70%", - }, -}) + alignItems: 'center', + flexDirection: 'row', + width: '70%' + } +}); -export default TaskLabels +export default TaskLabels; diff --git a/apps/mobile/app/screens/Authenticated/ProfileScreen/components/UserProfileTasks.tsx b/apps/mobile/app/screens/Authenticated/ProfileScreen/components/UserProfileTasks.tsx index aea3e2065..ac2e127c0 100644 --- a/apps/mobile/app/screens/Authenticated/ProfileScreen/components/UserProfileTasks.tsx +++ b/apps/mobile/app/screens/Authenticated/ProfileScreen/components/UserProfileTasks.tsx @@ -163,7 +163,7 @@ const UserProfileTasks: FC = observer(({ profile, content }) style={{ ...GS.mb4, marginHorizontal: 10, - marginTop: index === 0 && 20 + marginTop: index === 0 ? 20 : undefined }} > = observer(({ profile, content }) style={{ ...GS.mb4, marginHorizontal: 10, - marginTop: index === 0 && 20 + marginTop: index === 0 ? 20 : undefined }} > Date: Wed, 22 Nov 2023 14:35:36 +0200 Subject: [PATCH 10/13] Improve/danger zone section (#1848) * [web] refactor: change danger button text and remove all color * refactor(web): [danger-zone] change the text button content and "add delete all data" button * refactor(web): [danger-zone] add image description for danger-zone * fix: spelling --- .cspell.json | 1 + .../components/UserRemoveAccount.tsx | 6 +- .../web/lib/settings/danger-zone-personal.tsx | 142 +++++++++++------- apps/web/public/assets/svg/danger-zones.svg | 21 +++ apps/web/public/locales/ar/common.json | 5 +- apps/web/public/locales/bg/common.json | 5 +- apps/web/public/locales/de/common.json | 5 +- apps/web/public/locales/en/common.json | 13 +- apps/web/public/locales/es/common.json | 6 +- apps/web/public/locales/fr/common.json | 6 +- apps/web/public/locales/he/common.json | 1 + apps/web/public/locales/it/common.json | 7 +- apps/web/public/locales/nl/common.json | 1 + apps/web/public/locales/pl/common.json | 7 +- apps/web/public/locales/pt/common.json | 7 +- apps/web/public/locales/ru/common.json | 5 +- apps/web/public/locales/zh/common.json | 1 + 17 files changed, 162 insertions(+), 77 deletions(-) create mode 100644 apps/web/public/assets/svg/danger-zones.svg diff --git a/.cspell.json b/.cspell.json index 99ffbdb42..42b1aa603 100644 --- a/.cspell.json +++ b/.cspell.json @@ -5,6 +5,7 @@ "$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json", "words": [ "appdev", + "signin", "APPSTORE", "barcodes", "binutils", diff --git a/apps/mobile/app/screens/Authenticated/SettingScreen/components/UserRemoveAccount.tsx b/apps/mobile/app/screens/Authenticated/SettingScreen/components/UserRemoveAccount.tsx index ec11864a9..4b34ed9cd 100644 --- a/apps/mobile/app/screens/Authenticated/SettingScreen/components/UserRemoveAccount.tsx +++ b/apps/mobile/app/screens/Authenticated/SettingScreen/components/UserRemoveAccount.tsx @@ -1,10 +1,10 @@ /* eslint-disable react-native/no-color-literals */ /* eslint-disable react-native/no-inline-styles */ -import { View, Text, Image, TouchableOpacity, StyleSheet, TouchableWithoutFeedback } from 'react-native'; import React, { useCallback } from 'react'; -import { useOrganizationTeam } from '../../../../services/hooks/useOrganization'; -import { useUser } from '../../../../services/hooks/features/useUser'; +import { Image, StyleSheet, Text, TouchableOpacity, TouchableWithoutFeedback, View } from 'react-native'; import { translate } from '../../../../i18n'; +import { useUser } from '../../../../services/hooks/features/useUser'; +import { useOrganizationTeam } from '../../../../services/hooks/useOrganization'; import { typography, useAppTheme } from '../../../../theme'; const UserRemoveAccount = ({ diff --git a/apps/web/lib/settings/danger-zone-personal.tsx b/apps/web/lib/settings/danger-zone-personal.tsx index b77104410..05e01a013 100644 --- a/apps/web/lib/settings/danger-zone-personal.tsx +++ b/apps/web/lib/settings/danger-zone-personal.tsx @@ -1,76 +1,116 @@ /* eslint-disable no-mixed-spaces-and-tabs */ import { useAuthenticateUser, useModal, useOrganizationTeams, useUser } from '@app/hooks'; import { Button, Text } from 'lib/components'; +import Image from 'next/image'; import { useCallback, useState } from 'react'; import { useTranslation } from 'react-i18next'; +import dangerZoneImage from '../../public/assets/svg/danger-zones.svg'; import { RemoveModal } from './remove-modal'; +type RemoveModalType = 'REMOVE' | 'DELETE' | 'DELETE_ALL' | string; +type ActionFunction = () => void; export const DangerZone = () => { const { t } = useTranslation(); const { isOpen, closeModal, openModal } = useModal(); - const [removeModalType, setRemoveModalType] = useState<'REMOVE' | 'DELETE' | null>(null); + const [removeModalType, setRemoveModalType] = useState(''); const { deleteUser, deleteUserLoading } = useUser(); const { user } = useAuthenticateUser(); - const { removeUserFromAllTeam, removeUserFromAllTeamLoading } = useOrganizationTeams(); + const { removeUserFromAllTeam, removeUserFromAllTeamLoading } = useOrganizationTeams(); const handleRemoveUser = useCallback(() => { if (user) { return removeUserFromAllTeam(user.id); } }, [user, removeUserFromAllTeam]); + const handleDeleteAllUserData = useCallback(() => { + console.log(user); + }, [user]); + + const actionTypes: Record = { + DELETE: deleteUser, + DELETE_ALL: handleDeleteAllUserData, + REMOVE: handleRemoveUser + }; + const modalMessages: Record = { + REMOVE: t('pages.settingsPersonal.ABOUT_TO_REMOVE_FROM_ALL_TEAMS'), + DELETE: t('pages.settingsPersonal.ABOUT_TO_DELETE_ACCOUNT'), + DELETE_ALL: t('pages.settingsPersonal.ABOUT_TO_DELETE_ALL_ACCOUNT_DATA') + }; + const messageToShow = modalMessages[removeModalType] || ''; + const onAction = actionTypes[removeModalType] || handleRemoveUser; + return ( <>
-
-
- {t('common.REMOVE_ACCOUNT')} -
-
- - {t('alerts.ALERT_DELETE_ACCOUNT')} - -
-
- -
-
-
-
- - {t('common.REMOVE_ACCOUNT')} - -
-
- - {t('alerts.ALERT_ACCOUNT_PERMANENT_DELETE')} - +
+
+ Danger zone
-
- +
+
+
+ + {t('alerts.ALERT_DELETE_ACCOUNT')} + +
+
+ +
+
+
+
+ + {t('alerts.ALERT_ACCOUNT_PERMANENT_DELETE')} + +
+
+ +
+
+
+
+ + {t('alerts.ALERT_REMOVE_ALL_DATA')} + +
+
+ +
+
@@ -79,12 +119,8 @@ export const DangerZone = () => {
diff --git a/apps/web/public/assets/svg/danger-zones.svg b/apps/web/public/assets/svg/danger-zones.svg new file mode 100644 index 000000000..ad02e5fb5 --- /dev/null +++ b/apps/web/public/assets/svg/danger-zones.svg @@ -0,0 +1,21 @@ + + + + + + + + + diff --git a/apps/web/public/locales/ar/common.json b/apps/web/public/locales/ar/common.json index ecaf836fb..25723e096 100644 --- a/apps/web/public/locales/ar/common.json +++ b/apps/web/public/locales/ar/common.json @@ -176,6 +176,7 @@ "ALERT_DELETE_ACCOUNT": "سيتم إزالة الحساب من جميع الفرق، باستثناء حيث أنت المدير فقط", "ALERT_ACCOUNT_PERMANENT_DELETE": "سيتم حذف حسابك نهائياً مع إزالته من جميع الفرق", "ALERT_REMOVE_TEAM": "سيتم إزالة الفريق بالكامل من النظام وفقدان أعضاء الفريق للوصول", + "ALERT_REMOVE_ALL_DATA": "All Account Data will be removed from all teams where you are ONLY one existed manager", "ALERT_QUIT_TEAM": "أنت على وشك مغادرة الفريق" }, "pages": { @@ -284,7 +285,9 @@ "TIMEZONE_SEARCH_PLACEHOLDER": "المنطقة الزمنية الخاصة بك", "ABOUT_TO_CHANGE_EMAIL": "أنت على وشك تغيير البريد الإلكتروني", "ABOUT_TO_DELETE_ACCOUNT": "أنت على وشك حذف حسابك؟", - "ABOUT_TO_REMOVE_ACCOUNT": "أنت على وشك إزالة حسابك؟" + "ABOUT_TO_REMOVE_ACCOUNT": "أنت على وشك إزالة حسابك؟", + "ABOUT_TO_REMOVE_FROM_ALL_TEAMS": "You're about to be removed from all teams, unless you're the only manager ?", + "ABOUT_TO_DELETE_ALL_ACCOUNT_DATA": "You are about to Delete your account and all your data ?" }, "settingsTeam": { diff --git a/apps/web/public/locales/bg/common.json b/apps/web/public/locales/bg/common.json index da3a7b939..f58bf56a2 100644 --- a/apps/web/public/locales/bg/common.json +++ b/apps/web/public/locales/bg/common.json @@ -174,6 +174,7 @@ "ALERT_DELETE_ACCOUNT": "Профилът ще бъде премахнат от всички отбори, освен където сте само мениджър", "ALERT_ACCOUNT_PERMANENT_DELETE": "Вашият профил ще бъде изтрит завинаги с премахване от всички отбори", "ALERT_REMOVE_TEAM": "Отборът ще бъде премахнат напълно от системата и членовете на отбора ще загубят достъп", + "ALERT_REMOVE_ALL_DATA": "All Account Data will be removed from all teams where you are ONLY one existed manager", "ALERT_QUIT_TEAM": "Ще напуснете отбора" }, "pages": { @@ -283,7 +284,9 @@ "TIMEZONE_SEARCH_PLACEHOLDER": "Вашата часова зона", "ABOUT_TO_CHANGE_EMAIL": "Ще промените имейл", "ABOUT_TO_DELETE_ACCOUNT": "Ще изтриете профила си?", - "ABOUT_TO_REMOVE_ACCOUNT": "Ще премахнете профила си?" + "ABOUT_TO_REMOVE_ACCOUNT": "Ще премахнете профила си?", + "ABOUT_TO_REMOVE_FROM_ALL_TEAMS": "You're about to be removed from all teams, unless you're the only manager ?", + "ABOUT_TO_DELETE_ALL_ACCOUNT_DATA": "You are about to Delete your account and all your data ?" }, "settingsTeam": { "HEADING_TITLE": "Основни настройки", diff --git a/apps/web/public/locales/de/common.json b/apps/web/public/locales/de/common.json index bbe492d42..69b0753e0 100644 --- a/apps/web/public/locales/de/common.json +++ b/apps/web/public/locales/de/common.json @@ -176,6 +176,7 @@ "ALERT_DELETE_ACCOUNT": "Das Konto wird von allen Teams entfernt, außer wo Sie nur Manager sind", "ALERT_ACCOUNT_PERMANENT_DELETE": "Ihr Konto wird dauerhaft gelöscht und von allen Teams entfernt", "ALERT_REMOVE_TEAM": "Das Team wird vollständig aus dem System entfernt und die Teammitglieder verlieren den Zugriff", + "ALERT_REMOVE_ALL_DATA": "All Account Data will be removed from all teams where you are ONLY one existed manager", "ALERT_QUIT_TEAM": "Sie sind im Begriff, das Team zu verlassen" }, "pages": { @@ -282,7 +283,9 @@ "TIMEZONE_SEARCH_PLACEHOLDER": "Ihre Zeitzone", "ABOUT_TO_CHANGE_EMAIL": "Sie sind im Begriff, die E-Mail zu ändern", "ABOUT_TO_DELETE_ACCOUNT": "Sie sind im Begriff, Ihr Konto zu löschen?", - "ABOUT_TO_REMOVE_ACCOUNT": "Sie sind im Begriff, Ihr Konto zu entfernen?" + "ABOUT_TO_REMOVE_ACCOUNT": "Sie sind im Begriff, Ihr Konto zu entfernen?", + "ABOUT_TO_REMOVE_FROM_ALL_TEAMS": "You're about to be removed from all teams, unless you're the only manager ?", + "ABOUT_TO_DELETE_ALL_ACCOUNT_DATA": "You are about to Delete your account and all your data ?" }, "settingsTeam": { "HEADING_TITLE": "Allgemeine Einstellungen", diff --git a/apps/web/public/locales/en/common.json b/apps/web/public/locales/en/common.json index 43e88ae26..eb95b39a4 100644 --- a/apps/web/public/locales/en/common.json +++ b/apps/web/public/locales/en/common.json @@ -36,8 +36,9 @@ "ASSIGN_TASK": "Assign Task", "ASSIGN_TASK_TO": "Assign Task", "REMOVE_ACCOUNT": "Remove Account", - "REMOVE_EVERYWHERE": "Remove Everywhere", + "REMOVE_EVERYWHERE": "Remove From All Teams", "DELETE_ACCOUNT": "Delete This Account", + "DELETE_ALL_DATA": "Delete All Data", "UNASSIGN_TASK": "Unassign Task", "MAKE_A_MANAGER": "Make a Manager", "UNMAKE_A_MANAGER": "Unmake a Manager", @@ -174,8 +175,9 @@ "GITHUB_AUTO_SYNC_LABEL": "Select Auto-Sync Label" }, "alerts": { - "ALERT_DELETE_ACCOUNT": "Account will be removed from all teams, except where you are only the manager", - "ALERT_ACCOUNT_PERMANENT_DELETE": "Your Account will be deleted permanently with removing fromall teams", + "ALERT_DELETE_ACCOUNT": "You will be removed from all teams, except where you are the only manager in the team", + "ALERT_ACCOUNT_PERMANENT_DELETE": "Your Account will be deleted permanently with removing from all teams", + "ALERT_REMOVE_ALL_DATA": "All Account Data will be removed from all teams where you are ONLY one existed manager", "ALERT_REMOVE_TEAM": "Team will be completely removed for the system and team members lost access", "ALERT_QUIT_TEAM": "You are about to quit the team" }, @@ -280,10 +282,11 @@ "phoneNotValid": "Please provide a valid Phone Number", "WORK_SCHEDULE": "Work Schedule", "SUBSCRIPTION": "Subscription", - "TIMEZONE_SEARCH_PLACEHOLDER": "Your Timezone", "ABOUT_TO_CHANGE_EMAIL": "You are about to change Email", "ABOUT_TO_DELETE_ACCOUNT": "You are about to Delete your account ?", - "ABOUT_TO_REMOVE_ACCOUNT": "You are about to Remove your account ?" + "TIMEZONE_SEARCH_PLACEHOLDER": "Your Timezone", + "ABOUT_TO_REMOVE_FROM_ALL_TEAMS": "You're about to be removed from all teams, unless you're the only manager ?", + "ABOUT_TO_DELETE_ALL_ACCOUNT_DATA": "You are about to Delete your account and all your data ?" }, "settingsTeam": { "HEADING_TITLE": "General Settings", diff --git a/apps/web/public/locales/es/common.json b/apps/web/public/locales/es/common.json index 2072ecc48..d7b79d306 100644 --- a/apps/web/public/locales/es/common.json +++ b/apps/web/public/locales/es/common.json @@ -172,6 +172,7 @@ "ALERT_DELETE_ACCOUNT": "La cuenta será eliminada de todos los equipos, excepto donde eres sólo el administrador", "ALERT_ACCOUNT_PERMANENT_DELETE": "Tu cuenta será eliminada permanentemente con la eliminación de todos los equipos", "ALERT_REMOVE_TEAM": "El equipo será eliminado completamente del sistema y los miembros del equipo perderán el acceso", + "ALERT_REMOVE_ALL_DATA": "All Account Data will be removed from all teams where you are ONLY one existed manager", "ALERT_QUIT_TEAM": "Estás a punto de abandonar el equipo" }, "pages": { @@ -276,7 +277,10 @@ "SUBSCRIPTION": "Suscripción", "ABOUT_TO_CHANGE_EMAIL": "Estás a punto de cambiar el Email", "ABOUT_TO_DELETE_ACCOUNT": "Estás a punto de Eliminar tu cuenta ?", - "ABOUT_TO_REMOVE_ACCOUNT": "Estás a punto de Eliminar tu cuenta ?" + "ABOUT_TO_REMOVE_ACCOUNT": "Estás a punto de Eliminar tu cuenta ?", + "TIMEZONE_SEARCH_PLACEHOLDER": "Your Timezone", + "ABOUT_TO_REMOVE_FROM_ALL_TEAMS": "You're about to be removed from all teams, unless you're the only manager ?", + "ABOUT_TO_DELETE_ALL_ACCOUNT_DATA": "You are about to Delete your account and all your data ?" }, "settingsTeam": { "HEADING_TITLE": "Ajustes generales", diff --git a/apps/web/public/locales/fr/common.json b/apps/web/public/locales/fr/common.json index 35c4d51bb..c8c968cc0 100644 --- a/apps/web/public/locales/fr/common.json +++ b/apps/web/public/locales/fr/common.json @@ -174,6 +174,7 @@ "ALERT_DELETE_ACCOUNT": "Le compte sera supprimé de toutes les équipes, sauf si vous êtes uniquement le gestionnaire", "ALERT_ACCOUNT_PERMANENT_DELETE": "Votre compte sera supprimé définitivement avec suppression de toutes les équipes", "ALERT_REMOVE_TEAM": "L'équipe sera complètement supprimée du système et les membres de l'équipe perdront l'accès", + "ALERT_REMOVE_ALL_DATA": "All Account Data will be removed from all teams where you are ONLY one existed manager", "ALERT_QUIT_TEAM": "Vous êtes sur le point de quitter l'équipe" }, "pages": { @@ -276,7 +277,10 @@ "SUBSCRIPTION": "Abonnement", "ABOUT_TO_CHANGE_EMAIL": "Vous êtes sur le point de changer d'e-mail", "ABOUT_TO_DELETE_ACCOUNT": "Vous êtes sur le point de supprimer votre compte ?", - "ABOUT_TO_REMOVE_ACCOUNT": "Vous êtes sur le point de supprimer votre compte ?" + "ABOUT_TO_REMOVE_ACCOUNT": "Vous êtes sur le point de supprimer votre compte ?", + "TIMEZONE_SEARCH_PLACEHOLDER": "Your Timezone", + "ABOUT_TO_REMOVE_FROM_ALL_TEAMS": "You're about to be removed from all teams, unless you're the only manager ?", + "ABOUT_TO_DELETE_ALL_ACCOUNT_DATA": "You are about to Delete your account and all your data ?" }, "settingsTeam": { "HEADING_TITLE": "Paramètres généraux", diff --git a/apps/web/public/locales/he/common.json b/apps/web/public/locales/he/common.json index a5fdcfe44..f149b5bba 100644 --- a/apps/web/public/locales/he/common.json +++ b/apps/web/public/locales/he/common.json @@ -175,6 +175,7 @@ "alerts": { "ALERT_DELETE_ACCOUNT": "החשבון יוסר מכל הצוותים, למעט היכן שאתה רק המנהל", "ALERT_ACCOUNT_PERMANENT_DELETE": "החשבון שלך יימחק לצמיתות עם הסרה מכל הצוותים", + "ALERT_REMOVE_ALL_DATA": "All Account Data will be removed from all teams where you are ONLY one existed manager", "ALERT_REMOVE_TEAM": "הצוות יוסר לחלוטין מהמערכת וחברי הצוות יאבדו גישה", "ALERT_QUIT_TEAM": "אתה עומד לעזוב את הצוות" }, diff --git a/apps/web/public/locales/it/common.json b/apps/web/public/locales/it/common.json index cd557f82e..7d18b8d2b 100644 --- a/apps/web/public/locales/it/common.json +++ b/apps/web/public/locales/it/common.json @@ -36,7 +36,7 @@ "ASSIGN_TASK": "Assign Task", "ASSIGN_TASK_TO": "Assign Task", "REMOVE_ACCOUNT": "Remove Account", - "REMOVE_EVERYWHERE": "Remove Everywhere", + "REMOVE_EVERYWHERE": "Remove From All Teams", "DELETE_ACCOUNT": "Delete This Account", "UNASSIGN_TASK": "Unassign Task", "MAKE_A_MANAGER": "Make a Manager", @@ -173,8 +173,9 @@ "GITHUB_AUTO_SYNC_LABEL": "Seleziona etichetta di sincronizzazione automatica" }, "alerts": { - "ALERT_DELETE_ACCOUNT": "Account will be removed from all teams, except where you are only the manager", - "ALERT_ACCOUNT_PERMANENT_DELETE": "Your Account will be deleted permanently with removing fromall teams", + "ALERT_DELETE_ACCOUNT": "You will be removed from all teams, except where you are the only manager in the team", + "ALERT_ACCOUNT_PERMANENT_DELETE": "Your Account will be deleted permanently with removing from all teams", + "ALERT_REMOVE_ALL_DATA": "All Account Data will be removed from all teams where you are ONLY one existed manager", "ALERT_REMOVE_TEAM": "Team will be completely removed for the system and team members lost access", "ALERT_QUIT_TEAM": "You are about to quit the team" }, diff --git a/apps/web/public/locales/nl/common.json b/apps/web/public/locales/nl/common.json index f6da1ffc9..b6d7c13fb 100644 --- a/apps/web/public/locales/nl/common.json +++ b/apps/web/public/locales/nl/common.json @@ -175,6 +175,7 @@ "alerts": { "ALERT_DELETE_ACCOUNT": "Account wordt verwijderd van alle teams, behalve waar u alleen manager bent", "ALERT_ACCOUNT_PERMANENT_DELETE": "Uw account wordt permanent verwijderd en uit alle teams verwijderd", + "ALERT_REMOVE_ALL_DATA": "All Account Data will be removed from all teams where you are ONLY one existed manager", "ALERT_REMOVE_TEAM": "Team wordt volledig verwijderd uit het systeem en teamleden verliezen toegang", "ALERT_QUIT_TEAM": "U staat op het punt het team te verlaten" }, diff --git a/apps/web/public/locales/pl/common.json b/apps/web/public/locales/pl/common.json index 7f74fa575..535c44020 100644 --- a/apps/web/public/locales/pl/common.json +++ b/apps/web/public/locales/pl/common.json @@ -36,7 +36,7 @@ "ASSIGN_TASK": "Assign Task", "ASSIGN_TASK_TO": "Assign Task", "REMOVE_ACCOUNT": "Remove Account", - "REMOVE_EVERYWHERE": "Remove Everywhere", + "REMOVE_EVERYWHERE": "Remove From All Teams", "DELETE_ACCOUNT": "Delete This Account", "UNASSIGN_TASK": "Unassign Task", "MAKE_A_MANAGER": "Make a Manager", @@ -173,8 +173,9 @@ "GITHUB_AUTO_SYNC_LABEL": "Wybierz etykietę automatycznej synchronizacji" }, "alerts": { - "ALERT_DELETE_ACCOUNT": "Account will be removed from all teams, except where you are only the manager", - "ALERT_ACCOUNT_PERMANENT_DELETE": "Your Account will be deleted permanently with removing fromall teams", + "ALERT_DELETE_ACCOUNT": "You will be removed from all teams, except where you are the only manager in the team", + "ALERT_ACCOUNT_PERMANENT_DELETE": "Your Account will be deleted permanently with removing from all teams", + "ALERT_REMOVE_ALL_DATA": "All Account Data will be removed from all teams where you are ONLY one existed manager", "ALERT_REMOVE_TEAM": "Team will be completely removed for the system and team members lost access", "ALERT_QUIT_TEAM": "You are about to quit the team" }, diff --git a/apps/web/public/locales/pt/common.json b/apps/web/public/locales/pt/common.json index 527366411..73e4fb0ba 100644 --- a/apps/web/public/locales/pt/common.json +++ b/apps/web/public/locales/pt/common.json @@ -36,7 +36,7 @@ "ASSIGN_TASK": "Assign Task", "ASSIGN_TASK_TO": "Assign Task", "REMOVE_ACCOUNT": "Remove Account", - "REMOVE_EVERYWHERE": "Remove Everywhere", + "REMOVE_EVERYWHERE": "Remove From All Teams", "DELETE_ACCOUNT": "Delete This Account", "UNASSIGN_TASK": "Unassign Task", "MAKE_A_MANAGER": "Make a Manager", @@ -173,9 +173,10 @@ "GITHUB_AUTO_SYNC_LABEL": "Selecionar rótulo de sincronização automática" }, "alerts": { - "ALERT_DELETE_ACCOUNT": "Account will be removed from all teams, except where you are only the manager", - "ALERT_ACCOUNT_PERMANENT_DELETE": "Your Account will be deleted permanently with removing fromall teams", + "ALERT_DELETE_ACCOUNT": "You will be removed from all teams, except where you are the only manager in the team", + "ALERT_ACCOUNT_PERMANENT_DELETE": "Your Account will be deleted permanently with removing from all teams", "ALERT_REMOVE_TEAM": "Team will be completely removed for the system and team members lost access", + "ALERT_REMOVE_ALL_DATA": "All Account Data will be removed from all teams where you are ONLY one existed manager", "ALERT_QUIT_TEAM": "You are about to quit the team" }, "pages": { diff --git a/apps/web/public/locales/ru/common.json b/apps/web/public/locales/ru/common.json index f90f1d9ac..65359fe53 100644 --- a/apps/web/public/locales/ru/common.json +++ b/apps/web/public/locales/ru/common.json @@ -173,9 +173,10 @@ "GITHUB_AUTO_SYNC_LABEL": "Выберите метку автосинхронизации" }, "alerts": { - "ALERT_DELETE_ACCOUNT": "Account will be removed from all teams, except where you are only the manager", - "ALERT_ACCOUNT_PERMANENT_DELETE": "Your Account will be deleted permanently with removing fromall teams", + "ALERT_DELETE_ACCOUNT": "You will be removed from all teams, except where you are the only manager in the team", + "ALERT_ACCOUNT_PERMANENT_DELETE": "Your Account will be deleted permanently with removing from all teams", "ALERT_REMOVE_TEAM": "Team will be completely removed for the system and team members lost access", + "ALERT_REMOVE_ALL_DATA": "All Account Data will be removed from all teams where you are ONLY one existed manager", "ALERT_QUIT_TEAM": "You are about to quit the team" }, "pages": { diff --git a/apps/web/public/locales/zh/common.json b/apps/web/public/locales/zh/common.json index 37fbbd301..a1118a05e 100644 --- a/apps/web/public/locales/zh/common.json +++ b/apps/web/public/locales/zh/common.json @@ -176,6 +176,7 @@ "ALERT_DELETE_ACCOUNT": "账户将从所有团队中移除,您作为管理员的团队除外", "ALERT_ACCOUNT_PERMANENT_DELETE": "您的账户将被永久删除,并从所有团队中移除", "ALERT_REMOVE_TEAM": "团队将被完全移除出系统,成员也将失去访问权限", + "ALERT_REMOVE_ALL_DATA": "All Account Data will be removed from all teams where you are ONLY one existed manager", "ALERT_QUIT_TEAM": "您将要退出团队" }, "pages": { From df3d8cc7786f7f4808b5f7c8326bd58a4c89a537 Mon Sep 17 00:00:00 2001 From: desperado1802 <124465103+desperado1802@users.noreply.github.com> Date: Wed, 22 Nov 2023 15:01:49 +0200 Subject: [PATCH 11/13] Bug/navbar logo responsiveness android (#1852) * updated coordinates of logo for android devices * added the adjusted logo for android devices in login screen --- apps/mobile/app/components/HomeHeader.tsx | 17 ++- apps/mobile/app/components/svgs/icons.tsx | 101 ++++++++++++++++++ .../LoginScreen/Components/LoginHeader.tsx | 6 +- 3 files changed, 118 insertions(+), 6 deletions(-) diff --git a/apps/mobile/app/components/HomeHeader.tsx b/apps/mobile/app/components/HomeHeader.tsx index ad7e3d604..6a99046e9 100644 --- a/apps/mobile/app/components/HomeHeader.tsx +++ b/apps/mobile/app/components/HomeHeader.tsx @@ -1,12 +1,17 @@ /* eslint-disable react-native/no-inline-styles */ import React, { FC } from 'react'; -import { View, StyleSheet, TouchableOpacity } from 'react-native'; +import { View, StyleSheet, TouchableOpacity, Platform } from 'react-native'; import { Feather } from '@expo/vector-icons'; import HeaderTimer from './HeaderTimer'; import { useAppTheme } from '../theme'; import { useOrganizationTeam } from '../services/hooks/useOrganization'; import { SvgXml } from 'react-native-svg'; -import { everTeamsLogoDarkTheme, everTeamsLogoLightTheme } from './svgs/icons'; +import { + everTeamsLogoDarkTheme, + everTeamsLogoDarkThemeAndroid, + everTeamsLogoLightTheme, + everTeamsLogoLightThemeAndroid +} from './svgs/icons'; interface Props { showTimer: boolean; @@ -19,7 +24,13 @@ const HomeHeader: FC = ({ props, showTimer }) => { return ( - {dark ? : } + {dark ? ( + + ) : ( + + )} {showTimer && activeTeam && ( diff --git a/apps/mobile/app/components/svgs/icons.tsx b/apps/mobile/app/components/svgs/icons.tsx index 5baa83907..5f6841602 100644 --- a/apps/mobile/app/components/svgs/icons.tsx +++ b/apps/mobile/app/components/svgs/icons.tsx @@ -77,6 +77,63 @@ export const everTeamsLogoLightTheme = ` + + teams + + + + `; +export const everTeamsLogoLightThemeAndroid = ``; +export const everTeamsLogoDarkThemeAndroid = ``; export const grayCircleIcon = ` = ({ withTeam, screenStatus, workspaceScreen }) => { return ( <> - + {withTeam ? ( {workspaceScreen ? ( From e19c1dca90024eceb9085a108101ceace164ab58 Mon Sep 17 00:00:00 2001 From: desperado1802 Date: Wed, 22 Nov 2023 15:32:44 +0200 Subject: [PATCH 12/13] truncated text in android and aligned with task number --- .../components/TimerTaskSection.tsx | 238 +++++++++--------- 1 file changed, 120 insertions(+), 118 deletions(-) diff --git a/apps/mobile/app/screens/Authenticated/TimerScreen/components/TimerTaskSection.tsx b/apps/mobile/app/screens/Authenticated/TimerScreen/components/TimerTaskSection.tsx index 50007cc5e..a13d39315 100644 --- a/apps/mobile/app/screens/Authenticated/TimerScreen/components/TimerTaskSection.tsx +++ b/apps/mobile/app/screens/Authenticated/TimerScreen/components/TimerTaskSection.tsx @@ -1,6 +1,6 @@ /* eslint-disable react-native/no-color-literals */ /* eslint-disable react-native/no-inline-styles */ -import React, { useCallback, useEffect, useRef, useState } from "react" +import React, { useCallback, useEffect, useRef, useState } from 'react'; import { View, StyleSheet, @@ -10,28 +10,30 @@ import { TouchableWithoutFeedback, Dimensions, Pressable, -} from "react-native" -import { ActivityIndicator } from "react-native-paper" -import { GLOBAL_STYLE as GS } from "../../../../../assets/ts/styles" -import ComboBox from "./ComboBox" -import EstimateTime from "./EstimateTime" -import { Feather } from "@expo/vector-icons" -import { observer } from "mobx-react-lite" -import TaskPriorities from "../../../../components/TaskPriority" + Platform +} from 'react-native'; +import { ActivityIndicator } from 'react-native-paper'; +import { GLOBAL_STYLE as GS } from '../../../../../assets/ts/styles'; +import ComboBox from './ComboBox'; +import EstimateTime from './EstimateTime'; +import { Feather } from '@expo/vector-icons'; +import { observer } from 'mobx-react-lite'; +import TaskPriorities from '../../../../components/TaskPriority'; // import TaskLabel from "../../../../components/TaskLabel" -import { typography, useAppTheme } from "../../../../theme" -import { translate } from "../../../../i18n" -import TaskStatus from "../../../../components/TaskStatus" -import TimerCard from "../../../../components/TimerCard" -import TaskSize from "../../../../components/TaskSize" -import { RTuseTaskInput } from "../../../../services/hooks/features/useTaskInput" -import TaskLabels from "../../../../components/TaskLabels" -import IssuesModal from "../../../../components/IssuesModal" -import { useStores } from "../../../../models" +import { typography, useAppTheme } from '../../../../theme'; +import { translate } from '../../../../i18n'; +import TaskStatus from '../../../../components/TaskStatus'; +import TimerCard from '../../../../components/TimerCard'; +import TaskSize from '../../../../components/TaskSize'; +import { RTuseTaskInput } from '../../../../services/hooks/features/useTaskInput'; +import TaskLabels from '../../../../components/TaskLabels'; +import IssuesModal from '../../../../components/IssuesModal'; +import { useStores } from '../../../../models'; +import { limitTextCharaters } from '../../../../helpers/sub-text'; const TimerTaskSection = observer( ({ taskInput, outsideClick }: { taskInput: RTuseTaskInput; outsideClick: () => unknown }) => { - const { colors } = useAppTheme() + const { colors } = useAppTheme(); const { setEditMode, setQuery, @@ -40,32 +42,32 @@ const TimerTaskSection = observer( isModalOpen, hasCreateForm, handleTaskCreation, - createLoading, - } = taskInput + createLoading + } = taskInput; - const [combxShow, setCombxShow] = useState(false) - const inputRef = useRef(null) + const [combxShow, setCombxShow] = useState(false); + const inputRef = useRef(null); const { - TimerStore: { localTimerStatus }, - } = useStores() + TimerStore: { localTimerStatus } + } = useStores(); const closeCombox = useCallback(() => { - setCombxShow(false) - }, [setCombxShow]) + setCombxShow(false); + }, [setCombxShow]); useEffect(() => { if (isModalOpen || editMode) { - setCombxShow(true) + setCombxShow(true); } else { - setCombxShow(false) + setCombxShow(false); } - }, [isModalOpen, editMode]) + }, [isModalOpen, editMode]); useEffect(() => { if (!editMode) { - inputRef.current.blur() + inputRef.current.blur(); } - }, [editMode]) + }, [editMode]); return ( outsideClick()}> @@ -74,17 +76,17 @@ const TimerTaskSection = observer( style={[ styles.wrapInput, { - flexDirection: "row", - alignItems: "center", + flexDirection: 'row', + alignItems: 'center', borderColor: colors.border, - backgroundColor: colors.background, - }, + backgroundColor: colors.background + } ]} > - {!editMode && activeTask ? `#${activeTask.taskNumber} ` : ""} + {!editMode && activeTask ? `#${activeTask.taskNumber} ` : ''} { - handleTaskCreation() - setEditMode(false) + handleTaskCreation(); + setEditMode(false); }} > ) : null} - {createLoading ? ( - - ) : null} + {createLoading ? : null} {combxShow ? ( - closeCombox()} - setEditMode={setEditMode} - tasksHandler={taskInput} - /> + closeCombox()} setEditMode={setEditMode} tasksHandler={taskInput} /> ) : ( - {translate("myWorkScreen.estimateLabel")} :{" "} + {translate('myWorkScreen.estimateLabel')} :{' '} @@ -164,23 +166,23 @@ const TimerTaskSection = observer( task={activeTask} containerStyle={{ ...styles.sizeContainer, - borderColor: colors.border, + borderColor: colors.border }} /> @@ -188,7 +190,7 @@ const TimerTaskSection = observer( task={activeTask} containerStyle={{ ...styles.sizeContainer, - borderColor: colors.border, + borderColor: colors.border }} /> @@ -196,9 +198,9 @@ const TimerTaskSection = observer( task={activeTask} containerStyle={{ ...styles.sizeContainer, - width: activeTask?.tags.length ? "100%" : 160, + width: activeTask?.tags.length ? '100%' : 160, borderColor: colors.border, - marginVertical: 20, + marginVertical: 20 }} /> @@ -206,12 +208,12 @@ const TimerTaskSection = observer( )} - ) - }, -) -export default TimerTaskSection + ); + } +); +export default TimerTaskSection; -const width = Dimensions.get("window").width +const width = Dimensions.get('window').width; const $timerSection: ViewStyle = { marginTop: 20, @@ -220,103 +222,103 @@ const $timerSection: ViewStyle = { borderRadius: 16, ...GS.noBorder, borderWidth: 1, - shadowColor: "#000", + shadowColor: '#000', shadowOffset: { width: 0, - height: 14, + height: 14 }, shadowOpacity: 0.1, shadowRadius: 44, - elevation: 8, -} + elevation: 8 +}; const styles = StyleSheet.create({ container: {}, dashed: { - borderBottomColor: "#fff", - borderBottomWidth: 10, + borderBottomColor: '#fff', + borderBottomWidth: 10 }, estimate: { - alignSelf: "flex-end", - color: "#9490A0", + alignSelf: 'flex-end', + color: '#9490A0', fontSize: 12, - fontWeight: "600", - marginBottom: 10, + fontWeight: '600', + marginBottom: 10 }, horizontal: { - flexDirection: "row", - justifyContent: "center", - marginBottom: 20, + flexDirection: 'row', + justifyContent: 'center', + marginBottom: 20 }, horizontalInput: { - alignItems: "flex-end", - flexDirection: "row", + alignItems: 'flex-end', + flexDirection: 'row' }, loading: { - right: 10, + right: 10 }, mainContainer: { - backgroundColor: "#fff", + backgroundColor: '#fff', borderRadius: 25, paddingTop: 30, padding: 20, ...GS.noBorder, borderWidth: 1, elevation: 5, - shadowColor: "#1B005D0D", + shadowColor: '#1B005D0D', shadowOffset: { width: 10, height: 10.5 }, shadowOpacity: 1, - shadowRadius: 15, + shadowRadius: 15 }, sizeContainer: { - alignItems: "center", - borderColor: "rgba(255, 255, 255, 0.13)", + alignItems: 'center', + borderColor: 'rgba(255, 255, 255, 0.13)', borderWidth: 1, height: 32, paddingHorizontal: 9, - width: width / 2.7, + width: width / 2.7 }, taskNumberStyle: { - color: "#7B8089", + color: '#7B8089', fontFamily: typography.primary.semiBold, - fontSize: 14, - marginLeft: 5, + fontSize: 12, + marginLeft: 5 }, textInput: { - backgroundColor: "#fff", + backgroundColor: '#fff', borderRadius: 10, - color: "rgba(40, 32, 72, 0.4)", + color: 'rgba(40, 32, 72, 0.4)', fontFamily: typography.fonts.PlusJakartaSans.semiBold, fontSize: 12, height: 43, paddingHorizontal: 6, - paddingVertical: 13, - width: "80%", + paddingVertical: 0, + width: '80%' }, textInputOne: { - height: 30, + height: 30 }, working: { - color: "#9490A0", - fontWeight: "600", - marginBottom: 10, + color: '#9490A0', + fontWeight: '600', + marginBottom: 10 }, wrapBugIcon: { - alignItems: "center", - backgroundColor: "#C24A4A", + alignItems: 'center', + backgroundColor: '#C24A4A', borderRadius: 3, height: 20, - justifyContent: "center", - width: 20, + justifyContent: 'center', + width: 20 }, wrapInput: { - backgroundColor: "#fff", - borderColor: "rgba(0, 0, 0, 0.1)", + backgroundColor: '#fff', + borderColor: 'rgba(0, 0, 0, 0.1)', borderRadius: 10, borderWidth: 1, height: 45, paddingHorizontal: 16, paddingVertical: 2, - width: "100%", - }, -}) + width: '100%' + } +}); From 108aaed6188f7a4c022390200a365a1c0c329cb3 Mon Sep 17 00:00:00 2001 From: desperado1802 Date: Wed, 22 Nov 2023 17:56:11 +0200 Subject: [PATCH 13/13] fixed the timer responsiveness --- apps/mobile/app/components/TimerButton.tsx | 12 ++++++++---- apps/mobile/app/components/TimerCard.tsx | 14 ++++++-------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/apps/mobile/app/components/TimerButton.tsx b/apps/mobile/app/components/TimerButton.tsx index 6b9e64ca1..3c25fb808 100644 --- a/apps/mobile/app/components/TimerButton.tsx +++ b/apps/mobile/app/components/TimerButton.tsx @@ -3,7 +3,7 @@ // import { LinearGradient } from "expo-linear-gradient" import { observer } from 'mobx-react-lite'; import React, { FC } from 'react'; -import { View, StyleSheet, ViewStyle, ImageStyle, Pressable } from 'react-native'; +import { View, StyleSheet, ViewStyle, ImageStyle, Pressable, Dimensions, PixelRatio } from 'react-native'; import { useStores } from '../models'; import { useTimer } from '../services/hooks/useTimer'; @@ -18,6 +18,10 @@ type TimerButtonProps = { iconStyle?: ImageStyle; }; +const { width: screenWidth } = Dimensions.get('window'); + +const pixelDensity = PixelRatio.get(); + const TimerButton: FC = observer(({ containerStyle }) => { const { TimerStore: { localTimerStatus } @@ -73,7 +77,7 @@ const styles = StyleSheet.create({ elevation: 8, height: 60, justifyContent: 'center', - marginHorizontal: 15, + marginRight: screenWidth * 0.0467 * (pixelDensity / 3), shadowColor: '#e11d48', shadowOffset: { width: 0, @@ -92,7 +96,7 @@ const styles = StyleSheet.create({ elevation: 8, height: 60, justifyContent: 'center', - marginHorizontal: 15, + marginRight: screenWidth * 0.0467 * (pixelDensity / 3), width: 60 }, timerBtnInactive: { @@ -104,7 +108,7 @@ const styles = StyleSheet.create({ elevation: 8, height: 60, justifyContent: 'center', - marginHorizontal: 15, + marginRight: screenWidth * 0.0467 * (pixelDensity / 3), shadowColor: '#3826A6', shadowOffset: { width: 0, diff --git a/apps/mobile/app/components/TimerCard.tsx b/apps/mobile/app/components/TimerCard.tsx index 0789343b7..7dd4b4cdd 100644 --- a/apps/mobile/app/components/TimerCard.tsx +++ b/apps/mobile/app/components/TimerCard.tsx @@ -2,7 +2,7 @@ /* eslint-disable react-native/no-color-literals */ /* eslint-disable camelcase */ import React, { FC } from 'react'; -import { View } from 'react-native'; +import { Dimensions, View } from 'react-native'; import { ProgressBar, Text } from 'react-native-paper'; import EStyleSheet from 'react-native-extended-stylesheet'; @@ -16,6 +16,7 @@ import { useTaskStatistics } from '../services/hooks/features/useTaskStatics'; export interface Props {} +const { width: screenWidth } = Dimensions.get('window'); const TimerCard: FC = observer(() => { const { colors } = useAppTheme(); const { @@ -45,9 +46,9 @@ const TimerCard: FC = observer(() => { {pad(hours)}:{pad(minutes)}:{pad(seconds)} - :{pad(ms_p)} + :{pad(ms_p)} - + = observer(() => { /> + @@ -75,16 +77,12 @@ const styles = EStyleSheet.create({ marginVertical: 4, justifyContent: 'center', alignItems: 'center', - width: '34%', - borderLeftWidth: 2, - borderLeftColor: 'rgba(0, 0, 0, 0.08)', height: '100%' }, progressBar: { backgroundColor: '#E9EBF8', width: '100%', height: 6, borderRadius: 3 }, timeAndProgressBarWrapper: { flexDirection: 'column', justifyContent: 'space-between', - width: '66%', height: 70, paddingBottom: 0 }, @@ -102,7 +100,7 @@ const styles = EStyleSheet.create({ }, timerText: { fontWeight: '600', - fontSize: '2.3rem', + fontSize: screenWidth * 0.082, color: '#1B005D', marginTop: 0, paddingTop: 0,