diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 41ba2b4f..2a724701 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1113,10 +1113,16 @@ PODS: - React-jsi (= 0.73.5) - React-logger (= 0.73.5) - React-perflogger (= 0.73.5) + - RNCAsyncStorage (1.22.2): + - React-Core - RNScreens (3.29.0): - glog - RCT-Folly (= 2022.05.16.00) - React-Core + - RNVectorIcons (10.0.3): + - glog + - RCT-Folly (= 2022.05.16.00) + - React-Core - SocketRocket (0.6.1) - VisionCamera (3.9.0): - React @@ -1198,7 +1204,9 @@ DEPENDENCIES: - React-runtimescheduler (from `../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler`) - React-utils (from `../node_modules/react-native/ReactCommon/react/utils`) - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) + - "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)" - RNScreens (from `../node_modules/react-native-screens`) + - RNVectorIcons (from `../node_modules/react-native-vector-icons`) - VisionCamera (from `../node_modules/react-native-vision-camera`) - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) @@ -1316,8 +1324,12 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/react/utils" ReactCommon: :path: "../node_modules/react-native/ReactCommon" + RNCAsyncStorage: + :path: "../node_modules/@react-native-async-storage/async-storage" RNScreens: :path: "../node_modules/react-native-screens" + RNVectorIcons: + :path: "../node_modules/react-native-vector-icons" VisionCamera: :path: "../node_modules/react-native-vision-camera" Yoga: @@ -1384,11 +1396,13 @@ SPEC CHECKSUMS: React-runtimescheduler: 814b644a5f456c7df1fba7bcd9914707152527c6 React-utils: 987a4526a2fc0acdfaf87888adfe0bf9d0452066 ReactCommon: 2947b0bffd82ea0e58ca7928881152d4c6dae9af + RNCAsyncStorage: 014a78b2cc8cc107c9e92ee428dc0c1ac3223416 RNScreens: 17e2f657f1b09a71ec3c821368a04acbb7ebcb46 + RNVectorIcons: 73ab573085f65a572d3b6233e68996d4707fd505 SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17 VisionCamera: 7a5c87805b13adaaa557132b44879ed1e1e39786 - Yoga: a716eea57d0d3430219c0a5a233e1e93ee931eb7 + Yoga: 9e6a04eacbd94f97d94577017e9f23b3ab41cf6c PODFILE CHECKSUM: 0324d2f1bead3c67e34ad5270355479295c48a2e -COCOAPODS: 1.15.0 +COCOAPODS: 1.15.2 diff --git a/package-lock.json b/package-lock.json index 1758f99f..f40197f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "react-native-logs": "^5.1.0", "react-native-safe-area-context": "^4.9.0", "react-native-screens": "^3.29.0", + "react-native-vector-icons": "^10.0.3", "react-native-vision-camera": "^3.9.0", "react-redux": "^9.1.0" }, @@ -30,6 +31,7 @@ "@react-native/metro-config": "0.74.1", "@react-native/typescript-config": "0.74.1", "@types/react": "^18.2.60", + "@types/react-native-vector-icons": "^6.4.18", "@types/react-test-renderer": "^18.0.7", "babel-jest": "^29.7.0", "eslint": "^8.57.0", @@ -4762,6 +4764,25 @@ "csstype": "^3.0.2" } }, + "node_modules/@types/react-native": { + "version": "0.70.19", + "resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.70.19.tgz", + "integrity": "sha512-c6WbyCgWTBgKKMESj/8b4w+zWcZSsCforson7UdXtXMecG3MxCinYi6ihhrHVPyUrVzORsvEzK8zg32z4pK6Sg==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-native-vector-icons": { + "version": "6.4.18", + "resolved": "https://registry.npmjs.org/@types/react-native-vector-icons/-/react-native-vector-icons-6.4.18.tgz", + "integrity": "sha512-YGlNWb+k5laTBHd7+uZowB9DpIK3SXUneZqAiKQaj1jnJCZM0x71GDim5JCTMi4IFkhc9m8H/Gm28T5BjyivUw==", + "dev": true, + "dependencies": { + "@types/react": "*", + "@types/react-native": "^0.70" + } + }, "node_modules/@types/react-test-renderer": { "version": "18.0.7", "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-18.0.7.tgz", @@ -12495,6 +12516,56 @@ "react-native": "*" } }, + "node_modules/react-native-vector-icons": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-10.0.3.tgz", + "integrity": "sha512-ZgVlV5AdQgnPHHvBEihGf2xwyziT1acpXV1U+WfCgCv3lcEeCRsmwAsBU+kUSNsU+8TcWVsX04kdI6qUaS8D7w==", + "dependencies": { + "prop-types": "^15.7.2", + "yargs": "^16.1.1" + }, + "bin": { + "fa-upgrade.sh": "bin/fa-upgrade.sh", + "fa5-upgrade": "bin/fa5-upgrade.sh", + "fa6-upgrade": "bin/fa6-upgrade.sh", + "generate-icon": "bin/generate-icon.js" + } + }, + "node_modules/react-native-vector-icons/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/react-native-vector-icons/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/react-native-vector-icons/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "engines": { + "node": ">=10" + } + }, "node_modules/react-native-vision-camera": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/react-native-vision-camera/-/react-native-vision-camera-3.9.0.tgz", diff --git a/package.json b/package.json index 62ae1516..8cfc7541 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "android": "react-native run-android", "ios": "react-native run-ios", "lint": "eslint .", + "lint:fix": "eslint . --fix", "start": "react-native start", "test": "jest" }, @@ -20,6 +21,7 @@ "react-native-logs": "^5.1.0", "react-native-safe-area-context": "^4.9.0", "react-native-screens": "^3.29.0", + "react-native-vector-icons": "^10.0.3", "react-native-vision-camera": "^3.9.0", "react-redux": "^9.1.0" }, @@ -32,6 +34,7 @@ "@react-native/metro-config": "0.74.1", "@react-native/typescript-config": "0.74.1", "@types/react": "^18.2.60", + "@types/react-native-vector-icons": "^6.4.18", "@types/react-test-renderer": "^18.0.7", "babel-jest": "^29.7.0", "eslint": "^8.57.0", diff --git a/src/App.tsx b/src/App.tsx index 3433625e..cd473dd4 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,14 +1,23 @@ import React, {useEffect} from 'react'; -import {SafeAreaView, StyleSheet, Text} from 'react-native'; -import {Provider} from 'react-redux'; - -// import {NavigationContainer} from '@react-navigation/native'; -// import TabNavigator from './components/navigators/TabNavigator.tsx'; +import {NavigationContainer} from '@react-navigation/native'; +import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'; +import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; import {useCameraPermission} from 'react-native-vision-camera'; -import store from './service/redux/store.ts'; + +const Tab = createBottomTabNavigator(); + +const LastScanScreen = () => null; +const PlateScreen = () => null; +const QRScanScreen = () => null; +const SearchScreen = () => null; +const AccountScreen = () => null; const App = () => { const {hasPermission, requestPermission} = useCameraPermission(); + const renderIcon = + name => + ({color, size}) => + ; useEffect(() => { if (!hasPermission) { @@ -17,22 +26,46 @@ const App = () => { }, [hasPermission, requestPermission]); return ( - - - App - {/**/} - {/* */} - {/**/} - - + + + + + + + + + ); }; -const styles = StyleSheet.create({ - screen: { - flex: 1, - backgroundColor: 'white', - }, -}); - export default App; diff --git a/src/MockApiComponent.tsx b/src/MockApiComponent.tsx new file mode 100644 index 00000000..06a37ed5 --- /dev/null +++ b/src/MockApiComponent.tsx @@ -0,0 +1,39 @@ +import React from 'react'; +import {SafeAreaView, StyleSheet, ScrollView} from 'react-native'; +import NutritionInfo from './NutritionInfo'; + +const fakeApiData = { + product_name: 'Ourson Chocolat', + ingredients_text: 'Cacao, sucre, lait', + nutriments: { + carbohydrates: 54, + proteins: 7, + fat: 30, + sugars: 100, + salt: 0.2, + }, + ecoscore_score: '75', + nutriscore_grade: 'B', +}; + +const App = () => { + return ( + + + + + + ); +}; + +const styles = StyleSheet.create({ + screen: { + flex: 1, + backgroundColor: 'white', + }, + content: { + padding: 20, + }, +}); + +export default App; diff --git a/src/NutritionInfo.tsx b/src/NutritionInfo.tsx new file mode 100644 index 00000000..29c27dee --- /dev/null +++ b/src/NutritionInfo.tsx @@ -0,0 +1,54 @@ +import React from 'react'; +import {View, Text, StyleSheet} from 'react-native'; + +const NutritionInfo = ({data}) => { + const { + product_name, + ingredients_text, + nutriments, + ecoscore_score, + nutriscore_grade, + } = data; + + return ( + + {product_name} + Ingrédients: {ingredients_text} + + Informations Nutritionnelles: + Carbohydrates: {nutriments.carbohydrates}g + Protéines: {nutriments.proteins}g + Graisses: {nutriments.fat}g + Sucres: {nutriments.sugars}g + Sel: {nutriments.salt}g + + + Scores: + Eco-Score: {ecoscore_score} + Nutri-Score: {nutriscore_grade} + + + ); +}; + +const styles = StyleSheet.create({ + container: { + padding: 20, + }, + title: { + fontSize: 18, + fontWeight: 'bold', + }, + subtitle: { + fontSize: 14, + marginVertical: 10, + }, + section: { + marginVertical: 10, + }, + sectionTitle: { + fontWeight: 'bold', + }, +}); + +export default NutritionInfo; diff --git a/src/Product.tsx b/src/Product.tsx new file mode 100644 index 00000000..32689807 --- /dev/null +++ b/src/Product.tsx @@ -0,0 +1,163 @@ +import React from 'react'; +import { + SafeAreaView, + ScrollView, + View, + Text, + Image, + StyleSheet, + TouchableOpacity, +} from 'react-native'; +import Icon from 'react-native-vector-icons/FontAwesome'; + +interface ProductItemProps { + title: string; + subtitle: string; + badgeText: string; + defects: string[]; + qualities: string[]; +} + +const ProductItem = ({ + title, + subtitle, + badgeText, + defects, + qualities, +}: ProductItemProps) => { + return ( + + + + + {title} + {subtitle} + + {badgeText} + + + + Défauts + {defects.map((defect, index) => ( + + + {defect} + + ))} + + Qualités + {qualities.map((quality, index) => ( + + + {quality} + + ))} + + + ); +}; + +const App = () => { + return ( + + + + + + Détails + + + + + ); +}; + +const styles = StyleSheet.create({ + screen: { + flex: 1, + backgroundColor: 'white', + }, + scrollView: { + flexGrow: 1, + justifyContent: 'space-between', + }, + buttonContainer: { + justifyContent: 'center', + alignItems: 'center', + marginVertical: 20, + }, + button: { + backgroundColor: '#6200EE', + paddingHorizontal: 20, + paddingVertical: 10, + borderRadius: 25, + }, + buttonText: { + color: 'white', + fontSize: 16, + }, + card: { + backgroundColor: '#FFFFFF', + borderRadius: 8, + margin: 8, + padding: 16, + shadowColor: '#000', + shadowOffset: { + width: 0, + height: 2, + }, + shadowOpacity: 0.23, + shadowRadius: 2.62, + elevation: 4, + }, + header: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + }, + image: { + width: 40, + height: 40, + borderRadius: 20, + }, + headerText: { + marginLeft: 8, + }, + title: { + fontWeight: 'bold', + }, + subtitle: { + color: '#4B5563', + fontSize: 12, + }, + badge: { + backgroundColor: '#FECACA', + color: '#B91C1C', + borderRadius: 9999, + padding: 4, + }, + content: { + marginTop: 16, + }, + sectionTitle: { + fontWeight: 'bold', + color: '#1F2937', + marginBottom: 8, + }, + listItem: { + flexDirection: 'row', + alignItems: 'center', + marginBottom: 4, + }, + listText: { + marginLeft: 8, + }, +}); + +export default App;