Files
gitlab-instance-0a899031_d2…/components/PocketBaseAuthModal.tsx
2026-03-26 01:59:04 -05:00

136 lines
4.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 },
})