diff --git a/README.md b/README.md
index b45824f..01cee85 100644
--- a/README.md
+++ b/README.md
@@ -13,9 +13,7 @@ Lien du git : gitlab2.istic.univ-rennes1.fr/trochas/mmm-projet
Différentes commandes a effectuer pour lancer le projet:
-npm install firebase
-npm install react-native-maps
npx expo install react-native-maps@1.9.0
-npm install react-native-maps @react-navigation/native @react-navigation/bottom-tabs react-native-safe-area-context react-native-screens
+npm install react-native-maps @react-navigation/native @react-navigation/bottom-tabs react-native-safe-area-context react-native-screens firebase
npx expo start
\ No newline at end of file
diff --git a/components/chantierSummary.tsx b/components/chantierSummary.tsx
index e5f973c..1aad1a4 100644
--- a/components/chantierSummary.tsx
+++ b/components/chantierSummary.tsx
@@ -4,7 +4,6 @@ import React from 'react';
import { Image, StyleProp, StyleSheet, View, ViewStyle } from 'react-native';
import { ThemedText } from './theme/themed-text';
-
type Props = {
data: {
chantier:Chantier|null;
@@ -13,8 +12,6 @@ type Props = {
};
export default function ChantierSummary({data,style , ...otherProps }: Props) {
-
-
return(
{data.chantier ? (
diff --git a/components/selectChantier.tsx b/components/selectChantier.tsx
index 0a8879c..db6c7a9 100644
--- a/components/selectChantier.tsx
+++ b/components/selectChantier.tsx
@@ -1,10 +1,8 @@
import { useChantier } from "@/app/ContextChantier";
import { Chantier } from "@/class/class";
import { getChantiers } from "@/services/ressourcesService";
-import { useRouter } from "expo-router";
import { useEffect, useState } from "react";
import {
- ActivityIndicator,
Dimensions,
Image,
Pressable,
@@ -19,6 +17,7 @@ import { ThemedButton } from "./theme/themed-button";
import { ThemedText } from "./theme/themed-text";
import { ThemedTextInput } from "./theme/themed-textinput";
import { ThemedView } from "./theme/themed-view";
+import { router } from "expo-router";
const screenHeight = Dimensions.get("window").height;
const { width, height } = Dimensions.get("window");
@@ -31,28 +30,34 @@ const { width, height } = Dimensions.get("window");
*/
-export default function SelectChantier() {
+export default function SelectChantier(props: {
+ data?: any[];
+ multiple?: boolean;
+ selected?: string[] | string | null;
+ onChange?: (val: any) => void;
+ placeholder?: string;
+}) {
+ const { data: propData, multiple = false, selected, onChange, placeholder } = props || {};
const { chantier, setChantier } = useChantier();
const [search, setSearch] = useState("");
const [isOpen, setIsOpen] = useState(false);
- const [isLoaded, setIsLoaded] = useState(false);
- const [chantiers, setChantiers] = useState([]);
- const router = useRouter();
+ const [chantiers, setChantiers] = useState([]);
-
- // cast to any to avoid strict Animated typing issues for custom props like `lvl`/`border`
- const AnimatedThemedView: any = Animated.createAnimatedComponent(ThemedView as any);
- const AnimatedThemedText: any = Animated.createAnimatedComponent(ThemedText as any);
- const AnimatedThemedButton: any = Animated.createAnimatedComponent(ThemedButton as any);
- const AnimatedThemedTextInput: any = Animated.createAnimatedComponent(ThemedTextInput as any);
+ const AnimatedThemedView = Animated.createAnimatedComponent(ThemedView);
+ const AnimatedThemedText = Animated.createAnimatedComponent(ThemedText);
+ const AnimatedThemedButton = Animated.createAnimatedComponent(ThemedButton);
+ const AnimatedThemedTextInput =
+ Animated.createAnimatedComponent(ThemedTextInput);
async function onPressOpen(){
- setIsLoaded(false);
setIsOpen(!isOpen);
if(!isOpen){
- const updatedChantiers = await getChantiers();
- setIsLoaded(true);
- setChantiers(updatedChantiers)
+ if (propData && propData.length) {
+ setChantiers(propData as any[]);
+ } else {
+ const updatedChantiers = await getChantiers();
+ setChantiers(updatedChantiers);
+ }
}
}
@@ -62,6 +67,12 @@ export default function SelectChantier() {
}
useEffect(() => {
+ // If parent provided data, use it. Otherwise fetch chantiers.
+ if (propData && propData.length) {
+ setChantiers(propData as any[]);
+ return;
+ }
+
async function loadChantiers() {
const list = await getChantiers();
setChantiers(list);
@@ -70,22 +81,56 @@ export default function SelectChantier() {
loadChantiers();
}, []);
- function selectChantier(chantier: Chantier): void {
- setChantier(chantier);
+ function getId(item: any) {
+ return (item && (item.id ?? item._id ?? item.uid ?? item.key)) ?? String(item);
+ }
+
+ function getLabel(item: any) {
+ if (!item) return String(item);
+ if (item.adresse) return item.adresse;
+ if (item.nom) return item.nom;
+ if (item.name && item.last_name) return `${item.last_name} ${item.name}`;
+ if (item.name) return item.name;
+ if (item.label) return item.label;
+ if (typeof item === 'string') return item;
+ return JSON.stringify(item);
+ }
+
+ function selectChantier(item: any): void {
+ const id = String(getId(item));
+ if (multiple) {
+ // for multiple selection toggle id in selected array
+ const current = Array.isArray(selected) ? [...selected] : [];
+ const idx = current.indexOf(id);
+ if (idx >= 0) current.splice(idx, 1);
+ else current.push(id);
+ onChange?.(current);
+ // keep menu open for multiple selection
+ return;
+ }
+
+ // single selection
+ if (onChange) {
+ onChange(id);
+ } else {
+ // fallback behavior for old usage: if selecting a Chantier, update context
+ setChantier(item as Chantier);
+ }
setIsOpen(false);
}
- const renderChantier = (chantier: Chantier, index: number) => {
+ const renderChantier = (item: any, index: number) => {
+ const label = getLabel(item);
+ const id = String(getId(item));
+ const isSelected = Array.isArray(selected) ? selected.includes(id) : selected === id;
return (
- selectChantier(chantier)}>
-
+ selectChantier(item)}>
+
-
+
- Adresse: {chantier.adresse}
- Chef de chantier: {chantier.chef.last_name}{" "}{chantier.chef.name}
- État: {chantier.etat}
+ {label}
@@ -98,7 +143,19 @@ export default function SelectChantier() {
onPressOpen()}>
- {isOpen ? "Fermer" : (chantier!=null ? chantier.adresse : "Chantier")}
+ {isOpen
+ ? "Fermer"
+ : (multiple
+ ? (Array.isArray(selected) && selected.length ? `${selected.length} sélectionnés` : (placeholder ?? "Sélectionner"))
+ : (selected ? (() => {
+ // show label of selected single item if provided in propData
+ if (selected && propData) {
+ const found = propData.find((it: any) => String(getId(it)) === String(selected));
+ return found ? getLabel(found) : (chantier ? (chantier.adresse ?? getLabel(chantier)) : (placeholder ?? "Chantier"));
+ }
+ return chantier ? (chantier.adresse ?? getLabel(chantier)) : (placeholder ?? "Chantier");
+ })() : (placeholder ?? "Chantier"))
+ )}
{isOpen && (
@@ -111,16 +168,14 @@ export default function SelectChantier() {
+
-
- {isLoaded?
+
+
{chantiers.map((chantier, index) =>
renderChantier(chantier, index)
)}
- : }
-
-
+
)}
@@ -223,8 +278,5 @@ const styles = StyleSheet.create({
buttonAdd:{
borderRadius: 10,
marginBottom: 10,
- height: 30,
- alignItems: 'center',
- justifyContent: 'center',
}
});
diff --git a/services/ressourcesService.ts b/services/ressourcesService.ts
index 36ae527..2a32e8d 100644
--- a/services/ressourcesService.ts
+++ b/services/ressourcesService.ts
@@ -2,6 +2,7 @@ import { addDoc, collection, doc, getDoc, getDocs, Timestamp, updateDoc } from "
import { Chantier, Reservation, Ressources, User } from "../class/class";
import { db } from "../firebase_config";
+///////////////////////////////////USER/////////////////////////////////////
export async function getUsers(): Promise {
try {
const colRef = collection(db, "user");
@@ -18,7 +19,7 @@ export async function getUsers(): Promise {
return [];
}
}
-
+///////////////////////////////////RESSOURCE////////////////////////////////
export async function getRessources(): Promise {
try {
const colRef = collection(db, "ressources");
@@ -35,7 +36,7 @@ export async function getRessources(): Promise {
return [];
}
}
-
+///////////////////////////////////CHANTIER/////////////////////////////////
export async function getChantiers(): Promise {
const snap = await getDocs(collection(db, "chantier"));
const chantiers: Chantier[] = [];
@@ -72,16 +73,7 @@ export async function getChantiers(): Promise {
return chantiers;
}
-function convertReservation(res: any): Reservation {
- 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),
- };
-}
-
+//CHANGE CHANTIER STATUS
export async function changeChantierStatus(chantierId: string, newStatus: string): Promise {
try {
const chantierRef = doc(db, "chantier", chantierId);
@@ -92,6 +84,7 @@ export async function changeChantierStatus(chantierId: string, newStatus: string
}
}
+//ADD CHANTIER
export async function addChantier(chantierData: Omit): Promise {
try {
const colRef = collection(db, "chantier");
@@ -102,4 +95,57 @@ export async function addChantier(chantierData: Omit): Promise {
+ try {
+ const chantierRef = doc(db, "chantier", chantierId);
+ const chantierSnap = await getDoc(chantierRef);
+ if (chantierSnap.exists()) {
+ const chantierData = chantierSnap.data();
+ const anomalies = chantierData.anomalies || [];
+ const updatedAnomalies = anomalies.map((anomalie: any) => {
+ if (anomalie.description === anomalie_String) {
+ return { ...anomalie, status: newStatus };
+ }
+ return anomalie;
+ });
+ await updateDoc(chantierRef, { anomalies: updatedAnomalies });
+ console.log(`Anomalie status updated to ${newStatus}`);
+ } else {
+ console.error("Chantier not found");
+ }
+ } catch (err) {
+ console.error("Error", err);
+ }
+}
+
+//CHANGE CHANTIER ANOMALIE STATUS
+export async function deleteAnomalie(chantierId: string, anomalie_String: string): Promise {
+ try {
+ const chantierRef = doc(db, "chantier", chantierId);
+ const chantierSnap = await getDoc(chantierRef);
+ if (chantierSnap.exists()) {
+ const chantierData = chantierSnap.data();
+ const anomalies = chantierData.anomalies || [];
+ const updatedAnomalies = anomalies.filter((anomalie: any) => anomalie.description !== anomalie_String);
+ await updateDoc(chantierRef, { anomalies: updatedAnomalies });
+ console.log(`Anomalie deleted`);
+ } else {
+ console.error("Chantier not found");
+ }
+ } catch (err) {
+ console.error("Error", err);
+ }
+}
+
+function convertReservation(res: any): Reservation {
+ 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),
+ };
+}