import React, {useState, useEffect} from 'react'; import { View, Text, TextInput, TouchableOpacity, StyleSheet, Alert, Image, KeyboardAvoidingView, Platform, ScrollView, ActivityIndicator, } from 'react-native'; import {useTranslation} from 'react-i18next'; import {useAuthStore} from '../../store/authStore'; import {colors, spacing, typography} from '../../theme'; // Google Sign-In stubbed — auth bridges through pwap's Supabase const GoogleSignin = { configure: (_opts: unknown) => {}, hasPlayServices: async () => true, signIn: async () => ({ data: { idToken: '' } }) }; const statusCodes = { SIGN_IN_CANCELLED: 'SIGN_IN_CANCELLED', IN_PROGRESS: 'IN_PROGRESS', PLAY_SERVICES_NOT_AVAILABLE: 'PLAY_SERVICES_NOT_AVAILABLE' }; import client, {saveTokens} from '../../api/client'; import Svg, {Path} from 'react-native-svg'; import {GOOGLE_WEB_CLIENT_ID as WEB_CLIENT_ID} from '../../config'; export default function LoginScreen({navigation}: any) { const {t} = useTranslation(); const [identifier, setIdentifier] = useState(''); const [password, setPassword] = useState(''); const [googleLoading, setGoogleLoading] = useState(false); const {login, isLoading, error, clearError} = useAuthStore(); useEffect(() => { GoogleSignin.configure({ webClientId: WEB_CLIENT_ID, offlineAccess: true, }); }, []); const handleLogin = async () => { if (!identifier.trim() || !password) { Alert.alert(t('common.error'), t('auth.loginErrorRequired')); return; } try { await login(identifier.trim(), password); } catch { // Error zustand store'da } }; const handleGoogleLogin = async () => { setGoogleLoading(true); clearError(); try { await GoogleSignin.hasPlayServices(); const response = await GoogleSignin.signIn(); const idToken = response.data?.idToken; if (!idToken) { Alert.alert(t('common.error'), t('auth.googleTokenError')); setGoogleLoading(false); return; } // Send to backend const {data} = await client.post('/auth/google', {id_token: idToken}); await saveTokens(data.access_token, data.refresh_token); // Update auth store useAuthStore.setState({ user: data.user, isLoggedIn: true, isLoading: false, }); } catch (err: any) { if (err.code === statusCodes.SIGN_IN_CANCELLED) { // Kullanici iptal etti — sessiz } else if (err.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) { Alert.alert(t('common.error'), t('auth.googlePlayError')); } else { const msg = err.response?.data?.message || err.message || t('auth.googleLoginFailed'); Alert.alert(t('common.error'), msg); } } finally { setGoogleLoading(false); } }; return ( {t('auth.subtitle')} {error && ( {error} )} {t('auth.emailOrPhone')} { clearError(); setIdentifier(text); }} placeholder={t('auth.emailPlaceholder')} placeholderTextColor={colors.textLight} autoCapitalize="none" keyboardType="email-address" /> {t('auth.password')} { clearError(); setPassword(text); }} placeholder={t('auth.passwordPlaceholder')} placeholderTextColor={colors.textLight} secureTextEntry returnKeyType="go" onSubmitEditing={handleLogin} /> {isLoading ? t('auth.loggingIn') : t('auth.login')} {/* Divider */} {t('common.or')} {/* Google Sign-In */} {googleLoading ? ( ) : ( <> {t('auth.googleLogin')} )} navigation.navigate('Register')}> {t('auth.noAccount')} {t('auth.registerLink')} ); } const styles = StyleSheet.create({ container: {flex: 1, backgroundColor: colors.background}, scroll: {flexGrow: 1, justifyContent: 'center', padding: spacing.xl}, header: {alignItems: 'center', marginBottom: spacing.xxxl}, logoImage: {width: 120, height: 140, marginBottom: spacing.md}, title: { ...typography.h1, color: colors.primary, marginBottom: spacing.xs, }, subtitle: { ...typography.caption, color: colors.textSecondary, }, form: {width: '100%'}, label: { ...typography.captionBold, color: colors.textPrimary, marginBottom: spacing.xs, marginTop: spacing.lg, }, input: { backgroundColor: colors.backgroundWhite, borderWidth: 1, borderColor: colors.border, borderRadius: 10, padding: spacing.lg, fontSize: 16, color: colors.textPrimary, }, button: { backgroundColor: colors.primary, borderRadius: 10, padding: spacing.lg, alignItems: 'center', marginTop: spacing.xl, }, buttonDisabled: {opacity: 0.6}, buttonText: { ...typography.button, color: colors.textWhite, }, divider: { flexDirection: 'row', alignItems: 'center', marginVertical: spacing.xl, }, dividerLine: { flex: 1, height: 1, backgroundColor: colors.border, }, dividerText: { ...typography.caption, color: colors.textLight, marginHorizontal: spacing.md, }, googleButton: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', backgroundColor: '#FFFFFF', borderWidth: 1.5, borderColor: '#E5E7EB', borderRadius: 12, paddingVertical: 14, paddingHorizontal: 20, shadowColor: '#000', shadowOffset: {width: 0, height: 1}, shadowOpacity: 0.05, shadowRadius: 3, elevation: 2, }, googleText: { fontSize: 16, fontWeight: '600', color: '#374151', marginLeft: 12, }, linkButton: {alignItems: 'center', marginTop: spacing.xl}, linkText: {...typography.caption, color: colors.textSecondary}, linkBold: {color: colors.primary, fontWeight: '600'}, errorBox: { backgroundColor: '#FEE2E2', borderRadius: 8, padding: spacing.md, borderWidth: 1, borderColor: '#FECACA', }, errorText: {color: colors.error, ...typography.caption}, });