405 lines
11 KiB
TypeScript
405 lines
11 KiB
TypeScript
import React, { useState } from 'react';
|
|
import {View,Text,TextInput,TouchableOpacity,ScrollView,StyleSheet,SafeAreaView,Image,Pressable,} from 'react-native';
|
|
import { StatusBar } from 'expo-status-bar';
|
|
import { ArrowLeft, Eye, EyeOff, Coffee, MapPin } from 'lucide-react-native';
|
|
import { doc, setDoc } from 'firebase/firestore';
|
|
import { db } from '../../../firebase/config';
|
|
import { signUp } from '../../../firebase/auth';
|
|
import { Alert } from 'react-native';
|
|
import { router } from "expo-router";
|
|
|
|
|
|
|
|
export default function App() {
|
|
const [step, setStep] = useState(1);
|
|
const [showPassword, setShowPassword] = useState(false);
|
|
const [showConfirmPassword, setShowConfirmPassword] = useState(false);
|
|
const [formData, setFormData] = useState({
|
|
fullName: '',
|
|
email: '',
|
|
phone: '',
|
|
password: '',
|
|
confirmPassword: '',
|
|
cafeName: '',
|
|
cafeAddress: '',
|
|
city: '',
|
|
delegation: '',
|
|
fiscalId: '',
|
|
acceptTerms: false,
|
|
});
|
|
|
|
const handleInputChange = (name: string, value: string | boolean) => {
|
|
setFormData(prev => ({
|
|
...prev,
|
|
[name]: value
|
|
}));
|
|
};
|
|
|
|
const handleNext = () => {
|
|
setStep(2);
|
|
};
|
|
|
|
const handleSubmit = async () => {
|
|
if (!formData.acceptTerms) {
|
|
Alert.alert("Erreur", "Vous devez accepter les conditions.");
|
|
return;
|
|
}
|
|
|
|
if (formData.password !== formData.confirmPassword) {
|
|
Alert.alert("Erreur", "Les mots de passe ne correspondent pas.");
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const user = await signUp(formData.email, formData.password);
|
|
|
|
await setDoc(doc(db, 'users', user.uid), {
|
|
fullName: formData.fullName,
|
|
email: formData.email,
|
|
phone: formData.phone,
|
|
cafeName: formData.cafeName,
|
|
cafeAddress: formData.cafeAddress,
|
|
city: formData.city,
|
|
delegation: formData.delegation,
|
|
fiscalId: formData.fiscalId,
|
|
role: 'user',
|
|
createdAt: new Date(),
|
|
});
|
|
|
|
Alert.alert("Succès", "Compte créé avec succès !");
|
|
router.replace("/screens/user/UserHomeScreen"); // You can route based on role later
|
|
|
|
} catch (error: any) {
|
|
Alert.alert("Erreur", error.message);
|
|
console.log(error);
|
|
}
|
|
};
|
|
|
|
|
|
const renderStep1 = () => (
|
|
<View>
|
|
<View style={styles.inputGroup}>
|
|
<Text style={styles.label}>Nom et Prénom</Text>
|
|
<TextInput
|
|
style={styles.input}
|
|
placeholder="Nom et prénom"
|
|
value={formData.fullName}
|
|
onChangeText={(value) => handleInputChange('fullName', value)}
|
|
/>
|
|
</View>
|
|
|
|
<View style={styles.inputGroup}>
|
|
<Text style={styles.label}>E-mail</Text>
|
|
<TextInput
|
|
style={styles.input}
|
|
placeholder="E-mail"
|
|
keyboardType="email-address"
|
|
autoCapitalize="none"
|
|
value={formData.email}
|
|
onChangeText={(value) => handleInputChange('email', value)}
|
|
/>
|
|
</View>
|
|
|
|
<View style={styles.inputGroup}>
|
|
<Text style={styles.label}>Numéro de téléphone</Text>
|
|
<TextInput
|
|
style={styles.input}
|
|
placeholder="+216 00 000 000"
|
|
keyboardType="phone-pad"
|
|
value={formData.phone}
|
|
onChangeText={(value) => handleInputChange('phone', value)}
|
|
/>
|
|
</View>
|
|
|
|
<View style={styles.inputGroup}>
|
|
<Text style={styles.label}>Mot de passe</Text>
|
|
<View style={styles.passwordContainer}>
|
|
<TextInput
|
|
style={styles.passwordInput}
|
|
secureTextEntry={!showPassword}
|
|
value={formData.password}
|
|
onChangeText={(value) => handleInputChange('password', value)}
|
|
/>
|
|
<TouchableOpacity
|
|
style={styles.eyeIcon}
|
|
onPress={() => setShowPassword(!showPassword)}
|
|
>
|
|
{showPassword ? <EyeOff size={20} color="#666" /> : <Eye size={20} color="#666" />}
|
|
</TouchableOpacity>
|
|
</View>
|
|
</View>
|
|
|
|
<View style={styles.inputGroup}>
|
|
<Text style={styles.label}>Confirmer votre mot de passe</Text>
|
|
<View style={styles.passwordContainer}>
|
|
<TextInput
|
|
style={styles.passwordInput}
|
|
secureTextEntry={!showConfirmPassword}
|
|
value={formData.confirmPassword}
|
|
onChangeText={(value) => handleInputChange('confirmPassword', value)}
|
|
/>
|
|
<TouchableOpacity
|
|
style={styles.eyeIcon}
|
|
onPress={() => setShowConfirmPassword(!showConfirmPassword)}
|
|
>
|
|
{showConfirmPassword ? <EyeOff size={20} color="#666" /> : <Eye size={20} color="#666" />}
|
|
</TouchableOpacity>
|
|
</View>
|
|
</View>
|
|
|
|
<TouchableOpacity style={styles.button} onPress={handleNext}>
|
|
<Text style={styles.buttonText}>Suivant</Text>
|
|
</TouchableOpacity>
|
|
|
|
<View style={styles.loginContainer}>
|
|
<Text style={styles.loginText}>Vous avez déjà un compte? </Text>
|
|
<TouchableOpacity>
|
|
<Text style={styles.loginLink}>Connexion</Text>
|
|
</TouchableOpacity>
|
|
</View>
|
|
</View>
|
|
);
|
|
|
|
const renderStep2 = () => (
|
|
<View>
|
|
<View style={styles.inputGroup}>
|
|
<Text style={styles.label}>Nom de Café</Text>
|
|
<TextInput
|
|
style={styles.input}
|
|
placeholder="Nom de café"
|
|
value={formData.cafeName}
|
|
onChangeText={(value) => handleInputChange('cafeName', value)}
|
|
/>
|
|
</View>
|
|
|
|
<View style={styles.inputGroup}>
|
|
<Text style={styles.label}>Adresse de Café</Text>
|
|
<TextInput
|
|
style={styles.input}
|
|
placeholder="Adresse de Café"
|
|
value={formData.cafeAddress}
|
|
onChangeText={(value) => handleInputChange('cafeAddress', value)}
|
|
/>
|
|
</View>
|
|
|
|
<View style={styles.inputGroup}>
|
|
<Text style={styles.label}>Ville</Text>
|
|
<View style={styles.selectContainer}>
|
|
<Pressable
|
|
style={styles.select}
|
|
onPress={() => {
|
|
// Add city picker logic here
|
|
}}
|
|
>
|
|
<Text style={styles.selectText}>
|
|
{formData.city || 'Sélectionner une ville'}
|
|
</Text>
|
|
<MapPin size={20} color="#666" />
|
|
</Pressable>
|
|
</View>
|
|
</View>
|
|
|
|
<View style={styles.inputGroup}>
|
|
<Text style={styles.label}>Délégation</Text>
|
|
<View style={styles.selectContainer}>
|
|
<Pressable
|
|
style={styles.select}
|
|
onPress={() => {
|
|
// Add delegation picker logic here
|
|
}}
|
|
>
|
|
<Text style={styles.selectText}>
|
|
{formData.delegation || 'Sélectionner une délégation'}
|
|
</Text>
|
|
<MapPin size={20} color="#666" />
|
|
</Pressable>
|
|
</View>
|
|
</View>
|
|
|
|
<View style={styles.inputGroup}>
|
|
<Text style={styles.label}>Matricule Fiscale</Text>
|
|
<TextInput
|
|
style={styles.input}
|
|
placeholder="Matricule Fiscale"
|
|
value={formData.fiscalId}
|
|
onChangeText={(value) => handleInputChange('fiscalId', value)}
|
|
/>
|
|
</View>
|
|
|
|
<View style={styles.checkboxContainer}>
|
|
<Pressable
|
|
style={[styles.checkbox, formData.acceptTerms && styles.checkboxChecked]}
|
|
onPress={() => handleInputChange('acceptTerms', !formData.acceptTerms)}
|
|
/>
|
|
<Text style={styles.checkboxLabel}>
|
|
J'accepte les conditions générales et la politique de confidentialité.
|
|
</Text>
|
|
</View>
|
|
|
|
<TouchableOpacity style={styles.button} onPress={handleSubmit}>
|
|
<Text style={styles.buttonText}>Valider</Text>
|
|
</TouchableOpacity>
|
|
</View>
|
|
);
|
|
|
|
return (
|
|
<SafeAreaView style={styles.container}>
|
|
<StatusBar style="dark" />
|
|
<ScrollView contentContainerStyle={styles.scrollContainer}>
|
|
<View style={styles.header}>
|
|
{step > 1 && (
|
|
<TouchableOpacity
|
|
style={styles.backButton}
|
|
onPress={() => setStep(1)}
|
|
>
|
|
<ArrowLeft size={24} color="#666" />
|
|
</TouchableOpacity>
|
|
)}
|
|
<View style={styles.logoContainer}>
|
|
<Image source={require('../../../assets/images/logo.png')} style={styles.logo}/>
|
|
<Text style={styles.title}>Création de compte</Text>
|
|
</View>
|
|
</View>
|
|
{step === 1 ? renderStep1() : renderStep2()}
|
|
</ScrollView>
|
|
</SafeAreaView>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
backgroundColor: '#fff',
|
|
padding: 10,
|
|
},
|
|
scrollContainer: {
|
|
flexGrow: 1,
|
|
padding: 16,
|
|
},
|
|
header: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
marginBottom: 24,
|
|
},
|
|
backButton: {
|
|
padding: 0,
|
|
},
|
|
logoContainer: {
|
|
flex: 1,
|
|
alignItems: 'center',
|
|
marginRight:15,
|
|
|
|
},
|
|
logo: {
|
|
width: 80,
|
|
height: 80,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
verticalAlign:'middle',
|
|
marginTop:20,
|
|
marginBottom: 16,
|
|
marginRight:15,
|
|
|
|
},
|
|
title: {
|
|
fontSize: 24,
|
|
fontWeight: '600',
|
|
color: '#1f2937',
|
|
},
|
|
inputGroup: {
|
|
marginBottom: 16,
|
|
},
|
|
label: {
|
|
fontSize: 14,
|
|
fontWeight: '500',
|
|
color: '#374151',
|
|
marginBottom: 4,
|
|
},
|
|
input: {
|
|
borderWidth: 1,
|
|
borderColor: '#d1d5db',
|
|
borderRadius: 8,
|
|
padding: 12,
|
|
fontSize: 16,
|
|
color: '#1f2937',
|
|
},
|
|
passwordContainer: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
borderWidth: 1,
|
|
borderColor: '#d1d5db',
|
|
borderRadius: 8,
|
|
},
|
|
passwordInput: {
|
|
flex: 1,
|
|
padding: 12,
|
|
fontSize: 16,
|
|
color: '#1f2937',
|
|
},
|
|
eyeIcon: {
|
|
padding: 12,
|
|
},
|
|
selectContainer: {
|
|
borderWidth: 1,
|
|
borderColor: '#d1d5db',
|
|
borderRadius: 8,
|
|
},
|
|
select: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
justifyContent: 'space-between',
|
|
padding: 12,
|
|
},
|
|
selectText: {
|
|
fontSize: 16,
|
|
color: '#9ca3af',
|
|
},
|
|
checkboxContainer: {
|
|
flexDirection: 'row',
|
|
alignItems: 'flex-start',
|
|
marginBottom: 16,
|
|
},
|
|
checkbox: {
|
|
width: 20,
|
|
height: 20,
|
|
borderWidth: 2,
|
|
borderColor: '#d1d5db',
|
|
borderRadius: 4,
|
|
marginRight: 8,
|
|
marginTop: 2,
|
|
},
|
|
checkboxChecked: {
|
|
backgroundColor: '#22C55E',
|
|
borderColor: '#22C55E',
|
|
},
|
|
checkboxLabel: {
|
|
flex: 1,
|
|
fontSize: 14,
|
|
color: '#4b5563',
|
|
},
|
|
button: {
|
|
backgroundColor: '#B77729',
|
|
borderRadius: 8,
|
|
padding: 16,
|
|
alignItems: 'center',
|
|
marginBottom: 16,
|
|
},
|
|
buttonText: {
|
|
color: 'white',
|
|
fontSize: 16,
|
|
fontWeight: '500',
|
|
},
|
|
loginContainer: {
|
|
flexDirection: 'row',
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
},
|
|
loginText: {
|
|
fontSize: 14,
|
|
color: '#4b5563',
|
|
},
|
|
loginLink: {
|
|
fontSize: 14,
|
|
color: '#B77729',
|
|
},
|
|
}); |