chore: fix ui bug

This commit is contained in:
2026-03-25 09:41:53 +01:00
parent 79c050d689
commit ac5ec11f54
4 changed files with 66 additions and 24 deletions
+14
View File
@@ -180,6 +180,20 @@ export const updateMyLocation = async (
} }
}; };
export const getDeliveryNavLink = async (
deliveryId: number,
): Promise<{ success: boolean; waze_app?: string; error?: string }> => {
try {
const { data } = await apiClient.get(`${API}/deliveries/${deliveryId}/nav-link`);
return { success: true, waze_app: data.waze_app };
} catch (error: any) {
return {
success: false,
error: error.response?.data?.error || "Erreur réseau",
};
}
};
export const getMyLocation = async (): Promise<{ export const getMyLocation = async (): Promise<{
success: boolean; success: boolean;
latitude?: number; latitude?: number;
@@ -131,6 +131,7 @@ export default function UsersScreen() {
const [poolKeys, setPoolKeys] = useState<string[]>([]); const [poolKeys, setPoolKeys] = useState<string[]>([]);
const [pointsEnabled, setPointsEnabled] = useState(true); const [pointsEnabled, setPointsEnabled] = useState(true);
const [amendeEnabled, setAmendeEnabled] = useState(true); const [amendeEnabled, setAmendeEnabled] = useState(true);
const [referralEnabled, setReferralEnabled] = useState(true);
const [filter, setFilter] = useState<RoleFilter>("all"); const [filter, setFilter] = useState<RoleFilter>("all");
const [search, setSearch] = useState(""); const [search, setSearch] = useState("");
@@ -142,6 +143,8 @@ export default function UsersScreen() {
const [editNom, setEditNom] = useState(""); const [editNom, setEditNom] = useState("");
const [editPrenom, setEditPrenom] = useState(""); const [editPrenom, setEditPrenom] = useState("");
const [editTel, setEditTel] = useState(""); const [editTel, setEditTel] = useState("");
const [editClientUsername, setEditClientUsername] = useState("");
const [editClientPassword, setEditClientPassword] = useState("");
// Edit user modal (livreur/cabine) // Edit user modal (livreur/cabine)
const [editUserModal, setEditUserModal] = useState<{ const [editUserModal, setEditUserModal] = useState<{
@@ -192,6 +195,7 @@ export default function UsersScreen() {
setPoolKeys(pools.map((p) => p.key)); setPoolKeys(pools.map((p) => p.key));
setPointsEnabled(settingsRes.settings.points_enabled ?? true); setPointsEnabled(settingsRes.settings.points_enabled ?? true);
setAmendeEnabled(settingsRes.settings.show_amende_score ?? true); setAmendeEnabled(settingsRes.settings.show_amende_score ?? true);
setReferralEnabled(settingsRes.settings.referral_enabled ?? true);
} }
} catch { } catch {
/* ignore */ /* ignore */
@@ -283,21 +287,32 @@ export default function UsersScreen() {
setEditNom(client.nom); setEditNom(client.nom);
setEditPrenom(client.prenom); setEditPrenom(client.prenom);
setEditTel(client.telephone); setEditTel(client.telephone);
setEditClientUsername(client.username);
setEditClientPassword("");
setEditClientModal({ visible: true, client }); setEditClientModal({ visible: true, client });
}; };
const handleSaveClient = async () => { const handleSaveClient = async () => {
if (!editClientModal.client) return; if (!editClientModal.client) return;
if (editClientPassword.trim() && editClientPassword.trim().length < 8) {
showError("Erreur", "Le mot de passe doit contenir au moins 8 caractères");
return;
}
try { try {
await updateClientByAdmin(editClientModal.client.id, { const updates: Record<string, any> = {
nom: editNom, nom: editNom,
prenom: editPrenom, prenom: editPrenom,
telephone: editTel, telephone: editTel,
}); username: editClientUsername,
};
if (editClientPassword.trim()) {
updates.password = editClientPassword.trim();
}
await updateClientByAdmin(editClientModal.client.id, updates);
setEditClientModal({ visible: false, client: null }); setEditClientModal({ visible: false, client: null });
await loadData(); await loadData();
} catch (e: any) { } catch (e: any) {
showError("Erreur", e.message); showError("Erreur", e.response?.data?.error || e.message);
} }
}; };
@@ -723,16 +738,18 @@ export default function UsersScreen() {
<View style={{ flexDirection: "row", gap: spacing.xs }}> <View style={{ flexDirection: "row", gap: spacing.xs }}>
{isClient && ( {isClient && (
<> <>
<TouchableOpacity {referralEnabled && (
style={styles.editIconBtn} <TouchableOpacity
onPress={() => openReferralModal(item.clientData!)} style={styles.editIconBtn}
> onPress={() => openReferralModal(item.clientData!)}
<Ionicons >
name="gift-outline" <Ionicons
size={20} name="gift-outline"
color={colors.success} size={20}
/> color={colors.success}
</TouchableOpacity> />
</TouchableOpacity>
)}
<TouchableOpacity <TouchableOpacity
style={styles.editIconBtn} style={styles.editIconBtn}
onPress={() => openEditClient(item.clientData!)} onPress={() => openEditClient(item.clientData!)}
@@ -826,7 +843,7 @@ export default function UsersScreen() {
</Text> </Text>
<Text style={styles.statLabel}>Annul.</Text> <Text style={styles.statLabel}>Annul.</Text>
</View> </View>
{(item.clientData.referral_balance ?? 0) > 0 && ( {referralEnabled && (item.clientData.referral_balance ?? 0) > 0 && (
<View style={styles.stat}> <View style={styles.stat}>
<Text <Text
style={[ style={[
@@ -977,6 +994,18 @@ export default function UsersScreen() {
title="Modifier client" title="Modifier client"
icon="person-outline" icon="person-outline"
> >
<TextInput
label="Nom d'utilisateur"
value={editClientUsername}
onChangeText={setEditClientUsername}
autoCapitalize="none"
/>
<TextInput
label="Mot de passe (laisser vide pour ne pas changer)"
value={editClientPassword}
onChangeText={setEditClientPassword}
secureTextEntry
/>
<TextInput <TextInput
label="Nom" label="Nom"
value={editNom} value={editNom}
@@ -38,6 +38,7 @@ import {
getLivreurTelegramStatus, getLivreurTelegramStatus,
generateLivreurLinkToken, generateLivreurLinkToken,
unlinkLivreurTelegram, unlinkLivreurTelegram,
getDeliveryNavLink,
} from "../../api/api_delivery"; } from "../../api/api_delivery";
import { geocodeAddress, calculateRoute } from "../../api/tomtom"; import { geocodeAddress, calculateRoute } from "../../api/tomtom";
import type { RouteInfo } from "../../api/tomtom"; import type { RouteInfo } from "../../api/tomtom";
@@ -520,13 +521,12 @@ export default function DashboardScreen() {
} }
}; };
const openNavigation = (address: string) => { const openNavigation = async (deliveryId: number, address: string) => {
const encoded = encodeURIComponent(address); const res = await getDeliveryNavLink(deliveryId);
const wazeApp = `waze://?q=${encoded}&navigate=yes`; const link = res.success && res.waze_app
const wazeWeb = `https://waze.com/ul?q=${encoded}&navigate=yes`; ? res.waze_app
Linking.openURL(wazeApp).catch(() => { : `waze://?q=${encodeURIComponent(address)}&navigate=yes`;
Linking.openURL(wazeWeb); Linking.openURL(link);
});
}; };
// -------------------------------------------------- // --------------------------------------------------
@@ -577,7 +577,7 @@ export default function DashboardScreen() {
<TouchableOpacity <TouchableOpacity
style={styles.addressRow} style={styles.addressRow}
onPress={() => openNavigation(item.adresse)} onPress={() => openNavigation(item.id, item.adresse)}
activeOpacity={0.7} activeOpacity={0.7}
> >
<Ionicons <Ionicons
+1 -2
View File
@@ -34,8 +34,7 @@ export interface UserResponse {
role?: string; role?: string;
session_id?: string; session_id?: string;
command?: number; command?: number;
point?: number; point_extra?: number;
point_zipette?: number; // ✅ AJOUTER CETTE LIGNE
amende?: number; amende?: number;
must_change_password?: boolean; must_change_password?: boolean;
} }