/**
* 岗位对比页:并排对比 2-3 个岗位的九大维度评分、基本信息与福利标签。
* 数据通过 useCompareData 获取,页面只负责渲染与交互。
*/
import { Ionicons } from '@expo/vector-icons';
import { useRouter } from 'expo-router';
import { Pressable, ScrollView, StyleSheet, Text, View } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { useCompareData } from '../../src/hooks';
import { colors } from '../../src/theme';
function Header({ onBack }: { onBack: () => void }) {
return (
岗位对比
);
}
export default function CompareScreen() {
const router = useRouter();
const { jobs, dimensionScores, basicInfo, benefits, loading, error, refresh } =
useCompareData();
// 错误态
if (error) {
return (
router.back()} />
加载失败,请重试
重试
);
}
// 加载态
if (loading) {
return (
);
}
// 空态
if (jobs.length === 0) {
return (
router.back()} />
暂无对比岗位
在岗位详情页点击「加入对比」即可开始对比
router.push('/(tabs)/jobs')}>
去挑选岗位
);
}
return (
router.back()} />
{jobs.map((job) => (
{job.title}
{job.company}
{job.salary}
))}
九大维度评分
{dimensionScores.map((row, index) => {
const isLast = index === dimensionScores.length - 1;
return (
{row.dimension}
{row.scores.map((score, i) => (
{score}
))}
);
})}
基本信息
{basicInfo.fields.map((field, index) => {
const isLast = index === basicInfo.fields.length - 1;
return (
{field}
{jobs.map((job, i) => (
{basicInfo.values[index]?.[i] ?? '-'}
))}
);
})}
福利标签
{jobs.map((job, index) => {
const isLast = index === jobs.length - 1;
const tags = benefits[index] ?? [];
return (
{job.title}
{tags.length === 0 ? (
暂无
) : (
tags.map((tag) => (
{tag}
))
)}
);
})}
);
}
const styles = StyleSheet.create({
safeArea: { flex: 1, backgroundColor: colors.pageBg },
header: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingHorizontal: 16,
paddingVertical: 12,
backgroundColor: colors.surface,
borderBottomWidth: StyleSheet.hairlineWidth,
borderBottomColor: colors.borderLight,
},
headerBtn: { width: 32, alignItems: 'center' },
headerTitle: { fontSize: 17, fontWeight: '500', color: colors.textPrimary },
content: { padding: 8, paddingBottom: 32 },
stateWrap: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
gap: 12,
paddingHorizontal: 32,
},
stateText: { fontSize: 14, color: colors.textSecondary },
retryBtn: {
paddingHorizontal: 20,
paddingVertical: 8,
borderRadius: 8,
backgroundColor: colors.primaryLight,
},
retryText: { fontSize: 14, color: colors.primaryText },
emptyIconWrap: {
width: 64,
height: 64,
borderRadius: 32,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: colors.primaryLight,
marginBottom: 4,
},
emptyTitle: { fontSize: 15, fontWeight: '500', color: colors.textPrimary },
emptyDesc: { fontSize: 13, color: colors.textSecondary, textAlign: 'center' },
emptyBtn: {
marginTop: 8,
paddingHorizontal: 24,
paddingVertical: 10,
borderRadius: 10,
backgroundColor: colors.primaryBtn,
},
emptyBtnText: { fontSize: 14, fontWeight: '500', color: colors.white },
jobRow: { flexDirection: 'row', gap: 8 },
jobCard: {
flex: 1,
padding: 8,
borderRadius: 8,
backgroundColor: colors.surface,
borderWidth: StyleSheet.hairlineWidth,
borderColor: colors.borderLight,
overflow: 'hidden',
},
jobColorBar: { height: 3, borderRadius: 2, marginBottom: 8 },
jobTitle: { fontSize: 14, fontWeight: '500', color: colors.textPrimary, marginBottom: 2 },
jobCompany: { fontSize: 12, color: colors.textSecondary, marginBottom: 6 },
jobSalary: { fontSize: 13, fontWeight: '500', color: colors.actionText },
sectionHeader: { flexDirection: 'row', alignItems: 'center', marginTop: 20, marginBottom: 12 },
sectionBar: {
width: 3,
height: 14,
borderRadius: 2,
backgroundColor: colors.primaryBtn,
marginRight: 8,
},
sectionTitle: { fontSize: 15, fontWeight: '500', color: colors.textPrimary },
card: {
borderRadius: 8,
backgroundColor: colors.surface,
borderWidth: StyleSheet.hairlineWidth,
borderColor: colors.borderLight,
paddingHorizontal: 8,
},
scoreRow: {
paddingVertical: 12,
borderBottomWidth: StyleSheet.hairlineWidth,
borderBottomColor: colors.borderLight,
},
scoreRowLast: { borderBottomWidth: 0 },
scoreDimension: { fontSize: 13, color: colors.textPrimary, marginBottom: 8 },
scoreBars: { gap: 6 },
scoreBarItem: { flexDirection: 'row', alignItems: 'center', gap: 8 },
scoreValue: { width: 24, fontSize: 12, color: colors.textSecondary },
scoreTrack: {
flex: 1,
height: 6,
borderRadius: 3,
backgroundColor: colors.borderLight,
overflow: 'hidden',
},
scoreFill: { height: '100%', borderRadius: 3 },
infoRow: {
flexDirection: 'row',
alignItems: 'center',
paddingVertical: 12,
borderBottomWidth: StyleSheet.hairlineWidth,
borderBottomColor: colors.borderLight,
},
infoRowLast: { borderBottomWidth: 0 },
infoField: { width: 80, fontSize: 13, color: colors.textSecondary },
infoValues: { flex: 1, flexDirection: 'row' },
infoValue: { flex: 1, fontSize: 13, color: colors.textPrimary },
benefitRow: {
paddingVertical: 12,
borderBottomWidth: StyleSheet.hairlineWidth,
borderBottomColor: colors.borderLight,
},
benefitRowLast: { borderBottomWidth: 0 },
benefitJob: { fontSize: 13, color: colors.textPrimary, marginBottom: 8 },
benefitTags: { flexDirection: 'row', flexWrap: 'wrap', gap: 6 },
benefitTag: {
paddingHorizontal: 8,
paddingVertical: 3,
borderRadius: 4,
backgroundColor: colors.primaryLight,
},
benefitTagText: { fontSize: 11, color: colors.primaryText },
benefitEmpty: { fontSize: 12, color: colors.textHint },
});