|
|
@@ -0,0 +1,264 @@
|
|
|
+import { Button, Toast } from '@ant-design/react-native';
|
|
|
+import { Ionicons } from '@expo/vector-icons';
|
|
|
+import { router } from 'expo-router';
|
|
|
+import React, { useRef, useState } from 'react';
|
|
|
+import {
|
|
|
+ KeyboardAvoidingView,
|
|
|
+ Platform,
|
|
|
+ Pressable,
|
|
|
+ ScrollView,
|
|
|
+ StyleSheet,
|
|
|
+ Text,
|
|
|
+ TextInput,
|
|
|
+ View,
|
|
|
+} from 'react-native';
|
|
|
+import { SafeAreaView } from 'react-native-safe-area-context';
|
|
|
+
|
|
|
+function FieldLabel({ children }: { children: React.ReactNode }) {
|
|
|
+ return (
|
|
|
+ <Text className="mb-2 ml-1 text-xs font-bold uppercase tracking-widest text-outline">
|
|
|
+ {children}
|
|
|
+ </Text>
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+export default function SignUpScreen() {
|
|
|
+ const [mobile, setMobile] = useState('');
|
|
|
+ const [password, setPassword] = useState('');
|
|
|
+ const [email, setEmail] = useState('');
|
|
|
+ const [name, setName] = useState('');
|
|
|
+ const [organization, setOrganization] = useState('');
|
|
|
+ const [agreed, setAgreed] = useState(false);
|
|
|
+ const [flushAgree, setFlushAgree] = useState(false);
|
|
|
+ const [loading, setLoading] = useState(false);
|
|
|
+ const scrollView = useRef<ScrollView>(null);
|
|
|
+
|
|
|
+ const handleRegister = async () => {
|
|
|
+ setFlushAgree(false);
|
|
|
+
|
|
|
+ if (mobile.trim().length !== 11) {
|
|
|
+ Toast.fail('请输入正确的手机号');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (password.trim().length < 6) {
|
|
|
+ Toast.fail('请输入不少于 6 位的登录密码');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!email.includes('@')) {
|
|
|
+ Toast.fail('请输入正确的邮箱');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!name.trim()) {
|
|
|
+ Toast.fail('请输入姓名');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!organization.trim()) {
|
|
|
+ Toast.fail('请输入所属机构');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!agreed) {
|
|
|
+ Toast.fail('请先阅读并同意协议');
|
|
|
+ setFlushAgree(true);
|
|
|
+ scrollView.current?.scrollToEnd({ animated: true });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ setLoading(true);
|
|
|
+ const toastKey = Toast.loading('正在创建账号...');
|
|
|
+
|
|
|
+ try {
|
|
|
+ await new Promise((resolve) => setTimeout(resolve, 600));
|
|
|
+ Toast.success('注册成功,请登录');
|
|
|
+ router.replace('/sign-in');
|
|
|
+ } catch (error) {
|
|
|
+ console.error('注册失败:', error);
|
|
|
+ Toast.fail('注册失败,请稍后重试');
|
|
|
+ } finally {
|
|
|
+ setLoading(false);
|
|
|
+ Toast.remove(toastKey);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ return (
|
|
|
+ <SafeAreaView className="flex-1 bg-surface">
|
|
|
+ <KeyboardAvoidingView
|
|
|
+ className="flex-1"
|
|
|
+ behavior={Platform.OS === 'ios' ? 'padding' : undefined}
|
|
|
+ >
|
|
|
+ <ScrollView
|
|
|
+ ref={scrollView}
|
|
|
+ className="flex-1"
|
|
|
+ contentContainerClassName="px-8 pt-12 pb-10"
|
|
|
+ contentContainerStyle={{ flexGrow: 1 }}
|
|
|
+ keyboardShouldPersistTaps="handled"
|
|
|
+ showsVerticalScrollIndicator={false}
|
|
|
+ >
|
|
|
+ <View className="absolute -top-24 -right-24 h-96 w-96 rounded-full bg-primary-container/10" />
|
|
|
+ <View className="absolute top-32 -left-20 h-64 w-64 rounded-full bg-secondary-container/20" />
|
|
|
+ <View className="absolute -bottom-16 right-0 h-48 w-48 rounded-full bg-primary-fixed/50" />
|
|
|
+
|
|
|
+ <View className="flex-1 justify-between">
|
|
|
+ <View>
|
|
|
+ <View className="mb-12">
|
|
|
+ <View className="mb-6 h-16 w-16 items-center justify-center rounded-2xl bg-primary-container shadow-lg">
|
|
|
+ <Ionicons name="sparkles" size={30} color="#ffffff" />
|
|
|
+ </View>
|
|
|
+ <Text className="mb-2 text-4xl font-extrabold tracking-tight text-on-surface">
|
|
|
+ 创建账号
|
|
|
+ </Text>
|
|
|
+ <Text className="text-base font-medium leading-7 text-on-surface-variant">
|
|
|
+ 完善基础信息,开启您的智能借贷助手工作台
|
|
|
+ </Text>
|
|
|
+ </View>
|
|
|
+
|
|
|
+ <View className="mb-8 rounded-2xl bg-surface-container-lowest p-3 shadow-sm">
|
|
|
+ <View className="px-2 pb-2">
|
|
|
+ <FieldLabel>手机号码</FieldLabel>
|
|
|
+ <View className="mb-5 flex-row items-center rounded-2xl bg-surface-container-low px-5 py-4">
|
|
|
+ <Text className="text-2xl font-bold text-on-surface">+86</Text>
|
|
|
+ <View
|
|
|
+ className="mx-4 h-5 bg-outline-variant/40"
|
|
|
+ style={{ width: StyleSheet.hairlineWidth }}
|
|
|
+ />
|
|
|
+ <TextInput
|
|
|
+ value={mobile}
|
|
|
+ onChangeText={setMobile}
|
|
|
+ editable={!loading}
|
|
|
+ keyboardType="phone-pad"
|
|
|
+ maxLength={11}
|
|
|
+ placeholder="请输入手机号"
|
|
|
+ placeholderTextColor="#9ca3af"
|
|
|
+ className="flex-1 p-0 text-xl font-medium text-on-surface"
|
|
|
+ />
|
|
|
+ <Ionicons
|
|
|
+ name="phone-portrait-outline"
|
|
|
+ size={22}
|
|
|
+ color="#c3c6d7"
|
|
|
+ />
|
|
|
+ </View>
|
|
|
+
|
|
|
+ <FieldLabel>登录密码</FieldLabel>
|
|
|
+ <View className="mb-5 flex-row items-center rounded-2xl bg-surface-container-low px-5 py-4">
|
|
|
+ <TextInput
|
|
|
+ value={password}
|
|
|
+ onChangeText={setPassword}
|
|
|
+ editable={!loading}
|
|
|
+ secureTextEntry
|
|
|
+ maxLength={20}
|
|
|
+ placeholder="请输入不少于 6 位的密码"
|
|
|
+ placeholderTextColor="#9ca3af"
|
|
|
+ className="flex-1 p-0 text-xl font-medium text-on-surface"
|
|
|
+ />
|
|
|
+ <Ionicons name="lock-closed-outline" size={22} color="#c3c6d7" />
|
|
|
+ </View>
|
|
|
+
|
|
|
+ <FieldLabel>邮箱</FieldLabel>
|
|
|
+ <View className="mb-5 flex-row items-center rounded-2xl bg-surface-container-low px-5 py-4">
|
|
|
+ <TextInput
|
|
|
+ value={email}
|
|
|
+ onChangeText={setEmail}
|
|
|
+ editable={!loading}
|
|
|
+ keyboardType="email-address"
|
|
|
+ autoCapitalize="none"
|
|
|
+ placeholder="请输入常用邮箱"
|
|
|
+ placeholderTextColor="#9ca3af"
|
|
|
+ className="flex-1 p-0 text-xl font-medium text-on-surface"
|
|
|
+ />
|
|
|
+ <Ionicons name="mail-outline" size={22} color="#c3c6d7" />
|
|
|
+ </View>
|
|
|
+
|
|
|
+ <FieldLabel>姓名</FieldLabel>
|
|
|
+ <View className="mb-5 flex-row items-center rounded-2xl bg-surface-container-low px-5 py-4">
|
|
|
+ <TextInput
|
|
|
+ value={name}
|
|
|
+ onChangeText={setName}
|
|
|
+ editable={!loading}
|
|
|
+ placeholder="请输入姓名"
|
|
|
+ placeholderTextColor="#9ca3af"
|
|
|
+ className="flex-1 p-0 text-xl font-medium text-on-surface"
|
|
|
+ />
|
|
|
+ <Ionicons name="person-outline" size={22} color="#c3c6d7" />
|
|
|
+ </View>
|
|
|
+
|
|
|
+ <FieldLabel>所属机构</FieldLabel>
|
|
|
+ <View className="flex-row items-center rounded-2xl bg-surface-container-low px-5 py-4">
|
|
|
+ <TextInput
|
|
|
+ value={organization}
|
|
|
+ onChangeText={setOrganization}
|
|
|
+ editable={!loading}
|
|
|
+ placeholder="请输入所属机构"
|
|
|
+ placeholderTextColor="#9ca3af"
|
|
|
+ className="flex-1 p-0 text-xl font-medium text-on-surface"
|
|
|
+ />
|
|
|
+ <Ionicons name="business-outline" size={22} color="#c3c6d7" />
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
+
|
|
|
+ <View className="mb-8 gap-4">
|
|
|
+ <Button type="primary" loading={loading} onPress={handleRegister}>
|
|
|
+ 注册账号
|
|
|
+ </Button>
|
|
|
+
|
|
|
+ <View className="flex-row items-center justify-between px-3">
|
|
|
+ <Pressable hitSlop={8} onPress={() => router.back()}>
|
|
|
+ <Text className="text-lg font-medium text-on-surface-variant">
|
|
|
+ 返回登录
|
|
|
+ </Text>
|
|
|
+ </Pressable>
|
|
|
+ <Pressable hitSlop={8}>
|
|
|
+ <Text className="text-lg font-medium text-on-surface-variant">
|
|
|
+ 遇到问题?
|
|
|
+ </Text>
|
|
|
+ </Pressable>
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
+
|
|
|
+ <View className="pt-4">
|
|
|
+ <View
|
|
|
+ className={`flex-row items-start gap-3 rounded-md border-2 border-transparent px-2 transition delay-300 ${
|
|
|
+ flushAgree ? 'border-primary/50' : ''
|
|
|
+ }`}
|
|
|
+ >
|
|
|
+ <Pressable
|
|
|
+ onPress={() => setAgreed((value) => !value)}
|
|
|
+ hitSlop={8}
|
|
|
+ className="pt-1"
|
|
|
+ >
|
|
|
+ <View
|
|
|
+ className={`h-6 w-6 items-center justify-center rounded-full ${
|
|
|
+ agreed
|
|
|
+ ? 'border-primary bg-primary'
|
|
|
+ : 'border-outline-variant bg-surface-container-low'
|
|
|
+ }`}
|
|
|
+ >
|
|
|
+ {agreed ? (
|
|
|
+ <Ionicons name="checkmark" size={14} color="#ffffff" />
|
|
|
+ ) : null}
|
|
|
+ </View>
|
|
|
+ </Pressable>
|
|
|
+ <Text className="flex-1 text-sm leading-7 text-on-surface-variant">
|
|
|
+ 注册即代表您已阅读并同意
|
|
|
+ <Text className="cursor-pointer font-semibold text-primary">
|
|
|
+ 《用户服务协议》
|
|
|
+ </Text>
|
|
|
+ 、
|
|
|
+ <Text className="cursor-pointer font-semibold text-primary">
|
|
|
+ 《隐私政策》
|
|
|
+ </Text>
|
|
|
+ ,并授权该应用用于账户创建与服务通知。
|
|
|
+ </Text>
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
+ </ScrollView>
|
|
|
+ </KeyboardAvoidingView>
|
|
|
+ </SafeAreaView>
|
|
|
+ );
|
|
|
+}
|