197 lines
5.4 KiB
TypeScript
197 lines
5.4 KiB
TypeScript
import React, { useState } from "react";
|
|
import { Alert, StyleSheet, View, Text, Image } from "react-native";
|
|
import { Button, Input } from "@rn-vui/themed";
|
|
import { useAuthStore } from "@/stores/auth";
|
|
import { Link } from "expo-router";
|
|
import { Mail, Lock, User, Building2 } from "lucide-react-native";
|
|
import { PRIMARY, PRIMARY_LIGHT } from "@/constants/colors";
|
|
import { useThemeColor } from "@/hooks/useThemeColor";
|
|
import { useColorScheme } from "@/hooks/useColorScheme";
|
|
|
|
export default function SignUp() {
|
|
const [firstName, setFirstName] = useState("");
|
|
const [lastName, setLastName] = useState("");
|
|
const [companyName, setCompanyName] = useState("");
|
|
const [email, setEmail] = useState("");
|
|
const [password, setPassword] = useState("");
|
|
|
|
const signUp = useAuthStore((state) => state.signUp);
|
|
const authLoading = useAuthStore((state) => state.loading);
|
|
|
|
// Theme-aware colors
|
|
const backgroundColor = useThemeColor({ light: "#f5f5f5", dark: "#111827" }, "background");
|
|
const textColor = useThemeColor({ light: "#333", dark: "#f9fafb" }, "text");
|
|
const subtitleColor = useThemeColor({ light: "#666", dark: "#9ca3af" }, "text");
|
|
const linkColor = useThemeColor({ light: PRIMARY, dark: PRIMARY_LIGHT }, "text");
|
|
|
|
const dark = useColorScheme() === "dark";
|
|
|
|
const logo = dark
|
|
? require("@/assets/images/logo_white.png")
|
|
: require("@/assets/images/logo.png");
|
|
|
|
const handleSignUp = async () => {
|
|
try {
|
|
await signUp(email, password, firstName, lastName, companyName);
|
|
} catch (error) {
|
|
Alert.alert(
|
|
"Erreur",
|
|
error instanceof Error
|
|
? error.message
|
|
: "Impossible de créer votre compte pour le moment."
|
|
);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<View style={[styles.container, { backgroundColor }]}>
|
|
<Image source={logo} style={styles.logo} />
|
|
<Text style={[styles.title, { color: textColor }]}>Créer un compte XTablo</Text>
|
|
<Text style={[styles.subtitle, { color: subtitleColor }]}>Rejoignez-nous !</Text>
|
|
<View style={[styles.verticallySpaced, styles.mt10]}>
|
|
<Input
|
|
label="Prénom"
|
|
leftIcon={<User size={20} color="#666" />}
|
|
onChangeText={(text) => setFirstName(text)}
|
|
value={firstName}
|
|
placeholder="Jean"
|
|
autoCapitalize={"words"}
|
|
/>
|
|
</View>
|
|
<View style={styles.verticallySpaced}>
|
|
<Input
|
|
label="Nom"
|
|
leftIcon={<User size={20} color="#666" />}
|
|
onChangeText={(text) => setLastName(text)}
|
|
value={lastName}
|
|
placeholder="Dupont"
|
|
autoCapitalize="words"
|
|
/>
|
|
</View>
|
|
<View style={styles.verticallySpaced}>
|
|
<Input
|
|
label="Nom de l'entreprise"
|
|
leftIcon={<Building2 size={20} color="#666" />}
|
|
onChangeText={(text) => setCompanyName(text)}
|
|
value={companyName}
|
|
placeholder="Mon Entreprise"
|
|
autoCapitalize="words"
|
|
/>
|
|
</View>
|
|
<View style={styles.verticallySpaced}>
|
|
<Input
|
|
label="Adresse email"
|
|
leftIcon={<Mail size={20} color="#666" />}
|
|
onChangeText={(text) => setEmail(text)}
|
|
value={email}
|
|
placeholder="jean@dupont.com"
|
|
autoCapitalize="none"
|
|
keyboardType="email-address"
|
|
/>
|
|
</View>
|
|
<View style={styles.verticallySpaced}>
|
|
<Input
|
|
label="Mot de passe"
|
|
leftIcon={<Lock size={20} color="#666" />}
|
|
onChangeText={(text) => setPassword(text)}
|
|
value={password}
|
|
secureTextEntry
|
|
placeholder="Mot de passe"
|
|
autoCapitalize="none"
|
|
/>
|
|
</View>
|
|
<View style={[styles.verticallySpaced, styles.mt20]}>
|
|
<Button
|
|
title="S'inscrire"
|
|
disabled={authLoading}
|
|
onPress={handleSignUp}
|
|
buttonStyle={styles.button}
|
|
titleStyle={styles.buttonTitle}
|
|
/>
|
|
</View>
|
|
<View style={styles.linkContainer}>
|
|
<Text style={[styles.linkText, { color: subtitleColor }]}>Vous avez déjà un compte ? </Text>
|
|
<Link href="/login" style={[styles.link, { color: linkColor }]}>
|
|
Se connecter
|
|
</Link>
|
|
</View>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
// Using similar styles from login page for consistency
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
justifyContent: "center",
|
|
padding: 16,
|
|
},
|
|
logo: {
|
|
width: 80,
|
|
height: 80,
|
|
alignSelf: "center",
|
|
marginBottom: 8,
|
|
borderRadius: 40,
|
|
},
|
|
title: {
|
|
fontSize: 24,
|
|
fontWeight: "bold",
|
|
textAlign: "center",
|
|
marginBottom: 3,
|
|
},
|
|
subtitle: {
|
|
fontSize: 14,
|
|
textAlign: "center",
|
|
marginBottom: 16,
|
|
},
|
|
verticallySpaced: {
|
|
paddingTop: 2,
|
|
paddingBottom: 2,
|
|
alignSelf: "stretch",
|
|
},
|
|
mt20: {
|
|
marginTop: 12,
|
|
},
|
|
mt40: {
|
|
marginTop: 40,
|
|
},
|
|
mt10: {
|
|
marginTop: 6,
|
|
},
|
|
mt5: {
|
|
marginTop: 3,
|
|
},
|
|
button: {
|
|
paddingVertical: 12,
|
|
borderRadius: 8,
|
|
backgroundColor: PRIMARY,
|
|
},
|
|
buttonTitle: {
|
|
fontWeight: "bold",
|
|
color: "#fff",
|
|
},
|
|
separatorContainer: {
|
|
flexDirection: "row",
|
|
alignItems: "center",
|
|
marginVertical: 12,
|
|
},
|
|
separator: {
|
|
flex: 1,
|
|
height: 1,
|
|
backgroundColor: "#ddd",
|
|
},
|
|
separatorText: {
|
|
marginHorizontal: 15,
|
|
color: "#666",
|
|
fontSize: 14,
|
|
},
|
|
linkContainer: {
|
|
flexDirection: "row",
|
|
justifyContent: "center",
|
|
marginTop: 12,
|
|
},
|
|
linkText: {},
|
|
link: {
|
|
fontWeight: "bold",
|
|
},
|
|
});
|