import { useEffect, useRef, useState } from 'react'; import { Alert, Pressable, StyleSheet, Text, TextInput, View } from 'react-native'; import { colors, spacing } from '../../../src/theme'; import { SMS_HELP_BODY, SMS_HELP_TITLE } from '../../../src/constants'; import { useOnboarding } from '../../../src/hooks'; import { ScreenShell } from '../ui/ScreenShell'; import { PrimaryButton } from '../ui/PrimaryButton'; const RESEND_SECONDS = 60; /** P2W 微信登录短信验证码页:×关闭 + 4格验证码 + 重新发送倒计时 + 语音/收不到短信入口 */ export function P2WechatCode() { const { data, navigate, back } = useOnboarding(); const [code, setCode] = useState(''); const [left, setLeft] = useState(RESEND_SECONDS); const timer = useRef | null>(null); /** 隐藏输入框的引用:点格子区域时把焦点交回它,键盘才会弹出来 */ const inputRef = useRef(null); useEffect(() => { timer.current = setInterval(() => { setLeft((l) => { if (l <= 1) { if (timer.current) clearInterval(timer.current); return 0; } return l - 1; }); }, 1000); return () => { if (timer.current) clearInterval(timer.current); }; }, []); const phone = data.phone; /** * 手机尾号(含两侧空格,无尾号时为空串,句子里不留空)。 * 原先是 `phone.length === 11 ? phone.slice(7) : '9367'` —— 没有号码时拿编造的 * 「9367」当用户的号码展示。 */ const tail = phone.length === 11 ? ` ${phone.slice(7)} ` : ''; const canNext = code.length >= 4; /** 「接收不到短信」提示,与 P2 用同一份文案常量 */ const showSmsHelp = () => Alert.alert(SMS_HELP_TITLE, SMS_HELP_BODY); const resend = () => { if (left > 0) return; setLeft(RESEND_SECONDS); setCode(''); timer.current = setInterval(() => { setLeft((l) => { if (l <= 1) { if (timer.current) clearInterval(timer.current); return 0; } return l - 1; }); }, 1000); }; return ( 输入短信验证码 已向您的手机{tail}发送验证码 {/* 4 格分离输入:透明输入层覆盖,格子仅做展示;点格子把焦点交回输入框 */} inputRef.current?.focus()}> {[0, 1, 2, 3].map((i) => ( {code[i] ?? ''} ))} setCode(t.replace(/[^\d]/g, '').slice(0, 4))} keyboardType="number-pad" maxLength={4} autoFocus /> 0}> 0 && styles.resendDisabled]}> {left > 0 ? `重新发送(${left}s)` : '重新发送'} navigate('B1')} /> {/* 「语音接听验证码」入口已移除:项目没有语音验证码通道,摆一个点了没反应的入口 等于宣称有这个能力。等接入语音通道再恢复(同 P5 移除「自动定位」的理由) */} 接收不到短信? 短信验证码正在发送,请注意查收 ); } const styles = StyleSheet.create({ h1: { fontSize: 24, fontWeight: '800', color: colors.textPrimary, marginTop: spacing.block }, subtitle: { fontSize: 14, color: colors.textSecondary, marginTop: spacing.block }, cellsWrap: { marginTop: 34 }, cellsRow: { flexDirection: 'row', gap: spacing.block }, cell: { flex: 1, alignItems: 'center' }, cellText: { fontSize: 26, fontWeight: '700', color: colors.textPrimary, minHeight: 36 }, cellLine: { width: '100%', height: 2, backgroundColor: colors.border, marginTop: 8 }, cellLineActive: { backgroundColor: colors.primary }, hiddenInput: { ...StyleSheet.absoluteFill, opacity: 0, }, resend: { textAlign: 'center', fontSize: 14, color: colors.textSecondary, marginTop: spacing.section }, resendDisabled: { color: colors.textHint }, btnArea: { marginTop: 30 }, helpRow: { alignSelf: 'flex-start', marginTop: spacing.section }, // 已是可点入口,用可读对比度的 primaryText(textHint 在 13pt 下不达 AA) helpText: { fontSize: 13, color: colors.primaryText }, toastBar: { alignSelf: 'center', marginTop: 30, paddingHorizontal: 18, paddingVertical: spacing.sm, borderRadius: 8, backgroundColor: colors.borderLight, }, toastText: { fontSize: 13, color: colors.textDisabled }, });