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

143 lines
4.8 KiB

import { useState } from 'react';
import { Ionicons } from '@expo/vector-icons';
import { Pressable, ScrollView, StyleSheet, Text, View } from 'react-native';
import { StatusBar } from 'expo-status-bar';
import { LinearGradient } from 'expo-linear-gradient';
import { SafeAreaView } from 'react-native-safe-area-context';
import { colors } from '../../../src/theme';
import { useOnboarding } from '../../../src/hooks';
import { Illustration } from '../ui/Illustration';
import { AgreementCheckbox } from '../ui/AgreementCheckbox';
import { AgreementModal } from '../ui/AgreementModal';
/** P1 登录主页:对齐参考样式 —— 淡渐变顶部 + 居中 Logo + 微信绿实心/灰底一键登录 + 协议弹窗拦截 */
export function P1Login() {
const { data, setData, navigate } = useOnboarding();
const agreed = data.agreed;
/** 未勾选协议时被拦截的动作,弹窗「同意」后继续执行 */
const [pending, setPending] = useState<(() => void) | null>(null);
/** 协议门卫:已勾选直接执行;未勾选弹协议弹窗 */
const gate = (action: () => void) => {
if (agreed) {
action();
} else {
setPending(() => action);
}
};
const accept = () => {
setData({ agreed: true });
const act = pending;
setPending(null);
act?.();
};
return (
<SafeAreaView style={styles.screen} edges={['top', 'bottom']}>
<StatusBar style="dark" />
<LinearGradient colors={[colors.primaryLight, colors.pageBg]} style={styles.topGlow} />
<ScrollView contentContainerStyle={styles.content} showsVerticalScrollIndicator={false} bounces={false}>
<View style={styles.brandArea}>
<Illustration name="logo" size={96} radius={24} />
</View>
<View style={styles.flexSpacer} />
{/* 登录方式 */}
<Pressable style={styles.wechatBtn} onPress={() => gate(() => navigate('B1'))}>
<Ionicons name="logo-wechat" size={20} color={colors.textInverse} />
<Text style={styles.wechatText}>微信登录</Text>
</Pressable>
<Pressable style={styles.quickBtn} onPress={() => gate(() => navigate('P2Q'))}>
<Text style={styles.quickText}>一键登录</Text>
</Pressable>
<Pressable onPress={() => gate(() => navigate('P2'))} hitSlop={8}>
<Text style={styles.otherLink}>其他方式登录</Text>
</Pressable>
{/* 协议勾选 */}
<View style={styles.agree}>
<AgreementCheckbox
checked={agreed}
onToggle={() => setData({ agreed: !agreed })}
text={
<Text style={styles.agreeText}>
已阅读并同意
<Text style={styles.link} onPress={() => navigate('B2')}>《有职用户协议》</Text>
和
<Text style={styles.link} onPress={() => navigate('B2')}>《隐私政策》</Text>
,允许有职统一登录本账号信息
</Text>
}
/>
</View>
<View style={styles.flexSpacer} />
<View style={styles.footer}>
<Text style={styles.footItem}>服务热线</Text>
<Text style={styles.footItem}>举报监督电话</Text>
<Text style={styles.footItem}>资质证照</Text>
</View>
</ScrollView>
<AgreementModal
visible={pending !== null}
onAccept={accept}
onDecline={() => setPending(null)}
onOpenAgreement={() => {
setPending(null);
navigate('B2');
}}
/>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
screen: { flex: 1, backgroundColor: colors.pageBg },
topGlow: { position: 'absolute', top: 0, left: 0, right: 0, height: 200 },
content: { flexGrow: 1, paddingHorizontal: 24, paddingBottom: 12 },
brandArea: { alignItems: 'center', marginTop: '22%' },
flexSpacer: { flex: 1, minHeight: 28 },
wechatBtn: {
height: 50,
borderRadius: 12,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
gap: 8,
backgroundColor: colors.success,
},
wechatText: { fontSize: 16, fontWeight: '700', color: colors.textInverse },
quickBtn: {
height: 50,
borderRadius: 12,
alignItems: 'center',
justifyContent: 'center',
marginTop: 14,
backgroundColor: colors.borderLight,
},
quickText: { fontSize: 16, fontWeight: '700', color: colors.textPrimary },
otherLink: {
textAlign: 'center',
marginTop: 20,
fontSize: 14,
color: colors.textSecondary,
},
agree: { marginTop: 22 },
agreeText: { fontSize: 12, color: colors.textSecondary, lineHeight: 18 },
link: { color: colors.primary, fontWeight: '600' },
footer: {
flexDirection: 'row',
justifyContent: 'center',
gap: 18,
paddingTop: 24,
paddingBottom: 8,
},
footItem: { fontSize: 12, color: colors.textHint },
});