's'
This commit is contained in:
135
components/PocketBaseAuthModal.tsx
Normal file
135
components/PocketBaseAuthModal.tsx
Normal file
@@ -0,0 +1,135 @@
|
||||
import { useState } from 'react'
|
||||
import {
|
||||
ActivityIndicator,
|
||||
KeyboardAvoidingView,
|
||||
Linking,
|
||||
Modal,
|
||||
Platform,
|
||||
Pressable,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TextInput,
|
||||
View,
|
||||
} from 'react-native'
|
||||
|
||||
import { useAuth } from '@/context/AuthContext'
|
||||
import { theme } from '@/constants/theme'
|
||||
|
||||
const VIP_URL = 'https://vip.hackrobot.cn/'
|
||||
|
||||
export function PocketBaseAuthModal() {
|
||||
const { loginVisible, closeLogin, login } = useAuth()
|
||||
const [email, setEmail] = useState('')
|
||||
const [password, setPassword] = useState('')
|
||||
const [busy, setBusy] = useState(false)
|
||||
const [err, setErr] = useState<string | null>(null)
|
||||
|
||||
const onSubmit = async () => {
|
||||
setErr(null)
|
||||
setBusy(true)
|
||||
try {
|
||||
await login(email.trim(), password)
|
||||
setPassword('')
|
||||
} catch (e) {
|
||||
setErr(e instanceof Error ? e.message : String(e))
|
||||
} finally {
|
||||
setBusy(false)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal visible={loginVisible} animationType="fade" transparent onRequestClose={closeLogin}>
|
||||
<KeyboardAvoidingView
|
||||
style={styles.backdrop}
|
||||
behavior={Platform.OS === 'ios' ? 'padding' : undefined}
|
||||
>
|
||||
<Pressable style={styles.scrim} onPress={closeLogin} />
|
||||
<View style={styles.sheet}>
|
||||
<Text style={styles.title}>会员授权</Text>
|
||||
<Text style={styles.sub}>
|
||||
开始或重新开始直播前,请使用异度星球账号登录。授权保存在本机,可随时在首页退出。
|
||||
</Text>
|
||||
{err ? <Text style={styles.err}>{err}</Text> : null}
|
||||
<Text style={styles.lbl}>邮箱</Text>
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
value={email}
|
||||
onChangeText={setEmail}
|
||||
placeholder="you@example.com"
|
||||
placeholderTextColor={theme.muted}
|
||||
autoCapitalize="none"
|
||||
autoCorrect={false}
|
||||
keyboardType="email-address"
|
||||
/>
|
||||
<Text style={styles.lbl}>密码</Text>
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
value={password}
|
||||
onChangeText={setPassword}
|
||||
placeholder="••••••••"
|
||||
placeholderTextColor={theme.muted}
|
||||
secureTextEntry
|
||||
/>
|
||||
<Pressable
|
||||
style={[styles.btn, busy && styles.btnDisabled]}
|
||||
disabled={busy}
|
||||
onPress={() => void onSubmit()}
|
||||
>
|
||||
{busy ? (
|
||||
<ActivityIndicator color="#fff" />
|
||||
) : (
|
||||
<Text style={styles.btnText}>登录并授权</Text>
|
||||
)}
|
||||
</Pressable>
|
||||
<View style={styles.row}>
|
||||
<Pressable onPress={() => void Linking.openURL(VIP_URL)}>
|
||||
<Text style={styles.link}>注册</Text>
|
||||
</Pressable>
|
||||
<Text style={styles.sep}>·</Text>
|
||||
<Pressable onPress={closeLogin}>
|
||||
<Text style={styles.linkMuted}>取消</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
</View>
|
||||
</KeyboardAvoidingView>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
backdrop: { flex: 1, justifyContent: 'center', padding: 20 },
|
||||
scrim: { ...StyleSheet.absoluteFillObject, backgroundColor: 'rgba(0,0,0,0.55)' },
|
||||
sheet: {
|
||||
borderRadius: 16,
|
||||
padding: 20,
|
||||
backgroundColor: theme.bgCard,
|
||||
borderWidth: 1,
|
||||
borderColor: theme.border,
|
||||
},
|
||||
title: { fontSize: 18, fontWeight: '700', color: theme.text, marginBottom: 8 },
|
||||
sub: { fontSize: 13, color: theme.muted, lineHeight: 20, marginBottom: 14 },
|
||||
err: { color: theme.danger, fontSize: 13, marginBottom: 10 },
|
||||
lbl: { fontSize: 12, fontWeight: '600', color: theme.muted, marginBottom: 6 },
|
||||
input: {
|
||||
borderWidth: 1,
|
||||
borderColor: theme.border,
|
||||
borderRadius: 10,
|
||||
padding: 12,
|
||||
color: theme.text,
|
||||
marginBottom: 12,
|
||||
backgroundColor: theme.bg,
|
||||
},
|
||||
btn: {
|
||||
backgroundColor: theme.accent,
|
||||
paddingVertical: 14,
|
||||
borderRadius: 12,
|
||||
alignItems: 'center',
|
||||
marginTop: 4,
|
||||
},
|
||||
btnDisabled: { opacity: 0.6 },
|
||||
btnText: { color: '#fff', fontWeight: '700', fontSize: 15 },
|
||||
row: { flexDirection: 'row', justifyContent: 'center', alignItems: 'center', marginTop: 16, gap: 8 },
|
||||
link: { color: theme.accent, fontWeight: '600', fontSize: 14 },
|
||||
linkMuted: { color: theme.muted, fontSize: 14 },
|
||||
sep: { color: theme.muted },
|
||||
})
|
||||
Reference in New Issue
Block a user