Skip to content

Commit d54bea7

Browse files
committed
Fixed Conflict
1 parent 6b8dc20 commit d54bea7

File tree

4 files changed

+614
-271
lines changed

4 files changed

+614
-271
lines changed

frontend/src/components/appNavigation.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import Forum from '../screens/forum';
1010
import FoodForum from '../screens/foodForum';
1111
import EnergyForum from '../screens/energyForum';
1212
import TransportationForum from '../screens/transportationForum';
13+
import TransportationEntryEdit from '../screens/transportationEntryEdit';
1314
import FoodHistory from '../screens/foodHistory';
1415
import TransportationHistory from '../screens/transportationHistory';
1516

@@ -27,6 +28,7 @@ const AppNavigation = (): JSX.Element => {
2728
<Stack.Screen name="FoodForum" component={FoodForum} />
2829
<Stack.Screen name="EnergyForum" component={EnergyForum} />
2930
<Stack.Screen name="TransportationForum" component={TransportationForum} />
31+
<Stack.Screen name="TransportationEntryEdit" component={TransportationEntryEdit} />
3032
<Stack.Screen name="FoodHistory" component={FoodHistory} />
3133
<Stack.Screen name="TransportationHistory" component={TransportationHistory} />
3234
</Stack.Navigator>
Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
import {
2+
StyleSheet,
3+
Text,
4+
View,
5+
TouchableOpacity,
6+
ScrollView,
7+
Modal,
8+
Linking,
9+
} from 'react-native';
10+
import * as React from 'react';
11+
import Icon from 'react-native-vector-icons/FontAwesome';
12+
import { useEffect, useState } from 'react';
13+
import { type StackNavigationProp } from '@react-navigation/stack';
14+
import { type RootStackParamList } from '../components/types';
15+
import { useNavigation } from '@react-navigation/native';
16+
import { useFonts } from 'expo-font';
17+
import Colors from '../../assets/colorConstants';
18+
import { SafeAreaView } from 'react-native-safe-area-context';
19+
import Slider from '@react-native-community/slider';
20+
import { TransportationAPI } from '../APIs/TransportationAPI';
21+
import { type TransportationEntry } from '../models/Transportation';
22+
23+
export type StackNavigation = StackNavigationProp<RootStackParamList>;
24+
25+
export default function TransportationEntryEdit(): JSX.Element {
26+
interface SliderData {
27+
id: number;
28+
label: string;
29+
minValue: number;
30+
maxValue: number;
31+
initialValue: number;
32+
}
33+
34+
const [transportationEntry, setTransportationEntry] = useState<TransportationEntry>();
35+
36+
const [slidersData, setSliderData] = useState<SliderData[]>([]);
37+
38+
const [electricCarTravel, setElectricCarTravel] = useState(0);
39+
const [gasolineCarTravel, setGasolineCarTravel] = useState(0);
40+
const [busTravel, setBusTravel] = useState(0);
41+
const [trainTravel, setTrainTravel] = useState(0);
42+
const [bikeTravel, setBikeTravel] = useState(0);
43+
44+
const onSliderValueChange = (value: number, index: number): void => {
45+
slidersData[index].initialValue = value
46+
switch (index) {
47+
case 0:
48+
setElectricCarTravel(value);
49+
break;
50+
case 1:
51+
setGasolineCarTravel(value);
52+
break;
53+
case 2:
54+
setTrainTravel(value);
55+
break;
56+
case 3:
57+
setBusTravel(value);
58+
break;
59+
case 4:
60+
setBikeTravel(value);
61+
break;
62+
default:
63+
break;
64+
}
65+
};
66+
67+
const openLink = async (url: string): Promise<void> => {
68+
const supported = await Linking.canOpenURL(url);
69+
70+
if (supported) {
71+
await Linking.openURL(url);
72+
} else {
73+
console.error('Cannot open the URL');
74+
}
75+
};
76+
77+
const handleLinkPress = (): void => {
78+
const url = 'https://fcr-ccc.nrcan-rncan.gc.ca/en';
79+
openLink(url).catch((error) => {
80+
console.error('Error opening link:', error);
81+
});
82+
};
83+
84+
const [loaded] = useFonts({
85+
Montserrat: require('../../assets/fonts/MontserratThinRegular.ttf'),
86+
Josefin: require('../../assets/fonts/JosefinSansThinRegular.ttf'),
87+
});
88+
89+
const navigation = useNavigation<StackNavigation>();
90+
91+
const [modalVisible, setModalVisible] = useState(false);
92+
93+
const handleSurveySubmit = (): void => {
94+
// Process survey responses, e.g., send them to a server
95+
if (transportationEntry != null) {
96+
const newEntry: TransportationEntry = {
97+
_id: transportationEntry._id,
98+
user_id: transportationEntry.user_id,
99+
bus: busTravel,
100+
train: trainTravel,
101+
motorbike: bikeTravel,
102+
electric_car: electricCarTravel,
103+
gasoline_car: gasolineCarTravel,
104+
carbon_emissions: transportationEntry.carbon_emissions,
105+
date: transportationEntry.date
106+
}
107+
void TransportationAPI.updateTransportation(newEntry).then()
108+
}
109+
navigation.navigate('TransportationHistory');
110+
};
111+
112+
useEffect(() => {
113+
if (transportationEntry != null) {
114+
setSliderData([
115+
{ id: 1, label: 'Electric Car', minValue: 0, maxValue: 800, initialValue: transportationEntry.electric_car },
116+
{ id: 2, label: 'Gasoline Car', minValue: 0, maxValue: 800, initialValue: transportationEntry.gasoline_car },
117+
{ id: 3, label: 'Train', minValue: 0, maxValue: 800, initialValue: transportationEntry.train },
118+
{ id: 4, label: 'Bus', minValue: 0, maxValue: 800, initialValue: transportationEntry.bus },
119+
{ id: 5, label: 'Motobike', minValue: 0, maxValue: 800, initialValue: transportationEntry.motorbike },
120+
])
121+
setElectricCarTravel(transportationEntry.electric_car);
122+
setGasolineCarTravel(transportationEntry.gasoline_car);
123+
setBusTravel(transportationEntry.bus);
124+
setTrainTravel(transportationEntry.train);
125+
setBikeTravel(transportationEntry.motorbike);
126+
}
127+
}, [transportationEntry])
128+
129+
useEffect(() => {
130+
void TransportationAPI.getTransportationMetricForToday().then((res) => {
131+
if (res != null) {
132+
setTransportationEntry(res)
133+
}
134+
})
135+
}, [loaded])
136+
137+
if (!loaded || slidersData.length === 0) {
138+
return <></>;
139+
}
140+
141+
return (
142+
<SafeAreaView style={styles.container}>
143+
<ScrollView style={styles.scrollContainer}>
144+
<Text style={styles.header}>Calculate your emissions from transportation:</Text>
145+
146+
<Modal transparent={true} visible={modalVisible}>
147+
<View style={styles.modalBackground}>
148+
<View style={styles.modalContainer}>
149+
<Text style={styles.infoText}>
150+
If you don&apos;t know your vehicle&apos;s fuel efficiency, it&apos;s available
151+
online{' '}
152+
<Text style={styles.linkText} onPress={handleLinkPress}>
153+
here
154+
</Text>
155+
. Select the &quot;combination&quot; value under Comsumption in L/100km. The average
156+
fuel consumption of non-plug-in hybrid personal vehicles in Canada is 8.9 L / 100
157+
km.
158+
</Text>
159+
<TouchableOpacity
160+
style={styles.closeIcon}
161+
onPress={() => setModalVisible(!modalVisible)}
162+
>
163+
<Icon name="times-circle" size={30} color={Colors.DARKGREEN} />
164+
</TouchableOpacity>
165+
</View>
166+
</View>
167+
</Modal>
168+
169+
<Text style={styles.header}>
170+
On average, how much distance do you travel using the following methods per week:
171+
</Text>
172+
173+
{slidersData.map((slider, index) => (
174+
<View style={styles.questionContainer} key={slider.id}>
175+
<Text style={styles.question}>
176+
{slider.label}: {slidersData[index].initialValue} km
177+
</Text>
178+
<Slider
179+
style={styles.silder}
180+
minimumValue={slider.minValue}
181+
maximumValue={slider.maxValue}
182+
step={50}
183+
minimumTrackTintColor={Colors.DARKGREEN}
184+
maximumTrackTintColor={Colors.FILLGREEN}
185+
thumbTintColor={Colors.WHITE}
186+
value={slidersData[index].initialValue}
187+
onValueChange={(value) => onSliderValueChange(value, index)}
188+
/>
189+
<View style={styles.labelContainer}>
190+
<Text style={styles.label}>{slider.minValue}</Text>
191+
<Text style={styles.label}>{slider.maxValue}</Text>
192+
</View>
193+
{/* You can include additional components related to this slider here */}
194+
</View>
195+
))}
196+
197+
<TouchableOpacity style={styles.buttoning} onPress={handleSurveySubmit}>
198+
<Text style={styles.buttoningText}>Save</Text>
199+
</TouchableOpacity>
200+
</ScrollView>
201+
</SafeAreaView>
202+
);
203+
}
204+
205+
const styles = StyleSheet.create({
206+
container: {
207+
flex: 1,
208+
justifyContent: 'center',
209+
backgroundColor: Colors.LIGHTFGREEN,
210+
},
211+
labelContainer: {
212+
flexDirection: 'row',
213+
justifyContent: 'space-between',
214+
width: '100%',
215+
paddingHorizontal: 12,
216+
},
217+
modalBackground: {
218+
backgroundColor: Colors.BLACKTRANS,
219+
flex: 1,
220+
},
221+
modalContainer: {
222+
backgroundColor: Colors.WHITE,
223+
marginHorizontal: 50,
224+
marginVertical: 180,
225+
padding: 20,
226+
borderRadius: 10,
227+
flex: 1,
228+
flexDirection: 'row',
229+
},
230+
scrollContainer: {
231+
paddingTop: 30,
232+
flex: 1,
233+
paddingHorizontal: 30,
234+
backgroundColor: Colors.LIGHTFGREEN,
235+
},
236+
label: {
237+
fontSize: 15,
238+
},
239+
header: {
240+
color: Colors.DARKGREEN,
241+
fontFamily: 'Montserrat',
242+
fontSize: 25,
243+
fontWeight: '700',
244+
marginBottom: 50,
245+
},
246+
question: {
247+
fontFamily: 'Montserrat',
248+
fontSize: 20,
249+
fontWeight: '700',
250+
color: Colors.DARKGREEN,
251+
marginBottom: 20,
252+
},
253+
buttoning: {
254+
backgroundColor: Colors.DARKGREEN,
255+
borderRadius: 10,
256+
marginBottom: 70,
257+
padding: 18,
258+
},
259+
buttoningText: {
260+
color: Colors.WHITE,
261+
fontSize: 16,
262+
fontWeight: '700',
263+
textAlign: 'center',
264+
},
265+
questionContainer: {
266+
paddingBottom: 30,
267+
},
268+
infoText: {
269+
fontSize: 20,
270+
color: Colors.DARKGREEN,
271+
},
272+
linkText: {
273+
color: Colors.BLUE,
274+
},
275+
closeIcon: {
276+
marginLeft: 'auto',
277+
},
278+
silder: {
279+
height: 50,
280+
width: '100%',
281+
},
282+
});

0 commit comments

Comments
 (0)