import { Ionicons } from '@expo/vector-icons';
import { useRouter } from 'expo-router';
import {
ActivityIndicator,
Pressable,
ScrollView,
StyleSheet,
Text,
View,
} from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { useHollandIntro } from '../src/hooks';
import { colors, hollandTypeColors } from '../src/theme';
import { formatThousands } from '../src/utils';
import type { HollandDimensionIntro, HollandIntro } from '../src/types';
/* ===================== 子组件:顶部导航 ===================== */
function Header({ onBack }: { onBack: () => void }) {
return (
职业兴趣测评
{/* 原先这里是「记录」按钮:项目内没有测评记录页,留着等于点了没反应,先摘掉 */}
);
}
/* ===================== 子组件:六维类型网格 ===================== */
function DimensionGrid({ dimensions }: { dimensions: HollandDimensionIntro[] }) {
return (
{dimensions.map((d) => (
{d.type}
{d.name}
{d.desc}
))}
);
}
/* ===================== 子组件:亮点卡片 ===================== */
function FeatureCard({
feature,
}: {
feature: HollandIntro['features'][number];
}) {
return (
{feature.title}
{feature.desc}
);
}
/* ===================== 子组件:优势列表 ===================== */
function AdvantageList({ advantages }: { advantages: string[] }) {
return (
测评优势
{advantages.map((item, index) => (
{item}
))}
);
}
/* ===================== 页面 ===================== */
export default function HollandIntroScreen() {
const router = useRouter();
const { intro, loading, error, refresh } = useHollandIntro();
if (loading) {
return (
);
}
if (error || !intro) {
return (
router.back()} />
测评加载失败
点击重试
);
}
return (
router.back()} />
{/* 标题区 */}
{intro.title}
{intro.subtitle}
{/* 与成长页的「已有 N 人完成」是同一个字段、同一句话,两处必须同一种格式化:
原先这里用 toLocaleString()、那边用 formatThousands(),而 Hermes 在无完整 ICU
的构建上 toLocaleString() 可能不加千分位,两页就会显示成两个样子。 */}
已有 {formatThousands(intro.totalParticipants)} 人完成测评
{/* 六维类型 */}
6大兴趣维度
{/* 核心亮点 */}
核心亮点
{intro.features.map((feature) => (
))}
{/* 测评优势 */}
{/* 底部按钮 */}
router.push('/holland/question')}>
开始测评
);
}
const styles = StyleSheet.create({
container: { flex: 1, backgroundColor: colors.pageBg },
header: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingHorizontal: 12,
paddingVertical: 12,
backgroundColor: colors.white,
},
headerBtn: { width: 50, alignItems: 'center' },
headerTitle: { fontSize: 17, fontWeight: '700', color: colors.textPrimary },
headerRecord: { fontSize: 14, color: colors.primary, fontWeight: '500' },
body: { padding: 16, paddingBottom: 24 },
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 },
heroCard: {
backgroundColor: colors.white,
borderRadius: 8,
padding: 28,
alignItems: 'center',
marginBottom: 20,
},
heroIconWrap: {
width: 96,
height: 96,
borderRadius: 48,
backgroundColor: colors.primaryLight,
alignItems: 'center',
justifyContent: 'center',
marginBottom: 16,
},
heroTitle: {
fontSize: 20,
fontWeight: '800',
color: colors.textPrimary,
marginBottom: 8,
textAlign: 'center',
},
heroSubtitle: {
fontSize: 13,
color: colors.textSecondary,
textAlign: 'center',
lineHeight: 20,
marginBottom: 12,
},
heroParticipants: {
fontSize: 12,
color: colors.textHint,
},
sectionTitle: {
fontSize: 16,
fontWeight: '700',
color: colors.textPrimary,
marginBottom: 12,
marginTop: 4,
},
dimGrid: {
flexDirection: 'row',
flexWrap: 'wrap',
gap: 10,
marginBottom: 20,
},
dimItem: {
width: '30.8%',
backgroundColor: colors.white,
borderRadius: 12,
padding: 14,
alignItems: 'center',
},
dimBadge: {
width: 36,
height: 36,
borderRadius: 18,
alignItems: 'center',
justifyContent: 'center',
marginBottom: 8,
},
dimType: {
fontSize: 16,
fontWeight: '800',
},
dimName: {
fontSize: 14,
fontWeight: '700',
color: colors.textPrimary,
marginBottom: 4,
},
dimDesc: {
fontSize: 11,
color: colors.textSecondary,
textAlign: 'center',
lineHeight: 16,
},
featureList: {
gap: 10,
marginBottom: 20,
},
featureCard: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: colors.white,
borderRadius: 8,
padding: 16,
},
featureIcon: {
width: 44,
height: 44,
borderRadius: 22,
backgroundColor: colors.primaryLight,
alignItems: 'center',
justifyContent: 'center',
marginRight: 14,
},
featureBody: {
flex: 1,
},
featureTitle: {
fontSize: 15,
fontWeight: '700',
color: colors.textPrimary,
marginBottom: 4,
},
featureDesc: {
fontSize: 12,
color: colors.textSecondary,
lineHeight: 18,
},
advantageCard: {
backgroundColor: colors.white,
borderRadius: 8,
padding: 16,
},
advantageTitle: {
fontSize: 15,
fontWeight: '700',
color: colors.textPrimary,
marginBottom: 12,
},
advantageRow: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 10,
},
advantageText: {
fontSize: 13,
color: colors.textPrimary,
marginLeft: 10,
},
bottomSpacer: {
height: 80,
},
footer: {
position: 'absolute',
left: 0,
right: 0,
bottom: 0,
backgroundColor: colors.white,
borderTopWidth: 1,
borderTopColor: colors.borderLight,
paddingHorizontal: 16,
paddingTop: 12,
paddingBottom: 24,
},
startBtn: {
backgroundColor: colors.primaryBtn,
borderRadius: 12,
paddingVertical: 14,
alignItems: 'center',
},
startBtnText: {
color: colors.white,
fontSize: 16,
fontWeight: '700',
},
});