Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 48 additions & 12 deletions src/components/scenes/DevTestScene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import type {
} from '../../types/routerTypes'
import { parseDeepLink } from '../../util/DeepLinkParser'
import { consify } from '../../util/utils'
import { makeEdgeVault } from '../../util/vault/edgeVault'
import { ButtonsView } from '../buttons/ButtonsView'
import { EdgeButton } from '../buttons/EdgeButton'
import { AlertCardUi4 } from '../cards/AlertCard'
Expand Down Expand Up @@ -59,6 +60,7 @@ import { ModalFilledTextInput } from '../themed/FilledTextInput'
import { SceneHeader } from '../themed/SceneHeader'
import { SceneHeaderUi4 } from '../themed/SceneHeaderUi4'
import { SimpleTextInput } from '../themed/SimpleTextInput'
import type { BankFormData } from './RampBankFormScene'

type Props = EdgeTabsSceneProps<'devTab'>

Expand Down Expand Up @@ -262,10 +264,31 @@ export const DevTestScene: React.FC<Props> = props => {
}}
/>
<EdgeButton
label="KycFormScene"
label="KycFormScene (Legacy)"
onPress={handleKycFormPress}
marginRem={0.5}
/>
<EdgeButton
label="RampKycFormScene"
marginRem={0.5}
onPress={() => {
navigation2.navigate('buyTab', {
screen: 'kycForm',
params: {
headerTitle: 'KYC Information',
submitButtonText: 'Submit',
onSubmit: async formData => {
console.log('RampKycForm submitted:', formData)
await new Promise(resolve => setTimeout(resolve, 2000))
if (navigation2.canGoBack()) navigation2.goBack()
},
onCancel: () => {
console.log('RampKycForm cancelled')
}
}
})
}}
/>
<EdgeButton
label="Review Trigger Test"
marginRem={0.25}
Expand Down Expand Up @@ -310,17 +333,30 @@ export const DevTestScene: React.FC<Props> = props => {
label="Ramp Bank Details Scene"
marginRem={0.25}
onPress={() => {
navigation.navigate('rampBankForm', {
countryCode: 'US',
onSubmit: async (formData: any) => {
console.log('Bank details submitted:', formData)
// Simulate API call
await new Promise(resolve => setTimeout(resolve, 2000))
},
onCancel: () => {
console.log('Bank form cancelled')
}
})
// Fetch personal info from vault to prepopulate the form
const vault = makeEdgeVault({ disklet: account.disklet })
vault
.getUuid('personalInfo', 0)
.then(async uuid => {
const personalInfo =
uuid != null ? await vault.getPersonalInfo(uuid) : null
navigation.navigate('rampBankForm', {
countryCode: 'US',
initialFirstName: personalInfo?.name.firstName,
initialLastName: personalInfo?.name.lastName,
onSubmit: async (formData: BankFormData) => {
console.log('Bank details submitted:', formData)
// Simulate API call
await new Promise(resolve => setTimeout(resolve, 2000))
},
onCancel: () => {
console.log('Bank form cancelled')
}
})
})
.catch((error: unknown) => {
showError(error)
})
}}
/>
<EdgeButton
Expand Down
52 changes: 38 additions & 14 deletions src/components/scenes/RampBankFormScene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type { EdgeAppSceneProps } from '../../types/routerTypes'
import { SceneButtons } from '../buttons/SceneButtons'
import { ErrorCard } from '../cards/ErrorCard'
import { SceneWrapper } from '../common/SceneWrapper'
import { SectionHeader } from '../common/SectionHeader'
import { SceneContainer } from '../layout/SceneContainer'
import { showError } from '../services/AirshipInstance'
import { cacheStyles, type Theme, useTheme } from '../services/ThemeContext'
Expand All @@ -27,6 +28,10 @@ export interface BankFormData {
export interface RampBankFormParams {
/** ISO country code for region-specific validation */
countryCode: string
/** Optional initial value for owner first name (e.g., from KYC) */
initialFirstName?: string
/** Optional initial value for owner last name (e.g., from KYC) */
initialLastName?: string
onSubmit: (formData: BankFormData) => Promise<void>
/**
* Callback invoked when the user navigates away from the scene.
Expand All @@ -44,20 +49,36 @@ interface ValidationResult {

export const RampBankFormScene: React.FC<Props> = props => {
const { navigation, route } = props
const { countryCode, onSubmit, onCancel } = route.params
const {
countryCode,
initialFirstName = '',
initialLastName = '',
onSubmit,
onCancel
} = route.params

const theme = useTheme()
const styles = getStyles(theme)

// Handle back navigation
useBackEvent(navigation, onCancel)

// Generate default account nickname from initial names if both are provided
const initialAccountName =
initialFirstName !== '' && initialLastName !== ''
? sprintf(
lstrings.ramp_account_nickname_default_2s,
initialFirstName,
initialLastName
)
: ''

const [bankName, setBankName] = React.useState('')
const [accountNumber, setAccountNumber] = React.useState('')
const [routingNumber, setRoutingNumber] = React.useState('')
const [accountName, setAccountName] = React.useState('')
const [ownerFirstName, setOwnerFirstName] = React.useState('')
const [ownerLastName, setOwnerLastName] = React.useState('')
const [accountName, setAccountName] = React.useState(initialAccountName)
const [ownerFirstName, setOwnerFirstName] = React.useState(initialFirstName)
const [ownerLastName, setOwnerLastName] = React.useState(initialLastName)
const [isSubmitting, setIsSubmitting] = React.useState(false)
const [error, setError] = React.useState<unknown>(null)
const [fieldErrors, setFieldErrors] = React.useState({
Expand All @@ -68,7 +89,7 @@ export const RampBankFormScene: React.FC<Props> = props => {
// Create refs for each input field
const ownerFirstNameRef = React.useRef<TextInput>(null)
const ownerLastNameRef = React.useRef<TextInput>(null)
const accountNameRef = React.useRef<TextInput>(null)
const bankNameRef = React.useRef<TextInput>(null)
const accountNumberRef = React.useRef<TextInput>(null)
const routingNumberRef = React.useRef<TextInput>(null)

Expand Down Expand Up @@ -151,17 +172,19 @@ export const RampBankFormScene: React.FC<Props> = props => {

return (
<SceneWrapper scroll hasTabs>
<SceneContainer>
<SceneContainer headerTitle={lstrings.bank_info_title}>
<FilledTextInput
value={bankName}
onChangeText={setBankName}
placeholder={lstrings.ramp_bank_name_placeholder}
value={accountName}
onChangeText={setAccountName}
placeholder={lstrings.ramp_account_nickname_placeholder}
returnKeyType="next"
autoCapitalize="words"
aroundRem={0.5}
bottomRem={1}
onSubmitEditing={() => ownerFirstNameRef.current?.focus()}
/>

<SectionHeader leftTitle={lstrings.form_field_title_account_owner} />
<View style={styles.row}>
<FilledTextInput
expand
Expand All @@ -184,15 +207,16 @@ export const RampBankFormScene: React.FC<Props> = props => {
returnKeyType="next"
autoCapitalize="words"
aroundRem={0.5}
onSubmitEditing={() => accountNameRef.current?.focus()}
onSubmitEditing={() => bankNameRef.current?.focus()}
/>
</View>

<SectionHeader leftTitle={lstrings.ramp_bank_details_section_title} />
<FilledTextInput
ref={accountNameRef}
value={accountName}
onChangeText={setAccountName}
placeholder={lstrings.ramp_account_name_placeholder}
ref={bankNameRef}
value={bankName}
onChangeText={setBankName}
placeholder={lstrings.ramp_bank_name_placeholder}
returnKeyType="next"
autoCapitalize="words"
aroundRem={0.5}
Expand Down
17 changes: 15 additions & 2 deletions src/components/scenes/RampCreateScene/RampRegionSelect.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useFocusEffect } from '@react-navigation/native'
import * as React from 'react'
import { View } from 'react-native'
import Feather from 'react-native-vector-icons/Feather'
Expand All @@ -9,6 +10,7 @@ import { EdgeTouchableOpacity } from '../../common/EdgeTouchableOpacity'
import { SceneWrapper } from '../../common/SceneWrapper'
import { ChevronRightIcon } from '../../icons/ThemedIcons'
import { SceneContainer } from '../../layout/SceneContainer'
import { showError } from '../../services/AirshipInstance'
import { cacheStyles, useTheme } from '../../services/ThemeContext'
import { EdgeText } from '../../themed/EdgeText'

Expand All @@ -22,10 +24,21 @@ export const RampRegionSelect: React.FC<Props> = props => {
const theme = useTheme()
const styles = getStyles(theme)

const handleRegionSelect = useHandler(async () => {
await onRegionSelect()
const handleRegionSelect = useHandler(() => {
onRegionSelect().catch((error: unknown) => {
showError(error)
})
})

// Auto-open region selection modal every time the scene gains focus
// TODO: Replace the entire instructional scene with a country selection list
// instead of a modal in the event there is no region selected.
useFocusEffect(
React.useCallback(() => {
handleRegionSelect()
}, [handleRegionSelect])
)

return (
<SceneWrapper scroll hasTabs>
<SceneContainer headerTitle={headerTitle}>
Expand Down
Loading
Loading