diff --git a/app/home.tsx b/app/home.tsx
index 0c73cdb..c09f39e 100644
--- a/app/home.tsx
+++ b/app/home.tsx
@@ -1,43 +1,219 @@
-import { useState } from 'react';
-import { Text, TextInput, View } from 'react-native';
+//npx expo install expo-location expo-camera
-export default function Home() {
- const users = [
- "alice",
- "bob",
- "charlie"
- ]
+import {
+ CameraView,
+ useCameraPermissions,
+} from "expo-camera";
+
+import React, { useRef, useState } from "react";
+import {
+ ActivityIndicator,
+ Alert,
+ Image,
+ Linking,
+ StyleSheet,
+ Text,
+ TouchableOpacity,
+ View,
+} from "react-native";
- const variable = true;
+export default function App() {
+ const cameraRef = useRef(null);
- const [nom, setNom] = useState('');
+ const [statusText, setStatusText] = useState("Permission non demandée");
+ const [loading, setLoading] = useState(false);
+ const [cameraVisible, setCameraVisible] = useState(false);
+ const [photoUri, setPhotoUri] = useState(null);
- return (
-
- {variable && Test}
- {variable ? Vrai : Faux}
- {users.map(user => {
- return {user}
- })}
+ const [permission, requestPermission] =
+ useCameraPermissions();
-
+ const openSettings = () => {
+ Linking.openSettings();
+ };
-
- Saisie + bouton "Valider"
-
+ const openCamera = async () => {
+ try {
+ setLoading(true);
+ setStatusText("Demande de permission caméra...");
- Valeur validée : {nom || '(vide)'}
+ const result = await requestPermission();
-
+ if (!result.granted) {
+ if (result.canAskAgain === false) {
+ Alert.alert(
+ "Permission bloquée",
+ "La caméra doit être activée dans les paramètres.",
+ [
+ { text: "Annuler", style: "cancel" },
+ { text: "Paramètres", onPress: openSettings },
+ ]
+ );
+ } else {
+ Alert.alert(
+ "Permission refusée",
+ "Impossible d'utiliser la caméra."
+ );
+ }
-
+ setStatusText("Permission caméra refusée");
+ return;
+ }
- );
+ setPhotoUri(null);
+ setCameraVisible(true);
+ setStatusText("Caméra autorisée");
+ } catch (e) {
+ setStatusText("Erreur lors de la demande caméra");
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ const takePhoto = async () => {
+ try {
+ if (!cameraRef.current) {
+ Alert.alert("Erreur", "La caméra n'est pas encore prête.");
+ return;
+ }
+
+ setLoading(true);
+ setStatusText("Prise de photo...");
+
+ const photo = await cameraRef.current.takePictureAsync();
+
+ if (!photo || !photo.uri) {
+ Alert.alert("Erreur", "Aucune photo obtenue.");
+ return;
+ }
+
+ setPhotoUri(photo.uri);
+ setCameraVisible(false);
+ setStatusText("Photo prise");
+ } catch (e) {
+ setStatusText("Erreur lors de la prise de photo");
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ const closeCamera = () => {
+ setCameraVisible(false);
+ setStatusText("Caméra fermée");
+ };
+
+ if (cameraVisible) {
+ return (
+
+
+
+
+
+ Fermer
+
+
+
+ Prendre une photo
+
+
+
+ );
+ }
+
+ return (
+
+ TP permissions Expo
+
+
+ Ouvrir la caméra
+
+
+ {loading ? : null}
+
+ {statusText}
+
+ {photoUri ? (
+
+ Photo prise :
+
+
+ ) : null}
+
+ );
}
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: "center",
+ padding: 20,
+ backgroundColor: "#fff",
+ },
+ title: {
+ fontSize: 24,
+ fontWeight: "bold",
+ marginBottom: 20,
+ textAlign: "center",
+ },
+ subtitle: {
+ fontWeight: "bold",
+ marginBottom: 10,
+ },
+ button: {
+ backgroundColor: "#2563eb",
+ padding: 14,
+ borderRadius: 8,
+ marginBottom: 12,
+ },
+ secondaryButton: {
+ backgroundColor: "#666",
+ padding: 14,
+ borderRadius: 8,
+ marginBottom: 12,
+ },
+ buttonText: {
+ color: "#fff",
+ textAlign: "center",
+ fontWeight: "bold",
+ },
+ status: {
+ textAlign: "center",
+ marginVertical: 20,
+ },
+ box: {
+ padding: 16,
+ borderWidth: 1,
+ borderColor: "#ccc",
+ borderRadius: 8,
+ marginBottom: 20,
+ },
+ photoBox: {
+ marginTop: 10,
+ alignItems: "center",
+ },
+ photo: {
+ width: 250,
+ height: 250,
+ borderRadius: 8,
+ borderWidth: 1,
+ borderColor: "#ccc",
+ },
+ cameraContainer: {
+ flex: 1,
+ backgroundColor: "#000",
+ },
+ camera: {
+ flex: 1,
+ },
+ cameraControls: {
+ position: "absolute",
+ bottom: 40,
+ left: 20,
+ right: 20,
+ },
+});
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index d0e66ff..b3dd863 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,15 +9,19 @@
"version": "1.0.0",
"dependencies": {
"@expo/vector-icons": "^15.0.3",
+ "@react-native-async-storage/async-storage": "2.2.0",
"@react-navigation/bottom-tabs": "^7.4.0",
"@react-navigation/elements": "^2.6.3",
"@react-navigation/native": "^7.1.8",
"expo": "~54.0.33",
+ "expo-camera": "~17.0.10",
"expo-constants": "~18.0.13",
"expo-font": "~14.0.11",
"expo-haptics": "~15.0.8",
"expo-image": "~3.0.11",
+ "expo-image-picker": "~17.0.10",
"expo-linking": "~8.0.11",
+ "expo-location": "~19.0.8",
"expo-router": "~6.0.23",
"expo-splash-screen": "~31.0.13",
"expo-status-bar": "~3.0.9",
@@ -2756,6 +2760,18 @@
}
}
},
+ "node_modules/@react-native-async-storage/async-storage": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-2.2.0.tgz",
+ "integrity": "sha512-gvRvjR5JAaUZF8tv2Kcq/Gbt3JHwbKFYfmb445rhOj6NUMx3qPLixmDx5pZAyb9at1bYvJ4/eTUipU5aki45xw==",
+ "license": "MIT",
+ "dependencies": {
+ "merge-options": "^3.0.4"
+ },
+ "peerDependencies": {
+ "react-native": "^0.0.0-0 || >=0.65 <1.0"
+ }
+ },
"node_modules/@react-native/assets-registry": {
"version": "0.81.5",
"resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.81.5.tgz",
@@ -6062,6 +6078,26 @@
"react-native": "*"
}
},
+ "node_modules/expo-camera": {
+ "version": "17.0.10",
+ "resolved": "https://registry.npmjs.org/expo-camera/-/expo-camera-17.0.10.tgz",
+ "integrity": "sha512-w1RBw83mAGVk4BPPwNrCZyFop0VLiVSRE3c2V9onWbdFwonpRhzmB4drygG8YOUTl1H3wQvALJHyMPTbgsK1Jg==",
+ "license": "MIT",
+ "dependencies": {
+ "invariant": "^2.2.4"
+ },
+ "peerDependencies": {
+ "expo": "*",
+ "react": "*",
+ "react-native": "*",
+ "react-native-web": "*"
+ },
+ "peerDependenciesMeta": {
+ "react-native-web": {
+ "optional": true
+ }
+ }
+ },
"node_modules/expo-constants": {
"version": "18.0.13",
"resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-18.0.13.tgz",
@@ -6126,6 +6162,27 @@
}
}
},
+ "node_modules/expo-image-loader": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/expo-image-loader/-/expo-image-loader-6.0.0.tgz",
+ "integrity": "sha512-nKs/xnOGw6ACb4g26xceBD57FKLFkSwEUTDXEDF3Gtcu3MqF3ZIYd3YM+sSb1/z9AKV1dYT7rMSGVNgsveXLIQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "expo": "*"
+ }
+ },
+ "node_modules/expo-image-picker": {
+ "version": "17.0.10",
+ "resolved": "https://registry.npmjs.org/expo-image-picker/-/expo-image-picker-17.0.10.tgz",
+ "integrity": "sha512-a2xrowp2trmvXyUWgX3O6Q2rZaa2C59AqivKI7+bm+wLvMfTEbZgldLX4rEJJhM8xtmEDTNU+lzjtObwzBRGaw==",
+ "license": "MIT",
+ "dependencies": {
+ "expo-image-loader": "~6.0.0"
+ },
+ "peerDependencies": {
+ "expo": "*"
+ }
+ },
"node_modules/expo-keep-awake": {
"version": "15.0.8",
"resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-15.0.8.tgz",
@@ -6150,6 +6207,15 @@
"react-native": "*"
}
},
+ "node_modules/expo-location": {
+ "version": "19.0.8",
+ "resolved": "https://registry.npmjs.org/expo-location/-/expo-location-19.0.8.tgz",
+ "integrity": "sha512-H/FI75VuJ1coodJbbMu82pf+Zjess8X8Xkiv9Bv58ZgPKS/2ztjC1YO1/XMcGz7+s9DrbLuMIw22dFuP4HqneA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "expo": "*"
+ }
+ },
"node_modules/expo-modules-autolinking": {
"version": "3.0.24",
"resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-3.0.24.tgz",
@@ -7829,6 +7895,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-plain-obj": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
+ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/is-regex": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
@@ -8807,6 +8882,18 @@
"integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==",
"license": "MIT"
},
+ "node_modules/merge-options": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz",
+ "integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==",
+ "license": "MIT",
+ "dependencies": {
+ "is-plain-obj": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
diff --git a/package.json b/package.json
index 7d7170b..b07cf15 100644
--- a/package.json
+++ b/package.json
@@ -12,15 +12,19 @@
},
"dependencies": {
"@expo/vector-icons": "^15.0.3",
+ "@react-native-async-storage/async-storage": "2.2.0",
"@react-navigation/bottom-tabs": "^7.4.0",
"@react-navigation/elements": "^2.6.3",
"@react-navigation/native": "^7.1.8",
"expo": "~54.0.33",
+ "expo-camera": "~17.0.10",
"expo-constants": "~18.0.13",
"expo-font": "~14.0.11",
"expo-haptics": "~15.0.8",
"expo-image": "~3.0.11",
+ "expo-image-picker": "~17.0.10",
"expo-linking": "~8.0.11",
+ "expo-location": "~19.0.8",
"expo-router": "~6.0.23",
"expo-splash-screen": "~31.0.13",
"expo-status-bar": "~3.0.9",
@@ -31,11 +35,11 @@
"react-dom": "19.1.0",
"react-native": "0.81.5",
"react-native-gesture-handler": "~2.28.0",
- "react-native-worklets": "0.5.1",
"react-native-reanimated": "~4.1.1",
"react-native-safe-area-context": "~5.6.0",
"react-native-screens": "~4.16.0",
- "react-native-web": "~0.21.0"
+ "react-native-web": "~0.21.0",
+ "react-native-worklets": "0.5.1"
},
"devDependencies": {
"@types/react": "~19.1.0",
diff --git a/tsconfig.json b/tsconfig.json
index 909e901..4acaa77 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,7 +1,7 @@
{
"extends": "expo/tsconfig.base",
"compilerOptions": {
- "strict": true,
+ "strict": false,
"paths": {
"@/*": [
"./*"