NeoScan_Physician/app/modules/Auth/screens/LoginScreen.tsx
2025-07-24 20:06:12 +05:30

158 lines
4.6 KiB
TypeScript

/*
* File: LoginScreen.tsx
* Description: Login screen with a loading indicator on the submit button.
* Design & Developed by Tech4Biz Solutions
* Copyright (c) Spurrin Innovations. All rights reserved.
*/
import React, { useState } from 'react';
import {
View,
Text,
StyleSheet,
TouchableWithoutFeedback,
Keyboard,
TouchableOpacity,
TextInput, // Using default TextInput for container styling
} from 'react-native';
import { Button } from '../../../../shared/src/components/Button';
import { Colors, Spacing, Typography } from '../../../../shared/src/theme';
import { useAppDispatch } from '../../../redux/hooks';
import { login } from '../redux/authActions';
import { showError } from '../../../../shared/src/utils/helpers/Toast';
import { validateEmail } from '../../../../shared/src/utils/validation/validators';
import Icon from 'react-native-vector-icons/Feather';
import { useNavigation } from '@react-navigation/native';
const LoginScreen: React.FC = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [isPasswordVisible, setPasswordVisible] = useState(false);
const [loading, setLoading] = useState(false); // Add loading state
const dispatch = useAppDispatch();
const navigation=useNavigation();
const handleLogin = () => {
if (!email.trim() || !password.trim()) {
showError('Validation Error', 'Email and password are required.');
return;
}
if (!validateEmail(email)) {
showError('Validation Error', 'Please enter a valid email address.');
return;
}
setLoading(true); // Start loading
dispatch(login({ email, password }));
// Simulate a network request for 4 seconds
setTimeout(() => {
setLoading(false); // Stop loading after 4 seconds
}, 4000);
};
return (
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View style={styles.container}>
<Text style={styles.title}>Radiologist</Text>
{/* Email Input */}
<View style={styles.inputContainer}>
<Icon name="mail" size={20} color={Colors.textSecondary} style={styles.inputIcon} />
<TextInput
placeholder="Email"
value={email}
onChangeText={setEmail}
style={styles.inputField}
autoCapitalize="none"
keyboardType="email-address"
placeholderTextColor={Colors.textMuted}
/>
</View>
{/* Password Input */}
<View style={styles.inputContainer}>
<Icon name="lock" size={20} color={Colors.textSecondary} style={styles.inputIcon} />
<TextInput
placeholder="Password"
value={password}
onChangeText={setPassword}
style={styles.inputField}
secureTextEntry={!isPasswordVisible}
placeholderTextColor={Colors.textMuted}
/>
<TouchableOpacity
onPress={() => setPasswordVisible(!isPasswordVisible)}
style={styles.eyeIcon}>
<Icon name={isPasswordVisible ? 'eye-off' : 'eye'} size={22} color={Colors.textSecondary} />
</TouchableOpacity>
</View>
<Button
title="Login"
onPress={handleLogin}
style={styles.button}
loading={loading} // Pass loading state to button
/>
<Text style={{alignSelf:'center',marginTop:15}}>-----OR------</Text>
<Button
title="Sign Up"
onPress={()=>navigation.navigate('SignUpScreen')}
style={styles.button}
/>
</View>
</TouchableWithoutFeedback>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: Colors.background,
justifyContent: 'center',
padding: Spacing.lg,
},
title: {
fontFamily: Typography.fontFamily.bold,
fontSize: Typography.fontSize.title,
color: Colors.primary,
marginBottom: Spacing.xl,
textAlign: 'center',
},
inputContainer: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: Colors.backgroundAlt,
borderWidth: 1,
borderColor: Colors.border,
borderRadius: 8,
marginBottom: Spacing.md,
paddingHorizontal: Spacing.md,
paddingVertical:2
},
inputIcon: {
marginRight: Spacing.sm,
},
inputField: {
flex: 1,
paddingVertical: Spacing.md,
fontSize: Typography.fontSize.md,
color: Colors.textPrimary,
},
eyeIcon: {
paddingLeft: Spacing.sm,
},
button: {
marginTop: Spacing.md,
},
});
export default LoginScreen;
/*
* End of File: LoginScreen.tsx
* Design & Developed by Tech4Biz Solutions
* Copyright (c) Spurrin Innovations. All rights reserved.
*/