proposal-system/mobile/src/screens/auth/LoginScreen.tsx

116 lines
2.7 KiB
TypeScript
Raw Normal View History

import React, { useState } from 'react';
import { View, StyleSheet } from 'react-native';
import { Button, Text, Surface } from 'react-native-paper';
import { SafeAreaView } from 'react-native-safe-area-context';
import { useDispatch } from 'react-redux';
import { authApi } from '../../lib/api/auth';
import { setUser, setError } from '../../store/slices/authSlice';
export function LoginScreen() {
const dispatch = useDispatch();
const [loading, setLoading] = useState(false);
const handleLogin = async () => {
setLoading(true);
try {
const user = await authApi.login();
dispatch(setUser(user));
} catch (err) {
const message =
err instanceof Error ? err.message : 'Login failed. Please try again.';
dispatch(setError(message));
} finally {
setLoading(false);
}
};
return (
<SafeAreaView style={styles.container}>
<View style={styles.content}>
<Surface style={styles.logoContainer} elevation={0}>
<Text variant="headlineLarge" style={styles.brand}>
Sea Haven
</Text>
<Text variant="titleMedium" style={styles.brandSub}>
Industries
</Text>
</Surface>
<Text variant="headlineSmall" style={styles.title}>
Proposal System
</Text>
<Text variant="bodyLarge" style={styles.subtitle}>
Submit and manage proposals from anywhere
</Text>
<View style={styles.actions}>
<Button
mode="contained"
icon="google"
onPress={handleLogin}
loading={loading}
disabled={loading}
contentStyle={styles.buttonContent}
style={styles.button}
>
Sign in with Google
</Button>
</View>
<Text variant="bodySmall" style={styles.footer}>
Use your Sea Haven Workspace account
</Text>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#FAFAFA',
},
content: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
paddingHorizontal: 32,
},
logoContainer: {
alignItems: 'center',
marginBottom: 32,
backgroundColor: 'transparent',
},
brand: {
fontWeight: '800',
color: '#1565C0',
},
brandSub: {
color: '#757575',
marginTop: -4,
},
title: {
fontWeight: '700',
color: '#212121',
marginBottom: 8,
},
subtitle: {
color: '#757575',
textAlign: 'center',
marginBottom: 48,
},
actions: {
width: '100%',
},
buttonContent: {
paddingVertical: 8,
},
button: {
borderRadius: 8,
},
footer: {
color: '#9E9E9E',
marginTop: 24,
},
});