chore: fix

This commit is contained in:
2026-05-01 20:58:51 +02:00
parent 46b287c960
commit b34c239415
12 changed files with 87 additions and 24 deletions
-1
View File
@@ -130,7 +130,6 @@ func (d *Database) GetAllClients() ([]*models.Client, error) {
func (d *Database) UpdateClient(client *models.Client) error {
result := d.GDB.Model(&models.Client{}).Where("id = ?", client.ID).Updates(map[string]any{
"username": client.Username,
"password": client.Password,
"nom": client.Nom,
"prenom": client.Prenom,
"telephone": client.Telephone,
+4 -3
View File
@@ -1047,7 +1047,8 @@ func DeleteCommandItem(c *gin.Context) {
func UpdateCommandStatusAdmin(c *gin.Context) {
database := c.MustGet("database").(*db.Database)
if c.GetString("role") != "admin" {
role := c.GetString("role")
if role != "admin" && role != "cabine" {
c.JSON(http.StatusForbidden, gin.H{"error": "Accès refusé"})
return
}
@@ -1068,7 +1069,7 @@ func UpdateCommandStatusAdmin(c *gin.Context) {
allowed := map[string]bool{
"pending": true, "assigned": true, "en_route": true,
"livre": true, "approved": true, "cancelled": true,
"arrived": true, "livre": true, "approved": true, "cancelled": true,
}
if !allowed[req.Status] {
c.JSON(http.StatusBadRequest, gin.H{"error": "Statut invalide: " + req.Status})
@@ -1080,7 +1081,7 @@ func UpdateCommandStatusAdmin(c *gin.Context) {
return
}
log.Printf("✅ [STATUS_ADMIN] Cmd %d → %s", commandID, req.Status)
log.Printf("✅ [STATUS_ADMIN] Cmd %d → %s (par %s)", commandID, req.Status, role)
c.JSON(http.StatusOK, gin.H{
"success": true,
"message": "Statut mis à jour",
+15 -5
View File
@@ -345,18 +345,28 @@ func UpdateDeliveryStatus(c *gin.Context) {
var clientMsg string
switch req.Status {
case "en_route":
if etaMinutes > 0 {
notifETA := etaMinutes
if notifETA == 0 {
if etaData, err := database.GetCommandETA(commandID); err == nil {
if v, ok := etaData["total_eta_minutes"]; ok {
if n, err2 := strconv.Atoi(v); err2 == nil && n > 0 {
notifETA = n
}
}
}
}
if notifETA > 0 {
var etaStr string
if etaMinutes >= 60 {
h := etaMinutes / 60
m := etaMinutes % 60
if notifETA >= 60 {
h := notifETA / 60
m := notifETA % 60
if m > 0 {
etaStr = fmt.Sprintf("%dh%02d", h, m)
} else {
etaStr = fmt.Sprintf("%dh", h)
}
} else {
etaStr = fmt.Sprintf("%d min", etaMinutes)
etaStr = fmt.Sprintf("%d min", notifETA)
}
clientMsg = fmt.Sprintf("Un livreur vient de prendre en charge ta commande #%d, il est en route (~%s)", database.GetClientOrderID(commandID), etaStr)
} else {
+15 -4
View File
@@ -236,7 +236,8 @@ func UpdateClientByAdmin(c *gin.Context) {
log.Printf("✏️ [UPDATE_CLIENT_ADMIN] Username modifié: %s", req.Username)
}
// Mise à jour du mot de passe
// Mise à jour du mot de passe (opération séparée pour garantir l'écriture)
var newHashedPassword string
if req.Password != "" {
if len(req.Password) < 8 {
c.JSON(http.StatusBadRequest, gin.H{"error": "Le mot de passe doit contenir au moins 8 caractères"})
@@ -248,7 +249,7 @@ func UpdateClientByAdmin(c *gin.Context) {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur traitement mot de passe"})
return
}
client.Password = string(hashed)
newHashedPassword = string(hashed)
hasChanges = true
log.Printf("✏️ [UPDATE_CLIENT_ADMIN] Mot de passe modifié")
}
@@ -323,13 +324,23 @@ func UpdateClientByAdmin(c *gin.Context) {
log.Printf("📊 [UPDATE_CLIENT_ADMIN] État avant save - Command: %d, Amende: %.2f",
client.Command, client.Amende)
// Sauvegarder les modifications
// Sauvegarder les modifications de profil (hors mot de passe)
if err := database.UpdateClient(client); err != nil {
log.Printf("❌ [UPDATE_CLIENT_ADMIN] Erreur mise à jour: %v", err)
log.Printf("❌ [UPDATE_CLIENT_ADMIN] Erreur mise à jour profil: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur lors de la mise à jour"})
return
}
// Mettre à jour le mot de passe séparément si demandé
if newHashedPassword != "" {
if err := database.UpdateClientPasswordAndClearFlag(clientID, newHashedPassword); err != nil {
log.Printf("❌ [UPDATE_CLIENT_ADMIN] Erreur mise à jour mot de passe: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur lors de la mise à jour du mot de passe"})
return
}
log.Printf("✅ [UPDATE_CLIENT_ADMIN] Mot de passe mis à jour pour client ID=%d", clientID)
}
log.Printf("✅ [UPDATE_CLIENT_ADMIN] Client mis à jour par admin: %s (ID=%d)", client.Username, client.ID)
c.JSON(http.StatusOK, gin.H{
@@ -352,7 +352,14 @@ func StartDelivery(c *gin.Context) {
if clientUsername, _ := command["username"].(string); clientUsername != "" {
var msg string
etaMinutes := 0
if req.Latitude != 0 && req.Longitude != 0 {
if etaData, err := database.GetCommandETA(commandID); err == nil {
if v, ok := etaData["total_eta_minutes"]; ok {
if n, err2 := strconv.Atoi(v); err2 == nil && n > 0 {
etaMinutes = n
}
}
}
if etaMinutes == 0 && req.Latitude != 0 && req.Longitude != 0 {
destLat, _ := command["dest_latitude"].(float64)
destLon, _ := command["dest_longitude"].(float64)
if destLat != 0 && destLon != 0 {
+1
View File
@@ -302,6 +302,7 @@ func SetupRoutes(router *gin.Engine, database *db.Database, geoService *services
cabineGroupV1.POST("/commands/:id/confirm-reception", handlers.StaffApproveDelivery)
cabineGroupV1.POST("/commands/:id/assign", handlers.AssignDeliveryPerson)
cabineGroupV1.POST("/commands/:id/notify-client", handlers.NotifyClientToDescend)
cabineGroupV1.PUT("/commands/:id/status", handlers.UpdateCommandStatusAdmin)
cabineGroupV1.PUT("/items/:item_id/status", handlers.UpdateItemStatus)
cabineGroupV1.GET("/commands/:id/deliveryman/location", handlers.GetDeliverymanLocationForCommand)
cabineGroupV1.GET("/all/deliveryman", handlers.GetAllDeliveryMen)
+4
View File
@@ -0,0 +1,4 @@
// Surchargé par le ConfigMap Helm en production
window.__APP_CONFIG__ = {
apiUrl: "",
};
-4
View File
@@ -7,10 +7,6 @@ html, body, #root {
overflow-x: hidden;
}
/* Ne pas forcer de backgroundColor global pour permettre à login d'avoir son propre style */
body, html {
background-color: transparent !important;
}
#root {
width: 100%;
+7 -2
View File
@@ -2010,7 +2010,10 @@ export const updateMyProfile = async (fields: {
// 🤖 TELEGRAM
// ============================================
export const getTelegramStatus = async (): Promise<{ linked: boolean; enabled: boolean }> => {
export const getTelegramStatus = async (): Promise<{
linked: boolean;
enabled: boolean;
}> => {
const token = getAuthToken();
if (!token) return { linked: false, enabled: false };
try {
@@ -2048,5 +2051,7 @@ export const unlinkTelegram = async (): Promise<void> => {
method: "DELETE",
headers: { Authorization: `Bearer ${token}` },
});
} catch { /* silencieux */ }
} catch {
/* silencieux */
}
};
+27 -1
View File
@@ -16,12 +16,38 @@
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
/* Empêcher le zoom sur les inputs pour iOS */
font-size: 16px;
--bg: #09090b;
--surface: #111115;
--surface-2: #1c1c22;
--border: rgba(255, 255, 255, 0.07);
--primary: #8b5cf6;
--primary-soft: rgba(139, 92, 246, 0.12);
--primary-glow: rgba(139, 92, 246, 0.25);
--cyan: #22d3ee;
--cyan-soft: rgba(34, 211, 238, 0.1);
--red: #ef4444;
--text: #f4f4f5;
--text-muted: #71717a;
--radius: 10px;
--transition: 0.22s cubic-bezier(0.4, 0, 0.2, 1);
}
[data-theme="light"] {
color-scheme: light;
--bg: #f4f4f8;
--surface: #ffffff;
--surface-2: #ebebf2;
--border: rgba(0, 0, 0, 0.08);
--primary: #7c3aed;
--primary-soft: rgba(124, 58, 237, 0.08);
--primary-glow: rgba(124, 58, 237, 0.18);
--cyan: #0891b2;
--cyan-soft: rgba(8, 145, 178, 0.1);
--red: #dc2626;
--text: #18181b;
--text-muted: #52525b;
}
html, body {
+2 -1
View File
@@ -122,10 +122,11 @@ function Checkout() {
if (savedAddress) setAddress(savedAddress);
if (savedPhone) setPhone(savedPhone);
// Pré-remplir nom depuis le backend
// Pré-remplir nom/prénom depuis le backend
getMyProfile().then((res) => {
if (res.success && res.client) {
if (res.client.nom) setLastName(res.client.nom);
if (res.client.prenom) setFirstName(res.client.prenom);
}
});
}, []);
+4 -2
View File
@@ -1,6 +1,8 @@
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
const DEV_API_TARGET = "http://localhost:8080";
export default defineConfig({
plugins: [react()],
build: {
@@ -9,11 +11,11 @@ export default defineConfig({
server: {
proxy: {
"/api": {
target: "https://5.181.0.112.nip.io",
target: DEV_API_TARGET,
changeOrigin: true,
},
"/uploads": {
target: "https://5.181.0.112.nip.io",
target: DEV_API_TARGET,
changeOrigin: true,
},
},