diff --git a/app/(tabs)/_layout.tsx b/app/(tabs)/_layout.tsx
index 5646a34..784ad33 100644
--- a/app/(tabs)/_layout.tsx
+++ b/app/(tabs)/_layout.tsx
@@ -7,14 +7,15 @@ import { HapticTab } from '@/components/haptic-tab';
import { IconSymbol } from '@/components/ui/icon-symbol';
import { Colors } from '@/constants/theme';
import { useColorScheme } from '@/hooks/use-color-scheme';
-import AddChantier from './addChantier';
import GestionOuvrier from './gestion_ouvrier';
import ListMateriel from './gestionnaire_ressource';
import Home from './home';
import MapScreen from './mapScreen';
-
-
+import AddChantier from './addChantier';
import AntDesign from '@expo/vector-icons/AntDesign';
+import { UserProvider } from '../ContextUser';
+import { ChantierProvider } from '../ContextChantier';
+import { RessourcesProvider } from '../ContextRessource';
const Tabs = createBottomTabNavigator();
@@ -22,59 +23,67 @@ export default function TabLayout() {
const colorScheme = useColorScheme();
return (
-
- (
-
- ),
- }}
- />
- (
-
- ),
- }}
- />
- ,
- }}
- />
- ,
- }}
- >
-
- (),
- }}
- />
-
-
+
+
+
+
+ (
+
+ ),
+ }}
+ />
+ (
+
+ ),
+ }}
+ />
+ ,
+ }}
+ />
+ ,
+ }}
+ >
+
+ (
+
+ ),
+ }}
+ />
+
+
+
+
+
);
}
diff --git a/app/(tabs)/addChantier.tsx b/app/(tabs)/addChantier.tsx
index 944e9f4..f2bec10 100644
--- a/app/(tabs)/addChantier.tsx
+++ b/app/(tabs)/addChantier.tsx
@@ -1,27 +1,201 @@
+import ChantierSummary from '@/components/chantierSummary';
+import SelectChantier from '@/components/selectChantier';
+import SetStatus from '@/components/setStatus';
+import { ThemedView } from '@/components/themed-view';
+import React, { useEffect, useState } from 'react';
+import { StyleSheet, ScrollView, Button, TextInput, Text } from 'react-native';
+import { useChantier } from '../ContextChantier';
+import { useRessources } from '../ContextRessource';
+import { useUser } from '../ContextUser';
+import { getRessources, getUsers, addChantier } from '@/services/ressourcesService';
+import { Chantier, Ressources } from '@/class/class';
import { ThemedText } from '@/components/themed-text';
-import { ThemedView, } from '@/components/themed-view';
-import Constants from 'expo-constants'; //pour connaître la taille de la barre menu de l'OS en haut
-import React from 'react';
-import { StyleSheet, View } from 'react-native';
+import { ThemedButton } from '@/components/themed-button';
+import { ThemedTextInput } from '@/components/themed-textinput';
export default function AddChantier() {
+ const { chantier, setChantier } = useChantier();
+ const { user, setUser } = useUser();
+ const { ressources, setRessources } = useRessources();
+
+ const [loading, setLoading] = useState(false);
+ const [nom, setNom] = useState('');
+ const [chefChantier, setChefChantier] = useState('');
+ const [adresse, setAdresse] = useState('');
+ const [duree, setDuree] = useState('');
+ const [userSelect, setUserSelect] = useState([]);
+ const [ressourcesSelect, setRessourcesSelect] = useState([]);
- return(
-
-
- TODO
-
-
- )
+ // Charger les utilisateurs et ressources
+ useEffect(() => {
+ async function load() {
+ setLoading(true);
+ const usersDb = await getUsers();
+ const ressourcesDb = await getRessources();
+ setUser(usersDb);
+ setRessources(ressourcesDb);
+ setLoading(false);
+ }
+ load();
+ }, []);
+
+ async function handleAddChantier() {
+ setLoading(true);
+
+ // Vérification chef
+ const chefUser = user.find(u => u.id === chefChantier);
+ if (!chefUser) {
+ console.error("Chef introuvable !");
+ setLoading(false);
+ return;
+ }
+
+ // Trouver les Users de l'équipe
+ const equipeUsers = userSelect
+ .map(id => user.find(u => u.id === id))
+ .filter(Boolean) as typeof user;
+
+ // Trouver les ressources sélectionnées
+ const materielSelect = ressourcesSelect
+ .map(id => ressources.find(r => r.id.toString() === id))
+ .filter(Boolean) as Ressources[];
+
+
+ // Construire l'objet chantier complet
+ const chantierData: Omit = {
+ chef: chefUser!,
+ adresse,
+ dateDep: new Date(),
+ equipe: equipeUsers,
+ materiel: materielSelect,
+ etat: 'En attente',
+ latitude: 0,
+ longitude: 0,
+ anomalies: [],
+ tempsEst: 0,
+ vehicules: [],
+ contact: "",
+};
+
+ // Ajouter le chantier dans Firestore
+ const id = await addChantier(chantierData);
+ setLoading(false);
+
+ if (id) {
+ console.log("Chantier ajouté avec l'ID :", id);
+ setChantier({ ...chantierData, id });
+ }
+ }
+ return (
+
+
+ Ajouter un nouveau chantier
+
+
+
+
+ Équipe
+
+ Ressources
+
+ handleAddChantier()}
+ >
+
+
+
+
+
+ );
}
const styles = StyleSheet.create({
- back:{
- height:"100%",
- width:"100%",
- },
container: {
flex: 1,
- marginTop: Constants.statusBarHeight, //pour la barre menu du haut
+ marginTop: 60,
},
-});
\ No newline at end of file
+ header: {
+ marginBottom: 20,
+ alignItems: "center",
+ paddingHorizontal: 20,
+ },
+ text: {
+ fontSize: 22,
+ fontWeight: "bold",
+ marginBottom: 10,
+ },
+ inputBack: {
+ width: "100%",
+ borderRadius: 10,
+ backgroundColor: "transparent",
+ },
+ input: {
+ width: "100%",
+ borderRadius: 10,
+ padding: 10,
+ fontSize: 16,
+ },
+ card: {
+ flexDirection: "row",
+ marginHorizontal: 20,
+ marginBottom: 15,
+ borderRadius: 10,
+ padding: 10,
+ },
+ image: {
+ width: 80,
+ height: 80,
+ borderRadius: 8,
+ marginRight: 10,
+ },
+ info: {
+ flex: 1,
+ justifyContent: "center",
+ },
+ footer: {
+ padding: 20,
+ },
+ empty: {
+ textAlign: "center",
+ marginTop: 30,
+ color: "#888",
+ },
+ filterMenuOverlay: {
+ position: "absolute",
+ top: 0,
+ left: 0,
+ right: 0,
+ bottom: 0,
+ backgroundColor: "rgba(0,0,0,0.4)",
+ justifyContent: "center",
+ alignItems: "center",
+ zIndex: 999,
+ },
+ filterMenu: {
+ width: "80%",
+ borderRadius: 12,
+ padding: 20,
+ backgroundColor: "#fff",
+ },
+ filterTitle: {
+ fontSize: 18,
+ fontWeight: "bold",
+ marginBottom: 20,
+ textAlign: "center",
+ },
+});
diff --git a/components/selectChantier.tsx b/components/selectChantier.tsx
index 806c99c..a23521f 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,
@@ -31,15 +29,19 @@ 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([]);
-
const AnimatedThemedView = Animated.createAnimatedComponent(ThemedView);
const AnimatedThemedText = Animated.createAnimatedComponent(ThemedText);
const AnimatedThemedButton = Animated.createAnimatedComponent(ThemedButton);
@@ -47,21 +49,28 @@ export default function SelectChantier() {
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);
+ }
}
}
function onPressAddChantier(){
- router.push("/(tabs)/addChantier")
- setIsOpen(false)
+
}
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 +79,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 +141,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 +166,14 @@ export default function SelectChantier() {
+
-
- {isLoaded?
+
+
{chantiers.map((chantier, index) =>
renderChantier(chantier, index)
)}
- : }
-
-
+
)}
@@ -223,8 +276,5 @@ const styles = StyleSheet.create({
buttonAdd:{
borderRadius: 10,
marginBottom: 10,
- height: 30,
- alignItems: 'center',
- justifyContent: 'center',
}
});