Initial commit: Prism messenger with Expo + NestJS + GraphQL + PostgreSQL

This commit is contained in:
Bivekich
2025-08-06 02:19:37 +03:00
commit 6fb83334d6
56 changed files with 24295 additions and 0 deletions

View File

@ -0,0 +1,122 @@
import React, { useState } from 'react';
import { View, StyleSheet, KeyboardAvoidingView, Platform, ScrollView } from 'react-native';
import { TextInput, Button, Text, Headline, HelperText } from 'react-native-paper';
import { useMutation } from '@apollo/client';
import { LOGIN } from '../graphql/mutations';
import { useAuth } from '../contexts/AuthContext';
export const LoginScreen = ({ navigation }: any) => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [showPassword, setShowPassword] = useState(false);
const { login } = useAuth();
const [loginMutation, { loading, error }] = useMutation(LOGIN, {
onCompleted: async (data) => {
await login(data.login.access_token, data.login.user);
},
onError: (error) => {
console.error('Login error:', error);
},
});
const handleLogin = () => {
if (!username || !password) return;
loginMutation({ variables: { username, password } });
};
return (
<KeyboardAvoidingView
style={styles.container}
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
>
<ScrollView contentContainerStyle={styles.scrollContent}>
<View style={styles.content}>
<Headline style={styles.title}>Вход в Prism</Headline>
<TextInput
label="Имя пользователя"
value={username}
onChangeText={setUsername}
mode="outlined"
style={styles.input}
autoCapitalize="none"
disabled={loading}
/>
<TextInput
label="Пароль"
value={password}
onChangeText={setPassword}
mode="outlined"
style={styles.input}
secureTextEntry={!showPassword}
disabled={loading}
right={
<TextInput.Icon
icon={showPassword ? 'eye-off' : 'eye'}
onPress={() => setShowPassword(!showPassword)}
/>
}
/>
{error && (
<HelperText type="error" visible={true}>
{error.message}
</HelperText>
)}
<Button
mode="contained"
onPress={handleLogin}
loading={loading}
disabled={loading || !username || !password}
style={styles.button}
>
Войти
</Button>
<Button
mode="text"
onPress={() => navigation.navigate('Register')}
disabled={loading}
style={styles.linkButton}
>
Нет аккаунта? Зарегистрироваться
</Button>
</View>
</ScrollView>
</KeyboardAvoidingView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f5f5f5',
},
scrollContent: {
flexGrow: 1,
justifyContent: 'center',
},
content: {
padding: 20,
maxWidth: 400,
width: '100%',
alignSelf: 'center',
},
title: {
textAlign: 'center',
marginBottom: 30,
},
input: {
marginBottom: 15,
},
button: {
marginTop: 10,
marginBottom: 10,
},
linkButton: {
marginTop: 10,
},
});