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

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,4 +1,23 @@
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();
1
+ import {jsxs,jsx,Fragment}from'react/jsx-runtime';import React__default from'react';import {StyleSheet,Platform,View,TouchableOpacity,Text,ScrollView,ActivityIndicator,Modal,TextInput,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,countryFlag}from'./countryPicker.js';import {sanitizePhoneInput}from'./mobileNumberCheck.js';var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ const COUNTRIES = pickerCountries();
2
21
  function PhoneRow({
3
22
  countryCode,
4
23
  callingCode,
@@ -8,36 +27,76 @@ function PhoneRow({
8
27
  disabled,
9
28
  theme
10
29
  }) {
11
- var _a;
30
+ var _a, _b;
31
+ const [focused, setFocused] = React__default.useState(false);
12
32
  return /* @__PURE__ */ jsxs(View, { style: [styles.phoneRow, {
13
- flexDirection: "row",
14
- alignItems: "center",
15
- borderColor: theme.colors.border,
33
+ borderColor: focused ? theme.colors.primary : theme.colors.border,
34
+ borderWidth: focused ? 2 : 1,
16
35
  backgroundColor: (_a = theme.colors.card) != null ? _a : "#fff"
17
36
  }], children: [
18
37
  /* @__PURE__ */ jsxs(TouchableOpacity, { onPress: onCountryPress, disabled, style: [styles.countryChip, {
19
- flexDirection: "row",
20
- alignItems: "center"
21
- }], accessibilityRole: "button", accessibilityLabel: "Select country code", children: [
38
+ backgroundColor: `${theme.colors.primary}12`
39
+ }], accessibilityRole: "button", accessibilityLabel: `Country code ${callingCode}. Change country`, testID: "chat-registration-country", children: [
40
+ /* @__PURE__ */ jsx(Text, { style: styles.countryChipFlag, children: countryFlag(countryCode) }),
22
41
  /* @__PURE__ */ jsx(Text, { style: [styles.callingCode, {
23
42
  color: theme.colors.text
24
43
  }], children: callingCode }),
25
- /* @__PURE__ */ jsx(Ionicons, { name: "chevron-down", size: 18, color: theme.colors.textSecondary })
44
+ /* @__PURE__ */ jsx(Ionicons, { name: "chevron-down", size: 16, color: theme.colors.textSecondary })
26
45
  ] }),
27
- /* @__PURE__ */ jsx(View, { style: [styles.phoneDivider, {
28
- backgroundColor: theme.colors.border
29
- }] }),
30
46
  /* @__PURE__ */ jsx(TextInput, { style: [styles.phoneInput, {
31
47
  color: theme.colors.text
32
- }], placeholder: "", placeholderTextColor: theme.colors.placeholder, keyboardType: "phone-pad", textContentType: "telephoneNumber", value: phone, onChangeText: onChangePhone, editable: !disabled, maxLength: 15, testID: "chat-registration-phone" })
48
+ }], placeholder: "Phone number", placeholderTextColor: (_b = theme.colors.placeholder) != null ? _b : theme.colors.textSecondary, keyboardType: "phone-pad", textContentType: "telephoneNumber", autoComplete: "tel", value: phone, onChangeText: (text) => onChangePhone(sanitizePhoneInput(text)), onFocus: () => setFocused(true), onBlur: () => setFocused(false), editable: !disabled, maxLength: 15, autoFocus: true, testID: "chat-registration-phone" })
49
+ ] });
50
+ }
51
+ function StepIcon({
52
+ name,
53
+ color
54
+ }) {
55
+ return /* @__PURE__ */ jsx(View, { style: [styles.stepIcon, {
56
+ backgroundColor: `${color}1A`
57
+ }], children: /* @__PURE__ */ jsx(Ionicons, { name, size: 30, color }) });
58
+ }
59
+ const OTP_LENGTH = 6;
60
+ const RESEND_COOLDOWN_SECONDS = 30;
61
+ function OtpCodeInput({
62
+ value,
63
+ onChange,
64
+ disabled,
65
+ hasError,
66
+ theme
67
+ }) {
68
+ const inputRef = React__default.useRef(null);
69
+ const [focused, setFocused] = React__default.useState(false);
70
+ const digits = value.replace(/\D/g, "").slice(0, OTP_LENGTH);
71
+ const accent = theme.colors.primary;
72
+ return /* @__PURE__ */ jsxs(View, { style: styles.otpRow, children: [
73
+ Array.from({
74
+ length: OTP_LENGTH
75
+ }, (_, i) => {
76
+ var _a;
77
+ const active = focused && !disabled && i === Math.min(digits.length, OTP_LENGTH - 1);
78
+ const filled = i < digits.length;
79
+ const borderColor = hasError ? theme.colors.error : active ? accent : filled ? theme.colors.text : theme.colors.border;
80
+ return /* @__PURE__ */ jsx(View, { style: [styles.otpCell, {
81
+ borderColor,
82
+ borderWidth: active || hasError ? 2 : 1,
83
+ backgroundColor: (_a = theme.colors.card) != null ? _a : "#fff"
84
+ }], children: filled ? /* @__PURE__ */ jsx(Text, { style: [styles.otpDigit, {
85
+ color: theme.colors.text
86
+ }], children: digits[i] }) : active ? /* @__PURE__ */ jsx(View, { style: [styles.otpCaret, {
87
+ backgroundColor: accent
88
+ }] }) : null }, i);
89
+ }),
90
+ /* @__PURE__ */ jsx(TextInput, { ref: inputRef, value: digits, onChangeText: (text) => onChange(text.replace(/\D/g, "").slice(0, OTP_LENGTH)), onFocus: () => setFocused(true), onBlur: () => setFocused(false), editable: !disabled, keyboardType: "number-pad", textContentType: "oneTimeCode", autoComplete: Platform.OS === "android" ? "sms-otp" : "one-time-code", autoFocus: true, maxLength: OTP_LENGTH, caretHidden: true, style: styles.otpHiddenInput, accessibilityLabel: "Verification code", testID: "chat-registration-otp" })
33
91
  ] });
34
92
  }
35
93
  function RegistrationScreen({
36
94
  onRegistrationComplete,
37
95
  theme,
38
- testID
96
+ testID,
97
+ onClose
39
98
  }) {
40
- var _a, _b, _c, _d, _e;
99
+ var _a, _b, _c;
41
100
  const phoneVerification = usePhoneVerification("US");
42
101
  const selectedCountry = COUNTRIES.find((c) => c.code === phoneVerification.countryCode) || COUNTRIES[0];
43
102
  const [countryModalOpen, setCountryModalOpen] = React__default.useState(false);
@@ -65,17 +124,50 @@ function RegistrationScreen({
65
124
  const handleBack = React__default.useCallback(() => {
66
125
  if (phoneVerification.stage === "otp") {
67
126
  phoneVerification.resetToInput();
127
+ return;
68
128
  }
69
- }, [phoneVerification]);
129
+ onClose == null ? void 0 : onClose();
130
+ }, [phoneVerification, onClose]);
131
+ const [resendIn, setResendIn] = React__default.useState(0);
132
+ React__default.useEffect(() => {
133
+ if (resendIn <= 0) return void 0;
134
+ const timer = setTimeout(() => setResendIn((s) => s - 1), 1e3);
135
+ return () => clearTimeout(timer);
136
+ }, [resendIn]);
70
137
  const handleSendOtp = React__default.useCallback(async () => {
71
- await phoneVerification.sendOtp();
138
+ if (await phoneVerification.sendOtp()) setResendIn(RESEND_COOLDOWN_SECONDS);
72
139
  }, [phoneVerification]);
73
140
  const handleVerifyOtp = React__default.useCallback(async () => {
74
141
  await phoneVerification.verifyOtp();
75
142
  }, [phoneVerification]);
76
143
  const handleResend = React__default.useCallback(async () => {
77
- await phoneVerification.sendOtp();
144
+ if (await phoneVerification.sendOtp()) setResendIn(RESEND_COOLDOWN_SECONDS);
78
145
  }, [phoneVerification]);
146
+ const autoVerifiedFor = React__default.useRef("");
147
+ React__default.useEffect(() => {
148
+ if (phoneVerification.stage !== "otp" || usingTestOtp || phoneVerification.loading) return;
149
+ if (otpDigits.length !== OTP_LENGTH || autoVerifiedFor.current === otpDigits) return;
150
+ autoVerifiedFor.current = otpDigits;
151
+ void phoneVerification.verifyOtp();
152
+ }, [otpDigits, phoneVerification, usingTestOtp]);
153
+ const renderCountryRow = (country) => {
154
+ const selected = phoneVerification.countryCode === country.code;
155
+ return /* @__PURE__ */ jsxs(TouchableOpacity, { onPress: () => {
156
+ phoneVerification.setCountryCode(country.code);
157
+ closeCountryModal();
158
+ }, style: styles.countryListItem, accessibilityRole: "button", accessibilityState: {
159
+ selected
160
+ }, accessibilityLabel: `${country.name} ${country.callingCode}`, children: [
161
+ /* @__PURE__ */ jsx(Text, { style: styles.countryFlag, children: countryFlag(country.code) }),
162
+ /* @__PURE__ */ jsx(Text, { style: [styles.countryListText, {
163
+ color: theme.colors.text
164
+ }, selected && styles.countrySelected], numberOfLines: 1, children: country.name }),
165
+ /* @__PURE__ */ jsx(Text, { style: [styles.countryDial, {
166
+ color: theme.colors.textSecondary
167
+ }], children: country.callingCode }),
168
+ /* @__PURE__ */ jsx(View, { style: styles.countryCheck, children: selected ? /* @__PURE__ */ jsx(Ionicons, { name: "checkmark-circle", size: 22, color: accent }) : null })
169
+ ] });
170
+ };
79
171
  return /* @__PURE__ */ jsxs(SafeAreaView, { style: [styles.container, {
80
172
  backgroundColor: theme.colors.background
81
173
  }], edges: ["top", "left", "right"], testID, children: [
@@ -83,12 +175,12 @@ function RegistrationScreen({
83
175
  flexDirection: "row",
84
176
  alignItems: "center"
85
177
  }], children: [
86
- phoneVerification.stage === "otp" ? /* @__PURE__ */ jsx(TouchableOpacity, { onPress: handleBack, hitSlop: {
178
+ phoneVerification.stage === "otp" || onClose ? /* @__PURE__ */ jsx(TouchableOpacity, { onPress: handleBack, hitSlop: {
87
179
  top: 10,
88
180
  bottom: 10,
89
181
  left: 10,
90
182
  right: 10
91
- }, children: /* @__PURE__ */ jsx(Ionicons, { name: "chevron-back", size: 28, color: theme.colors.text }) }) : /* @__PURE__ */ jsx(View, { style: {
183
+ }, accessibilityRole: "button", accessibilityLabel: phoneVerification.stage === "otp" ? "Change phone number" : "Back", testID: "chat-registration-back", children: /* @__PURE__ */ jsx(Ionicons, { name: "chevron-back", size: 28, color: theme.colors.text }) }) : /* @__PURE__ */ jsx(View, { style: {
92
184
  width: 28
93
185
  } }),
94
186
  /* @__PURE__ */ jsx(Text, { style: [styles.title, {
@@ -101,14 +193,18 @@ function RegistrationScreen({
101
193
  } })
102
194
  ] }),
103
195
  /* @__PURE__ */ jsx(ScrollView, { contentContainerStyle: styles.content, showsVerticalScrollIndicator: false, keyboardShouldPersistTaps: "handled", children: phoneVerification.stage === "input" ? /* @__PURE__ */ jsxs(Fragment, { children: [
196
+ /* @__PURE__ */ jsx(StepIcon, { name: "chatbubbles", color: accent }),
104
197
  /* @__PURE__ */ jsx(Text, { style: [styles.subtitle, {
105
198
  color: theme.colors.text
106
- }], children: "Register to Chat" }),
199
+ }], children: "Enter your phone number" }),
107
200
  /* @__PURE__ */ jsx(Text, { style: [styles.description, {
108
201
  color: theme.colors.textSecondary
109
- }], children: "Enter your mobile number to get started. You'll receive an OTP to verify." }),
202
+ }], children: "Yantra Chat will send you a text with a 6-digit code to verify your number." }),
110
203
  /* @__PURE__ */ jsxs(View, { style: styles.form, children: [
111
- /* @__PURE__ */ jsx(PhoneRow, { countryCode: phoneVerification.countryCode, callingCode: selectedCountry.callingCode, phone: phoneVerification.inputPhone, onCountryPress: () => setCountryModalOpen(true), onChangePhone: phoneVerification.setInputPhone, disabled: phoneVerification.loading, theme }),
204
+ /* @__PURE__ */ jsx(PhoneRow, { countryCode: phoneVerification.countryCode, callingCode: selectedCountry.callingCode, phone: phoneVerification.inputPhone, onCountryPress: () => setCountryModalOpen(true), onChangePhone: (value) => {
205
+ if (phoneVerification.error) phoneVerification.clearError();
206
+ phoneVerification.setInputPhone(value);
207
+ }, disabled: phoneVerification.loading, theme }),
112
208
  phoneVerification.error ? /* @__PURE__ */ jsxs(View, { style: [styles.errorBox, {
113
209
  backgroundColor: `${theme.colors.error}10`
114
210
  }], children: [
@@ -117,30 +213,49 @@ function RegistrationScreen({
117
213
  color: theme.colors.error
118
214
  }], children: phoneVerification.error })
119
215
  ] }) : null,
120
- testOtpEnabled ? /* @__PURE__ */ jsx(TouchableOpacity, { onPress: phoneVerification.continueWithTestOtp, children: /* @__PURE__ */ jsx(Text, { style: [styles.linkText, {
121
- color: accent
122
- }], children: "Continue with test OTP" }) }) : null,
123
216
  /* @__PURE__ */ jsx(TouchableOpacity, { onPress: handleSendOtp, disabled: phoneVerification.loading || !phoneVerification.inputPhone.trim(), style: [styles.button, {
124
- backgroundColor: phoneVerification.inputPhone.trim() ? accent : theme.colors.border
125
- }], children: phoneVerification.loading ? /* @__PURE__ */ jsx(ActivityIndicator, { color: "#fff", size: "small" }) : /* @__PURE__ */ jsx(Text, { style: styles.buttonText, children: "Send OTP" }) })
217
+ backgroundColor: accent,
218
+ opacity: phoneVerification.inputPhone.trim() || phoneVerification.loading ? 1 : 0.4
219
+ }], children: phoneVerification.loading ? /* @__PURE__ */ jsx(ActivityIndicator, { color: "#fff", size: "small" }) : /* @__PURE__ */ jsx(Text, { style: styles.buttonText, children: "Send code" }) }),
220
+ testOtpEnabled ? /* @__PURE__ */ jsxs(TouchableOpacity, { onPress: phoneVerification.continueWithTestOtp, style: [styles.testOtpChip, {
221
+ borderColor: theme.colors.border
222
+ }], children: [
223
+ /* @__PURE__ */ jsx(Ionicons, { name: "flask-outline", size: 14, color: theme.colors.textSecondary }),
224
+ /* @__PURE__ */ jsx(Text, { style: [styles.testOtpText, {
225
+ color: theme.colors.textSecondary
226
+ }], children: "Continue with test OTP" })
227
+ ] }) : null
126
228
  ] })
127
229
  ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
230
+ /* @__PURE__ */ jsx(StepIcon, { name: "shield-checkmark", color: accent }),
128
231
  /* @__PURE__ */ jsx(Text, { style: [styles.subtitle, {
129
232
  color: theme.colors.text
130
233
  }], children: "Verify your number" }),
131
- /* @__PURE__ */ jsx(Text, { style: [styles.description, {
234
+ usingTestOtp ? /* @__PURE__ */ jsxs(Text, { style: [styles.description, {
235
+ color: theme.colors.textSecondary
236
+ }], children: [
237
+ "Test mode: use code ",
238
+ CHAT_REGISTRATION_TEST_OTP,
239
+ " and tap Continue."
240
+ ] }) : /* @__PURE__ */ jsxs(Text, { style: [styles.description, {
132
241
  color: theme.colors.textSecondary
133
- }], children: usingTestOtp ? `Test mode: use code ${CHAT_REGISTRATION_TEST_OTP} and tap Continue.` : `Enter the 6-digit code sent to ${selectedCountry.callingCode} ${phoneVerification.inputPhone}` }),
242
+ }], children: [
243
+ "Enter the 6-digit code we sent to",
244
+ "\n",
245
+ /* @__PURE__ */ jsxs(Text, { style: [styles.phoneStrong, {
246
+ color: theme.colors.text
247
+ }], children: [
248
+ selectedCountry.callingCode,
249
+ " ",
250
+ phoneVerification.inputPhone
251
+ ] }),
252
+ " ",
253
+ /* @__PURE__ */ jsx(Text, { style: [styles.inlineLink, {
254
+ color: accent
255
+ }], onPress: phoneVerification.loading ? void 0 : phoneVerification.resetToInput, accessibilityRole: "link", children: "Wrong number?" })
256
+ ] }),
134
257
  /* @__PURE__ */ jsxs(View, { style: styles.form, children: [
135
- /* @__PURE__ */ jsx(View, { style: [styles.otpInputContainer, {
136
- flexDirection: "row",
137
- alignItems: "center",
138
- borderColor: theme.colors.border,
139
- backgroundColor: (_a = theme.colors.card) != null ? _a : "#fff"
140
- }], children: /* @__PURE__ */ jsx(TextInput, { style: [styles.otpInput, {
141
- color: theme.colors.text,
142
- flex: 1
143
- }], placeholder: "", keyboardType: "number-pad", value: phoneVerification.otp, onChangeText: phoneVerification.setOtp, editable: !phoneVerification.loading, maxLength: 6, testID: "chat-registration-otp" }) }),
258
+ /* @__PURE__ */ jsx(OtpCodeInput, { value: phoneVerification.otp, onChange: phoneVerification.setOtp, disabled: phoneVerification.loading, hasError: Boolean(phoneVerification.error), theme }),
144
259
  phoneVerification.error ? /* @__PURE__ */ jsxs(View, { style: [styles.errorBox, {
145
260
  backgroundColor: `${theme.colors.error}10`
146
261
  }], children: [
@@ -149,61 +264,75 @@ function RegistrationScreen({
149
264
  color: theme.colors.error
150
265
  }], children: phoneVerification.error })
151
266
  ] }) : null,
152
- /* @__PURE__ */ jsx(TouchableOpacity, { onPress: handleVerifyOtp, disabled: phoneVerification.loading || otpDigits.length < 6, style: [styles.button, {
153
- backgroundColor: otpDigits.length >= 6 ? accent : theme.colors.border
154
- }], children: phoneVerification.loading ? /* @__PURE__ */ jsx(ActivityIndicator, { color: "#fff", size: "small" }) : /* @__PURE__ */ jsx(Text, { style: styles.buttonText, children: usingTestOtp ? "Continue" : "Verify & Register" }) }),
155
- !usingTestOtp ? /* @__PURE__ */ jsx(TouchableOpacity, { onPress: handleResend, disabled: phoneVerification.loading, children: /* @__PURE__ */ jsx(Text, { style: [styles.linkText, {
156
- color: accent
157
- }], children: "Didn't get the code? Resend" }) }) : null
267
+ /* @__PURE__ */ jsx(TouchableOpacity, { onPress: handleVerifyOtp, disabled: phoneVerification.loading || otpDigits.length < OTP_LENGTH, style: [styles.button, {
268
+ backgroundColor: accent,
269
+ opacity: otpDigits.length >= OTP_LENGTH || phoneVerification.loading ? 1 : 0.4
270
+ }], children: phoneVerification.loading ? /* @__PURE__ */ jsx(ActivityIndicator, { color: "#fff", size: "small" }) : /* @__PURE__ */ jsx(Text, { style: styles.buttonText, children: usingTestOtp ? "Continue" : "Verify" }) }),
271
+ !usingTestOtp ? /* @__PURE__ */ jsxs(View, { style: styles.resendRow, children: [
272
+ /* @__PURE__ */ jsx(Text, { style: [styles.resendHint, {
273
+ color: theme.colors.textSecondary
274
+ }], children: "Didn't get the code?" }),
275
+ resendIn > 0 ? /* @__PURE__ */ jsxs(Text, { style: [styles.resendHint, {
276
+ color: theme.colors.textSecondary
277
+ }], children: [
278
+ "Resend in 0:",
279
+ String(resendIn).padStart(2, "0")
280
+ ] }) : /* @__PURE__ */ jsx(TouchableOpacity, { onPress: handleResend, disabled: phoneVerification.loading, hitSlop: {
281
+ top: 8,
282
+ bottom: 8,
283
+ left: 8,
284
+ right: 8
285
+ }, children: /* @__PURE__ */ jsx(Text, { style: [styles.inlineLink, {
286
+ color: accent
287
+ }], children: "Resend code" }) })
288
+ ] }) : null
158
289
  ] })
159
290
  ] }) }),
160
291
  /* @__PURE__ */ jsx(Modal, { visible: countryModalOpen, animationType: "slide", presentationStyle: "pageSheet", onRequestClose: closeCountryModal, children: /* @__PURE__ */ jsxs(SafeAreaView, { style: [styles.modalFill, {
161
292
  backgroundColor: theme.colors.background
162
293
  }], children: [
163
- /* @__PURE__ */ jsxs(View, { style: [styles.modalHeader, {
164
- flexDirection: "row",
165
- alignItems: "center"
166
- }], children: [
294
+ /* @__PURE__ */ jsx(View, { style: styles.modalHandle, children: /* @__PURE__ */ jsx(View, { style: [styles.modalHandleBar, {
295
+ backgroundColor: theme.colors.border
296
+ }] }) }),
297
+ /* @__PURE__ */ jsxs(View, { style: styles.modalHeader, children: [
298
+ /* @__PURE__ */ jsx(TouchableOpacity, { onPress: closeCountryModal, accessibilityRole: "button", accessibilityLabel: "Close", hitSlop: {
299
+ top: 10,
300
+ bottom: 10,
301
+ left: 10,
302
+ right: 10
303
+ }, style: [styles.modalClose, {
304
+ backgroundColor: `${theme.colors.text}0D`
305
+ }], children: /* @__PURE__ */ jsx(Ionicons, { name: "close", size: 20, color: theme.colors.text }) }),
167
306
  /* @__PURE__ */ jsx(Text, { style: [styles.modalTitle, {
168
307
  color: theme.colors.text
169
- }], children: "Country code" }),
170
- /* @__PURE__ */ jsx(TouchableOpacity, { onPress: closeCountryModal, accessibilityRole: "button", accessibilityLabel: "Close", children: /* @__PURE__ */ jsx(Ionicons, { name: "close", size: 26, color: theme.colors.text }) })
308
+ }], children: "Choose a country" }),
309
+ /* @__PURE__ */ jsx(View, { style: styles.modalClose })
171
310
  ] }),
172
311
  /* @__PURE__ */ jsxs(View, { style: [styles.countrySearch, {
173
- borderColor: theme.colors.border,
174
- backgroundColor: (_b = theme.colors.card) != null ? _b : "#fff"
312
+ backgroundColor: `${theme.colors.text}0D`
175
313
  }], 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, {
314
+ /* @__PURE__ */ jsx(Ionicons, { name: "search", size: 18, color: (_a = theme.colors.textSecondary) != null ? _a : theme.colors.text }),
315
+ /* @__PURE__ */ jsx(TextInput, { value: countryQuery, onChangeText: setCountryQuery, placeholder: "Search countries", placeholderTextColor: (_b = theme.colors.textSecondary) != null ? _b : "#888", autoCorrect: false, autoCapitalize: "none", clearButtonMode: "while-editing", returnKeyType: "search", style: [styles.countrySearchInput, {
178
316
  color: theme.colors.text
179
317
  }], testID: "country-search" })
180
318
  ] }),
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
319
+ /* @__PURE__ */ jsx(FlatList, { data: visibleCountries, keyExtractor: (country) => country.code, keyboardShouldPersistTaps: "handled", keyboardDismissMode: "on-drag", initialNumToRender: 24, ListHeaderComponent: countryQuery.trim() ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
320
+ /* @__PURE__ */ jsx(Text, { style: [styles.countrySection, {
321
+ color: theme.colors.textSecondary
322
+ }], children: "SELECTED" }),
323
+ renderCountryRow(selectedCountry),
324
+ /* @__PURE__ */ jsx(Text, { style: [styles.countrySection, {
325
+ color: theme.colors.textSecondary
326
+ }], children: "ALL COUNTRIES" })
327
+ ] }), ListEmptyComponent: /* @__PURE__ */ jsxs(Text, { style: [styles.countryEmpty, {
328
+ color: (_c = theme.colors.textSecondary) != null ? _c : theme.colors.text
183
329
  }], children: [
184
330
  'No country matches "',
185
331
  countryQuery.trim(),
186
332
  '"'
187
333
  ] }), renderItem: ({
188
334
  item: country
189
- }) => /* @__PURE__ */ jsxs(TouchableOpacity, { onPress: () => {
190
- phoneVerification.setCountryCode(country.code);
191
- closeCountryModal();
192
- }, style: [styles.countryListItem, phoneVerification.countryCode === country.code && {
193
- backgroundColor: `${accent}18`
194
- }], accessibilityRole: "button", accessibilityState: {
195
- selected: phoneVerification.countryCode === country.code
196
- }, children: [
197
- /* @__PURE__ */ jsxs(Text, { style: [styles.countryListText, {
198
- color: theme.colors.text
199
- }], children: [
200
- country.name,
201
- " (",
202
- country.callingCode,
203
- ")"
204
- ] }),
205
- phoneVerification.countryCode === country.code ? /* @__PURE__ */ jsx(Ionicons, { name: "checkmark", size: 20, color: accent }) : null
206
- ] }) })
335
+ }) => renderCountryRow(country) })
207
336
  ] }) })
208
337
  ] });
209
338
  }
@@ -225,57 +354,121 @@ const styles = StyleSheet.create({
225
354
  paddingBottom: 40
226
355
  },
227
356
  subtitle: {
228
- fontSize: 22,
357
+ fontSize: 26,
229
358
  fontWeight: "700",
359
+ letterSpacing: -0.4,
230
360
  marginBottom: 8
231
361
  },
232
362
  description: {
233
- fontSize: 14,
234
- marginBottom: 24,
235
- lineHeight: 20
363
+ fontSize: 15,
364
+ marginBottom: 28,
365
+ lineHeight: 22
366
+ },
367
+ stepIcon: {
368
+ width: 60,
369
+ height: 60,
370
+ borderRadius: 18,
371
+ alignItems: "center",
372
+ justifyContent: "center",
373
+ marginBottom: 20
236
374
  },
237
375
  form: {
238
376
  gap: 14
239
377
  },
240
378
  phoneRow: {
241
- borderWidth: 1,
242
- borderRadius: 10,
243
- minHeight: 48,
244
- overflow: "hidden"
379
+ flexDirection: "row",
380
+ alignItems: "center",
381
+ borderRadius: 14,
382
+ minHeight: 56,
383
+ padding: 5,
384
+ gap: 6
245
385
  },
246
386
  countryChip: {
247
- paddingHorizontal: 12,
248
- paddingVertical: 12
387
+ flexDirection: "row",
388
+ alignItems: "center",
389
+ gap: 6,
390
+ borderRadius: 10,
391
+ paddingHorizontal: 10,
392
+ alignSelf: "stretch"
393
+ },
394
+ countryChipFlag: {
395
+ fontSize: 22
249
396
  },
250
397
  callingCode: {
251
398
  fontSize: 16,
252
- fontWeight: "600",
253
- marginRight: 4
254
- },
255
- phoneDivider: {
256
- width: StyleSheet.hairlineWidth,
257
- alignSelf: "stretch"
399
+ fontWeight: "600"
258
400
  },
259
401
  phoneInput: {
260
402
  flex: 1,
261
- paddingHorizontal: 12,
262
- paddingVertical: Platform.OS === "ios" ? 12 : 10,
263
- fontSize: 16
403
+ paddingHorizontal: 8,
404
+ paddingVertical: Platform.OS === "ios" ? 12 : 8,
405
+ fontSize: 18,
406
+ letterSpacing: 0.3
264
407
  },
265
- otpInputContainer: {
408
+ testOtpChip: {
409
+ flexDirection: "row",
410
+ alignItems: "center",
411
+ alignSelf: "center",
412
+ gap: 6,
266
413
  borderWidth: 1,
267
- borderRadius: 10,
268
- paddingHorizontal: 16
414
+ borderStyle: "dashed",
415
+ borderRadius: 999,
416
+ paddingHorizontal: 14,
417
+ paddingVertical: 8,
418
+ marginTop: 8
269
419
  },
270
- otpInput: {
271
- paddingVertical: 14,
272
- fontSize: 22,
273
- fontWeight: "600",
274
- letterSpacing: 6,
275
- textAlign: "center"
420
+ testOtpText: {
421
+ fontSize: 13,
422
+ fontWeight: "500"
423
+ },
424
+ otpRow: {
425
+ flexDirection: "row",
426
+ justifyContent: "space-between",
427
+ gap: 8
428
+ },
429
+ otpCell: {
430
+ flex: 1,
431
+ maxWidth: 52,
432
+ aspectRatio: 0.85,
433
+ borderRadius: 12,
434
+ alignItems: "center",
435
+ justifyContent: "center"
436
+ },
437
+ otpDigit: {
438
+ fontSize: 24,
439
+ fontWeight: "600"
440
+ },
441
+ otpCaret: {
442
+ width: 2,
443
+ height: 26,
444
+ borderRadius: 1
445
+ },
446
+ // Covers the boxes so a tap anywhere focuses it; near-zero opacity keeps iOS code autofill working.
447
+ otpHiddenInput: __spreadProps(__spreadValues({}, StyleSheet.absoluteFillObject), {
448
+ opacity: 0.011,
449
+ color: "transparent",
450
+ fontSize: 1
451
+ }),
452
+ phoneStrong: {
453
+ fontWeight: "600"
454
+ },
455
+ inlineLink: {
456
+ fontSize: 14,
457
+ fontWeight: "600"
458
+ },
459
+ resendRow: {
460
+ flexDirection: "row",
461
+ justifyContent: "center",
462
+ alignItems: "center",
463
+ gap: 6,
464
+ marginTop: 4
465
+ },
466
+ resendHint: {
467
+ fontSize: 14
276
468
  },
277
469
  button: {
278
- borderRadius: 10,
470
+ borderRadius: 14,
471
+ minHeight: 54,
279
472
  paddingVertical: 14,
280
473
  alignItems: "center",
281
474
  justifyContent: "center",
@@ -283,13 +476,13 @@ const styles = StyleSheet.create({
283
476
  },
284
477
  buttonText: {
285
478
  color: "#fff",
286
- fontSize: 16,
479
+ fontSize: 17,
287
480
  fontWeight: "600"
288
481
  },
289
482
  errorBox: {
290
483
  flexDirection: "row",
291
484
  alignItems: "center",
292
- borderRadius: 8,
485
+ borderRadius: 12,
293
486
  paddingHorizontal: 12,
294
487
  paddingVertical: 10,
295
488
  gap: 8
@@ -298,23 +491,44 @@ const styles = StyleSheet.create({
298
491
  fontSize: 13,
299
492
  flex: 1
300
493
  },
301
- linkText: {
302
- fontSize: 14,
303
- textAlign: "center",
304
- fontWeight: "500"
305
- },
306
494
  modalFill: {
307
495
  flex: 1
308
496
  },
497
+ modalHandle: {
498
+ alignItems: "center",
499
+ paddingTop: 8
500
+ },
501
+ modalHandleBar: {
502
+ width: 36,
503
+ height: 5,
504
+ borderRadius: 3
505
+ },
506
+ modalHeader: {
507
+ flexDirection: "row",
508
+ alignItems: "center",
509
+ justifyContent: "space-between",
510
+ paddingHorizontal: 16,
511
+ paddingVertical: 12
512
+ },
513
+ modalClose: {
514
+ width: 32,
515
+ height: 32,
516
+ borderRadius: 16,
517
+ alignItems: "center",
518
+ justifyContent: "center"
519
+ },
520
+ modalTitle: {
521
+ fontSize: 17,
522
+ fontWeight: "700"
523
+ },
309
524
  countrySearch: {
310
525
  flexDirection: "row",
311
526
  alignItems: "center",
312
527
  gap: 8,
313
528
  marginHorizontal: 16,
314
- marginBottom: 8,
529
+ marginBottom: 4,
315
530
  paddingHorizontal: 12,
316
- borderWidth: 1,
317
- borderRadius: 10,
531
+ borderRadius: 12,
318
532
  minHeight: 42
319
533
  },
320
534
  countrySearchInput: {
@@ -327,25 +541,40 @@ const styles = StyleSheet.create({
327
541
  padding: 24,
328
542
  fontSize: 14
329
543
  },
330
- modalHeader: {
331
- justifyContent: "space-between",
332
- paddingHorizontal: 16,
333
- paddingVertical: 12
334
- },
335
- modalTitle: {
336
- fontSize: 18,
337
- fontWeight: "700"
544
+ countrySection: {
545
+ fontSize: 12,
546
+ fontWeight: "600",
547
+ letterSpacing: 0.6,
548
+ paddingHorizontal: 20,
549
+ paddingTop: 18,
550
+ paddingBottom: 6
338
551
  },
339
552
  countryListItem: {
340
553
  flexDirection: "row",
341
554
  alignItems: "center",
342
- justifyContent: "space-between",
343
- paddingHorizontal: 16,
344
- paddingVertical: 14,
345
- borderBottomWidth: StyleSheet.hairlineWidth,
346
- borderBottomColor: "rgba(0,0,0,0.06)"
555
+ gap: 14,
556
+ paddingHorizontal: 20,
557
+ minHeight: 52
558
+ },
559
+ countryFlag: {
560
+ fontSize: 26,
561
+ width: 32,
562
+ textAlign: "center"
347
563
  },
348
564
  countryListText: {
565
+ flex: 1,
349
566
  fontSize: 16
567
+ },
568
+ countrySelected: {
569
+ fontWeight: "600"
570
+ },
571
+ countryDial: {
572
+ fontSize: 15,
573
+ minWidth: 48,
574
+ textAlign: "right"
575
+ },
576
+ countryCheck: {
577
+ width: 22,
578
+ alignItems: "center"
350
579
  }
351
580
  });export{RegistrationScreen};//# sourceMappingURL=RegistrationScreen.js.map