expo recipe app.md
... ...
@@ -0,0 +1,153 @@
1
+
2
+
3
+
4
+```
5
+// App.js
6
+import * as React from 'react';
7
+import { NavigationContainer } from '@react-navigation/native';
8
+import { createStackNavigator } from '@react-navigation/stack';
9
+import RecipeIndexScreen from './screens/RecipeIndexScreen';
10
+import RecipeDetailScreen from './screens/RecipeDetailScreen';
11
+
12
+const Stack = createStackNavigator();
13
+
14
+export default function App() {
15
+ return (
16
+ <NavigationContainer>
17
+ <Stack.Navigator initialRouteName="Recipes">
18
+ <Stack.Screen name="Recipes" component={RecipeIndexScreen} />
19
+ <Stack.Screen name="RecipeDetail" component={RecipeDetailScreen} />
20
+ </Stack.Navigator>
21
+ </NavigationContainer>
22
+ );
23
+}
24
+```
25
+
26
+// data.js
27
+export const recipes = [
28
+ {
29
+ id: '1',
30
+ title: 'Spaghetti Bolognese',
31
+ image: 'https://example.com/spaghetti.jpg',
32
+ tags: ['Pasta', 'Italian'],
33
+ ingredients: ['Spaghetti', 'Ground beef', 'Tomato sauce', 'Onion', 'Garlic'],
34
+ instructions: 'Boil spaghetti. Cook beef with sauce and onions. Serve hot.',
35
+ },
36
+ {
37
+ id: '2',
38
+ title: 'Caesar Salad',
39
+ image: 'https://example.com/caesar.jpg',
40
+ tags: ['Salad', 'Healthy'],
41
+ ingredients: ['Romaine lettuce', 'Croutons', 'Caesar dressing', 'Parmesan cheese'],
42
+ instructions: 'Combine all ingredients and toss with dressing.',
43
+ },
44
+];
45
+
46
+// screens/RecipeIndexScreen.js
47
+import React, { useEffect, useState } from 'react';
48
+import { View, Text, TouchableOpacity, FlatList } from 'react-native';
49
+import AsyncStorage from '@react-native-async-storage/async-storage';
50
+import { recipes } from '../data';
51
+
52
+const RecipeIndexScreen = ({ navigation }) => {
53
+ const [groupedRecipes, setGroupedRecipes] = useState({});
54
+
55
+ useEffect(() => {
56
+ async function loadRecipes() {
57
+ try {
58
+ await AsyncStorage.setItem('recipes', JSON.stringify(recipes));
59
+ const data = await AsyncStorage.getItem('recipes');
60
+ const parsedData = JSON.parse(data);
61
+
62
+ const grouped = parsedData.reduce((acc, recipe) => {
63
+ recipe.tags.forEach(tag => {
64
+ acc[tag] = acc[tag] ? [...acc[tag], recipe] : [recipe];
65
+ });
66
+ return acc;
67
+ }, {});
68
+ setGroupedRecipes(grouped);
69
+ } catch (error) {
70
+ console.error(error);
71
+ }
72
+ }
73
+ loadRecipes();
74
+ }, []);
75
+
76
+ return (
77
+ <FlatList
78
+ data={Object.keys(groupedRecipes)}
79
+ keyExtractor={(item) => item}
80
+ renderItem={({ item: tag }) => (
81
+ <View>
82
+ <Text style={{ fontSize: 18, fontWeight: 'bold' }}>{tag}</Text>
83
+ {groupedRecipes[tag].map(recipe => (
84
+ <TouchableOpacity
85
+ key={recipe.id}
86
+ onPress={() => navigation.navigate('RecipeDetail', { recipe })}
87
+ >
88
+ <Text>{recipe.title}</Text>
89
+ </TouchableOpacity>
90
+ ))}
91
+ </View>
92
+ )}
93
+ />
94
+ );
95
+};
96
+
97
+export default RecipeIndexScreen;
98
+
99
+
100
+// screens/RecipeIndexScreen.js
101
+import React, { useEffect, useState } from 'react';
102
+import { View, Text, TouchableOpacity, FlatList } from 'react-native';
103
+import AsyncStorage from '@react-native-async-storage/async-storage';
104
+import { recipes } from '../data';
105
+
106
+const RecipeIndexScreen = ({ navigation }) => {
107
+ const [groupedRecipes, setGroupedRecipes] = useState({});
108
+
109
+ useEffect(() => {
110
+ async function loadRecipes() {
111
+ try {
112
+ await AsyncStorage.setItem('recipes', JSON.stringify(recipes));
113
+ const data = await AsyncStorage.getItem('recipes');
114
+ const parsedData = JSON.parse(data);
115
+
116
+ const grouped = parsedData.reduce((acc, recipe) => {
117
+ recipe.tags.forEach(tag => {
118
+ acc[tag] = acc[tag] ? [...acc[tag], recipe] : [recipe];
119
+ });
120
+ return acc;
121
+ }, {});
122
+ setGroupedRecipes(grouped);
123
+ } catch (error) {
124
+ console.error(error);
125
+ }
126
+ }
127
+ loadRecipes();
128
+ }, []);
129
+
130
+ return (
131
+ <FlatList
132
+ data={Object.keys(groupedRecipes)}
133
+ keyExtractor={(item) => item}
134
+ renderItem={({ item: tag }) => (
135
+ <View>
136
+ <Text style={{ fontSize: 18, fontWeight: 'bold' }}>{tag}</Text>
137
+ {groupedRecipes[tag].map(recipe => (
138
+ <TouchableOpacity
139
+ key={recipe.id}
140
+ onPress={() => navigation.navigate('RecipeDetail', { recipe })}
141
+ >
142
+ <Text>{recipe.title}</Text>
143
+ </TouchableOpacity>
144
+ ))}
145
+ </View>
146
+ )}
147
+ />
148
+ );
149
+};
150
+
151
+export default RecipeIndexScreen;
152
+
153
+