import { Ionicons } from '@expo/vector-icons'; import { LinearGradient } from 'expo-linear-gradient'; import { useRouter } from 'expo-router'; import { useRef, useState } from 'react'; import { Pressable, ScrollView, StyleSheet, Text, useWindowDimensions, View, } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { colors, headerGradientShort } from '../src/theme'; import { useAuth } from '../src/context/AuthContext'; import type { AssetName } from '../components/onboarding/assets'; import { ImageSlot } from '../components/onboarding/ui/ImageSlot'; interface GuideSlide { /** 屏内插图素材位(见 components/onboarding/assets.ts) */ art: AssetName; title: string; desc: string; } /** * 引导页内容:聚焦有职四大差异化能力。 * 每屏的配图走 ImageSlot —— 素材未到位时页面上会显示「配图待补 + 该放什么图」的标注。 */ const SLIDES: GuideSlide[] = [ { art: 'guideEvaluate', title: '先看评价,再投简历', desc: '公司评分、在职员工评价、行业声誉都摆在明面上,信息差不该由求职者买单。', }, { art: 'guideWeightDim', title: '按你的标准打分', desc: '关注什么就调什么权重,实时算出综合得分,找到真正合适你的那家公司。', }, { art: 'guideGameMap', title: '用 7 关走完求职全流程', desc: '认识自己 → 明确方向 → 准备简历 → 面试 → 签约,边闯关边把该准备的都准备好。', }, { art: 'guideLegalAI', title: '签字之前,先看清权益', desc: '免费的 AI 咨询与合同模板,付费的律师与合同审核,入职前后都有人帮你把关。', }, ]; /** * 引导页(/guide)。 * * 两种进入方式,出口不同 —— 出口错了会把已登录用户甩回注册流程: * - 首次启动:`/` 判定没看过引导时跳来,看完落 /register(跳过等同看完); * - 已登录后回顾:设置页「查看引导页」推入,出口是返回上一页,不能再去 /register。 */ export default function GuideScreen() { const router = useRouter(); const { completeOnboarding, isTokenValid } = useAuth(); const { width } = useWindowDimensions(); const [page, setPage] = useState(0); const scrollRef = useRef(null); const isLast = page === SLIDES.length - 1; /** 已登录(含从设置页回顾)时只返回,不改引导标记、不进注册流程 */ const reviewing = isTokenValid; const finish = () => { if (reviewing) { if (router.canGoBack()) router.back(); else router.replace('/(tabs)/jobs'); return; } completeOnboarding(); router.replace('/register'); }; const goNext = () => { if (isLast) { finish(); return; } const next = page + 1; setPage(next); scrollRef.current?.scrollTo({ x: next * width, animated: true }); }; const slotWidth = Math.min(width - 96, 300); const slotHeight = Math.round(slotWidth * 0.72); return ( {reviewing ? ( ) : ( )} {reviewing ? '关闭' : '跳过'} { const index = Math.round(e.nativeEvent.contentOffset.x / width); setPage(index); }} style={styles.pager} > {SLIDES.map((slide) => ( {slide.title} {slide.desc} ))} {SLIDES.map((slide, i) => ( ))} {isLast ? (reviewing ? '完成' : '立即体验') : '下一步'} {page + 1} / {SLIDES.length} ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: colors.white }, topBar: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingHorizontal: 16, paddingVertical: 10, }, backBtn: { width: 36, height: 36, alignItems: 'center', justifyContent: 'center', }, skipText: { fontSize: 14, color: colors.textSecondary, paddingHorizontal: 4 }, pager: { flex: 1 }, slide: { flex: 1, alignItems: 'center', justifyContent: 'center', paddingHorizontal: 36, }, slideTitle: { fontSize: 22, fontWeight: '800', color: colors.textPrimary, textAlign: 'center', marginTop: 36, marginBottom: 14, }, slideDesc: { fontSize: 15, color: colors.textSecondary, textAlign: 'center', lineHeight: 24, }, bottom: { alignItems: 'center', paddingHorizontal: 36, paddingBottom: 28, }, dots: { flexDirection: 'row', gap: 8, marginBottom: 24 }, dot: { width: 8, height: 8, borderRadius: 4, backgroundColor: colors.border, }, dotActive: { width: 22, backgroundColor: colors.primary }, nextBtn: { width: '100%', height: 50, borderRadius: 25, overflow: 'hidden', }, nextGradient: { flex: 1, alignItems: 'center', justifyContent: 'center', }, nextText: { fontSize: 16, fontWeight: '700', color: colors.textInverse }, pageHint: { marginTop: 16, fontSize: 13, color: colors.textHint, }, });