import { Ionicons } from '@expo/vector-icons'; import { useRouter } from 'expo-router'; import { useState } from 'react'; import { ActivityIndicator, Pressable, ScrollView, StyleSheet, Text, View, } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { useIdentityOptions } from '../src/hooks'; import { useRole } from '../src/context/RoleContext'; import { useAuth } from '../src/context/AuthContext'; import { colors } from '../src/theme'; import type { IdentityOption } from '../src/types'; /* ===================== 子组件:顶部 Logo ===================== */ function LogoHeader() { return ( 职 职来 智能求职 · 企业招聘一站式服务平台 ); } /* ===================== 子组件:身份卡片 ===================== */ function IdentityCard({ option, selected, onSelect, }: { option: IdentityOption; selected: boolean; onSelect: () => void; }) { const isCandidate = option.role === 'candidate'; return ( {option.title} {option.desc} {selected && ( )} ); } /* ===================== 子组件:四态 ===================== */ function Loading() { return ( 正在加载… ); } function ErrorState({ onRetry }: { onRetry: () => void }) { return ( 加载失败 点击重试 ); } /* ===================== 页面 ===================== */ export default function IdentitySelectScreen() { const router = useRouter(); const { setRole } = useRole(); const { candidateSetupDone, enterpriseVerified } = useAuth(); const { options, loading, error, refresh } = useIdentityOptions(); const [selectedId, setSelectedId] = useState(null); /** * 选中身份即进入:先写 role,再进入该身份的下一步(避免点到卡片无反应)。 * - 求职者:未设置求职意向 → 求职意向页;已设置 → 求职端 * - 招聘者:未完成企业认证 → 企业认证页;已完成 → 企业端 * 注意:两个路由组均无 index,故一律用显式落地路由。 */ const handleSelect = (option: IdentityOption) => { setSelectedId(option.id); if (option.role === 'candidate') { setRole('candidate'); router.replace(candidateSetupDone ? '/(tabs)/jobs' : '/job-preference'); } else { setRole('enterprise'); router.replace( enterpriseVerified ? '/(enterprise)/job-management' : '/enterprise-certification', ); } }; return ( {loading ? ( ) : error ? ( ) : ( <> {options.map((opt) => ( handleSelect(opt)} /> ))} 点击上方身份卡片,立即进入对应端 )} router.push('/operation-rules')}> 管理规则 / 风控审计 ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: colors.pageBg }, body: { flexGrow: 1, padding: 20, paddingTop: 40 }, logoHeader: { alignItems: 'center', marginBottom: 32 }, logoCircle: { width: 72, height: 72, borderRadius: 36, backgroundColor: colors.primary, alignItems: 'center', justifyContent: 'center', marginBottom: 12, }, logoText: { fontSize: 32, fontWeight: '800', color: colors.textInverse }, brandName: { fontSize: 24, fontWeight: '800', color: colors.textPrimary }, brandSlogan: { fontSize: 13, color: colors.textSecondary, marginTop: 6 }, cards: { flexDirection: 'row', gap: 12, marginBottom: 24 }, card: { flex: 1, position: 'relative', backgroundColor: colors.white, borderRadius: 16, padding: 16, borderWidth: 1.5, borderColor: colors.borderLight, }, cardSelected: { borderColor: colors.primary, backgroundColor: colors.primaryLight }, iconWrap: { width: 52, height: 52, borderRadius: 14, alignItems: 'center', justifyContent: 'center', marginBottom: 12, }, cardTitle: { fontSize: 16, fontWeight: '700', color: colors.textPrimary }, cardTitleSelected: { color: colors.primaryText }, cardDesc: { fontSize: 12, color: colors.textSecondary, marginTop: 6, lineHeight: 18 }, check: { position: 'absolute', top: 12, right: 12 }, hint: { marginTop: 8, fontSize: 13, color: colors.textHint, textAlign: 'center', }, manageLink: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', paddingVertical: 16, }, manageText: { marginLeft: 6, fontSize: 13, color: colors.textHint }, center: { flex: 1, alignItems: 'center', justifyContent: 'center', paddingHorizontal: 40, gap: 12 }, tip: { fontSize: 14, color: colors.textSecondary }, retryBtn: { paddingHorizontal: 18, paddingVertical: 8, borderRadius: 16, backgroundColor: colors.primaryLight }, retryText: { fontSize: 13, fontWeight: '600', color: colors.primaryText }, });