From 27d13ace9d05712a1c12a717852f7faca72ff371 Mon Sep 17 00:00:00 2001 From: Rochas Date: Sun, 14 Dec 2025 03:04:12 +0100 Subject: [PATCH] test reservation todo corriger getChantier avec la nouvelelle structure --- app/(tabs)/addScreen.tsx | 4 + app/(tabs)/gestion_ouvrier.tsx | 16 +-- app/(tabs)/gestionnaire_ressource.tsx | 7 +- class/class.tsx | 11 +- components/add/addChantier.tsx | 105 ++++++++++++++++--- components/add/select/selectChefChantier.tsx | 1 + components/chantierSummary.tsx | 6 +- components/selectChantier.tsx | 2 +- data/concerts.json | 45 -------- services/ressourcesService.ts | 93 ++++++++++++++-- 10 files changed, 190 insertions(+), 100 deletions(-) delete mode 100644 data/concerts.json diff --git a/app/(tabs)/addScreen.tsx b/app/(tabs)/addScreen.tsx index a2ecf04..0cbe68a 100644 --- a/app/(tabs)/addScreen.tsx +++ b/app/(tabs)/addScreen.tsx @@ -9,7 +9,11 @@ import { ThemedView } from "@/components/theme/themed-view"; export default function AddScreen() { const [typeAdd, setTypeAdd] = useState(''); + const [editMode, setEditMode] = useState(false); + function onPressSwitchMode(){ + setEditMode(!editMode); + } return( diff --git a/app/(tabs)/gestion_ouvrier.tsx b/app/(tabs)/gestion_ouvrier.tsx index 0e8f8a0..e69e0f7 100644 --- a/app/(tabs)/gestion_ouvrier.tsx +++ b/app/(tabs)/gestion_ouvrier.tsx @@ -5,7 +5,6 @@ import Constants from "expo-constants"; //pour connaître la taille de la barre import { useLocalSearchParams, useRouter } from "expo-router"; import React, { useEffect, useMemo, useState } from "react"; import { FlatList, Image, StyleSheet, Text, View } from "react-native"; -import rawConcerts from "../../data/concerts.json"; import { getUsers } from "@/services/ressourcesService"; import { useChantier } from "../ContextChantier"; import SelectChantier from "@/components/selectChantier"; @@ -34,7 +33,7 @@ export default function GestionOuvrier() { async function loadData() { try { //Nous ne gardons que les Ouvriers, qui peuvent être assignés à un chantier - const data = (await getRessources()).filter(u => u.type === "ouvrier"); + const data = (await getRessources()).filter(u => u.type === "Ouvrier"); setRessources(data); } catch (error) { console.error("Erreur lors du chargement :", error); @@ -43,19 +42,6 @@ export default function GestionOuvrier() { loadData(); }, []); - const concertsData: Concert[] = Array.isArray(rawConcerts) - ? (rawConcerts as Concert[]) - : []; - - const filteredData = useMemo(() => { - if (!Array.isArray(concertsData)) return []; - const q = search.trim().toLowerCase(); - if (!q) return concertsData; - return concertsData.filter( - (item) => !!item && (item.group ?? "").toLowerCase().includes(q) - ); - }, [concertsData, search]); - const renderItem = ({ item, index }: { item?: Ressources; index: number }) => { if (!item) { return null; diff --git a/app/(tabs)/gestionnaire_ressource.tsx b/app/(tabs)/gestionnaire_ressource.tsx index 6f19aef..f0df52c 100644 --- a/app/(tabs)/gestionnaire_ressource.tsx +++ b/app/(tabs)/gestionnaire_ressource.tsx @@ -15,7 +15,7 @@ import { useRessources } from "../ContextRessource"; export default function GestionnaireRessource() { const [search, setSearch] = useState(""); const {ressources, setRessources} = useRessources(); - const [filterType, setFilterType] = useState("tout"); + const [filterType, setFilterType] = useState("Tout"); const [showFilterMenu, setShowFilterMenu] = useState(false); const router = useRouter(); @@ -33,7 +33,7 @@ export default function GestionnaireRessource() { const filteredData = ressources.filter((r) => { const matchName = r.name.toLowerCase().includes(search.toLowerCase()); - const matchType = filterType === "tout" || r.type === filterType; + const matchType = filterType === "Tout" || r.type === filterType; return matchName && matchType; }); @@ -43,6 +43,7 @@ export default function GestionnaireRessource() { + Id : {item.id} Nom : {item.name} Type : {item.type} Quantité totale : {item.quantity} @@ -68,7 +69,7 @@ export default function GestionnaireRessource() { Filtrer par type - {["tout", "Outil", "Machine"].map((t) => ( + {["Tout", "Outil", "Machine","Ouvrier"].map((t) => ( (); const [ouvriers, setOuviers] = useState(); + const [outils, setOutils] = useState(); const [showDateSelect,setSowDateSelect] = useState(false); const [openConfirmation,setOpenConfirmation] = useState(false); @@ -52,7 +52,6 @@ export default function AddChantier() { const [ressourcesSelect, setRessourcesSelect] = useState([]); async function handleAddChantier() { - setLoading(true); setOpenConfirmation(true); } @@ -64,15 +63,89 @@ export default function AddChantier() { } }; async function onConfirm(): Promise { - if (!isValidChantier() || !chefChantier) return; - try { - setLoading(true); + if (!isValidChantier() || !chefChantier){ + alert("Choisir un chef de Chantier"); + return; + } + setOpenConfirmation(false); + var latitude=0; + var longitude=0; + try { //verification de l'adresse + const coords = await geocodeAddress(adresse); + if (coords) { + latitude=coords.latitude; + longitude=coords.longitude; + } + else{ + console.error("Impossible de géocoder l'adresse"); + alert("Adresse introuvable. Veuillez vérifier l'adresse."); + } + } catch (error) { + console.error("Erreur lors de la création du chantier:", error); + alert("Erreur lors de la création du chantier"); + } + + + + var chantier: Chantier = { + id:"0", + name: objet, + adresse: adresse, + etat: 'En cours', + contact: contact, + chef: chefChantier, + dateDep: date, + tempsEst: Number(duree), + anomalies: [], + latitude: latitude, + longitude: longitude, + equipe: [], + materiel: [], + vehicules: [] + } + + if(machines){ + machines.forEach(item => { + chantier.vehicules.push({ + id:"0", + chantier: chantier, + ressource: item[0], + quantity: item[1], + }) + }); + } + if(ouvriers){ + ouvriers.forEach(item => { + chantier.equipe.push({ + id:"0", + chantier: chantier, + ressource: item[0], + quantity: item[1], + }) + }); + } + if(outils){ + outils.forEach(item => { + chantier.materiel.push({ + id:"0", + chantier: chantier, + ressource: item[0], + quantity: item[1], + }) + }); + } + + sendNewChantier(chantier); + + + + + /*try { const coords = await geocodeAddress(adresse); if (!coords) { console.error("Impossible de géocoder l'adresse"); alert("Adresse introuvable. Veuillez vérifier l'adresse."); - setLoading(false); return; } const chantierDate = new Date(date); @@ -85,17 +158,17 @@ export default function AddChantier() { contact, chef: doc(db, "user", chefChantier.id), equipe: [], - /*materiel: materiels - ? [doc(db, "ressources", String(materiels.id))] - : [],*/ + //materiel: materiels + // ? [doc(db, "ressources", String(materiels.id))] + // : [], vehicules: machines?.map(e => doc(db, "ressources", String(e[0].id)) ) || [], anomalies: [], dateDep: chantierDate, tempsEst: parseInt(duree) || 1, - latitude: coords.latitude, //TODO - longitude: coords.longitude, //TODO + latitude: coords.latitude, + longitude: coords.longitude, }; const id = await addChantier(chantierFirestore as any); if (id) { @@ -113,9 +186,7 @@ export default function AddChantier() { } catch (error) { console.error("Erreur lors de la création du chantier:", error); alert("Erreur lors de la création du chantier"); - } finally { - setLoading(false); - } + }*/ } function onCancel(): void { @@ -231,7 +302,7 @@ export default function AddChantier() { Outils: - + diff --git a/components/add/select/selectChefChantier.tsx b/components/add/select/selectChefChantier.tsx index 7b03594..f4d10e2 100644 --- a/components/add/select/selectChefChantier.tsx +++ b/components/add/select/selectChefChantier.tsx @@ -53,6 +53,7 @@ export default function SelectChafChantier({style,sendChefChantier , ...otherPro return( {onPressUser(item)}}> + {item.id} {item.name} {item.last_name} {item.role} diff --git a/components/chantierSummary.tsx b/components/chantierSummary.tsx index 3d649cd..b44e544 100644 --- a/components/chantierSummary.tsx +++ b/components/chantierSummary.tsx @@ -20,9 +20,9 @@ export default function ChantierSummary({data,style , ...otherProps }: Props) { - Adresse: {data.chantier.adresse} - Chef de chantier: {data.chantier.chef.last_name}{" "}{data.chantier.chef.name} - État: {data.chantier.etat} + Adresse: {data.chantier.adresse} + Chef de chantier: {data.chantier.chef.last_name}{" "}{data.chantier.chef.name} + État: {data.chantier.etat} ) : diff --git a/components/selectChantier.tsx b/components/selectChantier.tsx index 5447035..a7d32a5 100644 --- a/components/selectChantier.tsx +++ b/components/selectChantier.tsx @@ -78,7 +78,7 @@ export default function SelectChantier() { var keyWords:string[] = search.toLowerCase().split(" ") ; var containsAllKeyWord:boolean = true; keyWords.forEach(keyWord => { - containsAllKeyWord = containsAllKeyWord && (chantier.adresse.toLowerCase().includes(keyWord)) + containsAllKeyWord = containsAllKeyWord && (chantier.adresse.toLowerCase().includes(keyWord) || chantier.name.toLowerCase().includes(keyWord)) }); return containsAllKeyWord }); diff --git a/data/concerts.json b/data/concerts.json deleted file mode 100644 index a2fa93c..0000000 --- a/data/concerts.json +++ /dev/null @@ -1,45 +0,0 @@ -[ - { - "group": "Bernard DupYEEd", - "date":"Rennes", - "nationality": "French", - "location": "PlombYEEr", - "price": 20, - "ticketsLeft": 36, - "Image": "https://media.discordapp.net/attachments/1415267028201246812/1424825038657425518/a06e3304-86ca-4b4f-8016-c4ae9844b0df.png?ex=68e9f879&is=68e8a6f9&hm=b6ff1f540d5c382930b56bd6f90565f517ee179347d6ee6aebd5254b10cf4c88&=&format=webp&quality=lossless&width=579&height=579", - "favorite": false - }, - { - "group": "MYEEchel Câble", - "date":"Nantes", - "nationality": "French", - "location": "ElectrYEEcien", - "price": 22, - "ticketsLeft": 400, - "Image": "https://media.discordapp.net/attachments/1415267028201246812/1424826240090509332/7fdbfe06-8300-441e-81ac-87851d004dc3.png?ex=68e9f997&is=68e8a817&hm=cc71621c3e7c3c1aaeda5555e9dd4204d43414cd0332c2b116b10d009b68df3c&=&format=webp&quality=lossless&width=579&height=579", - "favorite": false - - }, - { - "group": "PYEErre soulever", - "date":"Redon", - "nationality": "French", - "location": "GrutYEEr", - "price": 32, - "ticketsLeft": 0, - "Image": "https://media.discordapp.net/attachments/1425108443571945644/1427207643180826757/raw.png?ex=68ee0632&is=68ecb4b2&hm=1efc51065c6abfb1af75b8382f9924c2eb177c7d7672f7ed9837e96ef3076d16&=&format=webp&quality=lossless&width=233&height=350", - "favorite": false - - }, - { - "group": "Greg NegatYEEf", - "date":"Pacé", - "nationality": "French", - "location": "ElectrYEEcien", - "price": 20, - "ticketsLeft": 36, - "Image": "https://media.discordapp.net/attachments/1415267028201246812/1424826240090509332/7fdbfe06-8300-441e-81ac-87851d004dc3.png?ex=68e9f997&is=68e8a817&hm=cc71621c3e7c3c1aaeda5555e9dd4204d43414cd0332c2b116b10d009b68df3c&=&format=webp&quality=lossless&width=579&height=579", - "favorite": true - - } -] \ No newline at end of file diff --git a/services/ressourcesService.ts b/services/ressourcesService.ts index daae994..eb9b13a 100644 --- a/services/ressourcesService.ts +++ b/services/ressourcesService.ts @@ -1,4 +1,4 @@ -import { addDoc, arrayUnion, collection, doc, getDoc, getDocs, Timestamp, updateDoc } from "firebase/firestore"; +import { addDoc, arrayUnion, collection, doc, Firestore, getDoc, getDocs, Timestamp, updateDoc, DocumentReference } from "firebase/firestore"; import { Chantier, Reservation, Ressources, User } from "../class/class"; import { db } from "../firebase_config"; @@ -28,6 +28,7 @@ export async function getRessources(): Promise { return snapshot.docs.map((doc) => { const data = doc.data(); return { + id: doc.id, ...data, allocation: data.allocation?.map(convertReservation) || [], } as Ressources; @@ -66,22 +67,46 @@ export async function getChantiers(): Promise { chef = chefSnap.data() as User; } } - let equipe: User[] = []; + + let equipe: Reservation[] = []; if (Array.isArray(data.equipe)) { equipe = await Promise.all( data.equipe.map(async (ref: any) => { const snap = await getDoc(ref); - return snap.exists() ? (snap.data() as User) : null; + return snap.exists() ? (snap.data() as Reservation) : null; }) - ).then(list => list.filter(x => x !== null)) as User[]; + ).then(list => list.filter(x => x !== null)) as Reservation[]; } + let vehicules: Reservation[] = []; + if (Array.isArray(data.vehicules)) { + vehicules = await Promise.all( + data.vehicules.map(async (ref: any) => { + const snap = await getDoc(ref); + return snap.exists() ? (snap.data() as Reservation) : null; + }) + ).then(list => list.filter(x => x !== null)) as Reservation[]; + } + + let materiel: Reservation[] = []; + if (Array.isArray(data.materiel)) { + materiel = await Promise.all( + data.materiel.map(async (ref: any) => { + const snap = await getDoc(ref); + return snap.exists() ? (snap.data() as Reservation) : null; + }) + ).then(list => list.filter(x => x !== null)) as Reservation[]; + } + + chantiers.push({ ...data, id: docSnap.id, dateDep, chef, - equipe + equipe, + vehicules, + materiel, } as Chantier); } return chantiers; @@ -144,12 +169,58 @@ export async function deleteAnomalie(chantierId: string, anomalie_String: string } } -function convertReservation(res: any): Reservation { +type ReservationFirestore = { + chantier: DocumentReference; + ressource: DocumentReference; + quantity: number; +}; + +async function convertReservation(res: any): Promise { + + const data = res.data() as ReservationFirestore; + const chantierSnap = await getDoc(data.chantier as DocumentReference); + const ressourceSnap = await getDoc(data.ressource as DocumentReference); + return { id: res.id, - dateChantier: - res.dateChantier instanceof Timestamp ? res.dateChantier.toDate() : new Date(res.dateChantier), - dateFin: - res.dateFin instanceof Timestamp ? res.dateFin.toDate() : new Date(res.dateFin), + chantier: chantierSnap.data() as Chantier, + ressource: ressourceSnap.data() as Ressources, + quantity: data.quantity, }; -} \ No newline at end of file +} + + + +//ENVOYER CHANTIER +export async function sendNewChantier(chantier:Chantier): Promise { + + const chantierRef = await addDoc(collection(db, "chantier"), { + name:chantier.name, + adresse:chantier.adresse, + etat:chantier.etat, + contact:chantier.contact, + chef: doc(db, "users", chantier.chef.id), //un objet déjà dans la base de donné + date: Timestamp.fromDate(chantier.dateDep), + tempsEst: chantier.tempsEst, + anomalies: chantier.anomalies ?? [], //strings[] + latitude: chantier.latitude, + longitude: chantier.longitude, + }) + await Promise.all([ + sendNewReservation(chantier.equipe, chantierRef.id), + sendNewReservation(chantier.materiel, chantierRef.id), + sendNewReservation(chantier.vehicules, chantierRef.id), + ]); +} + +export async function sendNewReservation(list: Reservation[],chantierId:string): Promise { + const promises = list.map((reservation) => + addDoc(collection(db,"Reservation"),{ + chantier: doc(db, "chantier", chantierId), + ressource: doc(db, "ressources", reservation.ressource.id), + quantity: reservation.quantity, + }) + ); + + await Promise.all(promises); +}