import React, { useState, useEffect } from 'react'; import { View, Text, TextInput, TouchableOpacity, StyleSheet, SafeAreaView, KeyboardAvoidingView, Platform, ScrollView, Alert, ActivityIndicator } from 'react-native'; import { Car, Music } from 'lucide-react-native'; import { colors } from '../../utils/colors'; import { supabase } from '../../services/supabase'; import { makeRedirectUri } from 'expo-auth-session'; import * as QueryParams from 'expo-auth-session/build/QueryParams'; import * as Linking from 'expo-linking'; import * as WebBrowser from 'expo-web-browser'; import { handleAuthRedirectUrl } from '../../auth/authRedirect'; import { addAuthDebugEvent, getAuthDebugEvents, clearAuthDebugEvents } from '../../debug/authDebug'; import { clearSpotifyTokens } from '../../auth/spotifyToken'; // @ts-ignore export default function LoginScreen({ navigation }) { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [loading, setLoading] = useState(false); const handleLogin = async () => { if (!email || !password) { Alert.alert('Erro', 'Por favor preenche todos os campos.'); return; } setLoading(true); const { error } = await supabase.auth.signInWithPassword({ email, password, }); if (error) { Alert.alert('Erro no login', error.message); } setLoading(false); }; const handleAuthDebug = async () => { const events = await getAuthDebugEvents(); Alert.alert('Auth Debug Events', JSON.stringify(events, null, 2)); }; const handleResetAuth = async () => { await supabase.auth.signOut(); await clearSpotifyTokens(); await clearAuthDebugEvents(); Alert.alert('Reset', 'Auth state cleared.'); }; const handleSpotifyLogin = async () => { try { const redirectTo = "roadtripdj://auth/callback"; await addAuthDebugEvent({ event: 'login_button_pressed', redirectTo }); const { data, error } = await supabase.auth.signInWithOAuth({ provider: 'spotify', options: { redirectTo, skipBrowserRedirect: true, scopes: "user-read-email user-read-private playlist-modify-public playlist-modify-private", queryParams: { show_dialog: "true" } } }); await addAuthDebugEvent({ event: 'oauth_url_created', success: !!data?.url, host: data?.url ? data.url.split('?')[0] : null }); if (error) { throw error; } if (data?.url) { const result = await WebBrowser.openAuthSessionAsync(data.url, redirectTo); await addAuthDebugEvent({ event: 'web_browser_closed', type: result.type }); if (result.type === 'success' && result.url) { await addAuthDebugEvent({ event: 'web_browser_success_url_received', success: true }); await addAuthDebugEvent({ event: 'processing_web_browser_success_url' }); await handleAuthRedirectUrl(result.url); const { data: sessionData } = await supabase.auth.getSession(); await addAuthDebugEvent({ event: 'post_browser_getSession', user_exists: Boolean(sessionData.session?.user), provider_token_exists: Boolean((sessionData.session as any)?.provider_token) }); } } } catch (e: any) { console.error('🚀 [LoginScreen] OAuth Error:', e); Alert.alert('Erro de Autenticação', e.message); } }; return ( {/* Header Section */} Roadtrip DJ O teu guia de carros e música {/* Form Card */} {loading ? ( ) : ( Entrar )} {/* Note: In a real app we would use an actual Spotify SVG logo. Using Music icon for now as a placeholder for the Spotify logo. */} Entrar com Spotify Auth Debug Reset Auth Não tens conta? navigation.navigate('Register')}> Criar conta ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: colors.primary, }, keyboardView: { flex: 1, }, scrollContent: { flexGrow: 1, justifyContent: 'center', alignItems: 'center', paddingHorizontal: 20, paddingTop: 60, paddingBottom: 40, }, headerContainer: { alignItems: 'center', marginBottom: 40, }, iconWrapper: { position: 'relative', marginBottom: 20, width: 100, height: 100, alignItems: 'center', justifyContent: 'center', }, carIconContainer: { width: 80, height: 80, borderRadius: 40, backgroundColor: 'rgba(255, 255, 255, 0.2)', alignItems: 'center', justifyContent: 'center', }, musicIconContainer: { position: 'absolute', bottom: 5, right: 5, width: 32, height: 32, borderRadius: 16, backgroundColor: '#000000', alignItems: 'center', justifyContent: 'center', }, title: { fontSize: 32, fontWeight: '800', color: colors.white, marginBottom: 8, }, subtitle: { fontSize: 16, color: colors.white, fontWeight: '500', }, card: { backgroundColor: colors.white, width: '100%', borderRadius: 24, padding: 24, shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.1, shadowRadius: 12, elevation: 5, }, input: { backgroundColor: colors.inputBackground, borderRadius: 12, paddingHorizontal: 16, paddingVertical: 16, fontSize: 16, marginBottom: 16, color: colors.textMain, }, primaryButton: { backgroundColor: colors.primary, borderRadius: 12, paddingVertical: 16, alignItems: 'center', marginBottom: 16, }, primaryButtonText: { color: colors.white, fontSize: 16, fontWeight: 'bold', }, spotifyButton: { backgroundColor: colors.spotify, borderRadius: 12, paddingVertical: 16, flexDirection: 'row', alignItems: 'center', justifyContent: 'center', marginBottom: 24, }, spotifyIcon: { marginRight: 8, }, spotifyButtonText: { color: colors.white, fontSize: 16, fontWeight: 'bold', }, footerContainer: { flexDirection: 'row', justifyContent: 'center', alignItems: 'center', }, footerText: { color: colors.textSecondary, fontSize: 14, }, footerLink: { color: colors.textMain, fontSize: 14, fontWeight: 'bold', }, });