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

112 lines
4.1 KiB

import { useState } from 'react';
import { Alert, Pressable, StyleSheet, Text, View } from 'react-native';
import { colors, spacing } from '../../../src/theme';
import { useAuth } from '../../../src/context/AuthContext';
import { useIdentitySwitch, useOnboarding } from '../../../src/hooks';
import { ScreenShell } from '../ui/ScreenShell';
import { Illustration } from '../ui/Illustration';
export function P3Identity() {
const { setData, navigate, back, reset } = useOnboarding();
const { logout } = useAuth();
const { switchTo, switching } = useIdentitySwitch();
const [failed, setFailed] = useState<string | null>(null);
/**
* 选求职者:**先由服务端确认身份再往下走**。
* 契约 POST /auth/identity/select 是账号身份的权威来源(并首次下发凭证);
* 早先这里只写本地 data.identity 就跳转,账号在服务端仍是 UNASSIGNED。
*/
const chooseCandidate = async () => {
setFailed(null);
const outcome = await switchTo('STUDENT');
if (!outcome.ok) {
setFailed(outcome.message ?? '身份选择失败,请重试');
return;
}
setData({ identity: 'candidate' });
navigate('P4');
};
/** 选招聘者:企业资料在 B3 采集,提交时一并调 selectIdentity(契约要求 COMPANY 带 company) */
const chooseRecruiter = () => {
setData({ identity: 'recruiter' });
navigate('B3');
};
/**
* 退出登录必须同时清掉令牌与角色。
* 此前只调 `reset()`(仅清流程 state 与引导资料),登录态原封不动 ——
* 界面回到了登录页,但重进 App 又会被判定为「已登录」而直接放进主界面。
*/
const handleLogout = () => {
Alert.alert('确认退出登录', '退出后需要重新登录', [
{ text: '取消', style: 'cancel' },
{
text: '退出',
style: 'destructive',
onPress: () => {
logout();
reset();
},
},
]);
};
return (
<ScreenShell showBack onBack={back}>
<Text style={styles.heading}>选择你的身份</Text>
<Pressable
style={[styles.card, switching && styles.cardBusy]}
disabled={switching}
onPress={() => void chooseCandidate()}
>
<View style={styles.cardTop}>
<Illustration name="illustCandidate" size={120} radius={16} />
</View>
<View style={styles.cardBtn}>
<Text style={styles.cardBtnText}>我要找工作</Text>
</View>
</Pressable>
<Text style={styles.or}>或者</Text>
<Pressable style={styles.card} onPress={chooseRecruiter}>
<View style={styles.cardTop}>
<Illustration name="illustRecruiter" size={120} radius={16} />
</View>
<View style={[styles.cardBtn, styles.cardBtnOutline]}>
<Text style={[styles.cardBtnText, { color: colors.primary }]}>我要招人</Text>
</View>
</Pressable>
{failed ? <Text style={styles.error}>{failed}</Text> : null}
<Pressable style={styles.logout} onPress={handleLogout}>
<Text style={styles.logoutText}>退出登录</Text>
</Pressable>
</ScreenShell>
);
}
const styles = StyleSheet.create({
heading: { fontSize: 22, fontWeight: '800', color: colors.textPrimary, textAlign: 'center', marginVertical: 16 },
card: { backgroundColor: colors.white, borderRadius: spacing.card, padding: spacing.card, alignItems: 'center', borderWidth: 1, borderColor: colors.border },
cardTop: { marginBottom: 16 },
cardBtn: {
width: '100%',
height: 48,
borderRadius: 24,
backgroundColor: colors.primary,
alignItems: 'center',
justifyContent: 'center',
},
cardBtnOutline: { backgroundColor: colors.white, borderWidth: 1, borderColor: colors.primary },
cardBtnText: { fontSize: 16, fontWeight: '700', color: colors.textInverse },
cardBusy: { opacity: 0.6 },
error: { marginTop: 12, textAlign: 'center', fontSize: 12, color: colors.dangerText },
or: { textAlign: 'center', color: colors.textHint, marginVertical: spacing.block, fontSize: 13 },
logout: { marginTop: spacing.section, alignItems: 'center' },
logoutText: { fontSize: 13, color: colors.textHint },
});