initial commit

This commit is contained in:
Med Kamel 2025-04-16 02:22:34 +01:00
parent bf20e7e3d7
commit e32c9d33fa
9 changed files with 1843 additions and 23 deletions

BIN
app.rar

Binary file not shown.

View File

@ -1,7 +1,7 @@
const COLORS = {
background_user: '#FFFFFF',
text: '#FFFFFF',
primary: '#B07B2C',
primary: '#B17741',
};
export default COLORS;

View File

@ -1,34 +1,299 @@
import React from 'react';
import { View, Text, StyleSheet, Button } from 'react-native';
import { router } from 'expo-router';
import { useState } from "react";
import {
View,
Text,
TextInput,
Pressable,
StyleSheet,
Image,
Alert,
TouchableOpacity,
} from "react-native";
import { Eye, EyeOff } from "lucide-react-native";
import { router } from "expo-router";
import { signIn } from "../../../firebase/auth"; // Assure-toi que le chemin est correct
import { Link } from "expo-router";
const SignInScreen = () => {
const [form, setForm] = useState({
email: "",
password: "",
rememberMe: false,
});
const [errors, setErrors] = useState({
email: "",
password: "",
});
const [showPassword, setShowPassword] = useState(false);
const validateForm = () => {
let valid = true;
const newErrors = { email: "", password: "" };
if (!form.email) {
newErrors.email = "L'e-mail est requis.";
valid = false;
}
if (!form.password) {
newErrors.password = "Le mot de passe est requis.";
valid = false;
}
setErrors(newErrors);
return valid;
};
const handleLogin = async () => {
if (!validateForm()) return;
try {
const { user } = await signIn(form.email, form.password); // Destructure to get user
console.log("Connexion réussie :", user.email); // Access the email directly
router.replace("/screens/user/UserHomeScreen"); // You can route based on role later
} catch (error: any) {
Alert.alert("Erreur", error.message); // Display the error message
}
};
return (
<View style={styles.container}>
<Text style={styles.welcomeText}>Sign In Screen</Text>
<Button
title="Back to Opening Screen"
onPress={() => router.back()}
/>
<Pressable onPress={() => router.back()} style={styles.backButton}>
<Text style={styles.backText}></Text>
</Pressable>
<Image source={require('../../../assets/images/logo.png')} style={styles.logo}/>
<Text style={styles.title}>Se connecter</Text>
<Text style={styles.welcome}>Bienvenue! 👋</Text>
<View style={styles.form}>
<View style={styles.inputGroup}>
<Text style={styles.label}>E-mail</Text>
<TextInput
placeholder="Entrez votre adresse e-mail"
placeholderTextColor="#666"
style={[styles.input, errors.email && styles.inputError]}
keyboardType="email-address"
autoCapitalize="none"
value={form.email}
onChangeText={(text) => {
setForm({ ...form, email: text });
if (errors.email) setErrors({ ...errors, email: "" });
}}
/>
{errors.email ? (
<Text style={styles.errorText}>{errors.email}</Text>
) : null}
</View>
<View style={styles.inputGroup}>
<Text style={styles.label}>Mot de passe</Text>
<View
style={[
styles.passwordContainer,
errors.password && styles.inputError,
]}
>
<TextInput
placeholder="Entrez votre mot de passe"
placeholderTextColor="#666"
style={styles.passwordInput}
secureTextEntry={!showPassword}
value={form.password}
onChangeText={(text) => {
setForm({ ...form, password: text });
if (errors.password) setErrors({ ...errors, password: "" });
}}
/>
<Pressable
onPress={() => setShowPassword(!showPassword)}
style={styles.eyeIcon}
>
{showPassword ? (
<EyeOff size={20} color="#666" />
) : (
<Eye size={20} color="#666" />
)}
</Pressable>
</View>
{errors.password ? (
<Text style={styles.errorText}>{errors.password}</Text>
) : null}
</View>
<View style={styles.optionsContainer}>
<Pressable
style={styles.rememberMe}
onPress={() => setForm({ ...form, rememberMe: !form.rememberMe })}
>
<View
style={[
styles.checkbox,
form.rememberMe && styles.checkboxChecked,
]}
/>
<Text style={styles.rememberText}>Rester Connecté</Text>
</Pressable>
<TouchableOpacity>
<Text style={styles.forgotText}>Mot de passe oublié?</Text>
</TouchableOpacity>
</View>
</View>
<Pressable style={styles.loginButton} onPress={handleLogin}>
<Text style={styles.loginButtonText}>Connexion</Text>
</Pressable>
<View style={styles.signupContainer}>
<Text style={styles.signupText}>Nouveau ici? </Text>
<Link href="/screens/auth/SignUpScreen" style={styles.signupLink}>
<Text style={styles.signupLinkText}>Créer un compte</Text>
</Link>
</View>
</View>
);
};
// Styles
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#FFFFFF',
alignItems: 'center',
justifyContent: 'center',
paddingHorizontal: 20,
backgroundColor: "#fff",
padding: 20,
},
welcomeText: {
fontSize: 24,
fontWeight: 'bold',
color: '#000000',
backButton: {
marginTop: 2,
marginBottom: 0,
},
backText: {
fontSize: 40,
color: "#000",
},
logo: {
width: 100,
height: 100,
alignSelf: "center",
marginBottom: 20,
},
title: {
fontSize: 24,
fontWeight: "bold",
textAlign: "center",
marginBottom: 30,
},
welcome: {
fontSize: 28,
fontWeight: "bold",
marginBottom: 30,
},
form: {
gap: 20,
},
inputGroup: {
gap: 8,
},
label: {
fontSize: 16,
fontWeight: "500",
color: "#333",
},
input: {
backgroundColor: "#f5f5f5",
padding: 16,
borderRadius: 8,
fontSize: 16,
},
inputError: {
borderWidth: 1,
borderColor: "#ff4444",
},
errorText: {
color: "#ff4444",
fontSize: 14,
marginTop: 4,
},
passwordContainer: {
flexDirection: "row",
alignItems: "center",
backgroundColor: "#f5f5f5",
borderRadius: 8,
},
passwordInput: {
flex: 1,
padding: 16,
fontSize: 16,
},
eyeIcon: {
padding: 16,
},
optionsContainer: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
marginTop: 8,
},
rememberMe: {
flexDirection: "row",
alignItems: "center",
gap: 8,
},
checkbox: {
width: 20,
height: 20,
borderRadius: 4,
borderWidth: 2,
borderColor: "#B17741",
},
checkboxChecked: {
backgroundColor: "#B17741",
},
rememberText: {
color: "#333",
fontSize: 14,
},
forgotPassword: {
padding: 4,
},
forgotText: {
color: "#B17741",
fontSize: 14,
fontWeight: "500",
},
loginButton: {
backgroundColor: "#B17741",
padding: 16,
borderRadius: 8,
marginTop: 30,
},
loginButtonText: {
color: "#fff",
textAlign: "center",
fontSize: 16,
fontWeight: "600",
},
signupContainer: {
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
marginTop: 20,
},
signupText: {
color: "#666",
fontSize: 14,
},
signupLink: {
padding: 4,
},
signupLinkText: {
color: "#B17741",
fontSize: 14,
fontWeight: "500",
},
});
export default SignInScreen;

View File

@ -1,5 +1,6 @@
import { Stack } from 'expo-router';
export default function AuthLayout() {
return (
<Stack screenOptions={{ headerShown: false }}>

View File

@ -1,16 +1,20 @@
import React from 'react';
import { View, Text, Image, StyleSheet, TouchableOpacity } from 'react-native';
import { View, Text, StyleSheet, Button } from 'react-native';
import { router } from 'expo-router';
const UserHomeScreen = () => {
return (
<View style={styles.container}>
<Text style={styles.welcomeText}>UserHomeScreen</Text>
<Button
title="Back to Opening Screen"
onPress={() => router.back()}
/>
</View>
);
};
// Styles
const styles = StyleSheet.create({
container: {
flex: 1,

49
firebase/auth.ts Normal file
View File

@ -0,0 +1,49 @@
// auth.ts
import auth from '@react-native-firebase/auth'; // Importing Firebase Authentication from React Native Firebase
import { FirebaseAuthTypes } from '@react-native-firebase/auth';
// Function to handle user sign-in with email and password
export const signIn = async (email: string, password: string) => {
try {
const userCredential = await auth().signInWithEmailAndPassword(email, password);
return { user: userCredential.user }; // Return the user on success
} catch (error: any) {
throw new Error(error.message); // Throw an error if sign-in fails
}
};
// Function to handle user sign-up with email and password
export const signUp = async (email: string, password: string) => {
try {
const userCredential = await auth().createUserWithEmailAndPassword(email, password);
const user = userCredential.user;
console.log('User signed up:', user);
return user;
} catch (error) {
console.error('Error signing up:', error);
throw error;
}
};
// Function to handle user sign-out
export const signOutUser = async () => {
try {
await auth().signOut();
console.log('User signed out');
} catch (error) {
console.error('Error signing out:', error);
throw error;
}
};
// Listen for changes in authentication state
export const authStateListener = (callback: (user: FirebaseAuthTypes.User | null) => void) => {
return auth().onAuthStateChanged(user => {
if (user) {
console.log('User is authenticated:', user);
} else {
console.log('No user is signed in.');
}
callback(user);
});
};

18
firebase/config.ts Normal file
View File

@ -0,0 +1,18 @@
// config.ts
import { FirebaseApp, initializeApp } from 'firebase/app';
// Your web app's Firebase configuration
const firebaseConfig = {
apiKey: 'AIzaSyDHoF8Eahk60s3APh7WxohL1bya_44v39k',
authDomain: 'brix-cafe-2ddf1.firebaseapp.com',
projectId: 'brix-cafe-2ddf1',
storageBucket: 'brix-cafe-2ddf1.firebasestorage.app',
messagingSenderId: '577471189504',
appId: '1:577471189504:web:7bf8819223bf0d4cf03ee5',
measurementId: 'G-FSV5ZQBJS3',
};
// Initialize Firebase
const app: FirebaseApp = initializeApp(firebaseConfig);
export { app };

1480
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -16,6 +16,9 @@
},
"dependencies": {
"@expo/vector-icons": "^14.0.2",
"@react-native-async-storage/async-storage": "^1.24.0",
"@react-native-firebase/app": "^21.14.0",
"@react-native-firebase/auth": "^21.14.0",
"@react-navigation/bottom-tabs": "^7.2.0",
"@react-navigation/native": "^7.0.14",
"expo": "~52.0.46",
@ -30,6 +33,8 @@
"expo-symbols": "~0.2.2",
"expo-system-ui": "~4.0.9",
"expo-web-browser": "~14.0.2",
"firebase": "^11.6.0",
"lucide-react-native": "^0.488.0",
"react": "18.3.1",
"react-dom": "18.3.1",
"react-native": "0.76.9",