├── .expo-shared
├── assets.json
└── README.md
├── .expo
├── devices.json
└── README.md
├── .DS_Store
├── assets
├── icon.png
├── splash.png
├── icons
│ ├── clear.png
│ ├── close.png
│ ├── home.png
│ ├── home1.png
│ ├── info.png
│ ├── list.png
│ ├── menu.png
│ ├── time.png
│ ├── search.png
│ ├── backArrow.png
│ ├── category.png
│ ├── cookie100.png
│ ├── cookie50.png
│ └── ingredients.png
└── adaptive-icon.png
├── App.js
├── babel.config.js
├── src
├── screens
│ ├── Home
│ │ ├── styles.js
│ │ └── HomeScreen.js
│ ├── RecipesList
│ │ ├── styles.js
│ │ └── RecipesListScreen.js
│ ├── Splash
│ │ ├── styles.js
│ │ └── SplashScreen.js
│ ├── DrawerContainer
│ │ ├── styles.js
│ │ └── DrawerContainer.js
│ ├── Ingredient
│ │ ├── styles.js
│ │ └── IngredientScreen.js
│ ├── Search
│ │ ├── styles.js
│ │ └── SearchScreen.js
│ ├── Categories
│ │ ├── styles.js
│ │ └── CategoriesScreen.js
│ ├── IngredientsDetails
│ │ ├── styles.js
│ │ └── IngredientsDetailsScreen.js
│ └── Recipe
│ │ ├── styles.js
│ │ └── RecipeScreen.js
├── components
│ ├── MenuImage
│ │ ├── styles.js
│ │ └── MenuImage.js
│ ├── MenuButton
│ │ ├── styles.js
│ │ └── MenuButton.js
│ ├── ViewIngredientsButton
│ │ ├── styles.js
│ │ └── ViewIngredientsButton.js
│ └── BackButton
│ │ ├── BackButton.js
│ │ └── styles.js
├── AppStyles.js
├── navigations
│ └── AppNavigation.js
└── data
│ ├── MockDataAPI.js
│ └── dataArrays.js
├── app.json
├── LICENSE
├── package.json
├── .gitignore
└── README.md
/.expo-shared/assets.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/.expo/devices.json:
--------------------------------------------------------------------------------
1 | {
2 | "devices": []
3 | }
4 |
--------------------------------------------------------------------------------
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dopebase/react-native-recipes-app/HEAD/.DS_Store
--------------------------------------------------------------------------------
/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dopebase/react-native-recipes-app/HEAD/assets/icon.png
--------------------------------------------------------------------------------
/assets/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dopebase/react-native-recipes-app/HEAD/assets/splash.png
--------------------------------------------------------------------------------
/assets/icons/clear.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dopebase/react-native-recipes-app/HEAD/assets/icons/clear.png
--------------------------------------------------------------------------------
/assets/icons/close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dopebase/react-native-recipes-app/HEAD/assets/icons/close.png
--------------------------------------------------------------------------------
/assets/icons/home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dopebase/react-native-recipes-app/HEAD/assets/icons/home.png
--------------------------------------------------------------------------------
/assets/icons/home1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dopebase/react-native-recipes-app/HEAD/assets/icons/home1.png
--------------------------------------------------------------------------------
/assets/icons/info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dopebase/react-native-recipes-app/HEAD/assets/icons/info.png
--------------------------------------------------------------------------------
/assets/icons/list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dopebase/react-native-recipes-app/HEAD/assets/icons/list.png
--------------------------------------------------------------------------------
/assets/icons/menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dopebase/react-native-recipes-app/HEAD/assets/icons/menu.png
--------------------------------------------------------------------------------
/assets/icons/time.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dopebase/react-native-recipes-app/HEAD/assets/icons/time.png
--------------------------------------------------------------------------------
/assets/adaptive-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dopebase/react-native-recipes-app/HEAD/assets/adaptive-icon.png
--------------------------------------------------------------------------------
/assets/icons/search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dopebase/react-native-recipes-app/HEAD/assets/icons/search.png
--------------------------------------------------------------------------------
/assets/icons/backArrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dopebase/react-native-recipes-app/HEAD/assets/icons/backArrow.png
--------------------------------------------------------------------------------
/assets/icons/category.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dopebase/react-native-recipes-app/HEAD/assets/icons/category.png
--------------------------------------------------------------------------------
/assets/icons/cookie100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dopebase/react-native-recipes-app/HEAD/assets/icons/cookie100.png
--------------------------------------------------------------------------------
/assets/icons/cookie50.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dopebase/react-native-recipes-app/HEAD/assets/icons/cookie50.png
--------------------------------------------------------------------------------
/assets/icons/ingredients.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dopebase/react-native-recipes-app/HEAD/assets/icons/ingredients.png
--------------------------------------------------------------------------------
/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import AppContainer from './src/navigations/AppNavigation';
3 |
4 | export default function App() {
5 | return (
6 |
7 | );
8 | }
9 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = function (api) {
2 | api.cache(true);
3 | return {
4 | presets: [
5 | 'babel-preset-expo',
6 | ],
7 | plugins: ["react-native-reanimated/plugin"],
8 | };
9 | };
10 |
--------------------------------------------------------------------------------
/src/screens/Home/styles.js:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from 'react-native';
2 | import { RecipeCard } from '../../AppStyles';
3 |
4 | const styles = StyleSheet.create({
5 | container: RecipeCard.container,
6 | photo: RecipeCard.photo,
7 | title: RecipeCard.title,
8 | category: RecipeCard.category
9 | });
10 |
11 | export default styles;
12 |
--------------------------------------------------------------------------------
/src/screens/RecipesList/styles.js:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from 'react-native';
2 | import { RecipeCard } from '../../AppStyles';
3 |
4 | const styles = StyleSheet.create({
5 | container: RecipeCard.container,
6 | photo: RecipeCard.photo,
7 | title: RecipeCard.title,
8 | category: RecipeCard.category
9 | });
10 |
11 | export default styles;
12 |
--------------------------------------------------------------------------------
/src/screens/Splash/styles.js:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from "react-native";
2 |
3 | const styles = StyleSheet.create({
4 | container: {
5 | flex: 1,
6 | justifyContent: "center",
7 | alignItems: "center",
8 | backgroundColor: "#2cd18a",
9 | },
10 | photo: {
11 | flex: 1,
12 | },
13 | });
14 |
15 | export default styles;
16 |
--------------------------------------------------------------------------------
/src/components/MenuImage/styles.js:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from 'react-native';
2 |
3 | const styles = StyleSheet.create({
4 | headerButtonContainer: {
5 | padding: 10
6 | },
7 | headerButtonImage: {
8 | justifyContent: 'center',
9 | width: 25,
10 | height: 25,
11 | margin: 6
12 | }
13 | });
14 |
15 | export default styles;
16 |
--------------------------------------------------------------------------------
/src/screens/Splash/SplashScreen.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { View, Image } from "react-native";
3 | import styles from "./styles";
4 |
5 | export default function SplashScreen() {
6 | return (
7 |
8 |
9 |
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/src/screens/DrawerContainer/styles.js:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from 'react-native';
2 |
3 | const styles = StyleSheet.create({
4 | content: {
5 | flex: 1,
6 | flexDirection: 'row',
7 | alignItems: 'center',
8 | justifyContent: 'center'
9 | },
10 | container: {
11 | flex: 1,
12 | alignItems: 'flex-start',
13 | paddingHorizontal: 20
14 | }
15 | });
16 |
17 | export default styles;
18 |
--------------------------------------------------------------------------------
/src/components/MenuButton/styles.js:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from 'react-native';
2 |
3 | const styles = StyleSheet.create({
4 | btnClickContain: {
5 | flexDirection: 'row',
6 | padding: 5,
7 | marginTop: 5,
8 | marginBottom: 5
9 | },
10 | btnContainer: {
11 | flex: 1,
12 | flexDirection: 'row',
13 | alignItems: 'flex-start'
14 | },
15 | btnIcon: {
16 | height: 25,
17 | width: 25
18 | },
19 | btnText: {
20 | fontSize: 16,
21 | marginLeft: 10,
22 | marginTop: 2
23 | }
24 | });
25 |
26 | export default styles;
27 |
--------------------------------------------------------------------------------
/src/components/MenuImage/MenuImage.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { TouchableOpacity, Image } from "react-native";
3 | import PropTypes from "prop-types";
4 | import styles from "./styles";
5 |
6 | export default function MenuImage(props) {
7 | return (
8 |
9 |
10 |
11 | );
12 | }
13 |
14 | MenuImage.propTypes = {
15 | onPress: PropTypes.func,
16 | };
17 |
--------------------------------------------------------------------------------
/src/components/ViewIngredientsButton/styles.js:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from 'react-native';
2 |
3 | const styles = StyleSheet.create({
4 | container: {
5 | flex: 1,
6 | height: 50,
7 | width: 270,
8 | marginTop: 20,
9 | marginLeft: 10,
10 | marginRight: 10,
11 | borderRadius: 100,
12 | borderColor: '#2cd18a',
13 | borderWidth: 1,
14 | justifyContent: 'center',
15 | alignItems: 'center'
16 | // backgroundColor: '#2cd18a'
17 | },
18 | text: {
19 | fontSize: 14,
20 | color: '#2cd18a'
21 | }
22 | });
23 |
24 | export default styles;
25 |
--------------------------------------------------------------------------------
/.expo-shared/README.md:
--------------------------------------------------------------------------------
1 | > Why do I have a folder named ".expo-shared" in my project?
2 |
3 | The ".expo-shared" folder is created when running commands that produce state that is intended to be shared with all developers on the project. For example, "npx expo-optimize".
4 |
5 | > What does the "assets.json" file contain?
6 |
7 | The "assets.json" file describes the assets that have been optimized through "expo-optimize" and do not need to be processed again.
8 |
9 | > Should I commit the ".expo-shared" folder?
10 |
11 | Yes, you should share the ".expo-shared" folder with your collaborators.
12 |
--------------------------------------------------------------------------------
/src/components/BackButton/BackButton.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { TouchableHighlight, Image, } from "react-native";
3 | import PropTypes from "prop-types";
4 | import styles from "./styles";
5 |
6 | export default function BackButton(props) {
7 | return (
8 |
9 |
10 |
11 | );
12 | }
13 |
14 | BackButton.propTypes = {
15 | onPress: PropTypes.func,
16 | source: PropTypes.number,
17 | title: PropTypes.string,
18 | };
19 |
--------------------------------------------------------------------------------
/src/components/BackButton/styles.js:
--------------------------------------------------------------------------------
1 | // BackButton/styles.js
2 | import { StyleSheet } from "react-native";
3 |
4 | const styles = StyleSheet.create({
5 | btnContainer: {
6 | alignItems: "center",
7 | justifyContent: "center",
8 | borderRadius: 20,
9 | padding: 10,
10 | margin: 8,
11 | backgroundColor: "white",
12 | shadowColor: "#000",
13 | shadowOffset: {
14 | width: 0,
15 | height: 2,
16 | },
17 | shadowOpacity: 0.25,
18 | shadowRadius: 3.84,
19 | elevation: 3,
20 | },
21 | btnIcon: {
22 | height: 20,
23 | width: 20,
24 | },
25 | });
26 |
27 | export default styles;
--------------------------------------------------------------------------------
/src/components/ViewIngredientsButton/ViewIngredientsButton.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { TouchableHighlight, Image, Text, View } from 'react-native';
3 | import PropTypes from 'prop-types';
4 | import styles from './styles';
5 |
6 | export default function ViewIngredientsButton (props) {
7 | return (
8 |
9 |
10 | View Ingredients
11 |
12 |
13 | );
14 | }
15 |
16 | ViewIngredientsButton.propTypes = {
17 | onPress: PropTypes.func,
18 | source: PropTypes.number,
19 | title: PropTypes.string
20 | };
21 |
--------------------------------------------------------------------------------
/src/screens/Ingredient/styles.js:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from 'react-native';
2 | import { RecipeCard } from '../../AppStyles';
3 |
4 | const styles = StyleSheet.create({
5 | mainContainer: {
6 | flex: 1,
7 | backgroundColor: 'white',
8 | },
9 | titleIngredient: {
10 | fontWeight: 'bold',
11 | fontSize: 20
12 | },
13 | photoIngredient: {
14 | width: '100%',
15 | height: 250,
16 | alignSelf: 'center'
17 | },
18 | ingredientInfo: {
19 | color: 'black',
20 | margin: 10,
21 | fontSize: 19,
22 | textAlign: 'left',
23 | fontWeight: 'bold'
24 | },
25 | container: RecipeCard.container,
26 | photo: RecipeCard.photo,
27 | title: RecipeCard.title,
28 | category: RecipeCard.category
29 | });
30 |
31 | export default styles;
--------------------------------------------------------------------------------
/src/components/MenuButton/MenuButton.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { TouchableHighlight, Image, Text, View } from "react-native";
3 | import PropTypes from "prop-types";
4 | import styles from "./styles";
5 |
6 | export default function MenuButton(props) {
7 | const { title, onPress, source } = props;
8 |
9 | return (
10 |
11 |
12 |
13 | {title}
14 |
15 |
16 | );
17 | }
18 |
19 | MenuButton.propTypes = {
20 | onPress: PropTypes.func,
21 | source: PropTypes.number,
22 | title: PropTypes.string,
23 | };
24 |
--------------------------------------------------------------------------------
/.expo/README.md:
--------------------------------------------------------------------------------
1 | > Why do I have a folder named ".expo" in my project?
2 |
3 | The ".expo" folder is created when an Expo project is started using "expo start" command.
4 |
5 | > What does the "packager-info.json" file contain?
6 |
7 | The "packager-info.json" file contains port numbers and process PIDs that are used to serve the application to the mobile device/simulator.
8 |
9 | > What does the "settings.json" file contain?
10 |
11 | The "settings.json" file contains the server configuration that is used to serve the application manifest.
12 |
13 | > Should I commit the ".expo" folder?
14 |
15 | No, you should not share the ".expo" folder. It does not contain any information that is relevant for other developers working on the project, it is specific to your machine.
16 |
17 | Upon project creation, the ".expo" folder is already added to your ".gitignore" file.
18 |
--------------------------------------------------------------------------------
/src/screens/Search/styles.js:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from "react-native";
2 | import { RecipeCard } from "../../AppStyles";
3 |
4 | const styles = StyleSheet.create({
5 | container: RecipeCard.container,
6 | photo: RecipeCard.photo,
7 | title: RecipeCard.title,
8 | category: RecipeCard.category,
9 | btnIcon: {
10 | height: 14,
11 | width: 14,
12 | },
13 | searchContainer: {
14 | flexDirection: "row",
15 | alignItems: "center",
16 | backgroundColor: "#EDEDED",
17 | borderRadius: 10,
18 | width: 250,
19 | justifyContent: "space-around"
20 | },
21 | searchIcon: {
22 | width: 20,
23 | height: 20,
24 | tintColor: 'grey'
25 | },
26 | searchInput: {
27 | backgroundColor: "#EDEDED",
28 | color: "black",
29 | width: 180,
30 | height: 50,
31 | }
32 | });
33 |
34 | export default styles;
35 |
--------------------------------------------------------------------------------
/src/screens/Categories/styles.js:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from 'react-native';
2 |
3 | const styles = StyleSheet.create({
4 | categoriesItemContainer: {
5 | flex: 1,
6 | margin: 10,
7 | justifyContent: 'center',
8 | alignItems: 'center',
9 | height: 215,
10 | borderColor: '#cccccc',
11 | borderWidth: 0.5,
12 | borderRadius: 20,
13 | },
14 | categoriesPhoto: {
15 | width: '100%',
16 | height: 155,
17 | borderRadius: 20,
18 | borderBottomLeftRadius: 0,
19 | borderBottomRightRadius: 0,
20 | shadowColor: 'blue',
21 | shadowOffset: {
22 | width: 0,
23 | height: 3
24 | },
25 | shadowRadius: 5,
26 | shadowOpacity: 1.0,
27 | elevation: 3
28 | },
29 | categoriesName: {
30 | flex: 1,
31 | fontSize: 20,
32 | fontWeight: 'bold',
33 | textAlign: 'center',
34 | color: '#333333',
35 | marginTop: 8
36 | },
37 | categoriesInfo: {
38 | marginTop: 3,
39 | marginBottom: 5
40 | }
41 | });
42 |
43 | export default styles;
44 |
--------------------------------------------------------------------------------
/src/screens/IngredientsDetails/styles.js:
--------------------------------------------------------------------------------
1 | import { StyleSheet, Dimensions } from 'react-native';
2 | // screen sizing
3 | const { width, height } = Dimensions.get('window');
4 | // orientation must fixed
5 | const SCREEN_WIDTH = width < height ? width : height;
6 |
7 | const numColumns = 3;
8 | // item size
9 | const RECIPE_ITEM_HEIGHT = 100;
10 | const RECIPE_ITEM_OFFSET = 10;
11 | const RECIPE_ITEM_MARGIN = RECIPE_ITEM_OFFSET * 2;
12 |
13 | const styles = StyleSheet.create({
14 | container: {
15 | flex: 1,
16 | alignItems: 'center',
17 | margin: RECIPE_ITEM_OFFSET,
18 | marginTop: 30,
19 | width: (SCREEN_WIDTH - RECIPE_ITEM_MARGIN) / numColumns - RECIPE_ITEM_OFFSET,
20 | height: RECIPE_ITEM_HEIGHT + 60
21 | },
22 | title: {
23 | margin: 10,
24 | marginBottom: 5,
25 | color: 'black',
26 | fontSize: 13,
27 | textAlign: 'center'
28 | },
29 | photo: {
30 | width: (SCREEN_WIDTH - RECIPE_ITEM_MARGIN) / numColumns - RECIPE_ITEM_OFFSET,
31 | height: RECIPE_ITEM_HEIGHT,
32 | borderRadius: 60
33 | }
34 | });
35 |
36 | export default styles;
37 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "expo": {
3 | "name": "Instafood",
4 | "slug": "instafood-recipes-app",
5 | "description": "React Native Recipes App Demo. Download source code for free at https://www.instamobile.io . You can also check out the Swift version at https://www.iosapptemplates.com and the Kotlin version at https://www.instakotlin.com .",
6 | "privacy": "public",
7 | "version": "1.0.0",
8 | "orientation": "portrait",
9 | "icon": "./assets/icon.png",
10 | "userInterfaceStyle": "light",
11 | "splash": {
12 | "image": "./assets/splash.png",
13 | "resizeMode": "cover",
14 | "backgroundColor": "#ffffff"
15 | },
16 | "updates": {
17 | "fallbackToCacheTimeout": 0
18 | },
19 | "assetBundlePatterns": [
20 | "**/*"
21 | ],
22 | "ios": {
23 | "supportsTablet": true
24 | },
25 | "android": {
26 | "adaptiveIcon": {
27 | "foregroundImage": "./assets/adaptive-icon.png",
28 | "backgroundColor": "#FFFFFF"
29 | }
30 | },
31 | "web": {
32 | "favicon": "./assets/favicon.png"
33 | },
34 | "newArchEnabled": true
35 | }
36 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Instamobile
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "instafood",
3 | "version": "1.0.0",
4 | "main": "node_modules/expo/AppEntry.js",
5 | "scripts": {
6 | "start": "expo start",
7 | "android": "expo start --android",
8 | "ios": "expo start --ios",
9 | "web": "expo start --web"
10 | },
11 | "dependencies": {
12 | "@react-native-community/cli-server-api": "15.1.0",
13 | "@react-navigation/drawer": "7.0.0",
14 | "@react-navigation/native": "7.0.0",
15 | "@react-navigation/stack": "7.0.0",
16 | "expo": "~52.0.0",
17 | "expo-status-bar": "~2.0.0",
18 | "react": "18.3.1",
19 | "react-native": "0.76.9",
20 | "react-native-gesture-handler": "~2.20.0",
21 | "react-native-reanimated": "~3.16.0",
22 | "react-native-reanimated-carousel": "4.0.0-alpha.12",
23 | "react-native-safe-area-context": "~4.12.0",
24 | "react-native-screens": "~4.4.0"
25 | },
26 | "devDependencies": {
27 | "@babel/core": "^7.26.0",
28 | "@babel/preset-flow": "^7.25.9"
29 | },
30 | "private": true,
31 | "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
32 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (https://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # TypeScript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | # next.js build output
61 | .next
62 | .expo/packager-info.json
63 | .expo/settings.json
64 | package-lock.json
65 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Recipes App in React Native
2 |
3 |
4 |
5 | Download this beautiful free React Native starter kit, featuring a recipes app, to bootstrap your mobile app development. Learn React Native by working on a real project. Get familiar with various native components, navigation, redux and more.
6 |
7 | ## Getting Started
8 |
9 | To run the app, simply run
10 |
11 | ```yarn install && expo start```
12 |
13 | And scan the QR code in the Expo client app.
14 |
15 | ## Expo Demo
16 |
17 |
18 |
19 | ## Features
20 |
21 | - Recipes List
22 | - Categories
23 | - Ingredients
24 | - Recipes Details Screen
25 | - Photo Gallery
26 | - Detailed Description
27 | - Ingredients button
28 | - Ingredients List
29 | - Recipes by Ingredient
30 | - Search
31 | - Drawer Menu
32 | - Navigation Bar
33 | - Beautiful UI Design Kit
34 | - Compatible with Expo
35 | - Highly modularized codebase
36 |
37 | Coded with 💖💖💖 by Instamobile, Instaflutter. and Instakotlin.
38 |
--------------------------------------------------------------------------------
/src/AppStyles.js:
--------------------------------------------------------------------------------
1 | import { StyleSheet, Dimensions } from 'react-native';
2 |
3 | // screen sizing
4 | const { width, height } = Dimensions.get('window');
5 | // orientation must fixed
6 | const SCREEN_WIDTH = width < height ? width : height;
7 |
8 | const recipeNumColums = 2;
9 | // item size
10 | const RECIPE_ITEM_HEIGHT = 150;
11 | const RECIPE_ITEM_MARGIN = 20;
12 |
13 | // 2 photos per width
14 | export const RecipeCard = StyleSheet.create({
15 | container: {
16 | flex: 1,
17 | justifyContent: 'center',
18 | alignItems: 'center',
19 | marginLeft: RECIPE_ITEM_MARGIN,
20 | marginTop: 20,
21 | width: (SCREEN_WIDTH - (recipeNumColums + 1) * RECIPE_ITEM_MARGIN) / recipeNumColums,
22 | height: RECIPE_ITEM_HEIGHT + 75,
23 | borderColor: '#cccccc',
24 | borderWidth: 0.5,
25 | borderRadius: 15
26 | },
27 | photo: {
28 | width: (SCREEN_WIDTH - (recipeNumColums + 1) * RECIPE_ITEM_MARGIN) / recipeNumColums,
29 | height: RECIPE_ITEM_HEIGHT,
30 | borderRadius: 15,
31 | borderBottomLeftRadius: 0,
32 | borderBottomRightRadius: 0
33 | },
34 | title: {
35 | flex: 1,
36 | fontSize: 17,
37 | fontWeight: 'bold',
38 | textAlign: 'center',
39 | color: '#444444',
40 | marginTop: 3,
41 | marginRight: 5,
42 | marginLeft: 5,
43 | },
44 | category: {
45 | marginTop: 5,
46 | marginBottom: 5
47 | }
48 | });
49 |
--------------------------------------------------------------------------------
/src/screens/RecipesList/RecipesListScreen.js:
--------------------------------------------------------------------------------
1 | import React, { useLayoutEffect } from "react";
2 | import { FlatList, Text, View, TouchableHighlight, Image } from "react-native";
3 | import styles from "./styles";
4 | import { getRecipes, getCategoryName } from "../../data/MockDataAPI";
5 |
6 | export default function RecipesListScreen(props) {
7 | const { navigation, route } = props;
8 |
9 | const item = route?.params?.category;
10 | const recipesArray = getRecipes(item.id);
11 |
12 | useLayoutEffect(() => {
13 | navigation.setOptions({
14 | title: route.params?.title,
15 | headerRight: () => ,
16 | });
17 | }, []);
18 |
19 | const onPressRecipe = (item) => {
20 | navigation.navigate("Recipe", { item });
21 | };
22 |
23 | const renderRecipes = ({ item }) => (
24 | onPressRecipe(item)}>
25 |
26 |
27 | {item.title}
28 | {getCategoryName(item.categoryId)}
29 |
30 |
31 | );
32 |
33 | return (
34 |
35 | `${item.recipeId}`} />
36 |
37 | );
38 | }
39 |
--------------------------------------------------------------------------------
/src/screens/DrawerContainer/DrawerContainer.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { View } from "react-native";
3 | import PropTypes from "prop-types";
4 | import styles from "./styles";
5 | import MenuButton from "../../components/MenuButton/MenuButton";
6 |
7 | export default function DrawerContainer(props) {
8 | const { navigation } = props;
9 | return (
10 |
11 |
12 | {
16 | navigation.navigate("Main", { screen: "Home" });
17 | navigation.closeDrawer();
18 | }}
19 | />
20 | {
24 | navigation.navigate("Main", { screen: "Categories" });
25 | navigation.closeDrawer();
26 | }}
27 | />
28 | {
32 | navigation.navigate("Main", { screen: "Search" });
33 | navigation.closeDrawer();
34 | }}
35 | />
36 |
37 |
38 | );
39 | }
40 |
41 | DrawerContainer.propTypes = {
42 | navigation: PropTypes.shape({
43 | navigate: PropTypes.func.isRequired,
44 | closeDrawer: PropTypes.func.isRequired,
45 | }),
46 | };
--------------------------------------------------------------------------------
/src/screens/Home/HomeScreen.js:
--------------------------------------------------------------------------------
1 | import React, { useLayoutEffect } from "react";
2 | import { FlatList, Text, View, TouchableHighlight, Image } from "react-native";
3 | import styles from "./styles";
4 | import { recipes } from "../../data/dataArrays";
5 | import MenuImage from "../../components/MenuImage/MenuImage";
6 | import { getCategoryName } from "../../data/MockDataAPI";
7 |
8 | export default function HomeScreen(props) {
9 | const { navigation } = props;
10 |
11 | useLayoutEffect(() => {
12 | navigation.setOptions({
13 | headerLeft: () => (
14 | {
16 | navigation.openDrawer();
17 | }}
18 | />
19 | ),
20 | headerRight: () => ,
21 | });
22 | }, []);
23 |
24 | const onPressRecipe = (item) => {
25 | navigation.navigate("Recipe", { item });
26 | };
27 |
28 | const renderRecipes = ({ item }) => (
29 | onPressRecipe(item)}>
30 |
31 |
32 | {item.title}
33 | {getCategoryName(item.categoryId)}
34 |
35 |
36 | );
37 |
38 | return (
39 |
40 | `${item.recipeId}`} />
41 |
42 | );
43 | }
44 |
--------------------------------------------------------------------------------
/src/screens/IngredientsDetails/IngredientsDetailsScreen.js:
--------------------------------------------------------------------------------
1 | import React, { useLayoutEffect } from "react";
2 | import { FlatList, Text, View, Image, TouchableHighlight } from "react-native";
3 | import styles from "./styles";
4 | import { getIngredientName, getAllIngredients } from "../../data/MockDataAPI";
5 |
6 | export default function IngredientsDetailsScreen(props) {
7 | const { navigation, route } = props;
8 |
9 | const item = route.params?.ingredients;
10 | const ingredientsArray = getAllIngredients(item);
11 |
12 | useLayoutEffect(() => {
13 | navigation.setOptions({
14 | title: route.params?.title,
15 | headerTitleStyle: {
16 | fontSize: 16,
17 | },
18 | });
19 | }, []);
20 |
21 | const onPressIngredient = (item) => {
22 | let name = getIngredientName(item.ingredientId);
23 | let ingredient = item.ingredientId;
24 | navigation.navigate("Ingredient", { ingredient, name });
25 | };
26 |
27 | const renderIngredient = ({ item, index }) => (
28 | onPressIngredient(item[0])}
31 | >
32 |
33 |
34 | {item[0].name}
35 | {item[1]}
36 |
37 |
38 | );
39 |
40 | return (
41 |
42 | `${item[0].ingredientId}_${index}`}
49 | />
50 |
51 | );
52 | }
--------------------------------------------------------------------------------
/src/screens/Categories/CategoriesScreen.js:
--------------------------------------------------------------------------------
1 | import React, { useLayoutEffect } from "react";
2 | import { FlatList, Text, View, Image, TouchableHighlight } from "react-native";
3 | import styles from "./styles";
4 | import { categories } from "../../data/dataArrays";
5 | import { getNumberOfRecipes } from "../../data/MockDataAPI";
6 | import MenuImage from "../../components/MenuImage/MenuImage";
7 |
8 | export default function CategoriesScreen(props) {
9 | const { navigation } = props;
10 |
11 | useLayoutEffect(() => {
12 | navigation.setOptions({
13 | headerTitleStyle: {
14 | fontWeight: "bold",
15 | textAlign: "center",
16 | alignSelf: "center",
17 | flex: 1,
18 | },
19 | headerLeft: () => (
20 | {
22 | navigation.openDrawer();
23 | }}
24 | />
25 | ),
26 | headerRight: () => ,
27 | });
28 | }, []);
29 |
30 | const onPressCategory = (item) => {
31 | const title = item.name;
32 | const category = item;
33 | navigation.navigate("RecipesList", { category, title });
34 | };
35 |
36 | const renderCategory = ({ item }) => (
37 | onPressCategory(item)}>
38 |
39 |
40 | {item.name}
41 | {getNumberOfRecipes(item.id)} recipes
42 |
43 |
44 | );
45 |
46 | return (
47 |
48 | `${item.id}`} />
49 |
50 | );
51 | }
52 |
--------------------------------------------------------------------------------
/src/screens/Ingredient/IngredientScreen.js:
--------------------------------------------------------------------------------
1 | import React, { useLayoutEffect } from "react";
2 | import { FlatList, Text, View, Image, TouchableHighlight } from "react-native";
3 | import styles from "./styles";
4 | import { getIngredientUrl, getRecipesByIngredient, getCategoryName } from "../../data/MockDataAPI";
5 |
6 | export default function IngredientScreen(props) {
7 | const { navigation, route } = props;
8 |
9 | const ingredientId = route.params?.ingredient;
10 | const ingredientUrl = getIngredientUrl(ingredientId);
11 | const ingredientName = route.params?.name;
12 |
13 | useLayoutEffect(() => {
14 | navigation.setOptions({
15 | title: route.params?.name,
16 | });
17 | }, []);
18 |
19 | const onPressRecipe = (item) => {
20 | navigation.navigate("Recipe", { item });
21 | };
22 |
23 | const renderRecipes = ({ item }) => (
24 | onPressRecipe(item)}>
25 |
26 |
27 | {item.title}
28 | {getCategoryName(item.categoryId)}
29 |
30 |
31 | );
32 |
33 | const ListHeader = () => (
34 | <>
35 |
36 |
37 |
38 | Recipes with {ingredientName}:
39 | >
40 | );
41 |
42 | return (
43 |
44 | `${item.recipeId}`}
52 | />
53 |
54 | );
55 | }
--------------------------------------------------------------------------------
/src/screens/Recipe/styles.js:
--------------------------------------------------------------------------------
1 | import { StyleSheet, Dimensions } from 'react-native';
2 |
3 | const { width: viewportWidth } = Dimensions.get('window');
4 |
5 | const styles = StyleSheet.create({
6 | container: {
7 | backgroundColor: 'white',
8 | flex: 1
9 | },
10 | carouselContainer: {
11 | height: 250
12 | },
13 | carousel: {},
14 |
15 | image: {
16 | ...StyleSheet.absoluteFillObject,
17 | width: '100%',
18 | height: 250
19 | },
20 | imageContainer: {
21 | flex: 1,
22 | justifyContent: 'center',
23 | width: viewportWidth,
24 | height: 250
25 | },
26 | paginationContainer: {
27 | flex: 1,
28 | position: 'absolute',
29 | alignSelf: 'center',
30 | paddingVertical: 8,
31 | marginTop: 200,
32 | gap: 20,
33 | },
34 | paginationDot: {
35 | width: 8,
36 | height: 8,
37 | borderRadius: 4,
38 | marginHorizontal: 0,
39 | backgroundColor: "rgba(255,255,255,0.2)",
40 | },
41 | infoRecipeContainer: {
42 | flex: 1,
43 | margin: 25,
44 | marginTop: 20,
45 | justifyContent: 'center',
46 | alignItems: 'center'
47 | },
48 | infoContainer: {
49 | flex: 1,
50 | flexDirection: 'row',
51 | alignItems: 'center',
52 | justifyContent: 'flex-start',
53 | },
54 | buttonContainer: {
55 | flex: 1,
56 | flexDirection: 'row',
57 | alignItems: 'center',
58 | justifyContent: 'flex-start',
59 | },
60 | infoPhoto: {
61 | height: 20,
62 | width: 20,
63 | marginRight: 0
64 | },
65 | infoRecipe: {
66 | fontSize: 14,
67 | fontWeight: 'bold',
68 | marginLeft: 5,
69 | },
70 | category: {
71 | fontSize: 14,
72 | fontWeight: 'bold',
73 | margin: 10,
74 | color: '#2cd18a'
75 | },
76 | infoDescriptionRecipe: {
77 | textAlign: 'left',
78 | fontSize: 16,
79 | marginTop: 30,
80 | margin: 15
81 | },
82 | infoRecipeName: {
83 | fontSize: 28,
84 | margin: 10,
85 | fontWeight: 'bold',
86 | color: 'black',
87 | textAlign: 'center'
88 | }
89 | });
90 |
91 | export default styles;
92 |
--------------------------------------------------------------------------------
/src/navigations/AppNavigation.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { createStackNavigator } from '@react-navigation/stack';
3 | import { NavigationContainer } from '@react-navigation/native';
4 | import { createDrawerNavigator } from '@react-navigation/drawer';
5 | import HomeScreen from '../screens/Home/HomeScreen';
6 | import CategoriesScreen from '../screens/Categories/CategoriesScreen';
7 | import RecipeScreen from '../screens/Recipe/RecipeScreen';
8 | import RecipesListScreen from '../screens/RecipesList/RecipesListScreen';
9 | import DrawerContainer from '../screens/DrawerContainer/DrawerContainer';
10 | import IngredientScreen from '../screens/Ingredient/IngredientScreen';
11 | import SearchScreen from '../screens/Search/SearchScreen';
12 | import IngredientsDetailsScreen from '../screens/IngredientsDetails/IngredientsDetailsScreen';
13 |
14 | const Stack = createStackNavigator();
15 |
16 | function MainNavigator() {
17 | return (
18 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | );
35 | }
36 |
37 | const Drawer = createDrawerNavigator();
38 |
39 | function DrawerStack() {
40 | return (
41 | }
49 | >
50 |
51 |
52 | );
53 | }
54 |
55 | export default function AppContainer() {
56 | return (
57 |
58 |
59 |
60 | );
61 | }
62 |
63 | console.disableYellowBox = true;
--------------------------------------------------------------------------------
/src/screens/Search/SearchScreen.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useLayoutEffect, useState } from "react";
2 | import { FlatList, Text, View, Image, TouchableHighlight, Pressable } from "react-native";
3 | import styles from "./styles";
4 | import MenuImage from "../../components/MenuImage/MenuImage";
5 | import { getCategoryName, getRecipesByRecipeName, getRecipesByCategoryName, getRecipesByIngredientName } from "../../data/MockDataAPI";
6 | import { TextInput } from "react-native-gesture-handler";
7 |
8 | export default function SearchScreen(props) {
9 | const { navigation } = props;
10 |
11 | const [value, setValue] = useState("");
12 | const [data, setData] = useState([]);
13 |
14 | useLayoutEffect(() => {
15 | navigation.setOptions({
16 | headerLeft: () => (
17 | {
19 | navigation.openDrawer();
20 | }}
21 | />
22 | ),
23 | headerTitle: () => (
24 |
25 |
26 |
31 | handleSearch("")}>
32 |
33 |
34 |
35 | ),
36 | headerRight: () => ,
37 | });
38 | }, [value]);
39 |
40 | useEffect(() => {}, [value]);
41 |
42 | const handleSearch = (text) => {
43 | setValue(text);
44 | var recipeArray1 = getRecipesByRecipeName(text);
45 | var recipeArray2 = getRecipesByCategoryName(text);
46 | var recipeArray3 = getRecipesByIngredientName(text);
47 | var aux = recipeArray1.concat(recipeArray2);
48 | var recipeArray = [...new Set(aux)];
49 |
50 | if (text == "") {
51 | setData([]);
52 | } else {
53 | setData(recipeArray);
54 | }
55 | };
56 |
57 | const onPressRecipe = (item) => {
58 | navigation.navigate("Recipe", { item });
59 | };
60 |
61 | const renderRecipes = ({ item }) => (
62 | onPressRecipe(item)}>
63 |
64 |
65 | {item.title}
66 | {getCategoryName(item.categoryId)}
67 |
68 |
69 | );
70 |
71 | return (
72 |
73 | `${item.recipeId}`} />
74 |
75 | );
76 | }
77 |
--------------------------------------------------------------------------------
/src/data/MockDataAPI.js:
--------------------------------------------------------------------------------
1 | import { Text } from 'react-native';
2 | import React, { Component } from 'react';
3 | import { recipes, categories, ingredients } from './dataArrays';
4 |
5 | export function getCategoryById(categoryId) {
6 | let category;
7 | categories.map(data => {
8 | if (data.id == categoryId) {
9 | category = data;
10 | }
11 | });
12 | return category;
13 | }
14 |
15 | export function getIngredientName(ingredientID) {
16 | let name;
17 | ingredients.map(data => {
18 | if (data.ingredientId == ingredientID) {
19 | name = data.name;
20 | }
21 | });
22 | return name;
23 | }
24 |
25 | export function getIngredientUrl(ingredientID) {
26 | let url;
27 | ingredients.map(data => {
28 | if (data.ingredientId == ingredientID) {
29 | url = data.photo_url;
30 | }
31 | });
32 | return url;
33 | }
34 |
35 | export function getCategoryName(categoryId) {
36 | let name;
37 | categories.map(data => {
38 | if (data.id == categoryId) {
39 | name = data.name;
40 | }
41 | });
42 | return name;
43 | }
44 |
45 | export function getRecipes(categoryId) {
46 | const recipesArray = [];
47 | recipes.map(data => {
48 | if (data.categoryId == categoryId) {
49 | recipesArray.push(data);
50 | }
51 | });
52 | return recipesArray;
53 | }
54 |
55 | // modifica
56 | export function getRecipesByIngredient(ingredientId) {
57 | const recipesArray = [];
58 | recipes.map(data => {
59 | data.ingredients.map(index => {
60 | if (index[0] == ingredientId) {
61 | recipesArray.push(data);
62 | }
63 | });
64 | });
65 | return recipesArray;
66 | }
67 |
68 | export function getNumberOfRecipes(categoryId) {
69 | let count = 0;
70 | recipes.map(data => {
71 | if (data.categoryId == categoryId) {
72 | count++;
73 | }
74 | });
75 | return count;
76 | }
77 |
78 | export function getAllIngredients(idArray) {
79 | const ingredientsArray = [];
80 | idArray.map(index => {
81 | ingredients.map(data => {
82 | if (data.ingredientId == index[0]) {
83 | ingredientsArray.push([data, index[1]]);
84 | }
85 | });
86 | });
87 | return ingredientsArray;
88 | }
89 |
90 | // functions for search
91 | export function getRecipesByIngredientName(ingredientName) {
92 | const nameUpper = ingredientName.toUpperCase();
93 | const recipesArray = [];
94 | ingredients.map(data => {
95 | if (data.name.toUpperCase().includes(nameUpper)) {
96 | // data.name.yoUpperCase() == nameUpper
97 | const recipes = getRecipesByIngredient(data.ingredientId);
98 | const unique = [...new Set(recipes)];
99 | unique.map(item => {
100 | recipesArray.push(item);
101 | });
102 | }
103 | });
104 | const uniqueArray = [...new Set(recipesArray)];
105 | return uniqueArray;
106 | }
107 |
108 | export function getRecipesByCategoryName(categoryName) {
109 | const nameUpper = categoryName.toUpperCase();
110 | const recipesArray = [];
111 | categories.map(data => {
112 | if (data.name.toUpperCase().includes(nameUpper)) {
113 | const recipes = getRecipes(data.id); // return a vector of recipes
114 | recipes.map(item => {
115 | recipesArray.push(item);
116 | });
117 | }
118 | });
119 | return recipesArray;
120 | }
121 |
122 | export function getRecipesByRecipeName(recipeName) {
123 | const nameUpper = recipeName.toUpperCase();
124 | const recipesArray = [];
125 | recipes.map(data => {
126 | if (data.title.toUpperCase().includes(nameUpper)) {
127 | recipesArray.push(data);
128 | }
129 | });
130 | return recipesArray;
131 | }
132 |
--------------------------------------------------------------------------------
/src/screens/Recipe/RecipeScreen.js:
--------------------------------------------------------------------------------
1 | import React, { useLayoutEffect, useRef, useState } from "react";
2 | import {
3 | ScrollView,
4 | Text,
5 | View,
6 | Image,
7 | Dimensions,
8 | TouchableHighlight,
9 | } from "react-native";
10 | import styles from "./styles";
11 | import { useSharedValue } from 'react-native-reanimated';
12 | import Carousel, { Pagination } from 'react-native-reanimated-carousel';
13 | import {
14 | getIngredientName,
15 | getCategoryName,
16 | getCategoryById,
17 | } from "../../data/MockDataAPI";
18 | import BackButton from "../../components/BackButton/BackButton";
19 | import ViewIngredientsButton from "../../components/ViewIngredientsButton/ViewIngredientsButton";
20 |
21 | const { width: viewportWidth } = Dimensions.get("window");
22 |
23 | export default function RecipeScreen(props) {
24 | const { navigation, route } = props;
25 | const item = route.params?.item;
26 | const category = getCategoryById(item.categoryId);
27 | const title = getCategoryName(category.id);
28 | const slider1Ref = useRef(null)
29 | const progress = useSharedValue(0)
30 |
31 | useLayoutEffect(() => {
32 | navigation.setOptions({
33 | headerTransparent: "true",
34 | headerLeft: () => (
35 | {
37 | navigation.goBack();
38 | }}
39 | />
40 | ),
41 | headerRight: () => ,
42 | });
43 | }, []);
44 |
45 | const renderImage = ({ item }) => (
46 |
47 |
48 |
49 |
50 |
51 | );
52 |
53 | const onPressIngredient = (item) => {
54 | var name = getIngredientName(item);
55 | let ingredient = item;
56 | navigation.navigate("Ingredient", { ingredient, name });
57 | };
58 |
59 |
60 | const onPressPagination = (index) =>
61 | {
62 | slider1Ref.current?.scrollTo({
63 | count: index - progress.value,
64 | animated: true,
65 | })
66 | }
67 |
68 |
69 | return (
70 |
71 |
72 |
73 |
75 | {
76 | slider1Ref.current = c
77 | }}
78 | loop={false}
79 | width={viewportWidth}
80 | height={viewportWidth}
81 | autoPlay={false}
82 | data={item.photosArray}
83 | scrollAnimationDuration={1000}
84 | renderItem={renderImage}
85 | onProgressChange={progress}
86 | />
87 | (
89 |
95 | )}
96 | progress={progress}
97 | data={item.photosArray}
98 | dotStyle={styles.paginationDot}
99 | containerStyle={styles.paginationContainer}
100 | onPress={onPressPagination}
101 | />
102 |
103 |
104 |
105 | {item.title}
106 |
107 |
109 | navigation.navigate("RecipesList", { category, title })
110 | }
111 | >
112 |
113 | {getCategoryName(item.categoryId).toUpperCase()}
114 |
115 |
116 |
117 |
118 |
119 |
123 | {item.time} minutes
124 |
125 |
126 |
127 | {
129 | let ingredients = item.ingredients;
130 | let title = "Ingredients for " + item.title;
131 | navigation.navigate("IngredientsDetails", { ingredients, title });
132 | }}
133 | />
134 |
135 |
136 | {item.description}
137 |
138 |
139 |
140 | );
141 | }
--------------------------------------------------------------------------------
/src/data/dataArrays.js:
--------------------------------------------------------------------------------
1 | export const categories = [
2 | {
3 | id: 3,
4 | name: 'Cookies',
5 | photo_url:
6 | 'https://www.telegraph.co.uk/content/dam/Travel/2019/January/france-food.jpg?imwidth=1400'
7 | },
8 | {
9 | id: 1,
10 | name: 'Mexican Food',
11 | photo_url: 'https://ak1.picdn.net/shutterstock/videos/19498861/thumb/1.jpg'
12 | },
13 | {
14 | id: 2,
15 | name: 'Italian Food',
16 | photo_url:
17 | 'https://images.unsplash.com/photo-1533777324565-a040eb52facd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&w=1000&q=80'
18 | },
19 | {
20 | id: 4,
21 | name: 'Smoothies',
22 | photo_url:
23 | 'https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/still-life-of-three-fresh-smoothies-in-front-of-royalty-free-image-561093647-1544042068.jpg?crop=0.715xw:0.534xh;0.0945xw,0.451xh&resize=768:*'
24 | },
25 | {
26 | id: 0,
27 | name: 'Pizza',
28 | photo_url: 'https://amp.businessinsider.com/images/5c084bf7bde70f4ea53f0436-750-563.jpg'
29 | },
30 | ];
31 |
32 | export const recipes = [
33 | {
34 | recipeId: 122,
35 | categoryId: 3,
36 | title: 'Oatmeal Cookies',
37 | photo_url: 'https://www.texanerin.com/content/uploads/2019/06/nobake-chocolate-cookies-1-650x975.jpg',
38 | photosArray: [
39 | 'https://www.texanerin.com/content/uploads/2019/06/nobake-chocolate-cookies-1-650x975.jpg',
40 | "https://namelymarly.com/wp-content/uploads/2018/04/20180415_Beet_Lasagna_10.jpg",
41 | 'https://advancelocal-adapter-image-uploads.s3.amazonaws.com/image.al.com/home/bama-media/width600/img/news_impact/photo/burger-fijpg-57e7e5907630c2ad.jpg',
42 | 'https://img.thedailybeast.com/image/upload/c_crop,d_placeholder_euli9k,h_1439,w_2560,x_0,y_0/dpr_1.5/c_limit,w_1044/fl_lossy,q_auto/v1492718105/articles/2013/09/24/burger-king-s-new-french-fries-took-ten-years-to-develop/130923-gross-burger-tease_izz59e',
43 | 'https://aht.seriouseats.com/images/2012/02/20120221-193971-fast-food-fries-Burger-King-fries-2.jpg'
44 | ],
45 | time: '15',
46 | ingredients: [[0, '200ml'], [1, '5g'], [2, '300g']],
47 | description:
48 | '-- Start with cleaned and peeled russet potatoes that you have cut into 3/8-inch match sticks. Place in bowl of very cold water: keep rinsing and changing the water until the water is clear; drain thoroughly and dry with paper towels or a clean lint-free kitchen towel.\n\n -- Meanwhile, you preheat your hot oil to 350 degrees F. Place prepared taters in oil and cook about 5 minutes. They will have that blond-tone color to them. \n\n -- Note: Once you add cold potatoes to the hot oil, the temperature of your oil is going to drop - you want it to be somewhere between 330 - 325 degrees F. \n\n -- Remove from oil; drain and cool. Now - either refrigerate until ready to finish cooking, or cool completely and freeze up to 3 months. To freeze properly - place completely cooled fries in single layer on tray and place in freezer until frozen. Then bag them.\n\n -- To finish cooking - preheat your oil to 400* F. Add your cold fries (which will drop the oil temp - which is fine because you want it near the 375 degrees F. temp) and cook a few minutes until done. Lightly salt them and shake well so that the salt distributes well and they are not salty.'
49 | },
50 | {
51 | recipeId: 3,
52 | categoryId: 4,
53 | title: 'Triple Berry Smoothie',
54 | photo_url:
55 | 'https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/delish-how-to-make-a-smoothie-horizontal-1542310071.png?crop=0.803xw:0.923xh;0.116xw,0.00510xh&resize=768:*',
56 | photosArray: [
57 | 'https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/delish-how-to-make-a-smoothie-horizontal-1542310071.png?crop=0.803xw:0.923xh;0.116xw,0.00510xh&resize=768:*',
58 | 'https://www.vitamix.com/media/other/images/xVitamix-Triple-Berry-Smoothie-square-crop__1.jpg.pagespeed.ic.OgTC3ILD3R.jpg',
59 | 'http://images.media-allrecipes.com/userphotos/960x960/3798204.jpg',
60 | 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTrzui8MM6W66I29VZwVvcjpGv99JW3O1owgupc3KwB65rhAyrZ'
61 | ],
62 | time: '10',
63 | ingredients: [
64 | [59, '1'],
65 | [60, '1/2 lbs'],
66 | [61, '1/2 liters'],
67 | ],
68 | description: 'In a blender, combine all ingredients and blend until smooth. Then divide between 2 cups and top with blackberries, if desired.'
69 | },
70 | {
71 | recipeId: 2,
72 | categoryId: 3,
73 | title: 'Vegan Cookies',
74 | photo_url: 'https://www.texanerin.com/content/uploads/2018/06/no-bake-lactation-cookies-1-650x975.jpg',
75 | photosArray: [
76 | 'https://www.texanerin.com/content/uploads/2018/06/no-bake-lactation-cookies-1-650x975.jpg',
77 | 'https://ichef.bbci.co.uk/news/660/cpsprodpb/B2C0/production/_106106754_vegnuggets976.jpg',
78 | 'https://pixel.nymag.com/imgs/daily/grub/2017/11/22/22-mcds-chicken-tenders.w330.h330.jpg',
79 | 'https://imagesvc.meredithcorp.io/v3/mm/image?url=https%3A%2F%2Fcdn-img.health.com%2Fsites%2Fdefault%2Ffiles%2Fstyles%2Flarge_16_9%2Fpublic%2Fstyles%2Fmain%2Fpublic%2Fgettyimages-508510211.jpg%3Fitok%3Dh-Uryi8r&w=400&c=sc&poi=face&q=85'
80 | ],
81 | time: '30',
82 | ingredients: [
83 | [0, '2 quarts'],
84 | [16, '1'],
85 | [12, '1 cup'],
86 | [18, '1 cup'],
87 | [19, '1 teaspoon'],
88 | [1, '2 teaspoons'],
89 | [4, '1/4 teaspoons'],
90 | [7, '1/8 teaspoons'],
91 | [20, '1/2 teaspoons'],
92 | [21, '4']
93 | ],
94 | description:
95 | '-- Beat the egg and then combine it with water in a bowl. Stir. Combine the flour, salt, MSG, pepper, onion powder and garlic powder in a gallon size zip lock bag. Pound each of the breast filets until about 1/4-inch thick. Then cut into bite sized pieces. Coat each piece with the flour mixture by shaking in the zip lock bag. Remove and coat in the egg mixture. Then coat in the flour mixture again. Shake to coat. Deep fry at 375 degrees for 10-12 minutes, until browned and crispy.'
96 | },
97 | {
98 | recipeId: 3,
99 | categoryId: 3,
100 | title: 'Pumpkin Spice Cookies',
101 | photo_url:
102 | 'https://www.texanerin.com/content/uploads/2018/11/pumpkin-spice-cookies-4-650x975.jpg',
103 | photosArray: [
104 | 'https://www.texanerin.com/content/uploads/2018/11/pumpkin-spice-cookies-4-650x975.jpg',
105 | 'https://cdn.junglecreations.com/wp/junglecms/2018/07/4164c5bd-wide-thumbnail.jpg',
106 | 'https://pinchofyum.com/wp-content/uploads/Crunchwrap-Inside.jpg',
107 | 'https://monsonmadethis.com/wp-content/uploads/2017/10/IMG_20171015_161017_025-e1533869302263.jpg'
108 | ],
109 | time: '45',
110 | ingredients: [
111 | [0, '2 tablespoons'],
112 | [22, '1/2'],
113 | [23, '2 tablespoons'],
114 | [7, '2 cloves'],
115 | [3, '1 teaspoon'],
116 | [24, '1 tablespoon'],
117 | [25, '1 lb'],
118 | [1, '2 teaspoons'],
119 | [4, '2 teaspoons'],
120 | [26, '15 oz'],
121 | [27, '8'],
122 | [28, '2'],
123 | [29, '1 cup']
124 | ],
125 | description:
126 | '-- In a medium pot over medium heat, heat 1 tablespoon oil. Add onion and cook until soft, 5 minutes. Add garlic and cook until fragrant, 1 minute more. Add tomato paste and stir to coat onion and garlic. Add ground beef and cook, breaking up meat with a wooden spoon, until no longer pink, 6 minutes. Drain fat.\n\n -- Return beef to pot and season with chili powder, paprika, salt, and pepper. Add tomato sauce and kidney beans. Bring to a boil, then reduce heat and let simmer 15 minutes. Add some chili to center of each tortilla, leaving room to fold in edges. Top with Fritos, then cheddar. Fold edges of tortillas toward the center, creating pleats. Invert Crunchwraps so pleats are on the bottom and stay together.\n\n -- In medium skillet over medium heat, heat remaining tablespoon oil. Add a Crunchwrap seam side down and cook until tortilla is golden, 3 to 5 minutes per side. Repeat with remaining Crunchwraps'
127 | },
128 | {
129 | recipeId: 1,
130 | categoryId: 3,
131 | title: 'Brownies',
132 | photo_url: 'https://www.texanerin.com/content/uploads/2018/01/coconut-flour-brownies-1-650x975.jpg',
133 | photosArray: [
134 | 'https://www.texanerin.com/content/uploads/2018/01/coconut-flour-brownies-1-650x975.jpg',
135 | 'https://images-gmi-pmc.edge-generalmills.com/6fbc6859-e2b1-499d-b0fa-ada600c9cc3f.jpg',
136 | 'http://www.recipe4living.com/assets/itemimages/400/400/3/83c29ac7418067c2e74f31c8abdd5a43_477607049.jpg',
137 | 'https://www.franchisechatter.com/wp-content/uploads/2014/08/KFC-Photo-by-James.jpg'
138 | ],
139 | time: '30',
140 | ingredients: [
141 | [1, '2 tablespoons'],
142 | [3, '1 tablespoon'],
143 | [4, '1 teaspoon'],
144 | [5, '1/2 teaspoons'],
145 | [6, '1/2 teaspoons'],
146 | [7, '1/2 teaspoons'],
147 | [8, '1/2 teaspoons'],
148 | [9, '1/2 teaspoons'],
149 | [10, '1/2 teaspoons'],
150 | [11, '1/2 teaspoons'],
151 | [12, '1/2 cups'],
152 | [13, '1 tablespoon'],
153 | [14, '1 tablespoon'],
154 | [15, '2 breasts, 2 thighs, 2 drumsticks, 2 wings'],
155 | [16, '1'],
156 | [17, '2 quarts']
157 | ],
158 | description:
159 | '-- Preheat fryer to 350°F. Thoroughly mix together all spices. Combine spices with flour, brown sugar and salt. Dip chicken pieces in egg white to lightly coat them, then transfer to flour mixture. Turn a few times and make sure the flour mix is really stuck to the chicken.\n\n -- Repeat with all the chicken pieces. Let chicken pieces rest for 5 minutes so crust has a chance to dry a bit. Fry chicken in batches. Breasts and wings should take 12-14 minutes, and legs and thighs will need a few more minutes. Chicken pieces are done when a meat thermometer inserted into the thickest part reads 165°F. Let chicken drain on a few paper towels when it comes out of the fryer. Serve hot.'
160 | },
161 | {
162 | recipeId: 4,
163 | categoryId: 1,
164 | title: 'Perfect Fish Tacos',
165 | photo_url: 'https://hips.hearstapps.com/hmg-prod/images/190307-fish-tacos-112-1553283299.jpg',
166 | photosArray: [
167 | 'http://d2814mmsvlryp1.cloudfront.net/wp-content/uploads/2014/04/WGC-Fish-Tacos-copy-2.jpg',
168 | 'https://thecozyapron.com/wp-content/uploads/2018/03/baja-fish-tacos_thecozyapron_1.jpg',
169 | 'https://www.simplyrecipes.com/wp-content/uploads/2017/06/2017-07-22-FishTacos-6.jpg'
170 | ],
171 | time: '35',
172 | ingredients: [
173 | [30, 'jucie of 1 '],
174 | [24, '2 teaspoons'],
175 | [0, '3 tablespoons'],
176 | [3, '1 teaspoon'],
177 | [31, '1/2 teaspoons'],
178 | [32, '1/2 teaspoons'],
179 | [4, '2 teaspoons'],
180 | [33, '1/2 lb'],
181 | [27, '8'],
182 | [14, '2 teasponns'],
183 | [34, '1']
184 | ],
185 | description:
186 | '-- In a medium shallow bowl, whisk together olive oil, lime juice, paprika, chili powder, cumin, and cayenne. Add cod, tossing until evenly coated. Let marinate 15 minutes. Meanwhile, make slaw: In a large bowl, whisk together mayonnaise, lime juice, cilantro, and honey. Stir in cabbage, corn, and jalapeño. Season with salt and pepper.\n\n -- In a large nonstick skillet over medium-high heat, heat vegetable oil. Remove cod from marinade and season both sides of each filet with salt and pepper. Add fish flesh side-down. Cook until opaque and cooked through, 3 to 5 minutes per side.\n\n -- Let rest 5 minutes before flaking with a fork. Assemble tacos: Serve fish over grilled tortillas with corn slaw and avocado. Squeeze lime juice on top and garnish with sour cream. '
187 | },
188 | {
189 | recipeId: 5,
190 | categoryId: 1,
191 | title: 'Chicken Fajitas',
192 | photo_url:
193 | 'https://tmbidigitalassetsazure.blob.core.windows.net/secure/RMS/attachments/37/1200x1200/Flavorful-Chicken-Fajitas_EXPS_GHBZ18_12540_B08_15_8b.jpg',
194 | photosArray: [
195 | 'https://dadwithapan.com/wp-content/uploads/2015/07/Spicy-Chicken-Fajitas-22-1200x480.jpg',
196 | 'https://3.bp.blogspot.com/-X-dHj7ORF9Q/XH4ssgTuSZI/AAAAAAAAEig/E46HP9wCfdsvyJFcMTX30cw-ICep8lF9ACHMYCw/s1600/chicken-fajitas-mexican-food-id-149559-buzzerg.jpg',
197 | 'https://cdn-image.foodandwine.com/sites/default/files/styles/medium_2x/public/201403-xl-chipotle-chicken-fajitas.jpg?itok=ghVcI5SQ'
198 | ],
199 | time: 35,
200 | ingredients: [
201 | [9, '1/2 teaspoons'],
202 | [0, '4 tablespoons'],
203 | [1, '1/2 teaspoons'],
204 | [30, '2 tablespoons'],
205 | [31, '1 teaspoon'],
206 | [7, '1 teaspoon'],
207 | [24, '1/2 teaspoons'],
208 | [3, '1/2 teaspoons'],
209 | [21, '1 pound'],
210 | [22, '1/2 cup'],
211 | [27, '6'],
212 | [36, '4'],
213 | [37, '1/2'],
214 | [38, '1/2']
215 | ],
216 | description:
217 | '-- In a large bowl, combine 2 tablespoons oil, lemon juice and seasonings; add the chicken. Turn to coat; cover. Refrigerate for 1-4 hours In a large skillet, saute peppers and onions in remaining oil until crisp-tender. Remove and keep warm. Drain chicken, discarding marinade. In the same skillet, cook chicken over medium-high heat for 5-6 minutes or until no longer pink.\n\n -- Return pepper mixture to pan; heat through. Spoon filling down the center of tortillas; fold in half. Serve with toppings as desired.'
218 | },
219 | {
220 | recipeId: 6,
221 | categoryId: 2,
222 | title: 'Buffalo Pizza',
223 | photo_url:
224 | 'https://images.unsplash.com/photo-1513104890138-7c749659a591?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&w=1000&q=80',
225 | photosArray: [
226 | 'https://www.tablefortwoblog.com/wp-content/uploads/2019/01/buffalo-chicken-pizza-recipe-photos-tablefortwoblog-3-500x500.jpg',
227 | 'http://pizzachoicema.com/wp-content/uploads/2018/08/Buffalo-Chicken-Pizza.jpg',
228 | 'https://static1.squarespace.com/static/565bb41ae4b0509ba9fdf769/t/5b9a8e80aa4a998b0be0fcf4/1536855690622/pizza.gif'
229 | ],
230 | time: 50,
231 | ingredients: [
232 | [39, '1 lb'],
233 | [40, '1 cup'],
234 | [41, '1/2 cup'],
235 | [42, '1/4 cup'],
236 | [43, '2 tablespoons'],
237 | [44, '1/2 cup'],
238 | [7, '1/4 teaspoons'],
239 | [5, '1/4 teaspoons'],
240 | [30, '1/4 teaspoons'],
241 | [45, '2 oz'],
242 | [12, 'for dusting'],
243 | [4, '1/2 teaspoons'],
244 | [47, '2'],
245 | [46, '9 oz']
246 | ],
247 | description:
248 | '-- Place a rack in upper third of oven. Place a large cast-iron skillet on rack and preheat oven to 500° (or as high as your oven will go). Place pizza dough in a large bowl, pour a little oil over, and turn to coat. Cover bowl with plastic and let dough proof at room temperature while pan and oven heat up.\n\n -- Meanwhile, cook hot sauce, marinara sauce, and butter in a medium saucepan over medium heat, stirring occasionally, until butter is melted. Stir in cream, reduce heat to low, and simmer, stirring occasionally, until slightly thickened and warmed through, about 10 minutes. Heat 1 Tbsp. oil in a large skillet over medium-high. Add chicken, toss to coat, then add ¼ cup Buffalo sauce.\n\n -- Cook chicken, tossing occasionally, until heated through, about 2 minutes. Reduce heat and simmer, stirring often, until chicken is well coated and sauce is slightly thickened, about 5 minutes. Meanwhile, whisk yogurt, lemon juice, celery salt, garlic powder, ¼ cup blue cheese, ½ tsp. pepper, and 2 Tbsp. water in a small bowl, adding more water if sauce seems too thick (it should be pourable); set aside.\n\n -- Turn out dough onto a lightly floured work surface. Shape with your hands into a round that’s slightly larger than the cast-iron skillet you’re using. Take hot skillet out of oven (watch that handle!) and place on a heatproof surface. Add a little flour to pan. Lay dough in skillet, then work edges of dough up sides of skillet with your fingertips (use a rubber spatula or wooden spoon if you’re nervous about touching the hot pan). Drizzle a little oil around inside edge of pan so that it trickles behind and underneath dough, which will encourage browning and help it release.\n\n -- Spread about ⅓ cup Buffalo sauce over dough. Arrange mozzarella over, then top with remaining ¼ cup blue cheese. Arrange chicken mixture on top. Bake pizza on top rack until crust and cheese are nicely browned, 15–20 minutes. Transfer skillet to stovetop (again, watch that handle!) and let pizza rest a few minutes. Using a spatula, slide pizza onto a cutting board or platter. Arrange celery over, then top with reserved blue cheese dressing. Season with pepper, then drizzle with oil.'
249 | },
250 | {
251 | recipeId: 0,
252 | categoryId: 0,
253 | title: 'Classic Lasagna',
254 | photo_url: 'https://namelymarly.com/wp-content/uploads/2018/04/20180415_Beet_Lasagna_10.jpg',
255 | photosArray: [
256 | "https://namelymarly.com/wp-content/uploads/2018/04/20180415_Beet_Lasagna_10.jpg",
257 | 'https://advancelocal-adapter-image-uploads.s3.amazonaws.com/image.al.com/home/bama-media/width600/img/news_impact/photo/burger-fijpg-57e7e5907630c2ad.jpg',
258 | 'https://img.thedailybeast.com/image/upload/c_crop,d_placeholder_euli9k,h_1439,w_2560,x_0,y_0/dpr_1.5/c_limit,w_1044/fl_lossy,q_auto/v1492718105/articles/2013/09/24/burger-king-s-new-french-fries-took-ten-years-to-develop/130923-gross-burger-tease_izz59e',
259 | 'https://aht.seriouseats.com/images/2012/02/20120221-193971-fast-food-fries-Burger-King-fries-2.jpg'
260 | ],
261 | time: '15',
262 | ingredients: [[0, '200ml'], [1, '5g'], [2, '300g']],
263 | description:
264 | '-- Start with cleaned and peeled russet potatoes that you have cut into 3/8-inch match sticks. Place in bowl of very cold water: keep rinsing and changing the water until the water is clear; drain thoroughly and dry with paper towels or a clean lint-free kitchen towel.\n\n -- Meanwhile, you preheat your hot oil to 350 degrees F. Place prepared taters in oil and cook about 5 minutes. They will have that blond-tone color to them. \n\n -- Note: Once you add cold potatoes to the hot oil, the temperature of your oil is going to drop - you want it to be somewhere between 330 - 325 degrees F. \n\n -- Remove from oil; drain and cool. Now - either refrigerate until ready to finish cooking, or cool completely and freeze up to 3 months. To freeze properly - place completely cooled fries in single layer on tray and place in freezer until frozen. Then bag them.\n\n -- To finish cooking - preheat your oil to 400* F. Add your cold fries (which will drop the oil temp - which is fine because you want it near the 375 degrees F. temp) and cook a few minutes until done. Lightly salt them and shake well so that the salt distributes well and they are not salty.'
265 | },
266 | {
267 | recipeId: 7,
268 | categoryId: 2,
269 | title: 'Spaghetti Carbonara',
270 | photo_url: 'https://truffle-assets.imgix.net/655ce202-862-butternutsquashcarbonara-land.jpg',
271 | photosArray: [
272 | 'https://ak3.picdn.net/shutterstock/videos/10431533/thumb/10.jpg',
273 | 'https://www.kcet.org/sites/kl/files/styles/kl_image_large/public/thumbnails/image/square_hero_desktop_2x_sfs_spaghetti_carbonara_clr-3.jpg?itok=T-rsBDIZ',
274 | 'https://cdn-image.foodandwine.com/sites/default/files/HD-201104-r-spaghetti-with-anchovy.jpg'
275 | ],
276 | time: 15,
277 | ingredients: [
278 | [48, '50g'],
279 | [49, '100g'],
280 | [50, '350g'],
281 | [51, '2 plump'],
282 | [42, '50g'],
283 | [16, '3'],
284 | [1, '2 teaspoons'],
285 | [4, '2 teaspoons']
286 | ],
287 | description:
288 | '-- Put the egg yolks into a bowl, finely grate in the Parmesan, season with pepper, then mix well with a fork and put to one side. Cut any hard skin off the pancetta and set aside, then chop the meat. Cook the spaghetti in a large pan of boiling salted water until al dente.\n\n -- Meanwhile, rub the pancetta skin, if you have any, all over the base of a medium frying pan (this will add fantastic flavour, or use 1 tablespoon of oil instead), then place over a medium-high heat. Peel the garlic, then crush with the palm of your hand, add it to the pan and leave it to flavour the fat for 1 minute. Stir in the pancetta, then cook for 4 minutes, or until it starts to crisp up. Pick out and discard the garlic from the pan, then, reserving some of the cooking water, drain and add the spaghetti.\n\n -- Toss well over the heat so it really soaks up all that lovely flavour, then remove the pan from the heat. Add a splash of the cooking water and toss well, season with pepper, then pour in the egg mixture – the pan will help to cook the egg gently, rather than scrambling it. Toss well, adding more cooking water until it’s lovely and glossy. Serve with a grating of Parmesan and an extra twist of pepper.'
289 | },
290 | {
291 | recipeId: 8,
292 | categoryId: 2,
293 | title: 'Lazania',
294 | photo_url: 'https://images8.alphacoders.com/817/817353.jpg',
295 | photosArray: [
296 | 'https://previews.123rf.com/images/somegirl/somegirl1509/somegirl150900048/46103208-top-view-of-a-delicious-traditional-italian-lasagna-made-with-minced-beef-bolognese-sauce-topped-wit.jpg',
297 | 'https://truffle-assets.imgix.net/87f324e4-YOUTUBE-NO-TXT.00_03_19_14.Imagen_fija001.jpg',
298 | 'https://images4.alphacoders.com/817/817350.jpg'
299 | ],
300 | time: 60,
301 | ingredients: [
302 | [36, '1 large'],
303 | [25, '1 pound'],
304 | [51, '5 cloves'],
305 | [52, '1 pound'],
306 | [53, '1 pound'],
307 | [54, '1 28 ounce can'],
308 | [23, '2 6 ounce can'],
309 | [55, '2 tablespoons'],
310 | [56, '1/4 cup'],
311 | [10, '1/2 cup'],
312 | [1, '1/2 teaspoons'],
313 | [58, '1 teaspoon'],
314 | [4, '1/4 teaspoons'],
315 | [16, '1 large'],
316 | [46, '1 pound'],
317 | [48, '1 cup'],
318 | [57, '30 ounces']
319 | ],
320 | description:
321 | '-- Cook noodles according to package directions; drain. Meanwhile, in a Dutch oven, cook sausage, beef and onion over medium heat 8-10 minutes or until meat is no longer pink, breaking up meat into crumbles. Add garlic; cook 1 minute. Drain. Stir in tomatoes, tomato paste, water, sugar, 3 tablespoons parsley, basil, fennel, 1/2 teaspoon salt and pepper; bring to a boil. Reduce heat; simmer, uncovered, 30 minutes, stirring occasionally. In a small bowl, mix egg, ricotta cheese, and remaining parsley and salt. Preheat oven to 375°. Spread 2 cups meat sauce into an ungreased 13x9-in. baking dish. Layer with 3 noodles and a third of the ricotta mixture. Sprinkle with 1 cup mozzarella cheese and 2 tablespoons Parmesan cheese.\n\n -- Repeat layers twice. Top with remaining meat sauce and cheeses (dish will be full). Bake, covered, 25 minutes. Bake, uncovered, 25 minutes longer or until bubbly. Let stand 15 minutes before serving.'
322 | }
323 | ];
324 |
325 | export const ingredients = [
326 | {
327 | ingredientId: 0,
328 | name: 'Oil',
329 | photo_url: 'https://ak7.picdn.net/shutterstock/videos/27252067/thumb/11.jpg'
330 | },
331 | {
332 | ingredientId: 1,
333 | name: 'Salt',
334 | photo_url:
335 | 'https://image.freepik.com/free-photo/sea-salt-wooden-bowl-isolated-white-background_29402-416.jpg'
336 | },
337 | {
338 | ingredientId: 2,
339 | name: 'Russet potatoes',
340 | photo_url: 'http://www.valleyspuds.com/wp-content/uploads/Russet-Potatoes-cut.jpg'
341 | },
342 | {
343 | ingredientId: 3,
344 | name: 'Paprika',
345 | photo_url:
346 | 'https://image.freepik.com/free-photo/red-chilli-pepper-powder-isolated-white-background_55610-28.jpg'
347 | },
348 | {
349 | ingredientId: 4,
350 | name: 'Black Pepper',
351 | photo_url: 'https://ak0.picdn.net/shutterstock/videos/26741680/thumb/1.jpg'
352 | },
353 | {
354 | ingredientId: 5,
355 | name: 'Celery salt',
356 | photo_url: 'https://www.hasiroglugurme.com/images/urunler/Koftelik-Esmer-Bulgur-resim-297.jpg'
357 | },
358 | {
359 | ingredientId: 6,
360 | name: 'Dried sage',
361 | photo_url:
362 | 'https://d2v9y0dukr6mq2.cloudfront.net/video/thumbnail/Esxjvv7/super-slow-motion-dried-sage-falling-on-white-background_n1xg2gxzg__F0000.png'
363 | },
364 | {
365 | ingredientId: 7,
366 | name: 'Garlic powder',
367 | photo_url:
368 | 'https://us.123rf.com/450wm/belchonock/belchonock1808/belchonock180818180/106007144-bowl-of-dry-garlic-powder-on-white-background.jpg?ver=6'
369 | },
370 | {
371 | ingredientId: 8,
372 | name: 'Ground allspice',
373 | photo_url:
374 | 'https://www.savoryspiceshop.com/content/mercury_modules/cart/items/2/6/9/2695/allspice-berries-jamaican-ground-1.jpg'
375 | },
376 | {
377 | ingredientId: 9,
378 | name: 'Dried oregano',
379 | photo_url: 'https://frutascharito.es/886-large_default/oregano.jpg'
380 | },
381 | {
382 | ingredientId: 10,
383 | name: 'Dried basil',
384 | photo_url: 'https://www.honeychop.com/wp-content/uploads/2015/09/Dried-Mint.png'
385 | },
386 | {
387 | ingredientId: 11,
388 | name: 'Dried marjoram',
389 | photo_url: 'https://images-na.ssl-images-amazon.com/images/I/71YATIBqBYL._SX355_.jpg'
390 | },
391 | {
392 | ingredientId: 12,
393 | name: 'All-purpose flour',
394 | photo_url:
395 | 'https://images.assetsdelivery.com/compings_v2/seregam/seregam1309/seregam130900036.jpg'
396 | },
397 | {
398 | ingredientId: 13,
399 | name: 'Brown sugar',
400 | photo_url:
401 | 'https://d2v9y0dukr6mq2.cloudfront.net/video/thumbnail/BALQTtekliuc6iu4u/rotating-brown-sugar-in-a-white-container-on-white-background_sis0xtbyl_thumbnail-full01.png'
402 | },
403 | {
404 | ingredientId: 14,
405 | name: 'Kosher salt',
406 | photo_url:
407 | 'https://d1yn1kh78jj1rr.cloudfront.net/image/preview/r64-6MxPQjlatyfjp/storyblocks-top-view-of-ceramic-salt-cellar-with-coarse-grained-sea-salt-isolated-on-white-background_SPzKionPuV_SB_PM.jpg'
408 | },
409 | {
410 | ingredientId: 15,
411 | name: 'Whole chicken',
412 | photo_url:
413 | 'https://image.shutterstock.com/image-photo/two-raw-chicken-drumsticks-isolated-260nw-632125991.jpg'
414 | },
415 | {
416 | ingredientId: 16,
417 | name: 'Eggs',
418 | photo_url:
419 | 'https://image.shutterstock.com/image-photo/egg-whites-yolk-cup-isolated-260nw-1072453787.jpg'
420 | },
421 | {
422 | ingredientId: 17,
423 | name: 'Quarts neutral oil',
424 | photo_url:
425 | 'https://imagesvc.meredithcorp.io/v3/mm/image?url=https%3A%2F%2Fimg1.cookinglight.timeinc.net%2Fsites%2Fdefault%2Ffiles%2Fstyles%2F4_3_horizontal_-_1200x900%2Fpublic%2Fgettyimages-464433694_0.jpg%3Fitok%3DK42YR2GV&w=400&c=sc&poi=face&q=85'
426 | },
427 | {
428 | ingredientId: 18,
429 | name: 'Water',
430 | photo_url: 'https://ak1.picdn.net/shutterstock/videos/829561/thumb/11.jpg'
431 | },
432 | {
433 | ingredientId: 19,
434 | name: 'Onion Powder',
435 | photo_url:
436 | 'https://image.shutterstock.com/image-photo/mixed-spices-isolated-on-white-260nw-662383828.jpg'
437 | },
438 | {
439 | ingredientId: 20,
440 | name: 'MSG',
441 | photo_url:
442 | 'https://img.freepik.com/free-photo/monosodium-glutamate-wood-spoon-white-background_55883-399.jpg?size=626&ext=jpg'
443 | },
444 | {
445 | ingredientId: 21,
446 | name: 'Chicken Breast',
447 | photo_url:
448 | 'https://us.123rf.com/450wm/utima/utima1602/utima160200063/53405187-raw-chicken-breast-fillets.jpg?ver=6'
449 | },
450 | {
451 | ingredientId: 22,
452 | name: 'Onion chopped',
453 | photo_url: 'https://s3.envato.com/files/246703499/IMG_1752_5.jpg'
454 | },
455 | {
456 | ingredientId: 23,
457 | name: 'Tomato paste',
458 | photo_url:
459 | 'http://d3e1m60ptf1oym.cloudfront.net/45bab59a-363c-11e1-ab4e-bf4c2e0bb026/PANELA_xgaplus.jpg'
460 | },
461 | {
462 | ingredientId: 24,
463 | name: 'Chilli Powder',
464 | photo_url:
465 | 'https://us.123rf.com/450wm/nuttapong/nuttapong1505/nuttapong150500009/40458002-paprika-powder-isolated-on-white-background.jpg?ver=6'
466 | },
467 | {
468 | ingredientId: 25,
469 | name: 'Ground Beef',
470 | photo_url:
471 | 'https://images.radio.com/kmoxam/s3fs-public/styles/nts_image_cover_tall_775x425/public/dreamstime_s_39607998.jpg?XCM.w1UGOp9sVKkWGQZe7_JIsRddxoIK&itok=3M6KcFLH&c=73fb6497175b4c1a5c79e3ede816656a'
472 | },
473 | {
474 | ingredientId: 26,
475 | name: 'Can kidney beans, rinsed and drained ',
476 | photo_url:
477 | 'https://www.seriouseats.com/images/2014/04/20140414-pile-of-beans-primary-1500x1125.jpg'
478 | },
479 | {
480 | ingredientId: 27,
481 | name: 'Large Tortillas',
482 | photo_url: 'https://upload.wikimedia.org/wikipedia/commons/5/56/NCI_flour_tortillas.jpg'
483 | },
484 | {
485 | ingredientId: 28,
486 | name: 'Firtos',
487 | photo_url:
488 | 'https://previews.123rf.com/images/ksena32/ksena321510/ksena32151000090/45863494-fried-fish-on-a-white-background.jpg'
489 | },
490 | {
491 | ingredientId: 29,
492 | name: 'Shredded cheddar',
493 | photo_url:
494 | 'https://image.shutterstock.com/image-photo/top-view-small-bowl-filled-260nw-284460308.jpg'
495 | },
496 | {
497 | ingredientId: 30,
498 | name: 'Lime',
499 | photo_url: 'https://ak8.picdn.net/shutterstock/videos/23271748/thumb/1.jpg'
500 | },
501 |
502 | {
503 | ingredientId: 31,
504 | name: 'Ground cumin',
505 | photo_url:
506 | 'https://image.shutterstock.com/image-photo/pile-cumin-powder-isolated-on-260nw-1193262853.jpg'
507 | },
508 | {
509 | ingredientId: 32,
510 | name: 'Cayenne pepper',
511 | photo_url: 'https://ak7.picdn.net/shutterstock/videos/11461337/thumb/1.jpg'
512 | },
513 | {
514 | ingredientId: 33,
515 | name: 'Flaky white fish',
516 | photo_url:
517 | 'https://image.shutterstock.com/image-photo/roach-river-fish-isolated-on-260nw-277764143.jpg'
518 | },
519 | {
520 | ingredientId: 34,
521 | name: 'Avocado',
522 | photo_url:
523 | 'https://www.redwallpapers.com/public/redwallpapers-large-thumb/avocado-cut-stone-leaves-white-background-free-stock-photos-images-hd-wallpaper.jpg'
524 | },
525 | {
526 | ingredientId: 35,
527 | name: 'Red Pepper Flakes',
528 | photo_url:
529 | 'https://as1.ftcdn.net/jpg/02/06/55/10/500_F_206551074_mVczUrAWOSMaw8kR48FQDQBqDw47jCtL.jpg'
530 | },
531 | {
532 | ingredientId: 36,
533 | name: 'Onions',
534 | photo_url: 'http://www.allwhitebackground.com/images/2/2650.jpg'
535 | },
536 | {
537 | ingredientId: 37,
538 | name: 'Green Pepper',
539 | photo_url: 'https://ak9.picdn.net/shutterstock/videos/4055509/thumb/1.jpg'
540 | },
541 | {
542 | ingredientId: 38,
543 | name: 'Red Pepper',
544 | photo_url: 'https://ak9.picdn.net/shutterstock/videos/10314179/thumb/1.jpg'
545 | },
546 | {
547 | ingredientId: 39,
548 | name: 'Pizza dough',
549 | photo_url:
550 | 'https://image.shutterstock.com/image-photo/fresh-raw-dough-pizza-bread-260nw-518950903.jpg'
551 | },
552 | {
553 | ingredientId: 40,
554 | name: 'Ketchup sauce',
555 | photo_url:
556 | 'https://st2.depositphotos.com/5262887/11050/i/950/depositphotos_110501208-stock-photo-ketchup-bowl-isolated-on-white.jpg'
557 | },
558 | {
559 | ingredientId: 41,
560 | name: 'Hot Sauce',
561 | photo_url:
562 | 'https://media.istockphoto.com/photos/opened-can-of-spaghetti-sauce-on-a-white-background-picture-id497704752?k=6&m=497704752&s=612x612&w=0&h=JnL54buYu1Z3fGtd8uNdjFxiAKwlxoDluD6jbIfSaZI='
563 | },
564 | {
565 | ingredientId: 42,
566 | name: 'Butter',
567 | photo_url: 'https://redrockstoffee.com/media/2016/11/AdobeStock_76417550.jpeg'
568 | },
569 | {
570 | ingredientId: 43,
571 | name: 'Heavy Cream',
572 | photo_url:
573 | 'https://media.istockphoto.com/photos/mayonnaise-in-bowl-isolated-on-white-background-picture-id614981116?k=6&m=614981116&s=612x612&w=0&h=LtbsI2HQXOTERYuP9YJ2PJfRF3W6DcyZ798fxMcQWC0='
574 | },
575 | {
576 | ingredientId: 44,
577 | name: 'whole-milk plain yogurt',
578 | photo_url:
579 | 'https://st.depositphotos.com/2757384/3317/i/950/depositphotos_33170129-stock-photo-pouring-a-glass-of-milk.jpg'
580 | },
581 | {
582 | ingredientId: 45,
583 | name: 'Chesse',
584 | photo_url: 'https://ak7.picdn.net/shutterstock/videos/3619997/thumb/1.jpg'
585 | },
586 | {
587 | ingredientId: 46,
588 | name: 'Mozzarella',
589 | photo_url:
590 | 'https://t3.ftcdn.net/jpg/02/06/73/98/500_F_206739841_suPu6qDPHlowFqx9qo8fLqV8sNevL2g3.jpg'
591 | },
592 | {
593 | ingredientId: 47,
594 | name: 'celery stalks',
595 | photo_url:
596 | 'https://cdn4.eyeem.com/thumb/6d1b3957c7caa9b73c3e0f820ef854b931808139-1538043742765/w/750'
597 | },
598 | {
599 | ingredientId: 48,
600 | name: 'Parmesan Chesse',
601 | photo_url: 'https://ak7.picdn.net/shutterstock/videos/3721877/thumb/1.jpg'
602 | },
603 | {
604 | ingredientId: 49,
605 | name: 'pancetta',
606 | photo_url:
607 | 'https://previews.123rf.com/images/onlyfabrizio/onlyfabrizio1606/onlyfabrizio160600002/60198502-raw-stripes-of-pancetta-stesa-on-a-white-background.jpg'
608 | },
609 | {
610 | ingredientId: 50,
611 | name: 'Spaghetti',
612 | photo_url:
613 | 'https://previews.123rf.com/images/mfron/mfron1204/mfron120400098/13306773-bunch-of-spaghetti-nudeln-isoliert-auf-wei%C3%9Fem-hintergrund.jpg'
614 | },
615 | {
616 | ingredientId: 51,
617 | name: 'Garlic',
618 | photo_url: 'https://image.freepik.com/free-photo/fresh-garlic-white-background_1339-17012.jpg'
619 | },
620 | {
621 | ingredientId: 52,
622 | name: 'Lasagna noodles',
623 | photo_url:
624 | 'https://previews.123rf.com/images/velkol/velkol1110/velkol111000004/11083085-an-image-of-raw-lasagna-on-white-background.jpg'
625 | },
626 | {
627 | ingredientId: 53,
628 | name: 'Italian sauce',
629 | photo_url:
630 | 'https://previews.123rf.com/images/arinahabich/arinahabich1504/arinahabich150400858/38827029-raw-italian-sausage-on-a-white-background-.jpg'
631 | },
632 | {
633 | ingredientId: 54,
634 | name: 'Crushed Tomatoes',
635 | photo_url:
636 | 'https://previews.123rf.com/images/merkulovnik/merkulovnik1406/merkulovnik140600100/28751626-crushed-tomato-isolated-on-white-background.jpg'
637 | },
638 | {
639 | ingredientId: 55,
640 | name: 'Sugar',
641 | photo_url:
642 | 'https://previews.123rf.com/images/sommai/sommai1411/sommai141100034/33199985-sugar-cubes-in-a-bowl-isolated-on-white-background.jpg'
643 | },
644 | {
645 | ingredientId: 56,
646 | name: 'minced fresh parsley',
647 | photo_url:
648 | 'https://t4.ftcdn.net/jpg/02/15/78/05/240_F_215780551_Eid0xpP1M2fokvuEcvJj8uqhROLJkb3p.jpg'
649 | },
650 | {
651 | ingredientId: 57,
652 | name: 'ricotta cheese',
653 | photo_url:
654 | 'https://previews.123rf.com/images/barkstudio/barkstudio1608/barkstudio160800351/61418602-ricotta-cheese-into-a-bowl-in-white-background.jpg'
655 | },
656 | {
657 | ingredientId: 58,
658 | name: ' fennel seed',
659 | photo_url:
660 | 'https://previews.123rf.com/images/pinkomelet/pinkomelet1710/pinkomelet171000227/88851299-close-up-the-fennel-seed-on-white-background.jpg'
661 | },
662 | {
663 | ingredientId: 59,
664 | name: 'Banana',
665 | photo_url:
666 | 'https://www.conservationmagazine.org/wp-content/uploads/2013/04/sterile-banana.jpg'
667 | },
668 | {
669 | ingredientId: 60,
670 | name: 'Frozen Straberries',
671 | photo_url:
672 | 'https://www.cascadianfarm.com/wp-content/uploads/2018/12/Strawberries_Main_0218.png'
673 | },
674 | {
675 | ingredientId: 61,
676 | name: 'Greek Yogurt',
677 | photo_url:
678 | 'http://images.media-allrecipes.com/userphotos/960x960/3758635.jpg'
679 | },
680 | ];
681 |
--------------------------------------------------------------------------------