chore: delete register page
This commit is contained in:
@@ -1,14 +1,10 @@
|
||||
name: Frontend Client - EAS Build
|
||||
name: Frontend Client - EAS Update
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- "mobile/**"
|
||||
pull_request:
|
||||
branches: [main]
|
||||
paths:
|
||||
- "mobile/**"
|
||||
|
||||
jobs:
|
||||
typecheck:
|
||||
@@ -32,7 +28,7 @@ jobs:
|
||||
working-directory: mobile
|
||||
run: npx tsc --noEmit
|
||||
|
||||
build-apk-prod:
|
||||
eas-update:
|
||||
needs: typecheck
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -62,25 +58,6 @@ jobs:
|
||||
jq '.expo.extra.eas.projectId = "${{ secrets.EXPO_PROJECT_ID_CLIENT }}"' app.json > app.tmp.json
|
||||
mv app.tmp.json app.json
|
||||
|
||||
- name: Debug app.json
|
||||
- name: Publish OTA update
|
||||
working-directory: mobile
|
||||
run: cat app.json
|
||||
|
||||
- name: Build production APK
|
||||
working-directory: mobile
|
||||
env:
|
||||
EAS_BUILD_NO_EXPO_GO_WARNING: true
|
||||
run: eas build --platform android --profile production --non-interactive
|
||||
|
||||
- name: Download production APK
|
||||
working-directory: mobile
|
||||
run: |
|
||||
APK_URL=$(eas build:list --platform android --status finished --limit 1 --json --non-interactive | jq -r '.[0].artifacts.buildUrl')
|
||||
curl -L -o client-panel-prod.apk "$APK_URL"
|
||||
|
||||
- name: Upload production APK artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: client-panel-android-prod-apk
|
||||
path: mobile/client-panel-prod.apk
|
||||
retention-days: 14
|
||||
run: eas update --channel production --message "${{ github.event.head_commit.message }}" --non-interactive
|
||||
|
||||
@@ -27,17 +27,6 @@ export default function HomeScreen({ navigation }: Props) {
|
||||
>
|
||||
<Text style={styles.buttonText}>Se connecter</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity
|
||||
style={[styles.button, styles.registerButton]}
|
||||
onPress={() => navigation.navigate("register")}
|
||||
>
|
||||
<Text
|
||||
style={[styles.buttonText, styles.registerButtonText]}
|
||||
>
|
||||
Créer un compte
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -1,330 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
TextInput,
|
||||
TouchableOpacity,
|
||||
StyleSheet,
|
||||
ScrollView,
|
||||
ActivityIndicator,
|
||||
} from "react-native";
|
||||
import { Feather, FontAwesome } from "@expo/vector-icons";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import type { NativeStackNavigationProp } from "@react-navigation/native-stack";
|
||||
import type { RootStackParamList } from "../../navigation/types";
|
||||
import { registerUser } from "../../api/api";
|
||||
import { useAuth } from "../../auth/AuthContext";
|
||||
import { useTheme } from "../../context/ThemeContext";
|
||||
|
||||
type RegisterScreenNavigationProp = NativeStackNavigationProp<
|
||||
RootStackParamList,
|
||||
"register"
|
||||
>;
|
||||
|
||||
const RegisterScreen = () => {
|
||||
const navigation = useNavigation<RegisterScreenNavigationProp>();
|
||||
const { loginClient } = useAuth();
|
||||
const { colors } = useTheme();
|
||||
|
||||
const [formData, setFormData] = useState({
|
||||
nom: "",
|
||||
prenom: "",
|
||||
telephone: "",
|
||||
username: "",
|
||||
password: "",
|
||||
});
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
const [errors, setErrors] = useState<{ [key: string]: string | undefined }>(
|
||||
{},
|
||||
);
|
||||
const [apiError, setApiError] = useState("");
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const handleChange = (name: string, value: string) => {
|
||||
setFormData((prev) => ({ ...prev, [name]: value }));
|
||||
setErrors((prev) => ({ ...prev, [name]: undefined }));
|
||||
if (apiError) setApiError("");
|
||||
};
|
||||
|
||||
const validateForm = () => {
|
||||
const newErrors: typeof errors = {};
|
||||
if (!formData.nom.trim()) newErrors.nom = "Le nom est requis";
|
||||
if (!formData.prenom.trim()) newErrors.prenom = "Le prénom est requis";
|
||||
const cleanPhone = formData.telephone.replace(/\s/g, "");
|
||||
if (!formData.telephone.trim())
|
||||
newErrors.telephone = "Le numéro de téléphone est requis";
|
||||
else if (!/^[0-9+]{10,15}$/.test(cleanPhone))
|
||||
newErrors.telephone =
|
||||
"Numéro de téléphone invalide (10-15 chiffres)";
|
||||
if (!formData.username.trim())
|
||||
newErrors.username = "Le nom d'utilisateur est requis";
|
||||
else if (formData.username.length < 3)
|
||||
newErrors.username = "Au moins 3 caractères requis";
|
||||
if (!formData.password)
|
||||
newErrors.password = "Le mot de passe est requis";
|
||||
else if (formData.password.length < 8)
|
||||
newErrors.password = "Au moins 8 caractères requis";
|
||||
setErrors(newErrors);
|
||||
return Object.keys(newErrors).length === 0;
|
||||
};
|
||||
|
||||
const handleRegister = async () => {
|
||||
if (!validateForm()) return;
|
||||
setIsLoading(true);
|
||||
setApiError("");
|
||||
try {
|
||||
const result = await registerUser(
|
||||
formData.username,
|
||||
formData.password,
|
||||
formData.nom,
|
||||
formData.prenom,
|
||||
formData.telephone,
|
||||
);
|
||||
if (result.success && result.access_token) {
|
||||
await loginClient(result.access_token);
|
||||
} else {
|
||||
const message =
|
||||
result.message || "Erreur lors de l'inscription";
|
||||
setApiError(message);
|
||||
setErrors({ username: message });
|
||||
}
|
||||
} catch (err: any) {
|
||||
setApiError(err.message || "Erreur serveur");
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<ScrollView
|
||||
contentContainerStyle={[
|
||||
styles.container,
|
||||
{ backgroundColor: colors.bgSecondary },
|
||||
]}
|
||||
>
|
||||
<View style={[styles.card, { backgroundColor: colors.bgPrimary }]}>
|
||||
<View style={styles.iconContainer}>
|
||||
<FontAwesome
|
||||
name="shopping-bag"
|
||||
size={48}
|
||||
color="#7c3aed"
|
||||
/>
|
||||
</View>
|
||||
|
||||
<Text style={[styles.title, { color: colors.textWhite }]}>
|
||||
Créer un compte
|
||||
</Text>
|
||||
|
||||
{apiError ? (
|
||||
<Text style={styles.apiError}>{apiError}</Text>
|
||||
) : null}
|
||||
|
||||
{/* Nom */}
|
||||
<View style={styles.inputGroup}>
|
||||
<Feather
|
||||
name="user"
|
||||
size={20}
|
||||
color={colors.textMuted}
|
||||
style={styles.icon}
|
||||
/>
|
||||
<TextInput
|
||||
style={[
|
||||
styles.input,
|
||||
{
|
||||
color: colors.textWhite,
|
||||
borderColor: colors.border,
|
||||
},
|
||||
errors.nom && styles.inputError,
|
||||
]}
|
||||
placeholder="Nom"
|
||||
placeholderTextColor={colors.textMuted}
|
||||
value={formData.nom}
|
||||
onChangeText={(value) => handleChange("nom", value)}
|
||||
/>
|
||||
{errors.nom && (
|
||||
<Text style={styles.errorText}>{errors.nom}</Text>
|
||||
)}
|
||||
</View>
|
||||
|
||||
{/* Prénom */}
|
||||
<View style={styles.inputGroup}>
|
||||
<Feather
|
||||
name="user"
|
||||
size={20}
|
||||
color={colors.textMuted}
|
||||
style={styles.icon}
|
||||
/>
|
||||
<TextInput
|
||||
style={[
|
||||
styles.input,
|
||||
{
|
||||
color: colors.textWhite,
|
||||
borderColor: colors.border,
|
||||
},
|
||||
errors.prenom && styles.inputError,
|
||||
]}
|
||||
placeholder="Prénom"
|
||||
placeholderTextColor={colors.textMuted}
|
||||
value={formData.prenom}
|
||||
onChangeText={(value) => handleChange("prenom", value)}
|
||||
/>
|
||||
{errors.prenom && (
|
||||
<Text style={styles.errorText}>{errors.prenom}</Text>
|
||||
)}
|
||||
</View>
|
||||
|
||||
{/* Téléphone */}
|
||||
<View style={styles.inputGroup}>
|
||||
<Feather
|
||||
name="phone"
|
||||
size={20}
|
||||
color={colors.textMuted}
|
||||
style={styles.icon}
|
||||
/>
|
||||
<TextInput
|
||||
style={[
|
||||
styles.input,
|
||||
{
|
||||
color: colors.textWhite,
|
||||
borderColor: colors.border,
|
||||
},
|
||||
errors.telephone && styles.inputError,
|
||||
]}
|
||||
placeholder="Téléphone"
|
||||
placeholderTextColor={colors.textMuted}
|
||||
value={formData.telephone}
|
||||
keyboardType="phone-pad"
|
||||
onChangeText={(value) =>
|
||||
handleChange("telephone", value)
|
||||
}
|
||||
/>
|
||||
{errors.telephone && (
|
||||
<Text style={styles.errorText}>{errors.telephone}</Text>
|
||||
)}
|
||||
</View>
|
||||
|
||||
{/* Username */}
|
||||
<View style={styles.inputGroup}>
|
||||
<Feather
|
||||
name="user"
|
||||
size={20}
|
||||
color={colors.textMuted}
|
||||
style={styles.icon}
|
||||
/>
|
||||
<TextInput
|
||||
style={[
|
||||
styles.input,
|
||||
{
|
||||
color: colors.textWhite,
|
||||
borderColor: colors.border,
|
||||
},
|
||||
errors.username && styles.inputError,
|
||||
]}
|
||||
placeholder="Nom d'utilisateur"
|
||||
placeholderTextColor={colors.textMuted}
|
||||
value={formData.username}
|
||||
onChangeText={(value) =>
|
||||
handleChange("username", value)
|
||||
}
|
||||
/>
|
||||
{errors.username && (
|
||||
<Text style={styles.errorText}>{errors.username}</Text>
|
||||
)}
|
||||
</View>
|
||||
|
||||
{/* Password */}
|
||||
<View style={styles.inputGroup}>
|
||||
<Feather
|
||||
name="lock"
|
||||
size={20}
|
||||
color={colors.textMuted}
|
||||
style={styles.icon}
|
||||
/>
|
||||
<TextInput
|
||||
style={[
|
||||
styles.input,
|
||||
{
|
||||
color: colors.textWhite,
|
||||
borderColor: colors.border,
|
||||
},
|
||||
errors.password && styles.inputError,
|
||||
]}
|
||||
placeholder="Mot de passe"
|
||||
placeholderTextColor={colors.textMuted}
|
||||
secureTextEntry={!showPassword}
|
||||
value={formData.password}
|
||||
onChangeText={(value) =>
|
||||
handleChange("password", value)
|
||||
}
|
||||
/>
|
||||
<TouchableOpacity
|
||||
style={styles.eyeButton}
|
||||
onPress={() => setShowPassword(!showPassword)}
|
||||
>
|
||||
<Feather
|
||||
name={showPassword ? "eye-off" : "eye"}
|
||||
size={20}
|
||||
color={colors.textMuted}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
{errors.password && (
|
||||
<Text style={styles.errorText}>{errors.password}</Text>
|
||||
)}
|
||||
</View>
|
||||
|
||||
<TouchableOpacity
|
||||
style={[styles.submitButton, isLoading && { opacity: 0.6 }]}
|
||||
onPress={handleRegister}
|
||||
disabled={isLoading}
|
||||
>
|
||||
{isLoading ? (
|
||||
<ActivityIndicator color="white" />
|
||||
) : (
|
||||
<Text style={styles.submitText}>Créer mon compte</Text>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity onPress={() => navigation.navigate("login")}>
|
||||
<Text style={[styles.loginText, { color: "#a78bfa" }]}>
|
||||
Vous avez déjà un compte ? Se connecter
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</ScrollView>
|
||||
);
|
||||
};
|
||||
|
||||
export default RegisterScreen;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flexGrow: 1,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
padding: 16,
|
||||
},
|
||||
card: { width: "100%", maxWidth: 400, borderRadius: 16, padding: 24 },
|
||||
iconContainer: { alignItems: "center", marginBottom: 16 },
|
||||
title: {
|
||||
fontSize: 24,
|
||||
fontWeight: "bold",
|
||||
marginBottom: 24,
|
||||
textAlign: "center",
|
||||
},
|
||||
inputGroup: { marginBottom: 16, position: "relative" },
|
||||
icon: { position: "absolute", left: 12, top: 12 },
|
||||
input: { height: 40, paddingLeft: 40, borderWidth: 1, borderRadius: 8 },
|
||||
inputError: { borderColor: "#ef4444" },
|
||||
eyeButton: { position: "absolute", right: 12, top: 8 },
|
||||
errorText: { color: "#f87171", marginTop: 4 },
|
||||
apiError: { color: "#f87171", textAlign: "center", marginBottom: 12 },
|
||||
submitButton: {
|
||||
backgroundColor: "#7c3aed",
|
||||
borderRadius: 8,
|
||||
padding: 12,
|
||||
alignItems: "center",
|
||||
marginTop: 8,
|
||||
},
|
||||
submitText: { color: "white", fontWeight: "600" },
|
||||
loginText: { textAlign: "center", marginTop: 16 },
|
||||
});
|
||||
Reference in New Issue
Block a user