From 7f2cc8ae55dbb85dda789a46a470a4d26d95233b Mon Sep 17 00:00:00 2001 From: mhawryluk Date: Mon, 20 Oct 2025 18:15:05 +0200 Subject: [PATCH 01/40] Create domain validation pages --- src/ROUTES.ts | 8 ++ src/SCREENS.ts | 5 + src/components/Domain/CopyableTextField.tsx | 42 +++++++ src/components/Domain/DomainsListRow.tsx | 69 +++++++++-- src/languages/en.ts | 19 +++ .../parameters/GetDomainValidateCodeParams.ts | 5 + .../API/parameters/ValidateDomainParams.ts | 5 + src/libs/API/parameters/index.ts | 2 + src/libs/API/types.ts | 6 + .../ModalStackNavigators/index.tsx | 7 ++ .../Navigators/RightModalNavigator.tsx | 4 + .../RELATIONS/WORKSPACES_LIST_TO_RHP.ts | 5 +- src/libs/Navigation/linkingConfig/config.ts | 6 + src/libs/Navigation/types.ts | 11 ++ src/libs/actions/Domain.ts | 12 ++ src/pages/domain/DomainVerifiedPage.tsx | 51 ++++++++ src/pages/domain/VerifyDomainPage.tsx | 115 ++++++++++++++++++ src/pages/workspace/WorkspacesListPage.tsx | 77 ++++++++---- 18 files changed, 412 insertions(+), 37 deletions(-) create mode 100644 src/components/Domain/CopyableTextField.tsx create mode 100644 src/libs/API/parameters/GetDomainValidateCodeParams.ts create mode 100644 src/libs/API/parameters/ValidateDomainParams.ts create mode 100644 src/libs/actions/Domain.ts create mode 100644 src/pages/domain/DomainVerifiedPage.tsx create mode 100644 src/pages/domain/VerifyDomainPage.tsx diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 9f6dc71f55a01..df71aaa3a1e7d 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -3299,6 +3299,14 @@ const ROUTES = { // eslint-disable-next-line no-restricted-syntax -- Legacy route generation getRoute: (backTo?: string) => getUrlWithBackToParam('test-tools' as const, backTo), }, + DOMAIN_VERIFY_DOMAIN: { + route: 'domain/:accountID/verify-domain', + getRoute: (accountID: number) => `domain/${accountID}/verify-domain` as const, + }, + DOMAIN_DOMAIN_VERIFIED: { + route: 'domain/:accountID/domain-verified', + getRoute: (accountID: number) => `domain/${accountID}/domain-verified` as const, + }, } as const; /** diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 7256a7ca151b4..e6a6b51ad91d1 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -253,6 +253,7 @@ const SCREENS = { SCHEDULE_CALL: 'ScheduleCall', REPORT_CHANGE_APPROVER: 'Report_Change_Approver', MERGE_TRANSACTION: 'MergeTransaction', + DOMAIN: 'Domain', }, PUBLIC_CONSOLE_DEBUG: 'Console_Debug', SIGN_IN_WITH_APPLE_DESKTOP: 'AppleSignInDesktop', @@ -811,6 +812,10 @@ const SCREENS = { TEST_TOOLS_MODAL: { ROOT: 'TestToolsModal_Root', }, + DOMAIN: { + VERIFY_DOMAIN: 'Domain_Verify_Domain', + DOMAIN_VERIFIED: 'Domain_Domain_Verified', + }, } as const; type Screen = DeepValueOf; diff --git a/src/components/Domain/CopyableTextField.tsx b/src/components/Domain/CopyableTextField.tsx new file mode 100644 index 0000000000000..1523d656c6405 --- /dev/null +++ b/src/components/Domain/CopyableTextField.tsx @@ -0,0 +1,42 @@ +import React, {useState} from 'react'; +import {View} from 'react-native'; +import Button from '@components/Button'; +import CopyTextToClipboard from '@components/CopyTextToClipboard'; +import * as Expensicons from '@components/Icon/Expensicons'; +import Text from '@components/Text'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; + +function CopyableTextField({value, isExpandable = false}: {value?: string; isExpandable?: boolean}) { + const styles = useThemeStyles(); + const {translate} = useLocalize(); + const [expanded, setExpanded] = useState(false); + + return ( + + + + {value} + + + + + + {isExpandable && ( + + + ); + + case 'loading': + return ; + + default: + return ; + } +} + +type VerifyDomainPageProps = PlatformStackScreenProps; + function VerifyDomainPage({route}: VerifyDomainPageProps) { const styles = useThemeStyles(); const theme = useTheme(); @@ -55,7 +81,7 @@ function VerifyDomainPage({route}: VerifyDomainPageProps) { return; } getDomainValidationCode(accountID); - }); + }, [accountID]); return ( {translate('domain.verifyDomain.addTXTRecord')} - - getDomainValidationCode(accountID)} /> @@ -116,7 +142,7 @@ function VerifyDomainPage({route}: VerifyDomainPageProps) { validateDomain(accountID)} - message={domain?.validationError} + message={domain?.validationError ?? undefined} isAlertVisible={!!domain?.validationError} containerStyles={styles.mb5} isLoading={domain?.isValidationPending} diff --git a/src/types/onyx/Domain.ts b/src/types/onyx/Domain.ts index ca844e3ace499..c5052df59b605 100644 --- a/src/types/onyx/Domain.ts +++ b/src/types/onyx/Domain.ts @@ -21,10 +21,10 @@ type Domain = OnyxCommon.OnyxValueWithOfflineFeedback<{ isValidationPending?: boolean; /** Whether domain validation is pending */ - validationError?: string; + validationError?: string | null; - /** Whether validation code is currently loading */ - isValidateCodeLoading?: boolean; + /** Whether validation code is currently loading or has failed/succeeded */ + validateCodeLoadingStatus?: 'loading' | 'error' | 'success'; }>; export default Domain; From a932956f1ef2aa14f92117c09a73ec4ce1b9c2a2 Mon Sep 17 00:00:00 2001 From: mhawryluk Date: Wed, 29 Oct 2025 12:27:57 +0100 Subject: [PATCH 14/40] Adjust domain validate code loading and error state UI --- src/components/Domain/CopyableTextField.tsx | 51 ++++++++---------- src/pages/domain/VerifyDomainPage.tsx | 60 +++++++++------------ 2 files changed, 47 insertions(+), 64 deletions(-) diff --git a/src/components/Domain/CopyableTextField.tsx b/src/components/Domain/CopyableTextField.tsx index 421ac6d7ce6d0..5343736ba2b94 100644 --- a/src/components/Domain/CopyableTextField.tsx +++ b/src/components/Domain/CopyableTextField.tsx @@ -1,47 +1,38 @@ -import React, {useState} from 'react'; +import React from 'react'; import {View} from 'react-native'; -import Button from '@components/Button'; +import ActivityIndicator from '@components/ActivityIndicator'; import CopyTextToClipboard from '@components/CopyTextToClipboard'; -import * as Expensicons from '@components/Icon/Expensicons'; import Text from '@components/Text'; -import useLocalize from '@hooks/useLocalize'; +import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; type CopyableTextFieldProps = { /** Text to display and to copy */ value?: string; - /** Whether the text field should limit the number of lines to 4 and display a button to show more */ - isExpandable?: boolean; + /** Should an activity indicator be shown instead of the text and button */ + isLoading?: boolean; }; -function CopyableTextField({value, isExpandable = false}: CopyableTextFieldProps) { - const styles = useThemeStyles(); - const {translate} = useLocalize(); - const [expanded, setExpanded] = useState(false); +const ACTIVITY_INDICATOR_SIZE = 24; +function CopyableTextField({value, isLoading = false}: CopyableTextFieldProps) { + const styles = useThemeStyles(); + const theme = useTheme(); return ( - - - - {value} - - - - - - {isExpandable && ( - - - ); - - case 'loading': - return ; - - default: - return ; - } -} - type VerifyDomainPageProps = PlatformStackScreenProps; function VerifyDomainPage({route}: VerifyDomainPageProps) { @@ -111,16 +87,32 @@ function VerifyDomainPage({route}: VerifyDomainPageProps) { - - + + {translate('domain.verifyDomain.addTXTRecord')} - getDomainValidationCode(accountID)} - /> - - + + {domain?.validateCodeLoadingStatus !== 'error' && ( + + )} + + + {domain?.validateCodeLoadingStatus === 'error' && ( + + +