chore: add createclientbyadmin
This commit is contained in:
@@ -274,6 +274,67 @@ func RegisterClient(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// AdminCreateClient crée un client depuis l'interface admin (sans session ni token)
|
||||
// POST /api/v2/admin/protected/clients
|
||||
func AdminCreateClient(c *gin.Context) {
|
||||
var req RegisterClientRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Données invalides"})
|
||||
return
|
||||
}
|
||||
|
||||
if !validatePhoneNumber(req.Telephone) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Numéro de téléphone invalide"})
|
||||
return
|
||||
}
|
||||
|
||||
normalizedPhone := normalizePhoneNumber(req.Telephone)
|
||||
database := c.MustGet("database").(*db.Database)
|
||||
|
||||
if existing, _ := database.GetClientByUsername(req.Username); existing != nil {
|
||||
c.JSON(http.StatusConflict, gin.H{"error": "Nom d'utilisateur déjà utilisé"})
|
||||
return
|
||||
}
|
||||
|
||||
if existing, _ := database.GetClientByTelephone(normalizedPhone); existing != nil {
|
||||
c.JSON(http.StatusConflict, gin.H{"error": "Ce numéro de téléphone est déjà utilisé"})
|
||||
return
|
||||
}
|
||||
|
||||
hashed, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur traitement mot de passe"})
|
||||
return
|
||||
}
|
||||
|
||||
client := &models.Client{
|
||||
Username: req.Username,
|
||||
Password: string(hashed),
|
||||
Nom: strings.TrimSpace(req.Nom),
|
||||
Prenom: strings.TrimSpace(req.Prenom),
|
||||
Telephone: normalizedPhone,
|
||||
}
|
||||
|
||||
if err := database.CreateClient(client); err != nil {
|
||||
log.Printf("❌ [ADMIN_CREATE_CLIENT] Erreur création: %v", err)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur création client"})
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("✅ [ADMIN_CREATE_CLIENT] Client créé par admin: %s (ID=%d)", client.Username, client.ID)
|
||||
|
||||
c.JSON(http.StatusCreated, gin.H{
|
||||
"message": "Client créé avec succès",
|
||||
"client": gin.H{
|
||||
"id": client.ID,
|
||||
"username": client.Username,
|
||||
"nom": client.Nom,
|
||||
"prenom": client.Prenom,
|
||||
"telephone": client.Telephone,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// LoginClient authentifie un client
|
||||
// POST /api/v1/auth/login
|
||||
func LoginClient(c *gin.Context) {
|
||||
|
||||
@@ -32,7 +32,6 @@ func SetupRoutes(router *gin.Engine, database *db.Database, geoService *services
|
||||
// ============================================
|
||||
authGroupV1 := router.Group("/api/v1/auth")
|
||||
{
|
||||
authGroupV1.POST("/register", handlers.RegisterClient)
|
||||
authGroupV1.POST("/login", handlers.LoginClient)
|
||||
authGroupV1.POST("/logout", handlers.LogoutClient)
|
||||
}
|
||||
@@ -154,6 +153,7 @@ func SetupRoutes(router *gin.Engine, database *db.Database, geoService *services
|
||||
// ⭐⭐ MODIFICATION DE PROFILS PAR ADMIN
|
||||
adminGroupV2.PUT("/clients/:id", handlers.UpdateClientByAdmin) // ✅ Modifier un client
|
||||
adminGroupV2.PUT("/users/:id", handlers.UpdateUserByAdmin) // ✅ Modifier un user
|
||||
adminGroupV2.POST("/clients", handlers.AdminCreateClient)
|
||||
adminGroupV2.DELETE("/clients/:id", handlers.DeleteClient)
|
||||
adminGroupV2.DELETE("/users/:id", handlers.DeleteUser)
|
||||
adminGroupV2.POST("/users", handlers.CreateUser)
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
const { getDefaultConfig } = require('expo/metro-config');
|
||||
|
||||
const IS_PROD = process.env.NODE_ENV === 'production';
|
||||
|
||||
const config = getDefaultConfig(__dirname);
|
||||
|
||||
if (IS_PROD) {
|
||||
config.transformer = {
|
||||
...config.transformer,
|
||||
babelTransformerPath: require.resolve('react-native-obfuscating-transformer'),
|
||||
obfuscatorOptions: {
|
||||
compact: true,
|
||||
identifierNamesGenerator: 'hexadecimal',
|
||||
renameGlobals: false,
|
||||
rotateStringArray: true,
|
||||
stringArray: true,
|
||||
stringArrayEncoding: ['base64'],
|
||||
stringArrayThreshold: 0.75,
|
||||
// Disabled: incompatible with Hermes
|
||||
selfDefending: false,
|
||||
controlFlowFlattening: false,
|
||||
deadCodeInjection: false,
|
||||
transformObjectKeys: false,
|
||||
debugProtection: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = config;
|
||||
+1639
File diff suppressed because it is too large
Load Diff
Generated
+1641
File diff suppressed because it is too large
Load Diff
@@ -40,6 +40,8 @@
|
||||
"devDependencies": {
|
||||
"@expo/ngrok": "^4.1.3",
|
||||
"@types/react": "~19.1.0",
|
||||
"javascript-obfuscator": "^4.1.1",
|
||||
"react-native-obfuscating-transformer": "^1.0.0",
|
||||
"typescript": "~5.9.2"
|
||||
},
|
||||
"private": true
|
||||
|
||||
@@ -427,13 +427,13 @@ export const createClientByAdmin = async (data: {
|
||||
telephone: string;
|
||||
}) => {
|
||||
const { data: res } = await apiClient.post(
|
||||
`https://uber-stup.club/api/v1/auth/register`,
|
||||
`${V2}/admin/protected/clients`,
|
||||
data,
|
||||
);
|
||||
return {
|
||||
success: true,
|
||||
message: res.message || "Client créé",
|
||||
user: res.user,
|
||||
client: res.client,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
const { getDefaultConfig } = require('expo/metro-config');
|
||||
|
||||
const IS_PROD = process.env.NODE_ENV === 'production';
|
||||
|
||||
const config = getDefaultConfig(__dirname);
|
||||
|
||||
if (IS_PROD) {
|
||||
config.transformer = {
|
||||
...config.transformer,
|
||||
babelTransformerPath: require.resolve('react-native-obfuscating-transformer'),
|
||||
obfuscatorOptions: {
|
||||
compact: true,
|
||||
identifierNamesGenerator: 'hexadecimal',
|
||||
renameGlobals: false,
|
||||
rotateStringArray: true,
|
||||
stringArray: true,
|
||||
stringArrayEncoding: ['base64'],
|
||||
stringArrayThreshold: 0.75,
|
||||
// Disabled: incompatible with Hermes
|
||||
selfDefending: false,
|
||||
controlFlowFlattening: false,
|
||||
deadCodeInjection: false,
|
||||
transformObjectKeys: false,
|
||||
debugProtection: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = config;
|
||||
Generated
+1630
File diff suppressed because it is too large
Load Diff
@@ -42,6 +42,8 @@
|
||||
"devDependencies": {
|
||||
"@expo/ngrok": "^4.1.3",
|
||||
"@types/react": "~19.1.0",
|
||||
"javascript-obfuscator": "^4.1.1",
|
||||
"react-native-obfuscating-transformer": "^1.0.0",
|
||||
"typescript": "~5.9.2"
|
||||
},
|
||||
"private": true,
|
||||
|
||||
@@ -545,16 +545,16 @@ export default function CheckoutScreen() {
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
{confirmationData?.assigned_to && (
|
||||
<View style={styles.confirmInfo}>
|
||||
<Ionicons
|
||||
name="bicycle-outline"
|
||||
size={16}
|
||||
color={colors.info}
|
||||
/>
|
||||
<Text style={styles.confirmInfoText}>Livreur</Text>
|
||||
</View>
|
||||
)}
|
||||
<View style={styles.confirmInfo}>
|
||||
<Ionicons
|
||||
name="location-outline"
|
||||
size={16}
|
||||
color={colors.info}
|
||||
/>
|
||||
<Text style={styles.confirmInfoText}>
|
||||
Suivez votre livraison en temps réel depuis la page Suivi
|
||||
</Text>
|
||||
</View>
|
||||
<Button
|
||||
title="Voir mes commandes"
|
||||
onPress={handleConfirmClose}
|
||||
|
||||
Reference in New Issue
Block a user