From ae63532503eb0b5c7a60d18ef17504c0632d508d Mon Sep 17 00:00:00 2001 From: Santo Cariotti Date: Thu, 29 Aug 2024 18:27:23 +0200 Subject: Login page --- app/(tabs)/index.tsx | 204 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 154 insertions(+), 50 deletions(-) (limited to 'app/(tabs)/index.tsx') diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx index 324aeb7..46a690f 100644 --- a/app/(tabs)/index.tsx +++ b/app/(tabs)/index.tsx @@ -1,51 +1,134 @@ -import { Image, StyleSheet, Platform } from 'react-native'; +import { Alert, Platform, Pressable, StyleSheet, Text, TextInput, View } from 'react-native'; -import { HelloWave } from '@/components/HelloWave'; import ParallaxScrollView from '@/components/ParallaxScrollView'; import { ThemedText } from '@/components/ThemedText'; import { ThemedView } from '@/components/ThemedView'; +import React, { useState, useEffect } from 'react'; +import { API_URL } from '@env'; +import AsyncStorage from '@react-native-async-storage/async-storage'; + export default function HomeScreen() { + const [username, setUsername] = useState(''); + const [password, setPassword] = useState(''); + const [token, setToken] = useState(''); + + const storeToken = async (token: string) => { + if (Platform.OS === 'web') { + localStorage.setItem('token', token); + } else { + await AsyncStorage.setItem('token', token); + } + }; + + const handleLogin = async () => { + if (!username || !password) { + Alert.alert('Error', 'Username and password are required.'); + return; + } + + try { + const response = await fetch(`${API_URL}/graphql`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + query: ` + mutation Login($input: LoginCredentials!) { + login(input: $input) { + accessToken + tokenType + } + }`, + variables: { + input: { + email: username, + password, + }, + }, + }), + }); + + const data = await response.json(); + + if (data.errors) { + const errorMessages = data.errors.map((error: any) => error.message); + Alert.alert('Error', errorMessages.join('\n')); + } else { + const { accessToken } = data.data.login; + await storeToken(accessToken); + setToken(accessToken); + } + } catch (err) { + console.error('Login Error:', err); + Alert.alert('Error', 'An error occurred during login.'); + } + }; + + const handleLogout = async () => { + await removeToken(); + setToken(''); + }; + + const removeToken = async () => { + if (Platform.OS === 'web') { + localStorage.removeItem('token'); + } else { + await AsyncStorage.removeItem('token'); + } + }; + + useEffect(() => { + const retrieveToken = async () => { + const storedToken = Platform.OS === 'web' ? localStorage.getItem('token') : await AsyncStorage.getItem('token'); + setToken(storedToken || ''); + }; + + retrieveToken(); + }, []); + return ( - - }> - - Welcome! - - - - Step 1: Try it - - Edit app/(tabs)/index.tsx to see changes. - Press{' '} - - {Platform.select({ ios: 'cmd + d', android: 'cmd + m' })} - {' '} - to open developer tools. - - - - Step 2: Explore - - Tap the Explore tab to learn more about what's included in this starter app. - - - - Step 3: Get a fresh start - - When you're ready, run{' '} - npm run reset-project to get a fresh{' '} - app directory. This will move the current{' '} - app to{' '} - app-example. - - + + {token ? ( + + + Logout + + + ) : ( + <> + + Welcome, mate! + + + + Username + + + + Password + + + + + Login + + + + + )} ); } @@ -54,17 +137,38 @@ const styles = StyleSheet.create({ titleContainer: { flexDirection: 'row', alignItems: 'center', - gap: 8, + marginBottom: 20, }, - stepContainer: { - gap: 8, + text: { marginBottom: 8, + color: '#333', }, - reactLogo: { - height: 178, - width: 290, - bottom: 0, - left: 0, - position: 'absolute', + formContainer: { + marginTop: 20, + paddingHorizontal: 20, }, + formInput: { + width: '100%', + paddingVertical: 12, + paddingHorizontal: 16, + borderRadius: 8, + borderWidth: 1, + borderColor: '#ccc', + backgroundColor: '#f9f9f9', + marginBottom: 20, + }, + buttonContainer: { + marginTop: 20, + }, + formButton: { + paddingVertical: 12, + paddingHorizontal: 24, + backgroundColor: '#007AFF', + fontSize: 16, + fontWeight: '600', + textAlign: 'center', + borderRadius: 8, + color: 'white', + } }); + -- cgit v1.2.3-18-g5258