@adminide-stack/yantra-mobile 12.0.73 → 12.0.74-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,86 +1,4 @@
1
- import {jsxs,jsx,Fragment}from'react/jsx-runtime';import React__default from'react';import {StyleSheet,Platform,View,TouchableOpacity,Text,ScrollView,ActivityIndicator,TextInput,Modal}from'react-native';import {SafeAreaView}from'react-native-safe-area-context';import {Ionicons}from'@expo/vector-icons';import {usePhoneVerification,isChatTestOtpEnabled,CHAT_REGISTRATION_TEST_OTP}from'./usePhoneVerification.js';const ALL_COUNTRIES = [{
2
- code: "US",
3
- name: "United States",
4
- callingCode: "+1"
5
- }, {
6
- code: "IN",
7
- name: "India",
8
- callingCode: "+91"
9
- }, {
10
- code: "PK",
11
- name: "Pakistan",
12
- callingCode: "+92"
13
- }, {
14
- code: "BD",
15
- name: "Bangladesh",
16
- callingCode: "+880"
17
- }, {
18
- code: "AE",
19
- name: "United Arab Emirates",
20
- callingCode: "+971"
21
- }, {
22
- code: "GB",
23
- name: "United Kingdom",
24
- callingCode: "+44"
25
- }, {
26
- code: "CA",
27
- name: "Canada",
28
- callingCode: "+1"
29
- }, {
30
- code: "AU",
31
- name: "Australia",
32
- callingCode: "+61"
33
- }, {
34
- code: "FR",
35
- name: "France",
36
- callingCode: "+33"
37
- }, {
38
- code: "DE",
39
- name: "Germany",
40
- callingCode: "+49"
41
- }, {
42
- code: "ES",
43
- name: "Spain",
44
- callingCode: "+34"
45
- }, {
46
- code: "IT",
47
- name: "Italy",
48
- callingCode: "+39"
49
- }, {
50
- code: "BR",
51
- name: "Brazil",
52
- callingCode: "+55"
53
- }, {
54
- code: "MX",
55
- name: "Mexico",
56
- callingCode: "+52"
57
- }, {
58
- code: "SG",
59
- name: "Singapore",
60
- callingCode: "+65"
61
- }, {
62
- code: "JP",
63
- name: "Japan",
64
- callingCode: "+81"
65
- }, {
66
- code: "CN",
67
- name: "China",
68
- callingCode: "+86"
69
- }];
70
- const DEFAULT_ALLOWED_DIAL_CODES = ["+1"];
71
- function allowedDialCodes(raw = process.env.EXPO_PUBLIC_PHONE_OTP_ALLOWED_DIAL_CODES) {
72
- const value = raw == null ? void 0 : raw.trim();
73
- if (value === "*") return null;
74
- if (!value) return DEFAULT_ALLOWED_DIAL_CODES;
75
- const codes = value.split(",").map((c) => c.trim()).filter(Boolean).map((c) => c.startsWith("+") ? c : `+${c}`);
76
- return codes.length ? codes : DEFAULT_ALLOWED_DIAL_CODES;
77
- }
78
- function pickerCountries(all = ALL_COUNTRIES, allowed = allowedDialCodes()) {
79
- if (!allowed) return all;
80
- const offered = all.filter((c) => allowed.includes(c.callingCode));
81
- return offered.length ? offered : [all[0]];
82
- }
83
- const COUNTRIES = pickerCountries();
1
+ import {jsxs,jsx,Fragment}from'react/jsx-runtime';import React__default from'react';import {StyleSheet,Platform,View,TouchableOpacity,Text,ScrollView,ActivityIndicator,TextInput,Modal,FlatList}from'react-native';import {SafeAreaView}from'react-native-safe-area-context';import {Ionicons}from'@expo/vector-icons';import {usePhoneVerification,isChatTestOtpEnabled,CHAT_REGISTRATION_TEST_OTP}from'./usePhoneVerification.js';import {pickerCountries,filterCountries}from'./countryPicker.js';const COUNTRIES = pickerCountries();
84
2
  function PhoneRow({
85
3
  countryCode,
86
4
  callingCode,
@@ -119,10 +37,16 @@ function RegistrationScreen({
119
37
  theme,
120
38
  testID
121
39
  }) {
122
- var _a;
40
+ var _a, _b, _c, _d, _e;
123
41
  const phoneVerification = usePhoneVerification("US");
124
42
  const selectedCountry = COUNTRIES.find((c) => c.code === phoneVerification.countryCode) || COUNTRIES[0];
125
43
  const [countryModalOpen, setCountryModalOpen] = React__default.useState(false);
44
+ const [countryQuery, setCountryQuery] = React__default.useState("");
45
+ const visibleCountries = React__default.useMemo(() => filterCountries(COUNTRIES, countryQuery), [countryQuery]);
46
+ const closeCountryModal = React__default.useCallback(() => {
47
+ setCountryModalOpen(false);
48
+ setCountryQuery("");
49
+ }, []);
126
50
  const accent = theme.colors.primary;
127
51
  const otpDigits = phoneVerification.otp.replace(/\D/g, "");
128
52
  const testOtpEnabled = isChatTestOtpEnabled();
@@ -186,7 +110,7 @@ function RegistrationScreen({
186
110
  /* @__PURE__ */ jsxs(View, { style: styles.form, children: [
187
111
  /* @__PURE__ */ jsx(PhoneRow, { countryCode: phoneVerification.countryCode, callingCode: selectedCountry.callingCode, phone: phoneVerification.inputPhone, onCountryPress: () => setCountryModalOpen(true), onChangePhone: phoneVerification.setInputPhone, disabled: phoneVerification.loading, theme }),
188
112
  phoneVerification.error ? /* @__PURE__ */ jsxs(View, { style: [styles.errorBox, {
189
- backgroundColor: theme.colors.error + "10"
113
+ backgroundColor: `${theme.colors.error}10`
190
114
  }], children: [
191
115
  /* @__PURE__ */ jsx(Ionicons, { name: "alert-circle", size: 16, color: theme.colors.error }),
192
116
  /* @__PURE__ */ jsx(Text, { style: [styles.errorText, {
@@ -218,7 +142,7 @@ function RegistrationScreen({
218
142
  flex: 1
219
143
  }], placeholder: "", keyboardType: "number-pad", value: phoneVerification.otp, onChangeText: phoneVerification.setOtp, editable: !phoneVerification.loading, maxLength: 6, testID: "chat-registration-otp" }) }),
220
144
  phoneVerification.error ? /* @__PURE__ */ jsxs(View, { style: [styles.errorBox, {
221
- backgroundColor: theme.colors.error + "10"
145
+ backgroundColor: `${theme.colors.error}10`
222
146
  }], children: [
223
147
  /* @__PURE__ */ jsx(Ionicons, { name: "alert-circle", size: 16, color: theme.colors.error }),
224
148
  /* @__PURE__ */ jsx(Text, { style: [styles.errorText, {
@@ -233,7 +157,7 @@ function RegistrationScreen({
233
157
  }], children: "Didn't get the code? Resend" }) }) : null
234
158
  ] })
235
159
  ] }) }),
236
- /* @__PURE__ */ jsx(Modal, { visible: countryModalOpen, animationType: "slide", presentationStyle: "pageSheet", children: /* @__PURE__ */ jsxs(SafeAreaView, { style: [styles.modalFill, {
160
+ /* @__PURE__ */ jsx(Modal, { visible: countryModalOpen, animationType: "slide", presentationStyle: "pageSheet", onRequestClose: closeCountryModal, children: /* @__PURE__ */ jsxs(SafeAreaView, { style: [styles.modalFill, {
237
161
  backgroundColor: theme.colors.background
238
162
  }], children: [
239
163
  /* @__PURE__ */ jsxs(View, { style: [styles.modalHeader, {
@@ -243,14 +167,33 @@ function RegistrationScreen({
243
167
  /* @__PURE__ */ jsx(Text, { style: [styles.modalTitle, {
244
168
  color: theme.colors.text
245
169
  }], children: "Country code" }),
246
- /* @__PURE__ */ jsx(TouchableOpacity, { onPress: () => setCountryModalOpen(false), children: /* @__PURE__ */ jsx(Ionicons, { name: "close", size: 26, color: theme.colors.text }) })
170
+ /* @__PURE__ */ jsx(TouchableOpacity, { onPress: closeCountryModal, accessibilityRole: "button", accessibilityLabel: "Close", children: /* @__PURE__ */ jsx(Ionicons, { name: "close", size: 26, color: theme.colors.text }) })
171
+ ] }),
172
+ /* @__PURE__ */ jsxs(View, { style: [styles.countrySearch, {
173
+ borderColor: theme.colors.border,
174
+ backgroundColor: (_b = theme.colors.card) != null ? _b : "#fff"
175
+ }], children: [
176
+ /* @__PURE__ */ jsx(Ionicons, { name: "search", size: 18, color: (_c = theme.colors.textSecondary) != null ? _c : theme.colors.text }),
177
+ /* @__PURE__ */ jsx(TextInput, { value: countryQuery, onChangeText: setCountryQuery, placeholder: "Search country or code", placeholderTextColor: (_d = theme.colors.textSecondary) != null ? _d : "#888", autoCorrect: false, autoCapitalize: "none", clearButtonMode: "while-editing", style: [styles.countrySearchInput, {
178
+ color: theme.colors.text
179
+ }], testID: "country-search" })
247
180
  ] }),
248
- /* @__PURE__ */ jsx(ScrollView, { children: COUNTRIES.map((country) => /* @__PURE__ */ jsxs(TouchableOpacity, { onPress: () => {
181
+ /* @__PURE__ */ jsx(FlatList, { data: visibleCountries, keyExtractor: (country) => country.code, keyboardShouldPersistTaps: "handled", initialNumToRender: 24, ListEmptyComponent: /* @__PURE__ */ jsxs(Text, { style: [styles.countryEmpty, {
182
+ color: (_e = theme.colors.textSecondary) != null ? _e : theme.colors.text
183
+ }], children: [
184
+ 'No country matches "',
185
+ countryQuery.trim(),
186
+ '"'
187
+ ] }), renderItem: ({
188
+ item: country
189
+ }) => /* @__PURE__ */ jsxs(TouchableOpacity, { onPress: () => {
249
190
  phoneVerification.setCountryCode(country.code);
250
- setCountryModalOpen(false);
191
+ closeCountryModal();
251
192
  }, style: [styles.countryListItem, phoneVerification.countryCode === country.code && {
252
- backgroundColor: accent + "18"
253
- }], children: [
193
+ backgroundColor: `${accent}18`
194
+ }], accessibilityRole: "button", accessibilityState: {
195
+ selected: phoneVerification.countryCode === country.code
196
+ }, children: [
254
197
  /* @__PURE__ */ jsxs(Text, { style: [styles.countryListText, {
255
198
  color: theme.colors.text
256
199
  }], children: [
@@ -260,7 +203,7 @@ function RegistrationScreen({
260
203
  ")"
261
204
  ] }),
262
205
  phoneVerification.countryCode === country.code ? /* @__PURE__ */ jsx(Ionicons, { name: "checkmark", size: 20, color: accent }) : null
263
- ] }, country.code)) })
206
+ ] }) })
264
207
  ] }) })
265
208
  ] });
266
209
  }
@@ -363,6 +306,27 @@ const styles = StyleSheet.create({
363
306
  modalFill: {
364
307
  flex: 1
365
308
  },
309
+ countrySearch: {
310
+ flexDirection: "row",
311
+ alignItems: "center",
312
+ gap: 8,
313
+ marginHorizontal: 16,
314
+ marginBottom: 8,
315
+ paddingHorizontal: 12,
316
+ borderWidth: 1,
317
+ borderRadius: 10,
318
+ minHeight: 42
319
+ },
320
+ countrySearchInput: {
321
+ flex: 1,
322
+ fontSize: 16,
323
+ paddingVertical: Platform.OS === "ios" ? 10 : 6
324
+ },
325
+ countryEmpty: {
326
+ textAlign: "center",
327
+ padding: 24,
328
+ fontSize: 14
329
+ },
366
330
  modalHeader: {
367
331
  justifyContent: "space-between",
368
332
  paddingHorizontal: 16,
@@ -384,4 +348,4 @@ const styles = StyleSheet.create({
384
348
  countryListText: {
385
349
  fontSize: 16
386
350
  }
387
- });export{RegistrationScreen,allowedDialCodes,pickerCountries};//# sourceMappingURL=RegistrationScreen.js.map
351
+ });export{RegistrationScreen};//# sourceMappingURL=RegistrationScreen.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"RegistrationScreen.js","sources":["../../../src/features/messaging/RegistrationScreen.tsx"],"sourcesContent":["/**\n * Registration screen for Yantra Chat.\n *\n * First-time users are prompted to register with their phone number.\n * The flow:\n * 1. User enters mobile number (country code in the same row)\n * 2. OTP is sent to their number\n * 3. User enters the OTP code to verify\n * 4. Phone number becomes their member ID in the Yantra Chat organization\n *\n * Follows the design from issue #1312.\n */\nimport React from 'react';\nimport {\n StyleSheet,\n View,\n Text,\n TouchableOpacity,\n TextInput,\n ActivityIndicator,\n ScrollView,\n Modal,\n Platform,\n} from 'react-native';\nimport { SafeAreaView } from 'react-native-safe-area-context';\nimport { Ionicons } from '@expo/vector-icons';\nimport { CHAT_REGISTRATION_TEST_OTP, isChatTestOtpEnabled, usePhoneVerification } from './usePhoneVerification';\n\ninterface RegistrationScreenProps {\n /** Called when registration completes successfully. */\n onRegistrationComplete: (phoneNumber: string) => void;\n /** Theme configuration. */\n theme: { colors: Record<string, string>; fonts: Record<string, Record<string, string>> };\n testID?: string;\n}\n\ninterface CountryOption {\n code: string;\n name: string;\n callingCode: string;\n}\n\n/** Every country the picker knows. Nothing is removed from here when a country is switched off. */\nconst ALL_COUNTRIES: CountryOption[] = [\n { code: 'US', name: 'United States', callingCode: '+1' },\n { code: 'IN', name: 'India', callingCode: '+91' },\n { code: 'PK', name: 'Pakistan', callingCode: '+92' },\n { code: 'BD', name: 'Bangladesh', callingCode: '+880' },\n { code: 'AE', name: 'United Arab Emirates', callingCode: '+971' },\n { code: 'GB', name: 'United Kingdom', callingCode: '+44' },\n { code: 'CA', name: 'Canada', callingCode: '+1' },\n { code: 'AU', name: 'Australia', callingCode: '+61' },\n { code: 'FR', name: 'France', callingCode: '+33' },\n { code: 'DE', name: 'Germany', callingCode: '+49' },\n { code: 'ES', name: 'Spain', callingCode: '+34' },\n { code: 'IT', name: 'Italy', callingCode: '+39' },\n { code: 'BR', name: 'Brazil', callingCode: '+55' },\n { code: 'MX', name: 'Mexico', callingCode: '+52' },\n { code: 'SG', name: 'Singapore', callingCode: '+65' },\n { code: 'JP', name: 'Japan', callingCode: '+81' },\n { code: 'CN', name: 'China', callingCode: '+86' },\n];\n\n/**\n * Which of those the picker offers. SMS verification is US-only for now: the AWS account is\n * still in the SMS sandbox and the non-US origination registrations are pending. The server\n * enforces the same rule (PHONE_OTP_ALLOWED_DIAL_CODES), so this must be widened together with\n * it. Override at build time with EXPO_PUBLIC_PHONE_OTP_ALLOWED_DIAL_CODES (\"+1,+92\", or \"*\").\n */\nconst DEFAULT_ALLOWED_DIAL_CODES = ['+1'];\n\nexport function allowedDialCodes(\n raw: string | undefined = process.env.EXPO_PUBLIC_PHONE_OTP_ALLOWED_DIAL_CODES,\n): string[] | null {\n const value = raw?.trim();\n if (value === '*') return null;\n if (!value) return DEFAULT_ALLOWED_DIAL_CODES;\n const codes = value\n .split(',')\n .map((c) => c.trim())\n .filter(Boolean)\n .map((c) => (c.startsWith('+') ? c : `+${c}`));\n return codes.length ? codes : DEFAULT_ALLOWED_DIAL_CODES;\n}\n\nexport function pickerCountries(\n all: CountryOption[] = ALL_COUNTRIES,\n allowed: string[] | null = allowedDialCodes(),\n): CountryOption[] {\n if (!allowed) return all;\n const offered = all.filter((c) => allowed.includes(c.callingCode));\n return offered.length ? offered : [all[0]];\n}\n\nconst COUNTRIES: CountryOption[] = pickerCountries();\n\nfunction PhoneRow({\n countryCode,\n callingCode,\n phone,\n onCountryPress,\n onChangePhone,\n disabled,\n theme,\n}: {\n countryCode: string;\n callingCode: string;\n phone: string;\n onCountryPress: () => void;\n onChangePhone: (v: string) => void;\n disabled: boolean;\n theme: RegistrationScreenProps['theme'];\n}) {\n return (\n <View\n style={[\n styles.phoneRow,\n {\n flexDirection: 'row',\n alignItems: 'center',\n borderColor: theme.colors.border,\n backgroundColor: theme.colors.card ?? '#fff',\n },\n ]}\n >\n <TouchableOpacity\n onPress={onCountryPress}\n disabled={disabled}\n style={[styles.countryChip, { flexDirection: 'row', alignItems: 'center' }]}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Select country code\"\n >\n <Text style={[styles.callingCode, { color: theme.colors.text }]}>{callingCode}</Text>\n <Ionicons name=\"chevron-down\" size={18} color={theme.colors.textSecondary} />\n </TouchableOpacity>\n <View style={[styles.phoneDivider, { backgroundColor: theme.colors.border }]} />\n <TextInput\n style={[styles.phoneInput, { color: theme.colors.text }]}\n placeholder=\"\"\n placeholderTextColor={theme.colors.placeholder}\n keyboardType=\"phone-pad\"\n textContentType=\"telephoneNumber\"\n value={phone}\n onChangeText={onChangePhone}\n editable={!disabled}\n maxLength={15}\n testID=\"chat-registration-phone\"\n />\n </View>\n );\n}\n\nexport function RegistrationScreen({ onRegistrationComplete, theme, testID }: RegistrationScreenProps) {\n const phoneVerification = usePhoneVerification('US');\n const selectedCountry = COUNTRIES.find((c) => c.code === phoneVerification.countryCode) || COUNTRIES[0];\n const [countryModalOpen, setCountryModalOpen] = React.useState(false);\n const accent = theme.colors.primary;\n const otpDigits = phoneVerification.otp.replace(/\\D/g, '');\n const testOtpEnabled = isChatTestOtpEnabled();\n const usingTestOtp = testOtpEnabled && (phoneVerification.testOtpMode || otpDigits === CHAT_REGISTRATION_TEST_OTP);\n\n const { registrationFailed } = phoneVerification;\n React.useEffect(() => {\n if (phoneVerification.stage === 'verified' && phoneVerification.verifiedPhone) {\n // A failed registration used to be dropped here, leaving the screen stuck with no reason.\n Promise.resolve(onRegistrationComplete(phoneVerification.verifiedPhone)).catch((err: unknown) => {\n const message = err instanceof Error && err.message ? err.message : '';\n registrationFailed(\n message\n ? `Could not register: ${message}`\n : 'Could not register for Yantra Chat. Please try again.',\n );\n });\n }\n }, [phoneVerification.stage, phoneVerification.verifiedPhone, onRegistrationComplete, registrationFailed]);\n\n const handleBack = React.useCallback(() => {\n if (phoneVerification.stage === 'otp') {\n phoneVerification.resetToInput();\n }\n }, [phoneVerification]);\n\n const handleSendOtp = React.useCallback(async () => {\n await phoneVerification.sendOtp();\n }, [phoneVerification]);\n\n const handleVerifyOtp = React.useCallback(async () => {\n await phoneVerification.verifyOtp();\n }, [phoneVerification]);\n\n const handleResend = React.useCallback(async () => {\n await phoneVerification.sendOtp();\n }, [phoneVerification]);\n\n return (\n <SafeAreaView\n style={[styles.container, { backgroundColor: theme.colors.background }]}\n edges={['top', 'left', 'right']}\n testID={testID}\n >\n <View style={[styles.header, { flexDirection: 'row', alignItems: 'center' }]}>\n {phoneVerification.stage === 'otp' ? (\n <TouchableOpacity onPress={handleBack} hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}>\n <Ionicons name=\"chevron-back\" size={28} color={theme.colors.text} />\n </TouchableOpacity>\n ) : (\n <View style={{ width: 28 }} />\n )}\n <Text style={[styles.title, { color: theme.colors.text, flex: 1, textAlign: 'center' }]}>\n Yantra Chat\n </Text>\n <View style={{ width: 28 }} />\n </View>\n\n <ScrollView\n contentContainerStyle={styles.content}\n showsVerticalScrollIndicator={false}\n keyboardShouldPersistTaps=\"handled\"\n >\n {phoneVerification.stage === 'input' ? (\n <>\n <Text style={[styles.subtitle, { color: theme.colors.text }]}>Register to Chat</Text>\n <Text style={[styles.description, { color: theme.colors.textSecondary }]}>\n Enter your mobile number to get started. You&apos;ll receive an OTP to verify.\n </Text>\n\n <View style={styles.form}>\n <PhoneRow\n countryCode={phoneVerification.countryCode}\n callingCode={selectedCountry.callingCode}\n phone={phoneVerification.inputPhone}\n onCountryPress={() => setCountryModalOpen(true)}\n onChangePhone={phoneVerification.setInputPhone}\n disabled={phoneVerification.loading}\n theme={theme}\n />\n\n {phoneVerification.error ? (\n <View style={[styles.errorBox, { backgroundColor: theme.colors.error + '10' }]}>\n <Ionicons name=\"alert-circle\" size={16} color={theme.colors.error} />\n <Text style={[styles.errorText, { color: theme.colors.error }]}>\n {phoneVerification.error}\n </Text>\n </View>\n ) : null}\n\n {testOtpEnabled ? (\n <TouchableOpacity onPress={phoneVerification.continueWithTestOtp}>\n <Text style={[styles.linkText, { color: accent }]}>Continue with test OTP</Text>\n </TouchableOpacity>\n ) : null}\n\n <TouchableOpacity\n onPress={handleSendOtp}\n disabled={phoneVerification.loading || !phoneVerification.inputPhone.trim()}\n style={[\n styles.button,\n {\n backgroundColor: phoneVerification.inputPhone.trim()\n ? accent\n : theme.colors.border,\n },\n ]}\n >\n {phoneVerification.loading ? (\n <ActivityIndicator color=\"#fff\" size=\"small\" />\n ) : (\n <Text style={styles.buttonText}>Send OTP</Text>\n )}\n </TouchableOpacity>\n </View>\n </>\n ) : (\n <>\n <Text style={[styles.subtitle, { color: theme.colors.text }]}>Verify your number</Text>\n <Text style={[styles.description, { color: theme.colors.textSecondary }]}>\n {usingTestOtp\n ? `Test mode: use code ${CHAT_REGISTRATION_TEST_OTP} and tap Continue.`\n : `Enter the 6-digit code sent to ${selectedCountry.callingCode} ${phoneVerification.inputPhone}`}\n </Text>\n\n <View style={styles.form}>\n <View\n style={[\n styles.otpInputContainer,\n {\n flexDirection: 'row',\n alignItems: 'center',\n borderColor: theme.colors.border,\n backgroundColor: theme.colors.card ?? '#fff',\n },\n ]}\n >\n <TextInput\n style={[styles.otpInput, { color: theme.colors.text, flex: 1 }]}\n placeholder=\"\"\n keyboardType=\"number-pad\"\n value={phoneVerification.otp}\n onChangeText={phoneVerification.setOtp}\n editable={!phoneVerification.loading}\n maxLength={6}\n testID=\"chat-registration-otp\"\n />\n </View>\n\n {phoneVerification.error ? (\n <View style={[styles.errorBox, { backgroundColor: theme.colors.error + '10' }]}>\n <Ionicons name=\"alert-circle\" size={16} color={theme.colors.error} />\n <Text style={[styles.errorText, { color: theme.colors.error }]}>\n {phoneVerification.error}\n </Text>\n </View>\n ) : null}\n\n <TouchableOpacity\n onPress={handleVerifyOtp}\n disabled={phoneVerification.loading || otpDigits.length < 6}\n style={[\n styles.button,\n {\n backgroundColor: otpDigits.length >= 6 ? accent : theme.colors.border,\n },\n ]}\n >\n {phoneVerification.loading ? (\n <ActivityIndicator color=\"#fff\" size=\"small\" />\n ) : (\n <Text style={styles.buttonText}>\n {usingTestOtp ? 'Continue' : 'Verify & Register'}\n </Text>\n )}\n </TouchableOpacity>\n\n {!usingTestOtp ? (\n <TouchableOpacity onPress={handleResend} disabled={phoneVerification.loading}>\n <Text style={[styles.linkText, { color: accent }]}>\n Didn&apos;t get the code? Resend\n </Text>\n </TouchableOpacity>\n ) : null}\n </View>\n </>\n )}\n </ScrollView>\n\n <Modal visible={countryModalOpen} animationType=\"slide\" presentationStyle=\"pageSheet\">\n <SafeAreaView style={[styles.modalFill, { backgroundColor: theme.colors.background }]}>\n <View style={[styles.modalHeader, { flexDirection: 'row', alignItems: 'center' }]}>\n <Text style={[styles.modalTitle, { color: theme.colors.text }]}>Country code</Text>\n <TouchableOpacity onPress={() => setCountryModalOpen(false)}>\n <Ionicons name=\"close\" size={26} color={theme.colors.text} />\n </TouchableOpacity>\n </View>\n <ScrollView>\n {COUNTRIES.map((country) => (\n <TouchableOpacity\n key={country.code}\n onPress={() => {\n phoneVerification.setCountryCode(country.code);\n setCountryModalOpen(false);\n }}\n style={[\n styles.countryListItem,\n phoneVerification.countryCode === country.code && {\n backgroundColor: accent + '18',\n },\n ]}\n >\n <Text style={[styles.countryListText, { color: theme.colors.text }]}>\n {country.name} ({country.callingCode})\n </Text>\n {phoneVerification.countryCode === country.code ? (\n <Ionicons name=\"checkmark\" size={20} color={accent} />\n ) : null}\n </TouchableOpacity>\n ))}\n </ScrollView>\n </SafeAreaView>\n </Modal>\n </SafeAreaView>\n );\n}\n\nconst styles = StyleSheet.create({\n container: { flex: 1 },\n header: {\n justifyContent: 'space-between',\n paddingHorizontal: 16,\n paddingVertical: 8,\n },\n title: { fontSize: 17, fontWeight: '600' },\n content: { padding: 20, paddingBottom: 40 },\n subtitle: { fontSize: 22, fontWeight: '700', marginBottom: 8 },\n description: { fontSize: 14, marginBottom: 24, lineHeight: 20 },\n form: { gap: 14 },\n phoneRow: {\n borderWidth: 1,\n borderRadius: 10,\n minHeight: 48,\n overflow: 'hidden',\n },\n countryChip: {\n paddingHorizontal: 12,\n paddingVertical: 12,\n },\n callingCode: { fontSize: 16, fontWeight: '600', marginRight: 4 },\n phoneDivider: { width: StyleSheet.hairlineWidth, alignSelf: 'stretch' },\n phoneInput: {\n flex: 1,\n paddingHorizontal: 12,\n paddingVertical: Platform.OS === 'ios' ? 12 : 10,\n fontSize: 16,\n },\n otpInputContainer: {\n borderWidth: 1,\n borderRadius: 10,\n paddingHorizontal: 16,\n },\n otpInput: {\n paddingVertical: 14,\n fontSize: 22,\n fontWeight: '600',\n letterSpacing: 6,\n textAlign: 'center',\n },\n button: {\n borderRadius: 10,\n paddingVertical: 14,\n alignItems: 'center',\n justifyContent: 'center',\n marginTop: 4,\n },\n buttonText: { color: '#fff', fontSize: 16, fontWeight: '600' },\n errorBox: {\n flexDirection: 'row',\n alignItems: 'center',\n borderRadius: 8,\n paddingHorizontal: 12,\n paddingVertical: 10,\n gap: 8,\n },\n errorText: { fontSize: 13, flex: 1 },\n linkText: { fontSize: 14, textAlign: 'center', fontWeight: '500' },\n modalFill: { flex: 1 },\n modalHeader: {\n justifyContent: 'space-between',\n paddingHorizontal: 16,\n paddingVertical: 12,\n },\n modalTitle: { fontSize: 18, fontWeight: '700' },\n countryListItem: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingHorizontal: 16,\n paddingVertical: 14,\n borderBottomWidth: StyleSheet.hairlineWidth,\n borderBottomColor: 'rgba(0,0,0,0.06)',\n },\n countryListText: { fontSize: 16 },\n});\n"],"names":["React"],"mappings":"4ZAkCA,MAAM,gBAAiC,CAAC;AAAA,EACtC,IAAM,EAAA,IAAA;AAAA,EACN,IAAM,EAAA,eAAA;AAAA,EACN,WAAa,EAAA;AACf,CAAG,EAAA;AAAA,EACD,IAAM,EAAA,IAAA;AAAA,EACN,IAAM,EAAA,OAAA;AAAA,EACN,WAAa,EAAA;AACf,CAAG,EAAA;AAAA,EACD,IAAM,EAAA,IAAA;AAAA,EACN,IAAM,EAAA,UAAA;AAAA,EACN,WAAa,EAAA;AACf,CAAG,EAAA;AAAA,EACD,IAAM,EAAA,IAAA;AAAA,EACN,IAAM,EAAA,YAAA;AAAA,EACN,WAAa,EAAA;AACf,CAAG,EAAA;AAAA,EACD,IAAM,EAAA,IAAA;AAAA,EACN,IAAM,EAAA,sBAAA;AAAA,EACN,WAAa,EAAA;AACf,CAAG,EAAA;AAAA,EACD,IAAM,EAAA,IAAA;AAAA,EACN,IAAM,EAAA,gBAAA;AAAA,EACN,WAAa,EAAA;AACf,CAAG,EAAA;AAAA,EACD,IAAM,EAAA,IAAA;AAAA,EACN,IAAM,EAAA,QAAA;AAAA,EACN,WAAa,EAAA;AACf,CAAG,EAAA;AAAA,EACD,IAAM,EAAA,IAAA;AAAA,EACN,IAAM,EAAA,WAAA;AAAA,EACN,WAAa,EAAA;AACf,CAAG,EAAA;AAAA,EACD,IAAM,EAAA,IAAA;AAAA,EACN,IAAM,EAAA,QAAA;AAAA,EACN,WAAa,EAAA;AACf,CAAG,EAAA;AAAA,EACD,IAAM,EAAA,IAAA;AAAA,EACN,IAAM,EAAA,SAAA;AAAA,EACN,WAAa,EAAA;AACf,CAAG,EAAA;AAAA,EACD,IAAM,EAAA,IAAA;AAAA,EACN,IAAM,EAAA,OAAA;AAAA,EACN,WAAa,EAAA;AACf,CAAG,EAAA;AAAA,EACD,IAAM,EAAA,IAAA;AAAA,EACN,IAAM,EAAA,OAAA;AAAA,EACN,WAAa,EAAA;AACf,CAAG,EAAA;AAAA,EACD,IAAM,EAAA,IAAA;AAAA,EACN,IAAM,EAAA,QAAA;AAAA,EACN,WAAa,EAAA;AACf,CAAG,EAAA;AAAA,EACD,IAAM,EAAA,IAAA;AAAA,EACN,IAAM,EAAA,QAAA;AAAA,EACN,WAAa,EAAA;AACf,CAAG,EAAA;AAAA,EACD,IAAM,EAAA,IAAA;AAAA,EACN,IAAM,EAAA,WAAA;AAAA,EACN,WAAa,EAAA;AACf,CAAG,EAAA;AAAA,EACD,IAAM,EAAA,IAAA;AAAA,EACN,IAAM,EAAA,OAAA;AAAA,EACN,WAAa,EAAA;AACf,CAAG,EAAA;AAAA,EACD,IAAM,EAAA,IAAA;AAAA,EACN,IAAM,EAAA,OAAA;AAAA,EACN,WAAa,EAAA;AACf,CAAC,CAAA;AAQD,MAAM,0BAAA,GAA6B,CAAC,IAAI,CAAA;AACjC,SAAS,gBAAiB,CAAA,GAAA,GAA0B,OAAQ,CAAA,GAAA,CAAI,wCAA2D,EAAA;AAChI,EAAA,MAAM,QAAQ,GAAK,IAAA,IAAA,GAAA,MAAA,GAAA,GAAA,CAAA,IAAA,EAAA;AACnB,EAAI,IAAA,KAAA,KAAU,KAAY,OAAA,IAAA;AAC1B,EAAI,IAAA,CAAC,OAAc,OAAA,0BAAA;AACnB,EAAM,MAAA,KAAA,GAAQ,MAAM,KAAM,CAAA,GAAG,EAAE,GAAI,CAAA,CAAA,CAAA,KAAK,CAAE,CAAA,IAAA,EAAM,CAAA,CAAE,OAAO,OAAO,CAAA,CAAE,GAAI,CAAA,CAAA,CAAA,KAAK,CAAE,CAAA,UAAA,CAAW,GAAG,CAAI,GAAA,CAAA,GAAI,CAAI,CAAA,EAAA,CAAC,CAAE,CAAA,CAAA;AAC1G,EAAO,OAAA,KAAA,CAAM,SAAS,KAAQ,GAAA,0BAAA;AAChC;AACO,SAAS,eAAgB,CAAA,GAAA,GAAuB,aAAe,EAAA,OAAA,GAA2B,kBAAqC,EAAA;AACpI,EAAI,IAAA,CAAC,SAAgB,OAAA,GAAA;AACrB,EAAM,MAAA,OAAA,GAAU,IAAI,MAAO,CAAA,CAAA,CAAA,KAAK,QAAQ,QAAS,CAAA,CAAA,CAAE,WAAW,CAAC,CAAA;AAC/D,EAAA,OAAO,QAAQ,MAAS,GAAA,OAAA,GAAU,CAAC,GAAA,CAAI,CAAC,CAAC,CAAA;AAC3C;AACA,MAAM,YAA6B,eAAgB,EAAA;AACnD,SAAS,QAAS,CAAA;AAAA,EAChB,WAAA;AAAA,EACA,WAAA;AAAA,EACA,KAAA;AAAA,EACA,cAAA;AAAA,EACA,aAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAQG,EAAA;AA5IH,EAAA,IAAA,EAAA;AA6IE,EAAA,uBAAQ,IAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,QAAU,EAAA;AAAA,IACpC,aAAe,EAAA,KAAA;AAAA,IACf,UAAY,EAAA,QAAA;AAAA,IACZ,WAAA,EAAa,MAAM,MAAO,CAAA,MAAA;AAAA,IAC1B,eAAiB,EAAA,CAAA,EAAA,GAAA,KAAA,CAAM,MAAO,CAAA,IAAA,KAAb,IAAqB,GAAA,EAAA,GAAA;AAAA,GACvC,CACS,EAAA,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,oBAAiB,OAAS,EAAA,cAAA,EAAgB,UAAoB,KAAO,EAAA,CAAC,OAAO,WAAa,EAAA;AAAA,MACjG,aAAe,EAAA,KAAA;AAAA,MACf,UAAY,EAAA;AAAA,KACb,CAAA,EAAG,iBAAkB,EAAA,QAAA,EAAS,oBAAmB,qBACtC,EAAA,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,WAAa,EAAA;AAAA,QAC1C,KAAA,EAAO,MAAM,MAAO,CAAA;AAAA,OACrB,GAAI,QAAY,EAAA,WAAA,EAAA,CAAA;AAAA,sBACP,GAAA,CAAC,YAAS,IAAK,EAAA,cAAA,EAAe,MAAM,EAAI,EAAA,KAAA,EAAO,KAAM,CAAA,MAAA,CAAO,aAAe,EAAA;AAAA,KAC/E,EAAA,CAAA;AAAA,oBACC,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,YAAc,EAAA;AAAA,MACzC,eAAA,EAAiB,MAAM,MAAO,CAAA;AAAA,KAC/B,CAAG,EAAA,CAAA;AAAA,oBACK,GAAA,CAAA,SAAA,EAAA,EAAU,KAAO,EAAA,CAAC,OAAO,UAAY,EAAA;AAAA,MAC5C,KAAA,EAAO,MAAM,MAAO,CAAA;AAAA,KACrB,GAAG,WAAY,EAAA,EAAA,EAAG,sBAAsB,KAAM,CAAA,MAAA,CAAO,WAAa,EAAA,YAAA,EAAa,WAAY,EAAA,eAAA,EAAgB,mBAAkB,KAAO,EAAA,KAAA,EAAO,cAAc,aAAe,EAAA,QAAA,EAAU,CAAC,QAAU,EAAA,SAAA,EAAW,EAAI,EAAA,MAAA,EAAO,yBAA0B,EAAA;AAAA,GAC1O,EAAA,CAAA;AACR;AACO,SAAS,kBAAmB,CAAA;AAAA,EACjC,sBAAA;AAAA,EACA,KAAA;AAAA,EACA;AACF,CAA4B,EAAA;AAxK5B,EAAA,IAAA,EAAA;AAyKE,EAAM,MAAA,iBAAA,GAAoB,qBAAqB,IAAI,CAAA;AACnD,EAAM,MAAA,eAAA,GAAkB,SAAU,CAAA,IAAA,CAAK,CAAK,CAAA,KAAA,CAAA,CAAE,SAAS,iBAAkB,CAAA,WAAW,CAAK,IAAA,SAAA,CAAU,CAAC,CAAA;AACpG,EAAA,MAAM,CAAC,gBAAkB,EAAA,mBAAmB,CAAI,GAAAA,cAAA,CAAM,SAAS,KAAK,CAAA;AACpE,EAAM,MAAA,MAAA,GAAS,MAAM,MAAO,CAAA,OAAA;AAC5B,EAAA,MAAM,SAAY,GAAA,iBAAA,CAAkB,GAAI,CAAA,OAAA,CAAQ,OAAO,EAAE,CAAA;AACzD,EAAA,MAAM,iBAAiB,oBAAqB,EAAA;AAC5C,EAAA,MAAM,YAAe,GAAA,cAAA,KAAmB,iBAAkB,CAAA,WAAA,IAAe,SAAc,KAAA,0BAAA,CAAA;AACvF,EAAM,MAAA;AAAA,IACJ;AAAA,GACE,GAAA,iBAAA;AACJ,EAAAA,cAAA,CAAM,UAAU,MAAM;AACpB,IAAA,IAAI,iBAAkB,CAAA,KAAA,KAAU,UAAc,IAAA,iBAAA,CAAkB,aAAe,EAAA;AAE7E,MAAQ,OAAA,CAAA,OAAA,CAAQ,uBAAuB,iBAAkB,CAAA,aAAa,CAAC,CAAE,CAAA,KAAA,CAAM,CAAC,GAAiB,KAAA;AAC/F,QAAA,MAAM,UAAU,GAAe,YAAA,KAAA,IAAS,GAAI,CAAA,OAAA,GAAU,IAAI,OAAU,GAAA,EAAA;AACpE,QAAA,kBAAA,CAAmB,OAAU,GAAA,CAAA,oBAAA,EAAuB,OAAO,CAAA,CAAA,GAAK,uDAAuD,CAAA;AAAA,OACxH,CAAA;AAAA;AACH,GACF,EAAG,CAAC,iBAAkB,CAAA,KAAA,EAAO,kBAAkB,aAAe,EAAA,sBAAA,EAAwB,kBAAkB,CAAC,CAAA;AACzG,EAAM,MAAA,UAAA,GAAaA,cAAM,CAAA,WAAA,CAAY,MAAM;AACzC,IAAI,IAAA,iBAAA,CAAkB,UAAU,KAAO,EAAA;AACrC,MAAA,iBAAA,CAAkB,YAAa,EAAA;AAAA;AACjC,GACF,EAAG,CAAC,iBAAiB,CAAC,CAAA;AACtB,EAAM,MAAA,aAAA,GAAgBA,cAAM,CAAA,WAAA,CAAY,YAAY;AAClD,IAAA,MAAM,kBAAkB,OAAQ,EAAA;AAAA,GAClC,EAAG,CAAC,iBAAiB,CAAC,CAAA;AACtB,EAAM,MAAA,eAAA,GAAkBA,cAAM,CAAA,WAAA,CAAY,YAAY;AACpD,IAAA,MAAM,kBAAkB,SAAU,EAAA;AAAA,GACpC,EAAG,CAAC,iBAAiB,CAAC,CAAA;AACtB,EAAM,MAAA,YAAA,GAAeA,cAAM,CAAA,WAAA,CAAY,YAAY;AACjD,IAAA,MAAM,kBAAkB,OAAQ,EAAA;AAAA,GAClC,EAAG,CAAC,iBAAiB,CAAC,CAAA;AACtB,EAAA,uBAAQ,IAAA,CAAA,YAAA,EAAA,EAAa,KAAO,EAAA,CAAC,OAAO,SAAW,EAAA;AAAA,IAC7C,eAAA,EAAiB,MAAM,MAAO,CAAA;AAAA,GAC/B,GAAG,KAAO,EAAA,CAAC,OAAO,MAAQ,EAAA,OAAO,GAAG,MAC3B,EAAA,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,MAAQ,EAAA;AAAA,MACnC,aAAe,EAAA,KAAA;AAAA,MACf,UAAY,EAAA;AAAA,KACb,CACY,EAAA,QAAA,EAAA;AAAA,MAAA,iBAAA,CAAkB,UAAU,KAAQ,mBAAA,GAAA,CAAC,gBAAiB,EAAA,EAAA,OAAA,EAAS,YAAY,OAAS,EAAA;AAAA,QAC7F,GAAK,EAAA,EAAA;AAAA,QACL,MAAQ,EAAA,EAAA;AAAA,QACR,IAAM,EAAA,EAAA;AAAA,QACN,KAAO,EAAA;AAAA,OAES,EAAA,QAAA,kBAAA,GAAA,CAAC,QAAS,EAAA,EAAA,IAAA,EAAK,gBAAe,IAAM,EAAA,EAAA,EAAI,KAAO,EAAA,KAAA,CAAM,OAAO,IAAM,EAAA,CAAA,EACtE,CAAsB,mBAAA,GAAA,CAAC,QAAK,KAAO,EAAA;AAAA,QAC/C,KAAO,EAAA;AAAA,OACN,EAAA,CAAA;AAAA,sBACQ,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,KAAO,EAAA;AAAA,QACpC,KAAA,EAAO,MAAM,MAAO,CAAA,IAAA;AAAA,QACpB,IAAM,EAAA,CAAA;AAAA,QACN,SAAW,EAAA;AAAA,OACZ,GAAG,QAEM,EAAA,aAAA,EAAA,CAAA;AAAA,sBACA,GAAA,CAAC,QAAK,KAAO,EAAA;AAAA,QACrB,KAAO,EAAA;AAAA,OACN,EAAA;AAAA,KACG,EAAA,CAAA;AAAA,oBAEC,GAAA,CAAA,UAAA,EAAA,EAAW,qBAAuB,EAAA,MAAA,CAAO,OAAS,EAAA,4BAAA,EAA8B,KAAO,EAAA,yBAAA,EAA0B,SAC7G,EAAA,QAAA,EAAA,iBAAA,CAAkB,KAAU,KAAA,OAAA,mBACrB,IAAA,CAAA,QAAA,EAAA,EAAA,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,QAAU,EAAA;AAAA,QAC7C,KAAA,EAAO,MAAM,MAAO,CAAA;AAAA,OACrB,GAAG,QAAgB,EAAA,kBAAA,EAAA,CAAA;AAAA,sBACH,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,WAAa,EAAA;AAAA,QAChD,KAAA,EAAO,MAAM,MAAO,CAAA;AAAA,OACrB,GAAG,QAEY,EAAA,2EAAA,EAAA,CAAA;AAAA,sBAEC,IAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,MAAA,CAAO,IAChB,EAAA,QAAA,EAAA;AAAA,wBAAC,GAAA,CAAA,QAAA,EAAA,EAAS,aAAa,iBAAkB,CAAA,WAAA,EAAa,aAAa,eAAgB,CAAA,WAAA,EAAa,OAAO,iBAAkB,CAAA,UAAA,EAAY,gBAAgB,MAAM,mBAAA,CAAoB,IAAI,CAAG,EAAA,aAAA,EAAe,kBAAkB,aAAe,EAAA,QAAA,EAAU,iBAAkB,CAAA,OAAA,EAAS,KAAc,EAAA,CAAA;AAAA,QAExR,kBAAkB,KAAQ,mBAAA,IAAA,CAAC,QAAK,KAAO,EAAA,CAAC,OAAO,QAAU,EAAA;AAAA,UAC1E,eAAA,EAAiB,KAAM,CAAA,MAAA,CAAO,KAAQ,GAAA;AAAA,SACvC,CACyB,EAAA,QAAA,EAAA;AAAA,0BAAC,GAAA,CAAA,QAAA,EAAA,EAAS,MAAK,cAAe,EAAA,IAAA,EAAM,IAAI,KAAO,EAAA,KAAA,CAAM,OAAO,KAAO,EAAA,CAAA;AAAA,0BAClE,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,SAAW,EAAA;AAAA,YACtD,KAAA,EAAO,MAAM,MAAO,CAAA;AAAA,WACrB,CAC4B,EAAA,QAAA,EAAA,iBAAA,CAAkB,KACvB,EAAA;AAAA,SAAA,EACJ,CAAU,GAAA,IAAA;AAAA,QAEb,cAAA,mBAAkB,GAAA,CAAA,gBAAA,EAAA,EAAiB,OAAS,EAAA,iBAAA,CAAkB,mBACvD,EAAA,QAAA,kBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,QAAU,EAAA;AAAA,UACrD,KAAO,EAAA;AAAA,SACR,CAAA,EAAG,QAAsB,EAAA,wBAAA,EAAA,CAAA,EACN,CAAsB,GAAA,IAAA;AAAA,wBAEzB,GAAA,CAAA,gBAAA,EAAA,EAAiB,OAAS,EAAA,aAAA,EAAe,UAAU,iBAAkB,CAAA,OAAA,IAAW,CAAC,iBAAA,CAAkB,WAAW,IAAK,EAAA,EAAG,KAAO,EAAA,CAAC,OAAO,MAAQ,EAAA;AAAA,UAC9J,iBAAiB,iBAAkB,CAAA,UAAA,CAAW,MAAS,GAAA,MAAA,GAAS,MAAM,MAAO,CAAA;AAAA,SAC9E,CACsB,EAAA,QAAA,EAAA,iBAAA,CAAkB,OAAU,mBAAA,GAAA,CAAC,qBAAkB,KAAM,EAAA,MAAA,EAAO,IAAK,EAAA,OAAA,EAAQ,oBAAM,GAAA,CAAA,IAAA,EAAA,EAAK,OAAO,MAAO,CAAA,UAAA,EAAY,sBAAQ,CAC3H,EAAA;AAAA,OACJ,EAAA;AAAA,KAAA,EACJ,oBACI,IAAA,CAAA,QAAA,EAAA,EAAA,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,QAAU,EAAA;AAAA,QAC7C,KAAA,EAAO,MAAM,MAAO,CAAA;AAAA,OACrB,GAAG,QAAkB,EAAA,oBAAA,EAAA,CAAA;AAAA,sBACL,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,WAAa,EAAA;AAAA,QAChD,KAAA,EAAO,MAAM,MAAO,CAAA;AAAA,OACrB,CAAA,EACoB,QAAe,EAAA,YAAA,GAAA,CAAA,oBAAA,EAAuB,0BAA0B,CAAA,kBAAA,CAAA,GAAuB,CAAkC,+BAAA,EAAA,eAAA,CAAgB,WAAW,CAAA,CAAA,EAAI,iBAAkB,CAAA,UAAU,CACzL,CAAA,EAAA,CAAA;AAAA,sBAEC,IAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,MAAA,CAAO,IAChB,EAAA,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,iBAAmB,EAAA;AAAA,UACxD,aAAe,EAAA,KAAA;AAAA,UACf,UAAY,EAAA,QAAA;AAAA,UACZ,WAAA,EAAa,MAAM,MAAO,CAAA,MAAA;AAAA,UAC1B,eAAiB,EAAA,CAAA,EAAA,GAAA,KAAA,CAAM,MAAO,CAAA,IAAA,KAAb,IAAqB,GAAA,EAAA,GAAA;AAAA,SACvC,CACqB,EAAA,QAAA,kBAAA,GAAA,CAAC,aAAU,KAAO,EAAA,CAAC,OAAO,QAAU,EAAA;AAAA,UACtD,KAAA,EAAO,MAAM,MAAO,CAAA,IAAA;AAAA,UACpB,IAAM,EAAA;AAAA,SACP,GAAG,WAAY,EAAA,EAAA,EAAG,cAAa,YAAa,EAAA,KAAA,EAAO,kBAAkB,GAAK,EAAA,YAAA,EAAc,kBAAkB,MAAQ,EAAA,QAAA,EAAU,CAAC,iBAAkB,CAAA,OAAA,EAAS,WAAW,CAAG,EAAA,MAAA,EAAO,yBAAwB,CACtL,EAAA,CAAA;AAAA,QAEC,kBAAkB,KAAQ,mBAAA,IAAA,CAAC,QAAK,KAAO,EAAA,CAAC,OAAO,QAAU,EAAA;AAAA,UAC1E,eAAA,EAAiB,KAAM,CAAA,MAAA,CAAO,KAAQ,GAAA;AAAA,SACvC,CACyB,EAAA,QAAA,EAAA;AAAA,0BAAC,GAAA,CAAA,QAAA,EAAA,EAAS,MAAK,cAAe,EAAA,IAAA,EAAM,IAAI,KAAO,EAAA,KAAA,CAAM,OAAO,KAAO,EAAA,CAAA;AAAA,0BAClE,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,SAAW,EAAA;AAAA,YACtD,KAAA,EAAO,MAAM,MAAO,CAAA;AAAA,WACrB,CAC4B,EAAA,QAAA,EAAA,iBAAA,CAAkB,KACvB,EAAA;AAAA,SAAA,EACJ,CAAU,GAAA,IAAA;AAAA,wBAEb,GAAA,CAAA,gBAAA,EAAA,EAAiB,OAAS,EAAA,eAAA,EAAiB,QAAU,EAAA,iBAAA,CAAkB,OAAW,IAAA,SAAA,CAAU,MAAS,GAAA,CAAA,EAAG,KAAO,EAAA,CAAC,OAAO,MAAQ,EAAA;AAAA,UAChJ,iBAAiB,SAAU,CAAA,MAAA,IAAU,CAAI,GAAA,MAAA,GAAS,MAAM,MAAO,CAAA;AAAA,SAChE,CACsB,EAAA,QAAA,EAAA,iBAAA,CAAkB,0BAAW,GAAA,CAAA,iBAAA,EAAA,EAAkB,OAAM,MAAO,EAAA,IAAA,EAAK,SAAQ,CAAK,mBAAA,GAAA,CAAC,QAAK,KAAO,EAAA,MAAA,CAAO,YAC1F,QAAe,EAAA,YAAA,GAAA,UAAA,GAAa,qBACjC,CACR,EAAA,CAAA;AAAA,QAEC,CAAC,YAAA,mBAAgB,GAAA,CAAA,gBAAA,EAAA,EAAiB,SAAS,YAAc,EAAA,QAAA,EAAU,iBAAkB,CAAA,OAAA,EAC9E,QAAC,kBAAA,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,QAAU,EAAA;AAAA,UACrD,KAAO,EAAA;AAAA,SACR,CAAA,EAAG,QAEoB,EAAA,6BAAA,EAAA,CAAA,EACJ,CAAsB,GAAA;AAAA,OAC9B,EAAA;AAAA,KAAA,EACJ,CACR,EAAA,CAAA;AAAA,oBAEC,GAAA,CAAA,KAAA,EAAA,EAAM,OAAS,EAAA,gBAAA,EAAkB,aAAc,EAAA,OAAA,EAAQ,iBAAkB,EAAA,WAAA,EACtE,QAAC,kBAAA,IAAA,CAAA,YAAA,EAAA,EAAa,KAAO,EAAA,CAAC,OAAO,SAAW,EAAA;AAAA,MAChD,eAAA,EAAiB,MAAM,MAAO,CAAA;AAAA,KAC/B,CACa,EAAA,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,WAAa,EAAA;AAAA,QAC5C,aAAe,EAAA,KAAA;AAAA,QACf,UAAY,EAAA;AAAA,OACb,CACe,EAAA,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,UAAY,EAAA;AAAA,UAC7C,KAAA,EAAO,MAAM,MAAO,CAAA;AAAA,SACrB,GAAG,QAAY,EAAA,cAAA,EAAA,CAAA;AAAA,4BACD,gBAAiB,EAAA,EAAA,OAAA,EAAS,MAAM,mBAAA,CAAoB,KAAK,CACtD,EAAA,QAAA,kBAAA,GAAA,CAAC,QAAS,EAAA,EAAA,IAAA,EAAK,SAAQ,IAAM,EAAA,EAAA,EAAI,OAAO,KAAM,CAAA,MAAA,CAAO,MAAM,CAC/D,EAAA;AAAA,OACJ,EAAA,CAAA;AAAA,sBACA,GAAA,CAAC,cACI,QAAU,EAAA,SAAA,CAAA,GAAA,CAAI,6BAAY,IAAA,CAAA,gBAAA,EAAA,EAAoC,SAAS,MAAM;AAC1F,QAAkB,iBAAA,CAAA,cAAA,CAAe,QAAQ,IAAI,CAAA;AAC7C,QAAA,mBAAA,CAAoB,KAAK,CAAA;AAAA,OAC3B,EAAG,OAAO,CAAC,MAAA,CAAO,iBAAiB,iBAAkB,CAAA,WAAA,KAAgB,QAAQ,IAAQ,IAAA;AAAA,QACnF,iBAAiB,MAAS,GAAA;AAAA,OAC3B,CACqB,EAAA,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,eAAiB,EAAA;AAAA,UACxD,KAAA,EAAO,MAAM,MAAO,CAAA;AAAA,SACrB,CACwB,EAAA,QAAA,EAAA;AAAA,UAAQ,OAAA,CAAA,IAAA;AAAA,UAAK,IAAA;AAAA,UAAG,OAAQ,CAAA,WAAA;AAAA,UAAY;AAAA,SACzC,EAAA,CAAA;AAAA,QACC,iBAAkB,CAAA,WAAA,KAAgB,OAAQ,CAAA,IAAA,mBAAQ,GAAA,CAAA,QAAA,EAAA,EAAS,IAAK,EAAA,WAAA,EAAY,IAAM,EAAA,EAAA,EAAI,KAAO,EAAA,MAAA,EAAQ,CAAK,GAAA;AAAA,OAXlE,EAAA,EAAA,OAAA,CAAQ,IAYrD,CAAmB,CAC3B,EAAA;AAAA,KAAA,EACJ,CACJ,EAAA;AAAA,GACJ,EAAA,CAAA;AACR;AACA,MAAM,MAAA,GAAS,WAAW,MAAO,CAAA;AAAA,EAC/B,SAAW,EAAA;AAAA,IACT,IAAM,EAAA;AAAA,GACR;AAAA,EACA,MAAQ,EAAA;AAAA,IACN,cAAgB,EAAA,eAAA;AAAA,IAChB,iBAAmB,EAAA,EAAA;AAAA,IACnB,eAAiB,EAAA;AAAA,GACnB;AAAA,EACA,KAAO,EAAA;AAAA,IACL,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA;AAAA,GACd;AAAA,EACA,OAAS,EAAA;AAAA,IACP,OAAS,EAAA,EAAA;AAAA,IACT,aAAe,EAAA;AAAA,GACjB;AAAA,EACA,QAAU,EAAA;AAAA,IACR,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA,KAAA;AAAA,IACZ,YAAc,EAAA;AAAA,GAChB;AAAA,EACA,WAAa,EAAA;AAAA,IACX,QAAU,EAAA,EAAA;AAAA,IACV,YAAc,EAAA,EAAA;AAAA,IACd,UAAY,EAAA;AAAA,GACd;AAAA,EACA,IAAM,EAAA;AAAA,IACJ,GAAK,EAAA;AAAA,GACP;AAAA,EACA,QAAU,EAAA;AAAA,IACR,WAAa,EAAA,CAAA;AAAA,IACb,YAAc,EAAA,EAAA;AAAA,IACd,SAAW,EAAA,EAAA;AAAA,IACX,QAAU,EAAA;AAAA,GACZ;AAAA,EACA,WAAa,EAAA;AAAA,IACX,iBAAmB,EAAA,EAAA;AAAA,IACnB,eAAiB,EAAA;AAAA,GACnB;AAAA,EACA,WAAa,EAAA;AAAA,IACX,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA,KAAA;AAAA,IACZ,WAAa,EAAA;AAAA,GACf;AAAA,EACA,YAAc,EAAA;AAAA,IACZ,OAAO,UAAW,CAAA,aAAA;AAAA,IAClB,SAAW,EAAA;AAAA,GACb;AAAA,EACA,UAAY,EAAA;AAAA,IACV,IAAM,EAAA,CAAA;AAAA,IACN,iBAAmB,EAAA,EAAA;AAAA,IACnB,eAAiB,EAAA,QAAA,CAAS,EAAO,KAAA,KAAA,GAAQ,EAAK,GAAA,EAAA;AAAA,IAC9C,QAAU,EAAA;AAAA,GACZ;AAAA,EACA,iBAAmB,EAAA;AAAA,IACjB,WAAa,EAAA,CAAA;AAAA,IACb,YAAc,EAAA,EAAA;AAAA,IACd,iBAAmB,EAAA;AAAA,GACrB;AAAA,EACA,QAAU,EAAA;AAAA,IACR,eAAiB,EAAA,EAAA;AAAA,IACjB,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA,KAAA;AAAA,IACZ,aAAe,EAAA,CAAA;AAAA,IACf,SAAW,EAAA;AAAA,GACb;AAAA,EACA,MAAQ,EAAA;AAAA,IACN,YAAc,EAAA,EAAA;AAAA,IACd,eAAiB,EAAA,EAAA;AAAA,IACjB,UAAY,EAAA,QAAA;AAAA,IACZ,cAAgB,EAAA,QAAA;AAAA,IAChB,SAAW,EAAA;AAAA,GACb;AAAA,EACA,UAAY,EAAA;AAAA,IACV,KAAO,EAAA,MAAA;AAAA,IACP,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA;AAAA,GACd;AAAA,EACA,QAAU,EAAA;AAAA,IACR,aAAe,EAAA,KAAA;AAAA,IACf,UAAY,EAAA,QAAA;AAAA,IACZ,YAAc,EAAA,CAAA;AAAA,IACd,iBAAmB,EAAA,EAAA;AAAA,IACnB,eAAiB,EAAA,EAAA;AAAA,IACjB,GAAK,EAAA;AAAA,GACP;AAAA,EACA,SAAW,EAAA;AAAA,IACT,QAAU,EAAA,EAAA;AAAA,IACV,IAAM,EAAA;AAAA,GACR;AAAA,EACA,QAAU,EAAA;AAAA,IACR,QAAU,EAAA,EAAA;AAAA,IACV,SAAW,EAAA,QAAA;AAAA,IACX,UAAY,EAAA;AAAA,GACd;AAAA,EACA,SAAW,EAAA;AAAA,IACT,IAAM,EAAA;AAAA,GACR;AAAA,EACA,WAAa,EAAA;AAAA,IACX,cAAgB,EAAA,eAAA;AAAA,IAChB,iBAAmB,EAAA,EAAA;AAAA,IACnB,eAAiB,EAAA;AAAA,GACnB;AAAA,EACA,UAAY,EAAA;AAAA,IACV,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA;AAAA,GACd;AAAA,EACA,eAAiB,EAAA;AAAA,IACf,aAAe,EAAA,KAAA;AAAA,IACf,UAAY,EAAA,QAAA;AAAA,IACZ,cAAgB,EAAA,eAAA;AAAA,IAChB,iBAAmB,EAAA,EAAA;AAAA,IACnB,eAAiB,EAAA,EAAA;AAAA,IACjB,mBAAmB,UAAW,CAAA,aAAA;AAAA,IAC9B,iBAAmB,EAAA;AAAA,GACrB;AAAA,EACA,eAAiB,EAAA;AAAA,IACf,QAAU,EAAA;AAAA;AAEd,CAAC,CAAA"}
1
+ {"version":3,"file":"RegistrationScreen.js","sources":["../../../src/features/messaging/RegistrationScreen.tsx"],"sourcesContent":["/**\n * Registration screen for Yantra Chat.\n *\n * First-time users are prompted to register with their phone number.\n * The flow:\n * 1. User enters mobile number (country code in the same row)\n * 2. OTP is sent to their number\n * 3. User enters the OTP code to verify\n * 4. Phone number becomes their member ID in the Yantra Chat organization\n *\n * Follows the design from issue #1312.\n */\nimport React from 'react';\nimport {\n StyleSheet,\n View,\n Text,\n TouchableOpacity,\n TextInput,\n ActivityIndicator,\n FlatList,\n ScrollView,\n Modal,\n Platform,\n} from 'react-native';\nimport { SafeAreaView } from 'react-native-safe-area-context';\nimport { Ionicons } from '@expo/vector-icons';\nimport { CHAT_REGISTRATION_TEST_OTP, isChatTestOtpEnabled, usePhoneVerification } from './usePhoneVerification';\nimport { filterCountries, pickerCountries, type CountryOption } from './countryPicker';\n\ninterface RegistrationScreenProps {\n /** Called when registration completes successfully. */\n onRegistrationComplete: (phoneNumber: string) => void;\n /** Theme configuration. */\n theme: { colors: Record<string, string>; fonts: Record<string, Record<string, string>> };\n testID?: string;\n}\n\n/**\n * Every country is offered (see countryPicker.ts). AWS decides where a code can be sent; when it\n * cannot reach a country the send fails with \"not available in <country> yet\" and the person\n * sees that sentence under the number, so nothing here needs to know which countries work.\n */\nconst COUNTRIES: CountryOption[] = pickerCountries();\n\nfunction PhoneRow({\n countryCode,\n callingCode,\n phone,\n onCountryPress,\n onChangePhone,\n disabled,\n theme,\n}: {\n countryCode: string;\n callingCode: string;\n phone: string;\n onCountryPress: () => void;\n onChangePhone: (v: string) => void;\n disabled: boolean;\n theme: RegistrationScreenProps['theme'];\n}) {\n return (\n <View\n style={[\n styles.phoneRow,\n {\n flexDirection: 'row',\n alignItems: 'center',\n borderColor: theme.colors.border,\n backgroundColor: theme.colors.card ?? '#fff',\n },\n ]}\n >\n <TouchableOpacity\n onPress={onCountryPress}\n disabled={disabled}\n style={[styles.countryChip, { flexDirection: 'row', alignItems: 'center' }]}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Select country code\"\n >\n <Text style={[styles.callingCode, { color: theme.colors.text }]}>{callingCode}</Text>\n <Ionicons name=\"chevron-down\" size={18} color={theme.colors.textSecondary} />\n </TouchableOpacity>\n <View style={[styles.phoneDivider, { backgroundColor: theme.colors.border }]} />\n <TextInput\n style={[styles.phoneInput, { color: theme.colors.text }]}\n placeholder=\"\"\n placeholderTextColor={theme.colors.placeholder}\n keyboardType=\"phone-pad\"\n textContentType=\"telephoneNumber\"\n value={phone}\n onChangeText={onChangePhone}\n editable={!disabled}\n maxLength={15}\n testID=\"chat-registration-phone\"\n />\n </View>\n );\n}\n\nexport function RegistrationScreen({ onRegistrationComplete, theme, testID }: RegistrationScreenProps) {\n const phoneVerification = usePhoneVerification('US');\n const selectedCountry = COUNTRIES.find((c) => c.code === phoneVerification.countryCode) || COUNTRIES[0];\n const [countryModalOpen, setCountryModalOpen] = React.useState(false);\n const [countryQuery, setCountryQuery] = React.useState('');\n const visibleCountries = React.useMemo(() => filterCountries(COUNTRIES, countryQuery), [countryQuery]);\n const closeCountryModal = React.useCallback(() => {\n setCountryModalOpen(false);\n setCountryQuery('');\n }, []);\n const accent = theme.colors.primary;\n const otpDigits = phoneVerification.otp.replace(/\\D/g, '');\n const testOtpEnabled = isChatTestOtpEnabled();\n const usingTestOtp = testOtpEnabled && (phoneVerification.testOtpMode || otpDigits === CHAT_REGISTRATION_TEST_OTP);\n\n const { registrationFailed } = phoneVerification;\n React.useEffect(() => {\n if (phoneVerification.stage === 'verified' && phoneVerification.verifiedPhone) {\n // A failed registration used to be dropped here, leaving the screen stuck with no reason.\n Promise.resolve(onRegistrationComplete(phoneVerification.verifiedPhone)).catch((err: unknown) => {\n const message = err instanceof Error && err.message ? err.message : '';\n registrationFailed(\n message\n ? `Could not register: ${message}`\n : 'Could not register for Yantra Chat. Please try again.',\n );\n });\n }\n }, [phoneVerification.stage, phoneVerification.verifiedPhone, onRegistrationComplete, registrationFailed]);\n\n const handleBack = React.useCallback(() => {\n if (phoneVerification.stage === 'otp') {\n phoneVerification.resetToInput();\n }\n }, [phoneVerification]);\n\n const handleSendOtp = React.useCallback(async () => {\n await phoneVerification.sendOtp();\n }, [phoneVerification]);\n\n const handleVerifyOtp = React.useCallback(async () => {\n await phoneVerification.verifyOtp();\n }, [phoneVerification]);\n\n const handleResend = React.useCallback(async () => {\n await phoneVerification.sendOtp();\n }, [phoneVerification]);\n\n return (\n <SafeAreaView\n style={[styles.container, { backgroundColor: theme.colors.background }]}\n edges={['top', 'left', 'right']}\n testID={testID}\n >\n <View style={[styles.header, { flexDirection: 'row', alignItems: 'center' }]}>\n {phoneVerification.stage === 'otp' ? (\n <TouchableOpacity onPress={handleBack} hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}>\n <Ionicons name=\"chevron-back\" size={28} color={theme.colors.text} />\n </TouchableOpacity>\n ) : (\n <View style={{ width: 28 }} />\n )}\n <Text style={[styles.title, { color: theme.colors.text, flex: 1, textAlign: 'center' }]}>\n Yantra Chat\n </Text>\n <View style={{ width: 28 }} />\n </View>\n\n <ScrollView\n contentContainerStyle={styles.content}\n showsVerticalScrollIndicator={false}\n keyboardShouldPersistTaps=\"handled\"\n >\n {phoneVerification.stage === 'input' ? (\n <>\n <Text style={[styles.subtitle, { color: theme.colors.text }]}>Register to Chat</Text>\n <Text style={[styles.description, { color: theme.colors.textSecondary }]}>\n Enter your mobile number to get started. You&apos;ll receive an OTP to verify.\n </Text>\n\n <View style={styles.form}>\n <PhoneRow\n countryCode={phoneVerification.countryCode}\n callingCode={selectedCountry.callingCode}\n phone={phoneVerification.inputPhone}\n onCountryPress={() => setCountryModalOpen(true)}\n onChangePhone={phoneVerification.setInputPhone}\n disabled={phoneVerification.loading}\n theme={theme}\n />\n\n {phoneVerification.error ? (\n <View style={[styles.errorBox, { backgroundColor: `${theme.colors.error}10` }]}>\n <Ionicons name=\"alert-circle\" size={16} color={theme.colors.error} />\n <Text style={[styles.errorText, { color: theme.colors.error }]}>\n {phoneVerification.error}\n </Text>\n </View>\n ) : null}\n\n {testOtpEnabled ? (\n <TouchableOpacity onPress={phoneVerification.continueWithTestOtp}>\n <Text style={[styles.linkText, { color: accent }]}>Continue with test OTP</Text>\n </TouchableOpacity>\n ) : null}\n\n <TouchableOpacity\n onPress={handleSendOtp}\n disabled={phoneVerification.loading || !phoneVerification.inputPhone.trim()}\n style={[\n styles.button,\n {\n backgroundColor: phoneVerification.inputPhone.trim()\n ? accent\n : theme.colors.border,\n },\n ]}\n >\n {phoneVerification.loading ? (\n <ActivityIndicator color=\"#fff\" size=\"small\" />\n ) : (\n <Text style={styles.buttonText}>Send OTP</Text>\n )}\n </TouchableOpacity>\n </View>\n </>\n ) : (\n <>\n <Text style={[styles.subtitle, { color: theme.colors.text }]}>Verify your number</Text>\n <Text style={[styles.description, { color: theme.colors.textSecondary }]}>\n {usingTestOtp\n ? `Test mode: use code ${CHAT_REGISTRATION_TEST_OTP} and tap Continue.`\n : `Enter the 6-digit code sent to ${selectedCountry.callingCode} ${phoneVerification.inputPhone}`}\n </Text>\n\n <View style={styles.form}>\n <View\n style={[\n styles.otpInputContainer,\n {\n flexDirection: 'row',\n alignItems: 'center',\n borderColor: theme.colors.border,\n backgroundColor: theme.colors.card ?? '#fff',\n },\n ]}\n >\n <TextInput\n style={[styles.otpInput, { color: theme.colors.text, flex: 1 }]}\n placeholder=\"\"\n keyboardType=\"number-pad\"\n value={phoneVerification.otp}\n onChangeText={phoneVerification.setOtp}\n editable={!phoneVerification.loading}\n maxLength={6}\n testID=\"chat-registration-otp\"\n />\n </View>\n\n {phoneVerification.error ? (\n <View style={[styles.errorBox, { backgroundColor: `${theme.colors.error}10` }]}>\n <Ionicons name=\"alert-circle\" size={16} color={theme.colors.error} />\n <Text style={[styles.errorText, { color: theme.colors.error }]}>\n {phoneVerification.error}\n </Text>\n </View>\n ) : null}\n\n <TouchableOpacity\n onPress={handleVerifyOtp}\n disabled={phoneVerification.loading || otpDigits.length < 6}\n style={[\n styles.button,\n {\n backgroundColor: otpDigits.length >= 6 ? accent : theme.colors.border,\n },\n ]}\n >\n {phoneVerification.loading ? (\n <ActivityIndicator color=\"#fff\" size=\"small\" />\n ) : (\n <Text style={styles.buttonText}>\n {usingTestOtp ? 'Continue' : 'Verify & Register'}\n </Text>\n )}\n </TouchableOpacity>\n\n {!usingTestOtp ? (\n <TouchableOpacity onPress={handleResend} disabled={phoneVerification.loading}>\n <Text style={[styles.linkText, { color: accent }]}>\n Didn&apos;t get the code? Resend\n </Text>\n </TouchableOpacity>\n ) : null}\n </View>\n </>\n )}\n </ScrollView>\n\n <Modal\n visible={countryModalOpen}\n animationType=\"slide\"\n presentationStyle=\"pageSheet\"\n onRequestClose={closeCountryModal}\n >\n <SafeAreaView style={[styles.modalFill, { backgroundColor: theme.colors.background }]}>\n <View style={[styles.modalHeader, { flexDirection: 'row', alignItems: 'center' }]}>\n <Text style={[styles.modalTitle, { color: theme.colors.text }]}>Country code</Text>\n <TouchableOpacity\n onPress={closeCountryModal}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Close\"\n >\n <Ionicons name=\"close\" size={26} color={theme.colors.text} />\n </TouchableOpacity>\n </View>\n <View\n style={[\n styles.countrySearch,\n { borderColor: theme.colors.border, backgroundColor: theme.colors.card ?? '#fff' },\n ]}\n >\n <Ionicons name=\"search\" size={18} color={theme.colors.textSecondary ?? theme.colors.text} />\n <TextInput\n value={countryQuery}\n onChangeText={setCountryQuery}\n placeholder=\"Search country or code\"\n placeholderTextColor={theme.colors.textSecondary ?? '#888'}\n autoCorrect={false}\n autoCapitalize=\"none\"\n clearButtonMode=\"while-editing\"\n style={[styles.countrySearchInput, { color: theme.colors.text }]}\n testID=\"country-search\"\n />\n </View>\n <FlatList\n data={visibleCountries}\n keyExtractor={(country) => country.code}\n keyboardShouldPersistTaps=\"handled\"\n initialNumToRender={24}\n ListEmptyComponent={\n <Text\n style={[\n styles.countryEmpty,\n { color: theme.colors.textSecondary ?? theme.colors.text },\n ]}\n >\n No country matches &quot;{countryQuery.trim()}&quot;\n </Text>\n }\n renderItem={({ item: country }) => (\n <TouchableOpacity\n onPress={() => {\n phoneVerification.setCountryCode(country.code);\n closeCountryModal();\n }}\n style={[\n styles.countryListItem,\n phoneVerification.countryCode === country.code && {\n backgroundColor: `${accent}18`,\n },\n ]}\n accessibilityRole=\"button\"\n accessibilityState={{ selected: phoneVerification.countryCode === country.code }}\n >\n <Text style={[styles.countryListText, { color: theme.colors.text }]}>\n {country.name} ({country.callingCode})\n </Text>\n {phoneVerification.countryCode === country.code ? (\n <Ionicons name=\"checkmark\" size={20} color={accent} />\n ) : null}\n </TouchableOpacity>\n )}\n />\n </SafeAreaView>\n </Modal>\n </SafeAreaView>\n );\n}\n\nconst styles = StyleSheet.create({\n container: { flex: 1 },\n header: {\n justifyContent: 'space-between',\n paddingHorizontal: 16,\n paddingVertical: 8,\n },\n title: { fontSize: 17, fontWeight: '600' },\n content: { padding: 20, paddingBottom: 40 },\n subtitle: { fontSize: 22, fontWeight: '700', marginBottom: 8 },\n description: { fontSize: 14, marginBottom: 24, lineHeight: 20 },\n form: { gap: 14 },\n phoneRow: {\n borderWidth: 1,\n borderRadius: 10,\n minHeight: 48,\n overflow: 'hidden',\n },\n countryChip: {\n paddingHorizontal: 12,\n paddingVertical: 12,\n },\n callingCode: { fontSize: 16, fontWeight: '600', marginRight: 4 },\n phoneDivider: { width: StyleSheet.hairlineWidth, alignSelf: 'stretch' },\n phoneInput: {\n flex: 1,\n paddingHorizontal: 12,\n paddingVertical: Platform.OS === 'ios' ? 12 : 10,\n fontSize: 16,\n },\n otpInputContainer: {\n borderWidth: 1,\n borderRadius: 10,\n paddingHorizontal: 16,\n },\n otpInput: {\n paddingVertical: 14,\n fontSize: 22,\n fontWeight: '600',\n letterSpacing: 6,\n textAlign: 'center',\n },\n button: {\n borderRadius: 10,\n paddingVertical: 14,\n alignItems: 'center',\n justifyContent: 'center',\n marginTop: 4,\n },\n buttonText: { color: '#fff', fontSize: 16, fontWeight: '600' },\n errorBox: {\n flexDirection: 'row',\n alignItems: 'center',\n borderRadius: 8,\n paddingHorizontal: 12,\n paddingVertical: 10,\n gap: 8,\n },\n errorText: { fontSize: 13, flex: 1 },\n linkText: { fontSize: 14, textAlign: 'center', fontWeight: '500' },\n modalFill: { flex: 1 },\n countrySearch: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 8,\n marginHorizontal: 16,\n marginBottom: 8,\n paddingHorizontal: 12,\n borderWidth: 1,\n borderRadius: 10,\n minHeight: 42,\n },\n countrySearchInput: { flex: 1, fontSize: 16, paddingVertical: Platform.OS === 'ios' ? 10 : 6 },\n countryEmpty: { textAlign: 'center', padding: 24, fontSize: 14 },\n modalHeader: {\n justifyContent: 'space-between',\n paddingHorizontal: 16,\n paddingVertical: 12,\n },\n modalTitle: { fontSize: 18, fontWeight: '700' },\n countryListItem: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingHorizontal: 16,\n paddingVertical: 14,\n borderBottomWidth: StyleSheet.hairlineWidth,\n borderBottomColor: 'rgba(0,0,0,0.06)',\n },\n countryListText: { fontSize: 16 },\n});\n"],"names":["React"],"mappings":"seAkCA,MAAM,YAA6B,eAAgB,EAAA;AACnD,SAAS,QAAS,CAAA;AAAA,EAChB,WAAA;AAAA,EACA,WAAA;AAAA,EACA,KAAA;AAAA,EACA,cAAA;AAAA,EACA,aAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAQG,EAAA;AAnDH,EAAA,IAAA,EAAA;AAoDE,EAAA,uBAAQ,IAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,QAAU,EAAA;AAAA,IACpC,aAAe,EAAA,KAAA;AAAA,IACf,UAAY,EAAA,QAAA;AAAA,IACZ,WAAA,EAAa,MAAM,MAAO,CAAA,MAAA;AAAA,IAC1B,eAAiB,EAAA,CAAA,EAAA,GAAA,KAAA,CAAM,MAAO,CAAA,IAAA,KAAb,IAAqB,GAAA,EAAA,GAAA;AAAA,GACvC,CACS,EAAA,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,oBAAiB,OAAS,EAAA,cAAA,EAAgB,UAAoB,KAAO,EAAA,CAAC,OAAO,WAAa,EAAA;AAAA,MACjG,aAAe,EAAA,KAAA;AAAA,MACf,UAAY,EAAA;AAAA,KACb,CAAA,EAAG,iBAAkB,EAAA,QAAA,EAAS,oBAAmB,qBACtC,EAAA,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,WAAa,EAAA;AAAA,QAC1C,KAAA,EAAO,MAAM,MAAO,CAAA;AAAA,OACrB,GAAI,QAAY,EAAA,WAAA,EAAA,CAAA;AAAA,sBACP,GAAA,CAAC,YAAS,IAAK,EAAA,cAAA,EAAe,MAAM,EAAI,EAAA,KAAA,EAAO,KAAM,CAAA,MAAA,CAAO,aAAe,EAAA;AAAA,KAC/E,EAAA,CAAA;AAAA,oBACC,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,YAAc,EAAA;AAAA,MACzC,eAAA,EAAiB,MAAM,MAAO,CAAA;AAAA,KAC/B,CAAG,EAAA,CAAA;AAAA,oBACK,GAAA,CAAA,SAAA,EAAA,EAAU,KAAO,EAAA,CAAC,OAAO,UAAY,EAAA;AAAA,MAC5C,KAAA,EAAO,MAAM,MAAO,CAAA;AAAA,KACrB,GAAG,WAAY,EAAA,EAAA,EAAG,sBAAsB,KAAM,CAAA,MAAA,CAAO,WAAa,EAAA,YAAA,EAAa,WAAY,EAAA,eAAA,EAAgB,mBAAkB,KAAO,EAAA,KAAA,EAAO,cAAc,aAAe,EAAA,QAAA,EAAU,CAAC,QAAU,EAAA,SAAA,EAAW,EAAI,EAAA,MAAA,EAAO,yBAA0B,EAAA;AAAA,GAC1O,EAAA,CAAA;AACR;AACO,SAAS,kBAAmB,CAAA;AAAA,EACjC,sBAAA;AAAA,EACA,KAAA;AAAA,EACA;AACF,CAA4B,EAAA;AA/E5B,EAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AAgFE,EAAM,MAAA,iBAAA,GAAoB,qBAAqB,IAAI,CAAA;AACnD,EAAM,MAAA,eAAA,GAAkB,SAAU,CAAA,IAAA,CAAK,CAAK,CAAA,KAAA,CAAA,CAAE,SAAS,iBAAkB,CAAA,WAAW,CAAK,IAAA,SAAA,CAAU,CAAC,CAAA;AACpG,EAAA,MAAM,CAAC,gBAAkB,EAAA,mBAAmB,CAAI,GAAAA,cAAA,CAAM,SAAS,KAAK,CAAA;AACpE,EAAA,MAAM,CAAC,YAAc,EAAA,eAAe,CAAI,GAAAA,cAAA,CAAM,SAAS,EAAE,CAAA;AACzD,EAAM,MAAA,gBAAA,GAAmBA,cAAM,CAAA,OAAA,CAAQ,MAAM,eAAA,CAAgB,WAAW,YAAY,CAAA,EAAG,CAAC,YAAY,CAAC,CAAA;AACrG,EAAM,MAAA,iBAAA,GAAoBA,cAAM,CAAA,WAAA,CAAY,MAAM;AAChD,IAAA,mBAAA,CAAoB,KAAK,CAAA;AACzB,IAAA,eAAA,CAAgB,EAAE,CAAA;AAAA,GACpB,EAAG,EAAE,CAAA;AACL,EAAM,MAAA,MAAA,GAAS,MAAM,MAAO,CAAA,OAAA;AAC5B,EAAA,MAAM,SAAY,GAAA,iBAAA,CAAkB,GAAI,CAAA,OAAA,CAAQ,OAAO,EAAE,CAAA;AACzD,EAAA,MAAM,iBAAiB,oBAAqB,EAAA;AAC5C,EAAA,MAAM,YAAe,GAAA,cAAA,KAAmB,iBAAkB,CAAA,WAAA,IAAe,SAAc,KAAA,0BAAA,CAAA;AACvF,EAAM,MAAA;AAAA,IACJ;AAAA,GACE,GAAA,iBAAA;AACJ,EAAAA,cAAA,CAAM,UAAU,MAAM;AACpB,IAAA,IAAI,iBAAkB,CAAA,KAAA,KAAU,UAAc,IAAA,iBAAA,CAAkB,aAAe,EAAA;AAE7E,MAAQ,OAAA,CAAA,OAAA,CAAQ,uBAAuB,iBAAkB,CAAA,aAAa,CAAC,CAAE,CAAA,KAAA,CAAM,CAAC,GAAiB,KAAA;AAC/F,QAAA,MAAM,UAAU,GAAe,YAAA,KAAA,IAAS,GAAI,CAAA,OAAA,GAAU,IAAI,OAAU,GAAA,EAAA;AACpE,QAAA,kBAAA,CAAmB,OAAU,GAAA,CAAA,oBAAA,EAAuB,OAAO,CAAA,CAAA,GAAK,uDAAuD,CAAA;AAAA,OACxH,CAAA;AAAA;AACH,GACF,EAAG,CAAC,iBAAkB,CAAA,KAAA,EAAO,kBAAkB,aAAe,EAAA,sBAAA,EAAwB,kBAAkB,CAAC,CAAA;AACzG,EAAM,MAAA,UAAA,GAAaA,cAAM,CAAA,WAAA,CAAY,MAAM;AACzC,IAAI,IAAA,iBAAA,CAAkB,UAAU,KAAO,EAAA;AACrC,MAAA,iBAAA,CAAkB,YAAa,EAAA;AAAA;AACjC,GACF,EAAG,CAAC,iBAAiB,CAAC,CAAA;AACtB,EAAM,MAAA,aAAA,GAAgBA,cAAM,CAAA,WAAA,CAAY,YAAY;AAClD,IAAA,MAAM,kBAAkB,OAAQ,EAAA;AAAA,GAClC,EAAG,CAAC,iBAAiB,CAAC,CAAA;AACtB,EAAM,MAAA,eAAA,GAAkBA,cAAM,CAAA,WAAA,CAAY,YAAY;AACpD,IAAA,MAAM,kBAAkB,SAAU,EAAA;AAAA,GACpC,EAAG,CAAC,iBAAiB,CAAC,CAAA;AACtB,EAAM,MAAA,YAAA,GAAeA,cAAM,CAAA,WAAA,CAAY,YAAY;AACjD,IAAA,MAAM,kBAAkB,OAAQ,EAAA;AAAA,GAClC,EAAG,CAAC,iBAAiB,CAAC,CAAA;AACtB,EAAA,uBAAQ,IAAA,CAAA,YAAA,EAAA,EAAa,KAAO,EAAA,CAAC,OAAO,SAAW,EAAA;AAAA,IAC7C,eAAA,EAAiB,MAAM,MAAO,CAAA;AAAA,GAC/B,GAAG,KAAO,EAAA,CAAC,OAAO,MAAQ,EAAA,OAAO,GAAG,MAC3B,EAAA,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,MAAQ,EAAA;AAAA,MACnC,aAAe,EAAA,KAAA;AAAA,MACf,UAAY,EAAA;AAAA,KACb,CACY,EAAA,QAAA,EAAA;AAAA,MAAA,iBAAA,CAAkB,UAAU,KAAQ,mBAAA,GAAA,CAAC,gBAAiB,EAAA,EAAA,OAAA,EAAS,YAAY,OAAS,EAAA;AAAA,QAC7F,GAAK,EAAA,EAAA;AAAA,QACL,MAAQ,EAAA,EAAA;AAAA,QACR,IAAM,EAAA,EAAA;AAAA,QACN,KAAO,EAAA;AAAA,OAES,EAAA,QAAA,kBAAA,GAAA,CAAC,QAAS,EAAA,EAAA,IAAA,EAAK,gBAAe,IAAM,EAAA,EAAA,EAAI,KAAO,EAAA,KAAA,CAAM,OAAO,IAAM,EAAA,CAAA,EACtE,CAAsB,mBAAA,GAAA,CAAC,QAAK,KAAO,EAAA;AAAA,QAC/C,KAAO,EAAA;AAAA,OACN,EAAA,CAAA;AAAA,sBACQ,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,KAAO,EAAA;AAAA,QACpC,KAAA,EAAO,MAAM,MAAO,CAAA,IAAA;AAAA,QACpB,IAAM,EAAA,CAAA;AAAA,QACN,SAAW,EAAA;AAAA,OACZ,GAAG,QAEM,EAAA,aAAA,EAAA,CAAA;AAAA,sBACA,GAAA,CAAC,QAAK,KAAO,EAAA;AAAA,QACrB,KAAO,EAAA;AAAA,OACN,EAAA;AAAA,KACG,EAAA,CAAA;AAAA,oBAEC,GAAA,CAAA,UAAA,EAAA,EAAW,qBAAuB,EAAA,MAAA,CAAO,OAAS,EAAA,4BAAA,EAA8B,KAAO,EAAA,yBAAA,EAA0B,SAC7G,EAAA,QAAA,EAAA,iBAAA,CAAkB,KAAU,KAAA,OAAA,mBACrB,IAAA,CAAA,QAAA,EAAA,EAAA,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,QAAU,EAAA;AAAA,QAC7C,KAAA,EAAO,MAAM,MAAO,CAAA;AAAA,OACrB,GAAG,QAAgB,EAAA,kBAAA,EAAA,CAAA;AAAA,sBACH,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,WAAa,EAAA;AAAA,QAChD,KAAA,EAAO,MAAM,MAAO,CAAA;AAAA,OACrB,GAAG,QAEY,EAAA,2EAAA,EAAA,CAAA;AAAA,sBAEC,IAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,MAAA,CAAO,IAChB,EAAA,QAAA,EAAA;AAAA,wBAAC,GAAA,CAAA,QAAA,EAAA,EAAS,aAAa,iBAAkB,CAAA,WAAA,EAAa,aAAa,eAAgB,CAAA,WAAA,EAAa,OAAO,iBAAkB,CAAA,UAAA,EAAY,gBAAgB,MAAM,mBAAA,CAAoB,IAAI,CAAG,EAAA,aAAA,EAAe,kBAAkB,aAAe,EAAA,QAAA,EAAU,iBAAkB,CAAA,OAAA,EAAS,KAAc,EAAA,CAAA;AAAA,QAExR,kBAAkB,KAAQ,mBAAA,IAAA,CAAC,QAAK,KAAO,EAAA,CAAC,OAAO,QAAU,EAAA;AAAA,UAC1E,eAAiB,EAAA,CAAA,EAAG,KAAM,CAAA,MAAA,CAAO,KAAK,CAAA,EAAA;AAAA,SACvC,CACyB,EAAA,QAAA,EAAA;AAAA,0BAAC,GAAA,CAAA,QAAA,EAAA,EAAS,MAAK,cAAe,EAAA,IAAA,EAAM,IAAI,KAAO,EAAA,KAAA,CAAM,OAAO,KAAO,EAAA,CAAA;AAAA,0BAClE,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,SAAW,EAAA;AAAA,YACtD,KAAA,EAAO,MAAM,MAAO,CAAA;AAAA,WACrB,CAC4B,EAAA,QAAA,EAAA,iBAAA,CAAkB,KACvB,EAAA;AAAA,SAAA,EACJ,CAAU,GAAA,IAAA;AAAA,QAEb,cAAA,mBAAkB,GAAA,CAAA,gBAAA,EAAA,EAAiB,OAAS,EAAA,iBAAA,CAAkB,mBACvD,EAAA,QAAA,kBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,QAAU,EAAA;AAAA,UACrD,KAAO,EAAA;AAAA,SACR,CAAA,EAAG,QAAsB,EAAA,wBAAA,EAAA,CAAA,EACN,CAAsB,GAAA,IAAA;AAAA,wBAEzB,GAAA,CAAA,gBAAA,EAAA,EAAiB,OAAS,EAAA,aAAA,EAAe,UAAU,iBAAkB,CAAA,OAAA,IAAW,CAAC,iBAAA,CAAkB,WAAW,IAAK,EAAA,EAAG,KAAO,EAAA,CAAC,OAAO,MAAQ,EAAA;AAAA,UAC9J,iBAAiB,iBAAkB,CAAA,UAAA,CAAW,MAAS,GAAA,MAAA,GAAS,MAAM,MAAO,CAAA;AAAA,SAC9E,CACsB,EAAA,QAAA,EAAA,iBAAA,CAAkB,OAAU,mBAAA,GAAA,CAAC,qBAAkB,KAAM,EAAA,MAAA,EAAO,IAAK,EAAA,OAAA,EAAQ,oBAAM,GAAA,CAAA,IAAA,EAAA,EAAK,OAAO,MAAO,CAAA,UAAA,EAAY,sBAAQ,CAC3H,EAAA;AAAA,OACJ,EAAA;AAAA,KAAA,EACJ,oBACI,IAAA,CAAA,QAAA,EAAA,EAAA,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,QAAU,EAAA;AAAA,QAC7C,KAAA,EAAO,MAAM,MAAO,CAAA;AAAA,OACrB,GAAG,QAAkB,EAAA,oBAAA,EAAA,CAAA;AAAA,sBACL,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,WAAa,EAAA;AAAA,QAChD,KAAA,EAAO,MAAM,MAAO,CAAA;AAAA,OACrB,CAAA,EACoB,QAAe,EAAA,YAAA,GAAA,CAAA,oBAAA,EAAuB,0BAA0B,CAAA,kBAAA,CAAA,GAAuB,CAAkC,+BAAA,EAAA,eAAA,CAAgB,WAAW,CAAA,CAAA,EAAI,iBAAkB,CAAA,UAAU,CACzL,CAAA,EAAA,CAAA;AAAA,sBAEC,IAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,MAAA,CAAO,IAChB,EAAA,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,iBAAmB,EAAA;AAAA,UACxD,aAAe,EAAA,KAAA;AAAA,UACf,UAAY,EAAA,QAAA;AAAA,UACZ,WAAA,EAAa,MAAM,MAAO,CAAA,MAAA;AAAA,UAC1B,eAAiB,EAAA,CAAA,EAAA,GAAA,KAAA,CAAM,MAAO,CAAA,IAAA,KAAb,IAAqB,GAAA,EAAA,GAAA;AAAA,SACvC,CACqB,EAAA,QAAA,kBAAA,GAAA,CAAC,aAAU,KAAO,EAAA,CAAC,OAAO,QAAU,EAAA;AAAA,UACtD,KAAA,EAAO,MAAM,MAAO,CAAA,IAAA;AAAA,UACpB,IAAM,EAAA;AAAA,SACP,GAAG,WAAY,EAAA,EAAA,EAAG,cAAa,YAAa,EAAA,KAAA,EAAO,kBAAkB,GAAK,EAAA,YAAA,EAAc,kBAAkB,MAAQ,EAAA,QAAA,EAAU,CAAC,iBAAkB,CAAA,OAAA,EAAS,WAAW,CAAG,EAAA,MAAA,EAAO,yBAAwB,CACtL,EAAA,CAAA;AAAA,QAEC,kBAAkB,KAAQ,mBAAA,IAAA,CAAC,QAAK,KAAO,EAAA,CAAC,OAAO,QAAU,EAAA;AAAA,UAC1E,eAAiB,EAAA,CAAA,EAAG,KAAM,CAAA,MAAA,CAAO,KAAK,CAAA,EAAA;AAAA,SACvC,CACyB,EAAA,QAAA,EAAA;AAAA,0BAAC,GAAA,CAAA,QAAA,EAAA,EAAS,MAAK,cAAe,EAAA,IAAA,EAAM,IAAI,KAAO,EAAA,KAAA,CAAM,OAAO,KAAO,EAAA,CAAA;AAAA,0BAClE,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,SAAW,EAAA;AAAA,YACtD,KAAA,EAAO,MAAM,MAAO,CAAA;AAAA,WACrB,CAC4B,EAAA,QAAA,EAAA,iBAAA,CAAkB,KACvB,EAAA;AAAA,SAAA,EACJ,CAAU,GAAA,IAAA;AAAA,wBAEb,GAAA,CAAA,gBAAA,EAAA,EAAiB,OAAS,EAAA,eAAA,EAAiB,QAAU,EAAA,iBAAA,CAAkB,OAAW,IAAA,SAAA,CAAU,MAAS,GAAA,CAAA,EAAG,KAAO,EAAA,CAAC,OAAO,MAAQ,EAAA;AAAA,UAChJ,iBAAiB,SAAU,CAAA,MAAA,IAAU,CAAI,GAAA,MAAA,GAAS,MAAM,MAAO,CAAA;AAAA,SAChE,CACsB,EAAA,QAAA,EAAA,iBAAA,CAAkB,0BAAW,GAAA,CAAA,iBAAA,EAAA,EAAkB,OAAM,MAAO,EAAA,IAAA,EAAK,SAAQ,CAAK,mBAAA,GAAA,CAAC,QAAK,KAAO,EAAA,MAAA,CAAO,YAC1F,QAAe,EAAA,YAAA,GAAA,UAAA,GAAa,qBACjC,CACR,EAAA,CAAA;AAAA,QAEC,CAAC,YAAA,mBAAgB,GAAA,CAAA,gBAAA,EAAA,EAAiB,SAAS,YAAc,EAAA,QAAA,EAAU,iBAAkB,CAAA,OAAA,EAC9E,QAAC,kBAAA,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,QAAU,EAAA;AAAA,UACrD,KAAO,EAAA;AAAA,SACR,CAAA,EAAG,QAEoB,EAAA,6BAAA,EAAA,CAAA,EACJ,CAAsB,GAAA;AAAA,OAC9B,EAAA;AAAA,KAAA,EACJ,CACR,EAAA,CAAA;AAAA,oBAEC,GAAA,CAAA,KAAA,EAAA,EAAM,OAAS,EAAA,gBAAA,EAAkB,eAAc,OAAQ,EAAA,iBAAA,EAAkB,WAAY,EAAA,cAAA,EAAgB,mBAClG,QAAC,kBAAA,IAAA,CAAA,YAAA,EAAA,EAAa,KAAO,EAAA,CAAC,OAAO,SAAW,EAAA;AAAA,MAChD,eAAA,EAAiB,MAAM,MAAO,CAAA;AAAA,KAC/B,CACa,EAAA,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,WAAa,EAAA;AAAA,QAC5C,aAAe,EAAA,KAAA;AAAA,QACf,UAAY,EAAA;AAAA,OACb,CACe,EAAA,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,UAAY,EAAA;AAAA,UAC7C,KAAA,EAAO,MAAM,MAAO,CAAA;AAAA,SACrB,GAAG,QAAY,EAAA,cAAA,EAAA,CAAA;AAAA,4BACD,gBAAiB,EAAA,EAAA,OAAA,EAAS,mBAAmB,iBAAkB,EAAA,QAAA,EAAS,oBAAmB,OACxF,EAAA,QAAA,kBAAA,GAAA,CAAC,QAAS,EAAA,EAAA,IAAA,EAAK,SAAQ,IAAM,EAAA,EAAA,EAAI,OAAO,KAAM,CAAA,MAAA,CAAO,MAAM,CAC/D,EAAA;AAAA,OACJ,EAAA,CAAA;AAAA,sBACC,IAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,aAAe,EAAA;AAAA,QAC9C,WAAA,EAAa,MAAM,MAAO,CAAA,MAAA;AAAA,QAC1B,eAAiB,EAAA,CAAA,EAAA,GAAA,KAAA,CAAM,MAAO,CAAA,IAAA,KAAb,IAAqB,GAAA,EAAA,GAAA;AAAA,OACvC,CACe,EAAA,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,QAAS,EAAA,EAAA,IAAA,EAAK,QAAS,EAAA,IAAA,EAAM,EAAI,EAAA,KAAA,EAAA,CAAO,EAAM,GAAA,KAAA,CAAA,MAAA,CAAO,aAAb,KAAA,IAAA,GAAA,EAAA,GAA8B,KAAM,CAAA,MAAA,CAAO,IAAM,EAAA,CAAA;AAAA,wBAC1F,GAAA,CAAC,aAAU,KAAO,EAAA,YAAA,EAAc,cAAc,eAAiB,EAAA,WAAA,EAAY,wBAAyB,EAAA,oBAAA,EAAA,CAAsB,EAAM,GAAA,KAAA,CAAA,MAAA,CAAO,kBAAb,IAA8B,GAAA,EAAA,GAAA,MAAA,EAAQ,WAAa,EAAA,KAAA,EAAO,cAAe,EAAA,MAAA,EAAO,iBAAgB,eAAgB,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,kBAAoB,EAAA;AAAA,UACzR,KAAA,EAAO,MAAM,MAAO,CAAA;AAAA,SACrB,CAAG,EAAA,MAAA,EAAO,gBAAiB,EAAA;AAAA,OAClB,EAAA,CAAA;AAAA,0BACC,QAAS,EAAA,EAAA,IAAA,EAAM,kBAAkB,YAAc,EAAA,CAAA,OAAA,KAAW,QAAQ,IAAM,EAAA,yBAAA,EAA0B,SAAU,EAAA,kBAAA,EAAoB,IAAI,kBAAoB,kBAAA,IAAA,CAAC,QAAK,KAAO,EAAA,CAAC,OAAO,YAAc,EAAA;AAAA,QACtM,QAAO,EAAM,GAAA,KAAA,CAAA,MAAA,CAAO,aAAb,KAAA,IAAA,GAAA,EAAA,GAA8B,MAAM,MAAO,CAAA;AAAA,OACnD,CAAG,EAAA,QAAA,EAAA;AAAA,QAAA,sBAAA;AAAA,QAC8C,aAAa,IAAK,EAAA;AAAA,QAAE;AAAA,OAClD,EAAA,CAAA,EAAS,YAAY,CAAC;AAAA,QACxC,IAAM,EAAA;AAAA,OACF,qBAAA,IAAA,CAAC,gBAAiB,EAAA,EAAA,OAAA,EAAS,MAAM;AACrC,QAAkB,iBAAA,CAAA,cAAA,CAAe,QAAQ,IAAI,CAAA;AAC7C,QAAkB,iBAAA,EAAA;AAAA,OACpB,EAAG,OAAO,CAAC,MAAA,CAAO,iBAAiB,iBAAkB,CAAA,WAAA,KAAgB,QAAQ,IAAQ,IAAA;AAAA,QACnF,eAAA,EAAiB,GAAG,MAAM,CAAA,EAAA;AAAA,OAC3B,CAAA,EAAG,iBAAkB,EAAA,QAAA,EAAS,kBAAoB,EAAA;AAAA,QACjD,QAAA,EAAU,iBAAkB,CAAA,WAAA,KAAgB,OAAQ,CAAA;AAAA,OAE9B,EAAA,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,eAAiB,EAAA;AAAA,UAC1D,KAAA,EAAO,MAAM,MAAO,CAAA;AAAA,SACrB,CAC0B,EAAA,QAAA,EAAA;AAAA,UAAQ,OAAA,CAAA,IAAA;AAAA,UAAK,IAAA;AAAA,UAAG,OAAQ,CAAA,WAAA;AAAA,UAAY;AAAA,SACzC,EAAA,CAAA;AAAA,QACC,iBAAkB,CAAA,WAAA,KAAgB,OAAQ,CAAA,IAAA,mBAAQ,GAAA,CAAA,QAAA,EAAA,EAAS,IAAK,EAAA,WAAA,EAAY,IAAM,EAAA,EAAA,EAAI,KAAO,EAAA,MAAA,EAAQ,CAAK,GAAA;AAAA,OAAA,EAC/G,CAAqB,EAAA;AAAA,KAAA,EACjC,CACJ,EAAA;AAAA,GACJ,EAAA,CAAA;AACR;AACA,MAAM,MAAA,GAAS,WAAW,MAAO,CAAA;AAAA,EAC/B,SAAW,EAAA;AAAA,IACT,IAAM,EAAA;AAAA,GACR;AAAA,EACA,MAAQ,EAAA;AAAA,IACN,cAAgB,EAAA,eAAA;AAAA,IAChB,iBAAmB,EAAA,EAAA;AAAA,IACnB,eAAiB,EAAA;AAAA,GACnB;AAAA,EACA,KAAO,EAAA;AAAA,IACL,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA;AAAA,GACd;AAAA,EACA,OAAS,EAAA;AAAA,IACP,OAAS,EAAA,EAAA;AAAA,IACT,aAAe,EAAA;AAAA,GACjB;AAAA,EACA,QAAU,EAAA;AAAA,IACR,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA,KAAA;AAAA,IACZ,YAAc,EAAA;AAAA,GAChB;AAAA,EACA,WAAa,EAAA;AAAA,IACX,QAAU,EAAA,EAAA;AAAA,IACV,YAAc,EAAA,EAAA;AAAA,IACd,UAAY,EAAA;AAAA,GACd;AAAA,EACA,IAAM,EAAA;AAAA,IACJ,GAAK,EAAA;AAAA,GACP;AAAA,EACA,QAAU,EAAA;AAAA,IACR,WAAa,EAAA,CAAA;AAAA,IACb,YAAc,EAAA,EAAA;AAAA,IACd,SAAW,EAAA,EAAA;AAAA,IACX,QAAU,EAAA;AAAA,GACZ;AAAA,EACA,WAAa,EAAA;AAAA,IACX,iBAAmB,EAAA,EAAA;AAAA,IACnB,eAAiB,EAAA;AAAA,GACnB;AAAA,EACA,WAAa,EAAA;AAAA,IACX,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA,KAAA;AAAA,IACZ,WAAa,EAAA;AAAA,GACf;AAAA,EACA,YAAc,EAAA;AAAA,IACZ,OAAO,UAAW,CAAA,aAAA;AAAA,IAClB,SAAW,EAAA;AAAA,GACb;AAAA,EACA,UAAY,EAAA;AAAA,IACV,IAAM,EAAA,CAAA;AAAA,IACN,iBAAmB,EAAA,EAAA;AAAA,IACnB,eAAiB,EAAA,QAAA,CAAS,EAAO,KAAA,KAAA,GAAQ,EAAK,GAAA,EAAA;AAAA,IAC9C,QAAU,EAAA;AAAA,GACZ;AAAA,EACA,iBAAmB,EAAA;AAAA,IACjB,WAAa,EAAA,CAAA;AAAA,IACb,YAAc,EAAA,EAAA;AAAA,IACd,iBAAmB,EAAA;AAAA,GACrB;AAAA,EACA,QAAU,EAAA;AAAA,IACR,eAAiB,EAAA,EAAA;AAAA,IACjB,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA,KAAA;AAAA,IACZ,aAAe,EAAA,CAAA;AAAA,IACf,SAAW,EAAA;AAAA,GACb;AAAA,EACA,MAAQ,EAAA;AAAA,IACN,YAAc,EAAA,EAAA;AAAA,IACd,eAAiB,EAAA,EAAA;AAAA,IACjB,UAAY,EAAA,QAAA;AAAA,IACZ,cAAgB,EAAA,QAAA;AAAA,IAChB,SAAW,EAAA;AAAA,GACb;AAAA,EACA,UAAY,EAAA;AAAA,IACV,KAAO,EAAA,MAAA;AAAA,IACP,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA;AAAA,GACd;AAAA,EACA,QAAU,EAAA;AAAA,IACR,aAAe,EAAA,KAAA;AAAA,IACf,UAAY,EAAA,QAAA;AAAA,IACZ,YAAc,EAAA,CAAA;AAAA,IACd,iBAAmB,EAAA,EAAA;AAAA,IACnB,eAAiB,EAAA,EAAA;AAAA,IACjB,GAAK,EAAA;AAAA,GACP;AAAA,EACA,SAAW,EAAA;AAAA,IACT,QAAU,EAAA,EAAA;AAAA,IACV,IAAM,EAAA;AAAA,GACR;AAAA,EACA,QAAU,EAAA;AAAA,IACR,QAAU,EAAA,EAAA;AAAA,IACV,SAAW,EAAA,QAAA;AAAA,IACX,UAAY,EAAA;AAAA,GACd;AAAA,EACA,SAAW,EAAA;AAAA,IACT,IAAM,EAAA;AAAA,GACR;AAAA,EACA,aAAe,EAAA;AAAA,IACb,aAAe,EAAA,KAAA;AAAA,IACf,UAAY,EAAA,QAAA;AAAA,IACZ,GAAK,EAAA,CAAA;AAAA,IACL,gBAAkB,EAAA,EAAA;AAAA,IAClB,YAAc,EAAA,CAAA;AAAA,IACd,iBAAmB,EAAA,EAAA;AAAA,IACnB,WAAa,EAAA,CAAA;AAAA,IACb,YAAc,EAAA,EAAA;AAAA,IACd,SAAW,EAAA;AAAA,GACb;AAAA,EACA,kBAAoB,EAAA;AAAA,IAClB,IAAM,EAAA,CAAA;AAAA,IACN,QAAU,EAAA,EAAA;AAAA,IACV,eAAiB,EAAA,QAAA,CAAS,EAAO,KAAA,KAAA,GAAQ,EAAK,GAAA;AAAA,GAChD;AAAA,EACA,YAAc,EAAA;AAAA,IACZ,SAAW,EAAA,QAAA;AAAA,IACX,OAAS,EAAA,EAAA;AAAA,IACT,QAAU,EAAA;AAAA,GACZ;AAAA,EACA,WAAa,EAAA;AAAA,IACX,cAAgB,EAAA,eAAA;AAAA,IAChB,iBAAmB,EAAA,EAAA;AAAA,IACnB,eAAiB,EAAA;AAAA,GACnB;AAAA,EACA,UAAY,EAAA;AAAA,IACV,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA;AAAA,GACd;AAAA,EACA,eAAiB,EAAA;AAAA,IACf,aAAe,EAAA,KAAA;AAAA,IACf,UAAY,EAAA,QAAA;AAAA,IACZ,cAAgB,EAAA,eAAA;AAAA,IAChB,iBAAmB,EAAA,EAAA;AAAA,IACnB,eAAiB,EAAA,EAAA;AAAA,IACjB,mBAAmB,UAAW,CAAA,aAAA;AAAA,IAC9B,iBAAmB,EAAA;AAAA,GACrB;AAAA,EACA,eAAiB,EAAA;AAAA,IACf,QAAU,EAAA;AAAA;AAEd,CAAC,CAAA"}
@@ -0,0 +1,20 @@
1
+ import {PHONE_COUNTRIES}from'./phoneCountries.js';function allowedDialCodes(raw = process.env.EXPO_PUBLIC_PHONE_OTP_ALLOWED_DIAL_CODES) {
2
+ const value = raw == null ? void 0 : raw.trim();
3
+ if (!value || value === "*") return null;
4
+ const codes = value.split(",").map((c) => c.trim()).filter(Boolean).map((c) => c.startsWith("+") ? c : `+${c}`).filter((c) => /^\+\d{1,4}$/.test(c));
5
+ return codes.length ? codes : null;
6
+ }
7
+ function pickerCountries(all = PHONE_COUNTRIES, allowed = allowedDialCodes(), defaultCode = "US") {
8
+ var _a;
9
+ if (!allowed) return [...all];
10
+ const offered = all.filter((c) => allowed.includes(c.callingCode));
11
+ if (offered.length) return offered;
12
+ const fallback = (_a = all.find((c) => c.code === defaultCode)) != null ? _a : all[0];
13
+ return fallback ? [fallback] : [];
14
+ }
15
+ function filterCountries(countries, query) {
16
+ const q = query.trim().toLowerCase();
17
+ if (!q) return [...countries];
18
+ const digits = q.replace(/^\+/, "");
19
+ return countries.filter((c) => c.name.toLowerCase().includes(q) || c.code.toLowerCase() === q || digits && /^\d+$/.test(digits) && c.callingCode.slice(1).startsWith(digits));
20
+ }export{allowedDialCodes,filterCountries,pickerCountries};//# sourceMappingURL=countryPicker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"countryPicker.js","sources":["../../../src/features/messaging/countryPicker.ts"],"sourcesContent":["import { PHONE_COUNTRIES, type PhoneCountry } from './phoneCountries';\n\n/**\n * The country picker on the chat registration screen.\n *\n * Every country is offered: AWS, not the app, decides where a verification text can go, and\n * when it cannot reach a country the send comes back with \"not available in <country> yet\"\n * (the server turns AWS's refusal into that sentence). EXPO_PUBLIC_PHONE_OTP_ALLOWED_DIAL_CODES\n * stays as a build-time switch for a staged rollout: a comma list of calling codes (\"+1,+92\")\n * narrows the picker; empty, unset or \"*\" offers everything.\n */\nexport type CountryOption = PhoneCountry;\n\nexport function allowedDialCodes(\n raw: string | undefined = process.env.EXPO_PUBLIC_PHONE_OTP_ALLOWED_DIAL_CODES,\n): string[] | null {\n const value = raw?.trim();\n if (!value || value === '*') return null;\n const codes = value\n .split(',')\n .map((c) => c.trim())\n .filter(Boolean)\n .map((c) => (c.startsWith('+') ? c : `+${c}`))\n .filter((c) => /^\\+\\d{1,4}$/.test(c));\n return codes.length ? codes : null;\n}\n\n/** The picker's list: everything, or the narrowed set, with the default country always present. */\nexport function pickerCountries(\n all: readonly CountryOption[] = PHONE_COUNTRIES,\n allowed: string[] | null = allowedDialCodes(),\n defaultCode = 'US',\n): CountryOption[] {\n if (!allowed) return [...all];\n const offered = all.filter((c) => allowed.includes(c.callingCode));\n if (offered.length) return offered;\n const fallback = all.find((c) => c.code === defaultCode) ?? all[0];\n return fallback ? [fallback] : [];\n}\n\n/** Case-insensitive match on the name, the ISO code or the calling code (\"+44\", \"44\", \"uk\"). */\nexport function filterCountries(countries: readonly CountryOption[], query: string): CountryOption[] {\n const q = query.trim().toLowerCase();\n if (!q) return [...countries];\n const digits = q.replace(/^\\+/, '');\n return countries.filter(\n (c) =>\n c.name.toLowerCase().includes(q) ||\n c.code.toLowerCase() === q ||\n (digits && /^\\d+$/.test(digits) && c.callingCode.slice(1).startsWith(digits)),\n );\n}\n"],"names":[],"mappings":"kDAYO,SAAS,gBAAiB,CAAA,GAAA,GAA0B,OAAQ,CAAA,GAAA,CAAI,wCAA2D,EAAA;AAChI,EAAA,MAAM,QAAQ,GAAK,IAAA,IAAA,GAAA,MAAA,GAAA,GAAA,CAAA,IAAA,EAAA;AACnB,EAAA,IAAI,CAAC,KAAA,IAAS,KAAU,KAAA,GAAA,EAAY,OAAA,IAAA;AACpC,EAAA,MAAM,KAAQ,GAAA,KAAA,CAAM,KAAM,CAAA,GAAG,CAAE,CAAA,GAAA,CAAI,CAAK,CAAA,KAAA,CAAA,CAAE,IAAK,EAAC,CAAE,CAAA,MAAA,CAAO,OAAO,CAAE,CAAA,GAAA,CAAI,CAAK,CAAA,KAAA,CAAA,CAAE,UAAW,CAAA,GAAG,CAAI,GAAA,CAAA,GAAI,CAAI,CAAA,EAAA,CAAC,CAAE,CAAA,CAAA,CAAE,MAAO,CAAA,CAAA,CAAA,KAAK,aAAc,CAAA,IAAA,CAAK,CAAC,CAAC,CAAA;AAC7I,EAAO,OAAA,KAAA,CAAM,SAAS,KAAQ,GAAA,IAAA;AAChC;AAGO,SAAS,gBAAgB,GAAgC,GAAA,eAAA,EAAiB,UAA2B,gBAAiB,EAAA,EAAG,cAAc,IAAuB,EAAA;AApBrK,EAAA,IAAA,EAAA;AAqBE,EAAA,IAAI,CAAC,OAAA,EAAgB,OAAA,CAAC,GAAG,GAAG,CAAA;AAC5B,EAAM,MAAA,OAAA,GAAU,IAAI,MAAO,CAAA,CAAA,CAAA,KAAK,QAAQ,QAAS,CAAA,CAAA,CAAE,WAAW,CAAC,CAAA;AAC/D,EAAI,IAAA,OAAA,CAAQ,QAAe,OAAA,OAAA;AAC3B,EAAM,MAAA,QAAA,GAAA,CAAW,EAAI,GAAA,GAAA,CAAA,IAAA,CAAK,CAAK,CAAA,KAAA,CAAA,CAAE,SAAS,WAAW,CAAA,KAApC,IAAyC,GAAA,EAAA,GAAA,GAAA,CAAI,CAAC,CAAA;AAC/D,EAAA,OAAO,QAAW,GAAA,CAAC,QAAQ,CAAA,GAAI,EAAC;AAClC;AAGgB,SAAA,eAAA,CAAgB,WAAqC,KAAgC,EAAA;AACnG,EAAA,MAAM,CAAI,GAAA,KAAA,CAAM,IAAK,EAAA,CAAE,WAAY,EAAA;AACnC,EAAA,IAAI,CAAC,CAAA,EAAU,OAAA,CAAC,GAAG,SAAS,CAAA;AAC5B,EAAA,MAAM,MAAS,GAAA,CAAA,CAAE,OAAQ,CAAA,KAAA,EAAO,EAAE,CAAA;AAClC,EAAO,OAAA,SAAA,CAAU,MAAO,CAAA,CAAA,CAAA,KAAK,CAAE,CAAA,IAAA,CAAK,WAAY,EAAA,CAAE,QAAS,CAAA,CAAC,CAAK,IAAA,CAAA,CAAE,IAAK,CAAA,WAAA,EAAkB,KAAA,CAAA,IAAK,MAAU,IAAA,OAAA,CAAQ,IAAK,CAAA,MAAM,CAAK,IAAA,CAAA,CAAE,WAAY,CAAA,KAAA,CAAM,CAAC,CAAA,CAAE,UAAW,CAAA,MAAM,CAAC,CAAA;AAC5K"}