Skip to content

Commit d2d057e

Browse files
author
Jean Rauwers
committed
final: episode 4
1 parent bc17338 commit d2d057e

File tree

4 files changed

+135
-122
lines changed

4 files changed

+135
-122
lines changed

episode-4-fetch-created-events/mobile-app/components/ModalComponent.js

+106-45
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
import React, { useState } from 'react';
2-
import { View, Text, StyleSheet, ImageBackground, TouchableOpacity, TextInput, Modal, Dimensions, Image } from 'react-native';
3-
import { Picker } from '@react-native-picker/picker'
2+
import { View, Text, StyleSheet, TouchableOpacity, TextInput, Modal, Dimensions, Image } from 'react-native';
3+
4+
import { MaterialIcons } from '@expo/vector-icons';
45

56
const widowWidth = Dimensions.get('window').width;
67
const windowHeight = Dimensions.get('window').height;
78

89
import * as ImagePicker from 'expo-image-picker';
10+
import DateTimePicker from '@react-native-community/datetimepicker';
11+
import { Picker } from '@react-native-picker/picker'
912

1013

11-
const ModalComponent = ({ isVisible, setIsVisible, user }) => {
14+
const ModalComponent = ({ isVisible, setIsVisible, user, loadEvents }) => {
1215
const [eventTitle, setEventTitle] = useState(null)
1316
const [eventDescription, setEventDescription] = useState(null)
1417
const [eventPrice, setEventPrice] = useState(null)
1518
const [eventSport, setEventSport] = useState('Running')
19+
const [eventDate, setEventDate] = useState(new Date())
1620
const [image, setImage] = useState(null)
1721

18-
1922
const pickImage = async () => {
2023
const result = await ImagePicker.launchImageLibraryAsync({
2124
mediaTypes: ImagePicker.MediaTypeOptions.All,
@@ -31,6 +34,50 @@ const ModalComponent = ({ isVisible, setIsVisible, user }) => {
3134
}
3235
};
3336

37+
const submitEventHandler = async () => {
38+
const localUri = image;
39+
const filename = localUri.split('/').pop()
40+
const match = /\.(\w+)$/.exec(filename)
41+
const type = match ? `image/${match[1]}` : `image`;
42+
43+
const data = new FormData()
44+
45+
data.append('thumbnail', { uri: localUri, name: filename, type })
46+
data.append('title', eventTitle)
47+
data.append('description', eventDescription)
48+
data.append('price', eventPrice)
49+
data.append('date', eventDate)
50+
data.append('sport', eventSport)
51+
52+
try {
53+
await fetch(`http://localhost:8080/api/event`, {
54+
method: 'POST',
55+
body: data,
56+
headers: { user: user }
57+
})
58+
loadEvents()
59+
cancelEventHandler()
60+
} catch (error) {
61+
console.log('🚀 -------------------------------------------------------------------------')
62+
console.log('🚀 ~ file: ModalComponent.js ~ line 60 ~ submitEventHandler ~ error', error)
63+
console.log('🚀 -------------------------------------------------------------------------')
64+
65+
}
66+
}
67+
68+
const onChange = (event, selectedDate) => {
69+
const currentDate = selectedDate || eventDate;
70+
setEventDate(currentDate);
71+
};
72+
73+
const cancelEventHandler = () => {
74+
setIsVisible(!isVisible)
75+
setImage(null)
76+
setEventTitle(null)
77+
setEventDescription(null)
78+
setEventDate(new Date())
79+
setEventSport('Running')
80+
}
3481
return (
3582
<Modal
3683
animationType="slide"
@@ -43,42 +90,55 @@ const ModalComponent = ({ isVisible, setIsVisible, user }) => {
4390
>
4491
<View style={styles.centeredView}>
4592
<View style={styles.modalView}>
46-
<Text style={styles.modalText}>Create a New Event</Text>
4793
<View style={styles.form}>
4894
<View>
49-
<TouchableOpacity
50-
style={[styles.button, styles.buttonClose]}
51-
onPress={pickImage}
52-
>
53-
<Text>Pick an Image!</Text>
54-
</TouchableOpacity>
55-
{image && <Image source={{ uri: image }} style={{ width: 200, height: 200 }} />}
95+
96+
{image ? <TouchableOpacity onPress={pickImage}>
97+
<Image source={{ uri: image }} style={styles.loadedImage} />
98+
</TouchableOpacity> :
99+
<TouchableOpacity
100+
style={styles.addImage}
101+
onPress={pickImage}
102+
>
103+
<MaterialIcons name="add-a-photo" size={56} color="black" />
104+
</TouchableOpacity>}
56105
</View>
57106
<View>
58107
<Text style={styles.label}>Event Title:</Text>
59-
<TextInput style={styles.input} placeholder={"Event Title"} autoCapitalize='none' autoCorrect={false} value={eventTitle} onChangeText={text => console.log(text)} />
108+
<TextInput style={styles.input} placeholder={"Event Title"} autoCapitalize='none' autoCorrect={false} value={eventTitle} onChangeText={text => setEventTitle(text)} />
60109
<Text style={styles.label}>Event Description:</Text>
61-
<TextInput style={styles.input} placeholder={"Event Description"} autoCapitalize='none' autoCorrect={false} value={eventDescription} onChangeText={text => console.log(text)} />
110+
<TextInput style={styles.input} placeholder={"Event Description"} autoCapitalize='none' autoCorrect={false} value={eventDescription} onChangeText={text => setEventDescription(text)} />
62111
<Text style={styles.label}>Event Price:</Text>
63-
<TextInput style={styles.input} placeholder={"Price in $00,00"} autoCapitalize='none' autoCorrect={false} value={eventPrice} onChangeText={text => console.log(text)} />
112+
<TextInput style={styles.input} placeholder={"Price in $00,00"} autoCapitalize='none' autoCorrect={false} value={eventPrice} onChangeText={text => setEventPrice(text)} />
113+
</View>
114+
<View>
115+
<Text style={styles.label}>Event Date:</Text>
116+
<DateTimePicker
117+
value={eventDate}
118+
mode='date'
119+
onChange={onChange}
120+
/>
64121
</View>
65122
<View>
66123
<Text style={styles.label}>Sport: {eventSport}</Text>
67-
<Picker selectedValue={eventSport} onValueChange={value => setEventSport(value)}>
124+
<Picker mode={"dialog"} style={styles.sportPicker} selectedValue={eventSport} onValueChange={value => setEventSport(value)}>
68125
<Picker.Item label={'Running'} value={'Running'} />
69126
<Picker.Item label={'Cycling'} value={'Cycling'} />
70127
<Picker.Item label={'Swimming'} value={'Swimming'} />
71128
</Picker>
72-
73129
</View>
74-
75-
76130
</View>
77131
<TouchableOpacity
78-
style={[styles.button, styles.buttonClose]}
79-
onPress={() => setIsVisible(!isVisible)}
132+
style={styles.primaryBtn}
133+
onPress={submitEventHandler}
80134
>
81-
<Text style={styles.textStyle}>Hide Modal</Text>
135+
<Text style={styles.textStyle}>Submit Event</Text>
136+
</TouchableOpacity>
137+
<TouchableOpacity
138+
style={styles.secondaryBtn}
139+
onPress={cancelEventHandler}
140+
>
141+
<Text style={styles.textStyle}>Cancel</Text>
82142
</TouchableOpacity>
83143
</View>
84144
</View>
@@ -92,16 +152,15 @@ const styles = StyleSheet.create({
92152
centeredView: {
93153
flex: 1,
94154
justifyContent: "center",
95-
alignItems: "center",
96-
marginTop: 22
155+
alignItems: "center"
97156
},
98157
modalView: {
99158
margin: 20,
100159
height: windowHeight,
101160
width: widowWidth,
102161
backgroundColor: "white",
103162
borderRadius: 20,
104-
padding: 35,
163+
padding: 25,
105164
alignItems: "center",
106165
shadowColor: "#000",
107166
shadowOffset: {
@@ -112,30 +171,14 @@ const styles = StyleSheet.create({
112171
shadowRadius: 4,
113172
elevation: 5
114173
},
115-
button: {
116-
borderRadius: 20,
117-
padding: 10,
118-
elevation: 2
119-
},
120-
buttonOpen: {
121-
backgroundColor: "#F194FF",
122-
},
123-
buttonClose: {
124-
backgroundColor: "#2196F3",
125-
},
126174
textStyle: {
127175
color: "white",
128176
fontWeight: "bold",
129177
textAlign: "center"
130178
},
131-
modalText: {
132-
marginBottom: 15,
133-
textAlign: "center"
134-
},
135179
form: {
136180
alignSelf: "stretch",
137-
paddingHorizontal: 30,
138-
marginTop: 30
181+
marginTop: 16
139182
},
140183
label: {
141184
fontSize: 16,
@@ -152,24 +195,42 @@ const styles = StyleSheet.create({
152195
fontWeight: "400",
153196
height: 44,
154197
shadowColor: '#000000',
155-
marginBottom: 30,
198+
marginBottom: 15,
156199
borderRadius: 4
157200
},
158201
primaryBtn: {
159202
height: 42,
203+
width: '100%',
160204
backgroundColor: '#007bff',
161205
justifyContent: 'center',
162206
alignItems: 'center',
163207
borderRadius: 4,
164-
marginTop: 20
208+
marginTop: 10
165209
},
166210
secondaryBtn: {
167211
height: 42,
212+
width: '100%',
168213
backgroundColor: '#f04a5b',
169214
justifyContent: 'center',
170215
alignItems: 'center',
171216
borderRadius: 4,
172-
marginTop: 20
217+
marginTop: 10
218+
},
219+
addImage: {
220+
justifyContent: 'center',
221+
alignItems: 'center',
222+
marginBottom: 28,
223+
width: '100%',
224+
height: 150
225+
},
226+
loadedImage: {
227+
width: '100%',
228+
height: 150,
229+
justifyContent: 'center',
230+
alignItems: 'center',
231+
},
232+
sportPicker: {
233+
173234
}
174235
});
175236

episode-4-fetch-created-events/mobile-app/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
},
1010
"dependencies": {
1111
"@react-native-async-storage/async-storage": "^1.13.4",
12+
"@react-native-community/datetimepicker": "3.0.4",
1213
"@react-native-community/masked-view": "0.1.10",
1314
"@react-native-picker/picker": "^1.9.11",
1415
"@react-navigation/native": "^5.9.2",

episode-4-fetch-created-events/mobile-app/pages/Dashboard.js

+16-25
Original file line numberDiff line numberDiff line change
@@ -11,30 +11,21 @@ import { FontAwesome5, MaterialCommunityIcons, Ionicons } from '@expo/vector-ico
1111
const DashBoard = ({ navigation }) => {
1212
const [user, user_id] = isLoggedIn({ navigation });
1313
const [modalIsVisible, setModalIsVisible] = useState(false);
14-
const [events, setEvents] = useState([{
15-
_id: 'idblah',
16-
title: 'London 5K running',
17-
sport: 'Running',
18-
description: "The best 5K event in London",
19-
price: "39.00",
20-
thumbnail_url: 'https://admin.concern.org.uk/sites/default/files/styles/hero_desktop/public/media/images/2019-06/London%20Marathon%20-%20Jenny%20Flynn.jpg/'
21-
},
22-
{
23-
_id: 'idbah',
24-
title: 'London 5K running',
25-
sport: 'Running',
26-
description: "The best 5K event in London",
27-
price: "39.00",
28-
thumbnail_url: 'https://admin.concern.org.uk/sites/default/files/styles/hero_desktop/public/media/images/2019-06/London%20Marathon%20-%20Jenny%20Flynn.jpg/'
29-
},
30-
{
31-
_id: 'idbla',
32-
title: 'London 5K running',
33-
sport: 'Running',
34-
description: "The best 5K event in London",
35-
price: "39.00",
36-
thumbnail_url: 'https://admin.concern.org.uk/sites/default/files/styles/hero_desktop/public/media/images/2019-06/London%20Marathon%20-%20Jenny%20Flynn.jpg/'
37-
}])
14+
const [events, setEvents] = useState([])
15+
16+
useEffect(() => {
17+
loadEvents()
18+
}, [])
19+
20+
const loadEvents = async () => {
21+
const response = await fetch(`http://localhost:8080/api/dashboard`, {
22+
method: 'GET',
23+
headers: { user: user }
24+
})
25+
26+
const jsonResponse = await response.json()
27+
setEvents(jsonResponse.events)
28+
}
3829

3930
const logoutHandler = async () => {
4031
await AsyncStorage.removeItem('user');
@@ -69,7 +60,7 @@ const DashBoard = ({ navigation }) => {
6960
}}>
7061

7162
</FlatList>
72-
<ModalComponent isVisible={modalIsVisible} setIsVisible={setModalIsVisible} user={user}></ModalComponent>
63+
<ModalComponent isVisible={modalIsVisible} setIsVisible={setModalIsVisible} user={user} loadEvents={loadEvents} />
7364
<TouchableOpacity onPress={logoutHandler}>
7465
<Text>Logout</Text>
7566
</TouchableOpacity>

0 commit comments

Comments
 (0)