轻松聘
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

181 lines
7.1 KiB

import { useEffect, useState } from 'react';
import { Ionicons } from '@expo/vector-icons';
import { Pressable, ScrollView, StyleSheet, Text, View } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { StatusBar } from 'expo-status-bar';
import { colors } from '../../../src/theme';
import { Illustration } from '../ui/Illustration';
import { Modal } from '../ui/Modal';
type Step = 'guide' | 'location' | 'notify' | null;
const JOBS = [
{ company: '巴适伙伴', pos: '前端开发工程师', salary: '12-18K', city: '上海' },
{ company: '星河科技', pos: '鸿蒙开发工程师', salary: '15-22K', city: '上海' },
{ company: '云图网络', pos: '全栈工程师', salary: '13-20K', city: '杭州' },
{ company: '启明软件', pos: '数据分析师', salary: '10-16K', city: '深圳' },
];
const TABS = [
{ key: 'home', icon: 'home', label: '首页' },
{ key: 'msg', icon: 'chatbubble', label: '消息' },
{ key: 'me', icon: 'person', label: '我的' },
] as const;
export function P23Home() {
const [tab, setTab] = useState<(typeof TABS)[number]['key']>('home');
const [step, setStep] = useState<Step>('guide');
useEffect(() => {
setStep('guide');
}, []);
return (
<SafeAreaView style={styles.screen} edges={['top']}>
<StatusBar style="dark" />
<View style={styles.topBar}>
<Text style={styles.topTitle}>推荐职位</Text>
<Ionicons name="location" size={16} color={colors.primary} />
<Text style={styles.topCity}>上海</Text>
</View>
<ScrollView style={styles.list} contentContainerStyle={styles.listContent} showsVerticalScrollIndicator={false}>
{JOBS.map((j) => (
<View key={j.company} style={styles.card}>
<Illustration name="logo" size={44} radius={10} />
<View style={styles.cardBody}>
<Text style={styles.pos}>{j.pos}</Text>
<Text style={styles.company}>{j.company}</Text>
</View>
<View style={styles.cardRight}>
<Text style={styles.salary}>{j.salary}</Text>
<View style={styles.cityTag}>
<Text style={styles.cityText}>{j.city}</Text>
</View>
</View>
</View>
))}
</ScrollView>
<View style={styles.tabBar}>
{TABS.map((t) => (
<Pressable key={t.key} style={styles.tab} onPress={() => setTab(t.key)}>
<Ionicons name={t.icon} size={22} color={tab === t.key ? colors.primary : colors.textHint} />
<Text style={[styles.tabLabel, tab === t.key && styles.tabLabelActive]}>{t.label}</Text>
</Pressable>
))}
</View>
{step === 'guide' && (
<View style={styles.guide}>
<View style={styles.guideCard}>
<Ionicons name="arrow-down" size={20} color={colors.primary} />
<Text style={styles.guideText}>点击查看职位详情</Text>
</View>
<Pressable style={styles.guideBtn} onPress={() => setStep('location')}>
<Text style={styles.guideBtnText}>知道了</Text>
</Pressable>
</View>
)}
<Modal
visible={step === 'location'}
title="允许获取位置"
onClose={() => setStep('notify')}
footer={
<View style={styles.modalBtns}>
<Pressable style={[styles.modalBtn, styles.modalBtnGhost]} onPress={() => setStep('notify')}>
<Text style={styles.modalBtnGhostText}>暂不</Text>
</Pressable>
<Pressable style={[styles.modalBtn, styles.modalBtnPrimary]} onPress={() => setStep('notify')}>
<Text style={styles.modalBtnPrimaryText}>允许</Text>
</Pressable>
</View>
}
>
<Text style={styles.modalBody}>开启定位可为你推荐附近的职位与机会。</Text>
</Modal>
<Modal
visible={step === 'notify'}
title="开启通知"
onClose={() => setStep(null)}
footer={
<View style={styles.modalBtns}>
<Pressable style={[styles.modalBtn, styles.modalBtnGhost]} onPress={() => setStep(null)}>
<Text style={styles.modalBtnGhostText}>暂不</Text>
</Pressable>
<Pressable style={[styles.modalBtn, styles.modalBtnPrimary]} onPress={() => setStep(null)}>
<Text style={styles.modalBtnPrimaryText}>允许</Text>
</Pressable>
</View>
}
>
<Text style={styles.modalBody}>开启通知可及时接收面试邀请与 Boss 消息。</Text>
</Modal>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
screen: { flex: 1, backgroundColor: colors.pageBg },
topBar: { flexDirection: 'row', alignItems: 'center', gap: 6, paddingHorizontal: 20, paddingVertical: 12, backgroundColor: colors.white },
topTitle: { fontSize: 18, fontWeight: '800', color: colors.textPrimary, marginRight: 'auto' },
topCity: { fontSize: 13, color: colors.primary, fontWeight: '600' },
list: { flex: 1 },
listContent: { padding: 16, gap: 12 },
card: {
flexDirection: 'row',
alignItems: 'center',
gap: 12,
backgroundColor: colors.white,
borderRadius: 14,
padding: 14,
borderWidth: 1,
borderColor: colors.border,
},
cardBody: { flex: 1, gap: 4 },
pos: { fontSize: 15, fontWeight: '700', color: colors.textPrimary },
company: { fontSize: 12, color: colors.textSecondary },
cardRight: { alignItems: 'flex-end', gap: 6 },
salary: { fontSize: 15, fontWeight: '700', color: colors.info },
cityTag: { backgroundColor: colors.primaryLight, paddingHorizontal: 8, paddingVertical: 2, borderRadius: 8 },
cityText: { fontSize: 11, color: colors.primaryText },
tabBar: {
flexDirection: 'row',
borderTopWidth: 1,
borderColor: colors.borderLight,
backgroundColor: colors.white,
paddingVertical: 8,
},
tab: { flex: 1, alignItems: 'center', gap: 2 },
tabLabel: { fontSize: 11, color: colors.textHint },
tabLabelActive: { color: colors.primary, fontWeight: '700' },
guide: {
...StyleSheet.absoluteFill,
backgroundColor: colors.scrim,
alignItems: 'center',
justifyContent: 'flex-start',
paddingTop: 150,
},
guideCard: {
flexDirection: 'row',
alignItems: 'center',
gap: 6,
backgroundColor: colors.white,
paddingHorizontal: 16,
paddingVertical: 10,
borderRadius: 12,
},
guideText: { fontSize: 14, fontWeight: '600', color: colors.textPrimary },
guideBtn: { marginTop: 16, backgroundColor: colors.primary, paddingHorizontal: 28, paddingVertical: 10, borderRadius: 20 },
guideBtnText: { color: colors.textInverse, fontWeight: '700' },
modalBtns: { flexDirection: 'row', gap: 12 },
modalBtn: { flex: 1, height: 44, borderRadius: 22, alignItems: 'center', justifyContent: 'center' },
modalBtnGhost: { backgroundColor: colors.borderLight },
modalBtnGhostText: { color: colors.textSecondary, fontWeight: '600' },
modalBtnPrimary: { backgroundColor: colors.primary },
modalBtnPrimaryText: { color: colors.textInverse, fontWeight: '700' },
modalBody: { fontSize: 14, color: colors.textSecondary, lineHeight: 22, textAlign: 'center' },
});