轻松聘
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.
 
 
 

149 lines
6.2 KiB

import { useState } from 'react';
import { Ionicons } from '@expo/vector-icons';
import { Pressable, StyleSheet, Text, View } from 'react-native';
import { colors } from '../../../src/theme';
import { useOnboarding, useRegisterFinish } from '../../../src/hooks';
import { onboardingStepLabel } from '../../../src/utils';
import { ScreenShell } from '../ui/ScreenShell';
import { SearchInput } from '../ui/SearchInput';
import { Tag, TagGroup } from '../ui/Tag';
import { PrimaryButton } from '../ui/PrimaryButton';
const CATEGORIES = ['高级管理', '采购贸易', '生产制造', '互联网AI', '设计', '金融', '客服运营', '咨询翻译法律', '房地产建筑', '医疗健康'];
const POSITIONS: Record<string, string[]> = {
高级管理: ['CEO', 'CTO', '产品经理', '项目负责人'],
采购贸易: ['采购专员', '贸易跟单', '供应链专员'],
生产制造: ['工艺工程师', '质量工程师', '生产主管'],
互联网AI: ['前端开发工程师', '鸿蒙开发工程师', '全栈工程师', 'Java工程师', '测试工程师', '运维工程师', '数据分析师', '算法工程师'],
设计: ['UI设计师', '视觉设计师', '交互设计师'],
金融: ['风控专员', '投资经理', '财务分析'],
客服运营: ['客服专员', '用户运营', '内容运营'],
咨询翻译法律: ['咨询顾问', '翻译', '法务专员'],
房地产建筑: ['建筑设计师', '土木工程师', '房产经纪'],
医疗健康: ['临床医师', '药剂师', '健康管理'],
};
/** 全部分类的职位去重展开,供搜索跨分类匹配 */
const ALL_POSITIONS: string[] = Array.from(new Set(Object.values(POSITIONS).flat()));
export function P6ExpectedPosition() {
const { data, setData, navigate, back } = useOnboarding();
const finish = useRegisterFinish();
const [cat, setCat] = useState('互联网AI');
const [query, setQuery] = useState('');
const positions = data.expectedPositions;
const step = onboardingStepLabel('P6');
const keyword = query.trim();
// 搜索态跨分类匹配:只搜当前分类时,在「互联网AI」下搜「UI设计师」会得到空结果,
// 看起来像平台没有这个职位,实际只是没切分类
const visible = keyword ? ALL_POSITIONS.filter((p) => p.includes(keyword)) : POSITIONS[cat];
const toggle = (p: string) =>
setData({
expectedPositions: positions.includes(p) ? positions.filter((x) => x !== p) : [...positions, p],
});
return (
<ScreenShell showBack onBack={back}>
<View style={styles.header}>
<Text style={styles.title}>期望职位</Text>
{/* 快速通道:填完意向即可落地,剩余资料后续再补。文案据实写「跳过」,
不再叫「保存」——它并不保存,而是直接结束注册流程 */}
<Pressable onPress={() => void finish('candidate')} hitSlop={6}>
<Text style={styles.save}>跳过,直接进入</Text>
</Pressable>
</View>
{step ? (
<View style={styles.progress}>
<Text style={styles.progressText}>{step}</Text>
</View>
) : null}
<SearchInput value={query} onChangeText={setQuery} placeholder="搜索职位" onClear={() => setQuery('')} />
<View style={styles.body}>
<View style={styles.cats}>
{CATEGORIES.map((c) => (
<Pressable
key={c}
style={[styles.catItem, c === cat && styles.catItemActive]}
onPress={() => {
// 搜索态下分类不参与过滤,只切分类看不出任何变化 —— 一并清掉关键词,
// 让「点分类」这个动作始终有可见结果
setQuery('');
setCat(c);
}}
>
<Text style={[styles.catText, c === cat && styles.catTextActive]}>{c}</Text>
</Pressable>
))}
</View>
<View style={styles.posCol}>
{positions.length > 0 && (
<View style={styles.chips}>
{positions.map((p) => (
<View key={p} style={styles.chip}>
<Text style={styles.chipText}>{p}</Text>
<Pressable onPress={() => toggle(p)} hitSlop={6}>
<Ionicons name="close" size={14} color={colors.textInverse} />
</Pressable>
</View>
))}
</View>
)}
{visible.length > 0 ? (
<TagGroup>
{visible.map((p) => (
<Tag key={p} label={p} selected={positions.includes(p)} onPress={() => toggle(p)} />
))}
</TagGroup>
) : (
<Text style={styles.empty}>没有匹配「{keyword}」的职位,换个关键词试试</Text>
)}
</View>
</View>
<View style={styles.footer}>
<PrimaryButton label="下一步" active={positions.length > 0} onPress={() => navigate('P7')} />
</View>
</ScreenShell>
);
}
const styles = StyleSheet.create({
header: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', marginBottom: 10 },
title: { fontSize: 20, fontWeight: '800', color: colors.textPrimary },
progress: {
alignSelf: 'flex-start',
backgroundColor: colors.primaryLight,
paddingHorizontal: 10,
paddingVertical: 3,
borderRadius: 10,
marginBottom: 12,
},
progressText: { fontSize: 12, fontWeight: '700', color: colors.primaryText },
save: { fontSize: 15, fontWeight: '700', color: colors.primary },
empty: { fontSize: 13, color: colors.textHint, lineHeight: 20 },
body: { flexDirection: 'row', gap: 14, marginTop: 8 },
cats: { width: 92 },
catItem: { paddingVertical: 12, borderRadius: 10 },
catItemActive: { backgroundColor: colors.primaryLight },
catText: { fontSize: 13, color: colors.textSecondary, textAlign: 'center' },
catTextActive: { color: colors.primaryText, fontWeight: '700' },
posCol: { flex: 1 },
chips: { flexDirection: 'row', flexWrap: 'wrap', gap: 8, marginBottom: 14 },
chip: {
flexDirection: 'row',
alignItems: 'center',
gap: 6,
backgroundColor: colors.primary,
paddingHorizontal: 10,
paddingVertical: 6,
borderRadius: 14,
},
chipText: { fontSize: 13, color: colors.textInverse },
footer: { marginTop: 28 },
});