diff --git a/README.md b/README.md index 2f24e92..8b13789 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# StemDevops_INFIX \ No newline at end of file + diff --git a/frontend/infix/assets/card2.jpg b/frontend/infix/assets/card2.jpg index 703b020..a300f9c 100644 Binary files a/frontend/infix/assets/card2.jpg and b/frontend/infix/assets/card2.jpg differ diff --git a/frontend/infix/assets/profile2.jpeg b/frontend/infix/assets/profile2.jpeg new file mode 100644 index 0000000..25c0e0c Binary files /dev/null and b/frontend/infix/assets/profile2.jpeg differ diff --git a/frontend/infix/components/InputTextField.js b/frontend/infix/components/InputTextField.js new file mode 100644 index 0000000..c3e38ec --- /dev/null +++ b/frontend/infix/components/InputTextField.js @@ -0,0 +1,60 @@ +import { + Text, + StyleSheet, + TextInput, + View, + TouchableOpacity, +} from "react-native"; +import {useEffect, useState} from "react"; +import Ionicons from "@expo/vector-icons/Ionicons"; + +const InputTextField = ({placeholder, icon, action, value, secureTextEntry,style}) => { + + return ( + + + + ); +}; + +const styles = StyleSheet.create({ + inputContainer: { + width: '100%', + flexDirection: "row", + alignItems: "center", + marginHorizontal: 10, + paddingLeft: 20, + marginVertical: 5, + elevation: 3, + shadowColor: "#000", + shadowOffset: {width: 0, height: 2}, + shadowOpacity: 0.4, + shadowRadius: 2, + backgroundColor: "rgb(131,163,190)", + borderRadius: 50, + height: 50, + borderColor: "#2C5D87", + borderWidth: 1, + }, + input: { + flex: 8, + width: "100%", + height: "100%", + fontSize: 16, + fontWeight: "bold", + paddingHorizontal: 10, + color: "rgb(255,255,255)", + }, + toggleIcon: { + flex: 1, + marginRight: 10, + }, +}); + +export default InputTextField; diff --git a/frontend/infix/components/MultiTrip.js b/frontend/infix/components/MultiTrip.js new file mode 100644 index 0000000..d1722cc --- /dev/null +++ b/frontend/infix/components/MultiTrip.js @@ -0,0 +1,129 @@ +import {ScrollView, StyleSheet, Text, TouchableOpacity, View} from "react-native"; +import InputTextField from "./InputTextField"; +import React, {useState} from "react"; +import Ionicons from "@expo/vector-icons/Ionicons"; + +const MultiTrip = () => { + + const [count, setCount] = useState(1) + + const returnTopField = () => { + return Array.from({ length: count }, (_, i) => ( + + + + + + )); + } + + const addTrip =()=>{ + setCount(count+1); + } + + return ( + + + {returnTopField()} + + + Add trip + + + + + + + Checkout + + + + + + Lunar days can be scorching hot, while nights are freezing cold. Radiation from the Sun and cosmic + rays is a constant concern. + + To combat these challenges, colony habitats would be equipped with advanced climate control systems, + insulation, and radiation shielding. Renewable energy sources such as solar panels and possibly even + harnessing lunar resources for energy generation would be crucial. The thin lunar atmosphere might + be harnessed for limited agricultural purposes, using controlled hydroponic or aeroponic systems. + + + + ) +} +const styles = StyleSheet.create({ + container: { + flex: 1, + width: '100%', + height: '100%', + }, + inputContainer: { + width: '90%', + alignItems: 'center', + marginTop: 20, + + }, + divider: { + width: '100%', + height: 1, + backgroundColor: 'rgba(219,233,245,0.7)', + marginTop: 30 + }, + detailsContainer: { + width: '90%', + alignItems: 'center', + marginTop: 20, + backgroundColor: 'rgba(137,169,192,0.7)', + borderRadius: 10, + padding: 20, + borderWidth: 2, + borderColor: 'rgba(0,43,72,0.7)', + minHeight: 200, + overflow: 'scroll' + }, + detailsText: { + color: '#fff', + fontSize: 15, + }, + dateContainer: { + flexDirection: 'row', + width: '100%', + alignItems:'center', + justifyContent: 'space-between', + + }, + dateInput:{ + width: '32%', + marginHorizontal: 0, + }, + checkoutContainer: { + width: '60%', + borderRadius: 20, + marginTop: 20, + paddingVertical: 10, + backgroundColor: '#003A6B', + alignItems: "center", + justifyContent: "center" + }, + checkoutText: { + color: '#fff', + fontSize: 20, + fontWeight: "bold", + }, + addTripContainer: { + flexDirection: 'row', + alignItems: 'center', + alignSelf: 'flex-start', + marginTop: 10, + marginBottom: 10, + marginLeft: 10 + }, + addTripText:{ + fontSize: 16, + color: '#fff', + marginLeft: 10 + } + +}); +export default MultiTrip; \ No newline at end of file diff --git a/frontend/infix/components/Notification.js b/frontend/infix/components/Notification.js new file mode 100644 index 0000000..5df6768 --- /dev/null +++ b/frontend/infix/components/Notification.js @@ -0,0 +1,68 @@ +import React from 'react'; +import {View, Text, StyleSheet, Image, Platform} from 'react-native'; + +const Notification = ({profile, notiHeader, notiContent}) => { + + return ( + + + + {notiHeader} + {notiContent} + + + ); +}; +export default Notification; + +const styles = StyleSheet.create({ + profileImg: { + width: 50, + height: 50, + borderRadius: 25, + marginRight: 10, + }, + + notificationContainer: { + width: '90%', + margin: 12, + padding: 10, + backgroundColor: 'rgba(44, 93, 135, 0.6)', + borderRadius: 25, + flexDirection: 'row', + justifyContent: 'flex-start', + ...Platform.select({ + ios: { + shadowColor: '#000', + shadowOffset: { width: 0, height: 1 }, + shadowOpacity: 0.25, + shadowRadius: 4, + }, + android: { + elevation: 10, + }, + }) + }, + notificationContainer2: { + padding: 5, + justifyContent: 'flex-start', + }, + notiHeader:{ + color: '#ffffff', + fontSize: 18, + fontWeight: 'bold', + }, + noti:{ + color: '#ffffff', + fontSize: 12, + }, + notiCategory:{ + color: '#ffffff', + fontSize: 18, + fontWeight: 'bold', + alignSelf: 'flex-start', + marginLeft: '15%', + marginTop: 20, + }, +} +) \ No newline at end of file diff --git a/frontend/infix/components/RoundTrip.js b/frontend/infix/components/RoundTrip.js new file mode 100644 index 0000000..c813437 --- /dev/null +++ b/frontend/infix/components/RoundTrip.js @@ -0,0 +1,108 @@ +import {ScrollView, StyleSheet, Text, TouchableOpacity, View} from "react-native"; +import InputTextField from "./InputTextField"; +import React, {useState} from "react"; + +const RoundTrip = () => { + + const [departure, setDeparture] = useState(""); + const [destination, setDestination] = useState(""); + const [departureDate, setDepartureDate] = useState(""); + const [arrivalDate, setArrivalDate] =useState("") + const [travelMode, setTravelMode] = useState("Spaceship"); + const [ticketCount, setTicketCount] = useState(1); + + return ( + + + + + + + + + + + + + + Checkout + + + + + + Lunar days can be scorching hot, while nights are freezing cold. Radiation from the Sun and cosmic + rays is a constant concern. + + To combat these challenges, colony habitats would be equipped with advanced climate control systems, + insulation, and radiation shielding. Renewable energy sources such as solar panels and possibly even + harnessing lunar resources for energy generation would be crucial. The thin lunar atmosphere might + be harnessed for limited agricultural purposes, using controlled hydroponic or aeroponic systems. + + + + ) +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + width: '100%', + height: '100%', + }, + inputContainer: { + width: '90%', + alignItems: 'center', + marginTop: 20, + + }, + divider: { + width: '100%', + height: 1, + backgroundColor: 'rgba(219,233,245,0.7)', + marginTop: 30 + }, + detailsContainer: { + width: '90%', + alignItems: 'center', + marginTop: 20, + backgroundColor: 'rgba(137,169,192,0.7)', + borderRadius: 10, + padding: 20, + borderWidth: 2, + borderColor: 'rgba(0,43,72,0.7)', + minHeight: 200, + overflow: 'scroll' + }, + detailsText: { + color: '#fff', + fontSize: 15, + }, + dateContainer: { + flexDirection: 'row', + width: '100%', + alignItems:'center', + justifyContent: 'space-between', + + }, + dateInput:{ + width: '48%', + marginHorizontal: 0, + }, + checkoutContainer: { + width: '60%', + borderRadius: 20, + marginTop: 20, + paddingVertical: 10, + backgroundColor: '#003A6B', + alignItems: "center", + justifyContent: "center" + }, + checkoutText: { + color: '#fff', + fontSize: 20, + fontWeight: "bold", + } + +}); +export default RoundTrip; \ No newline at end of file diff --git a/frontend/infix/components/SingleTrip.js b/frontend/infix/components/SingleTrip.js new file mode 100644 index 0000000..d38e5a0 --- /dev/null +++ b/frontend/infix/components/SingleTrip.js @@ -0,0 +1,95 @@ +import {Text, View, StyleSheet, ScrollView, TouchableOpacity} from "react-native"; +import InputTextField from "./InputTextField"; +import React, {useState} from "react"; + +const SingleTrip = () => { + + const [departure, setDeparture] = useState(""); + const [destination, setDestination] = useState(""); + const [departureDate, setDepartureDate] = useState(""); + const [travelMode, setTravelMode] = useState("Spaceship"); + const [ticketCount, setTicketCount] = useState(1); + + + return ( + + + + + + + + + + + Checkout + + + + + + Lunar days can be scorching hot, while nights are freezing cold. Radiation from the Sun and cosmic + rays is a constant concern. + + To combat these challenges, colony habitats would be equipped with advanced climate control systems, + insulation, and radiation shielding. Renewable energy sources such as solar panels and possibly even + harnessing lunar resources for energy generation would be crucial. The thin lunar atmosphere might + be harnessed for limited agricultural purposes, using controlled hydroponic or aeroponic systems. + + + + ) +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + width: '100%', + height: '100%', + + }, + inputContainer: { + width: '90%', + alignItems: 'center', + marginTop: 20, + + }, + divider: { + width: '100%', + height: 1, + backgroundColor: 'rgba(219,233,245,0.7)', + marginTop: 30 + }, + detailsContainer: { + width: '90%', + alignItems: 'center', + marginTop: 20, + backgroundColor: 'rgba(137,169,192,0.7)', + borderRadius: 10, + padding: 20, + borderWidth: 2, + borderColor: 'rgba(0,43,72,0.7)', + minHeight: 200, + overflow: 'scroll' + }, + detailsText: { + color: '#fff', + fontSize: 15, + }, + checkoutContainer: { + width: '60%', + borderRadius: 20, + marginTop: 20, + paddingVertical: 10, + backgroundColor: '#003A6B', + alignItems: "center", + justifyContent: "center" + }, + checkoutText: { + color: '#fff', + fontSize: 20, + fontWeight: "bold", + } + +}); +export default SingleTrip; \ No newline at end of file diff --git a/frontend/infix/components/TicketCard.js b/frontend/infix/components/TicketCard.js new file mode 100644 index 0000000..5a4346d --- /dev/null +++ b/frontend/infix/components/TicketCard.js @@ -0,0 +1,145 @@ +import React, {useState} from 'react'; +import {View, Text, LayoutAnimation, StyleSheet, Image, TouchableWithoutFeedback, Animated, Platform, ImageBackground} from 'react-native'; +import logo from '../assets/Logo.png'; + +const TicketCard = ({travelTo, travelFrom, ticketCount,shipType,ticketID,date, imageSource }) => { + const [expanded, setExpanded] = useState(false); + const ticketContainerHeight = (expanded ? 230 : 85); + const picSize = (expanded ? '40%' : '20%'); + + const handleTicketContainerPress = () => { + LayoutAnimation.configureNext(LayoutAnimation.Presets.spring); + setExpanded(!expanded); + }; + return ( + + + {!expanded && + + + + {expanded && {'From : '+travelFrom}} + {'To : '+travelTo} + {date} + + } + + {expanded && + + + + {'From : '} + {'\t'+travelFrom} + + + {'To : '} + {'\t'+travelTo} + + + + + + {'Depature :'} + {'\t'+date} + + + {'Ship Type :'} + {'\t'+shipType} + + + + + + + {'Ticket Count :'} + {'\t'+ticketCount} + + + {'Ticket ID :'} + {ticketID} + + + + + + + + + + } + + + + ); +}; +export default TicketCard; + +const styles = StyleSheet.create({ + cont1:{ + width:'100%', + flexDirection: 'row', + justifyContent: "space-between", + + }, + cont2:{ + width:'50%', + paddingVertical:5, + }, + text1:{ + color: '#ffffff', + fontSize: 18, + fontWeight: 'bold', + }, + text2:{ + color: '#ffffff', + fontSize: 18, + }, + logo:{ + height:100, + aspectRatio: 1, + alignSelf:'center', + }, + ticketContainer2:{ + flexDirection: 'row', + + }, + ticketContainer:{ + alignSelf: 'center', + width: '90%', + borderRadius: 25, + padding:10, + margin: 12, + + backgroundColor: 'rgba(44, 93, 135, 1)', + justifyContent: 'center', + ...Platform.select({ + ios: { + shadowColor: '#000', + shadowOffset: { width: 0, height: 1 }, + shadowOpacity: 0.25, + shadowRadius: 4, + }, + android: { + elevation: 10, + }, + }) + }, + planetPic:{ + borderRadius: 25, + marginRight: 15, + aspectRatio: 1, + }, + notificationContainer2: { + padding: 5, + marginRight: 10, + alignItems: 'flex-start', + justifyContent: 'space-between', + }, + + travelContent:{ + color: '#ffffff', + fontSize: 18, + fontWeight: 'bold', + }, +} +) \ No newline at end of file diff --git a/frontend/infix/package-lock.json b/frontend/infix/package-lock.json index a22f656..0347062 100644 --- a/frontend/infix/package-lock.json +++ b/frontend/infix/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "dependencies": { "@expo/vector-icons": "^13.0.0", + "@react-native-picker/picker": "^2.5.0", "@react-navigation/bottom-tabs": "^6.5.8", "@react-navigation/native": "^6.1.7", "@react-navigation/native-stack": "^6.9.13", @@ -16,9 +17,12 @@ "axios": "^1.4.0", "expo": "~49.0.7", "expo-status-bar": "~1.6.0", + "lodash.debounce": "^4.0.8", "react": "18.2.0", "react-native": "0.72.3", - "react-native-elements": "^3.4.3" + "react-native-elements": "^3.4.3", + "react-native-gesture-handler": "^2.12.1", + "react-native-reanimated": "^3.4.2" }, "devDependencies": { "@babel/core": "^7.20.0" @@ -1361,6 +1365,20 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-object-assign": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.22.5.tgz", + "integrity": "sha512-iDhx9ARkXq4vhZ2CYOSnQXkmxkDgosLi3J8Z17mKz7LyzthtkdVchLD7WZ3aXeCuvJDOW3+1I5TpJmwIbF9MKQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-transform-object-rest-spread": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.5.tgz", @@ -1964,7 +1982,6 @@ "version": "2.0.17", "resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz", "integrity": "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==", - "peer": true, "dependencies": { "@types/hammerjs": "^2.0.36" }, @@ -5663,6 +5680,15 @@ "node": ">= 8" } }, + "node_modules/@react-native-picker/picker": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@react-native-picker/picker/-/picker-2.5.0.tgz", + "integrity": "sha512-AEZPKwXavmP4VkUUD6bskCrNF+zgd1RvsXJ208YewZSikGZCo0RLlnQxPDrdKoFpbigSYxbvRU5d8h3TzzeQ8Q==", + "peerDependencies": { + "react": ">=16", + "react-native": ">=0.57" + } + }, "node_modules/@react-native/assets-registry": { "version": "0.72.0", "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.72.0.tgz", @@ -5866,8 +5892,7 @@ "node_modules/@types/hammerjs": { "version": "2.0.41", "resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.41.tgz", - "integrity": "sha512-ewXv/ceBaJprikMcxCmWU1FKyMAQ2X7a9Gtmzw8fcg2kIePI1crERDM818W+XYrxqdBBOdlf2rm137bU+BltCA==", - "peer": true + "integrity": "sha512-ewXv/ceBaJprikMcxCmWU1FKyMAQ2X7a9Gtmzw8fcg2kIePI1crERDM818W+XYrxqdBBOdlf2rm137bU+BltCA==" }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.4", @@ -8042,19 +8067,6 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -9593,139 +9605,6 @@ "lightningcss-win32-x64-msvc": "1.19.0" } }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.19.0.tgz", - "integrity": "sha512-wIJmFtYX0rXHsXHSr4+sC5clwblEMji7HHQ4Ub1/CznVRxtCFha6JIt5JZaNf8vQrfdZnBxLLC6R8pC818jXqg==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.19.0.tgz", - "integrity": "sha512-Lif1wD6P4poaw9c/4Uh2z+gmrWhw/HtXFoeZ3bEsv6Ia4tt8rOJBdkfVaUJ6VXmpKHALve+iTyP2+50xY1wKPw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.19.0.tgz", - "integrity": "sha512-P15VXY5682mTXaiDtbnLYQflc8BYb774j2R84FgDLJTN6Qp0ZjWEFyN1SPqyfTj2B2TFjRHRUvQSSZ7qN4Weig==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.19.0.tgz", - "integrity": "sha512-zwXRjWqpev8wqO0sv0M1aM1PpjHz6RVIsBcxKszIG83Befuh4yNysjgHVplF9RTU7eozGe3Ts7r6we1+Qkqsww==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.19.0.tgz", - "integrity": "sha512-vSCKO7SDnZaFN9zEloKSZM5/kC5gbzUjoJQ43BvUpyTFUX7ACs/mDfl2Eq6fdz2+uWhUh7vf92c4EaaP4udEtA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.19.0.tgz", - "integrity": "sha512-0AFQKvVzXf9byrXUq9z0anMGLdZJS+XSDqidyijI5njIwj6MdbvX2UZK/c4FfNmeRa2N/8ngTffoIuOUit5eIQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-musl": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.19.0.tgz", - "integrity": "sha512-SJoM8CLPt6ECCgSuWe+g0qo8dqQYVcPiW2s19dxkmSI5+Uu1GIRzyKA0b7QqmEXolA+oSJhQqCmJpzjY4CuZAg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, "node_modules/lightningcss-win32-x64-msvc": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.19.0.tgz", @@ -12037,7 +11916,6 @@ "version": "2.12.1", "resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.12.1.tgz", "integrity": "sha512-deqh36bw82CFUV9EC4tTo2PP1i9HfCOORGS3Zmv71UYhEZEHkzZv18IZNPB+2Awzj45vLIidZxGYGFxHlDSQ5A==", - "peer": true, "dependencies": { "@egjs/hammerjs": "^2.0.17", "hoist-non-react-statics": "^3.3.0", @@ -12062,6 +11940,32 @@ "react-native": "*" } }, + "node_modules/react-native-reanimated": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.4.2.tgz", + "integrity": "sha512-FbtG+f1PB005vDTJSv4zAnTK7nNXi+FjFgbAM5gOzIZDajfph2BFMSUstzIsN8T77+OKuugUBmcTqLnQ24EBVg==", + "dependencies": { + "@babel/plugin-transform-object-assign": "^7.16.7", + "@babel/preset-typescript": "^7.16.7", + "convert-source-map": "^2.0.0", + "invariant": "^2.2.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0-0", + "@babel/plugin-proposal-optional-chaining": "^7.0.0-0", + "@babel/plugin-transform-arrow-functions": "^7.0.0-0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0-0", + "@babel/plugin-transform-template-literals": "^7.0.0-0", + "react": "*", + "react-native": "*" + } + }, + "node_modules/react-native-reanimated/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + }, "node_modules/react-native-safe-area-context": { "version": "4.7.1", "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.7.1.tgz", diff --git a/frontend/infix/package.json b/frontend/infix/package.json index ab46977..43ef92b 100644 --- a/frontend/infix/package.json +++ b/frontend/infix/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "@expo/vector-icons": "^13.0.0", + "@react-native-picker/picker": "^2.5.0", "@react-navigation/bottom-tabs": "^6.5.8", "@react-navigation/native": "^6.1.7", "@react-navigation/native-stack": "^6.9.13", @@ -17,9 +18,12 @@ "axios": "^1.4.0", "expo": "~49.0.7", "expo-status-bar": "~1.6.0", + "lodash.debounce": "^4.0.8", "react": "18.2.0", "react-native": "0.72.3", - "react-native-elements": "^3.4.3" + "react-native-elements": "^3.4.3", + "react-native-gesture-handler": "^2.12.1", + "react-native-reanimated": "^3.4.2" }, "devDependencies": { "@babel/core": "^7.20.0" diff --git a/frontend/infix/views/NotificationsScreen.js b/frontend/infix/views/NotificationsScreen.js index 31e30ae..9138320 100644 --- a/frontend/infix/views/NotificationsScreen.js +++ b/frontend/infix/views/NotificationsScreen.js @@ -1,18 +1,21 @@ -import {View, Text, TouchableOpacity, SafeAreaView, StyleSheet, ImageBackground, Image, ScrollView} from 'react-native'; +import {View, Text, TouchableOpacity, SafeAreaView, StyleSheet, ImageBackground, Image, ScrollView, Platform} from 'react-native'; import React, {useState} from 'react'; -import { Platform } from 'react-native'; import bg from "../assets/Notifications_bg.png"; import Ionicons from "@expo/vector-icons/Ionicons"; -import profile from "../assets/profile.png"; +import Notification from "../components/Notification"; export default NotificationsScreen = ({ navigation }) => { - const [notiHeader, setNotiHeader] = useState('Susan Robert'); - const [noti, setNoti] = useState('Susan Robert likes your memory on Moon001'); const gotoBack = () => { navigation.navigate('Home'); } + + const [your_notifications, set_your_notifications] = useState([ + {id: 1, profile: require('../assets/profile2.jpeg'), notiHeader:'Susan Robert', notiContent: 'Susan Robert likes your memory on Moon001',}, + {id: 2, profile: require('../assets/card13.png'), notiHeader:'Offer', notiContent: '20% offer to Moon 2069',}, + {id: 3, profile: require('../assets/card3.png'), notiHeader:'Offer', notiContent: '20% offer to ZL 0043',}, + ]) return ( @@ -30,13 +33,16 @@ export default NotificationsScreen = ({ navigation }) => { Today - - - - {notiHeader} - {noti} - - + + {your_notifications.map((notifi) => ( + + ))} + @@ -77,8 +83,6 @@ export default NotificationsScreen = ({ navigation }) => { alignSelf: 'center', }, headerBtnContainer: { - justifyContent: 'space-between', - flexDirection: 'row', marginRight: 40, }, profileImg: { @@ -105,7 +109,7 @@ export default NotificationsScreen = ({ navigation }) => { shadowRadius: 4, }, android: { - elevation: 1, + elevation: 10, }, }) }, @@ -130,5 +134,9 @@ export default NotificationsScreen = ({ navigation }) => { marginLeft: '15%', marginTop: 20, }, + scrollContainer: { + width: "100%", + marginTop: 10, + }, } ) \ No newline at end of file diff --git a/frontend/infix/views/PlanetDetailScreen.js b/frontend/infix/views/PlanetDetailScreen.js new file mode 100644 index 0000000..0784dd8 --- /dev/null +++ b/frontend/infix/views/PlanetDetailScreen.js @@ -0,0 +1,152 @@ +import {View, Text, TouchableOpacity, SafeAreaView, StyleSheet, ImageBackground, Image, ScrollView} from 'react-native'; +import React, {useState} from 'react'; +import { Platform } from 'react-native'; + +import bg from "../assets/Notifications_bg.png"; +import planetProfile from "../assets/card2.jpg"; +import Ionicons from "@expo/vector-icons/Ionicons"; + +export default PlanetDetailsScreen = ({ navigation }) => { + + const [planetName, setPlanetName] = useState('Moon 001'); + + const gotoTravel = () => { + navigation.navigate('Travel'); + } + + const [planet_photoes, set_planet_photoes] = useState([ + {id: 1, image: require('../assets/card1.png'),}, + {id: 2, image: require('../assets/card2.jpg'),}, + {id: 3, image: require('../assets/card3.png'),}, + {id: 4, image: require('../assets/card4.png'),}, + {id: 5, image: require('../assets/card5.png'),}, + {id: 6, image: require('../assets/card6.png'),}, + ]) + return ( + + + + + + + + + + + {planetName} + + + + + + + + + Book Now + + + + + {planet_photoes ? planet_photoes.map((item) => { + return + }) : null} + + + + + + + + + + + + + ) + } +const styles = StyleSheet.create({ + container: { + flex: 1, + width: '100%', + height: '100%', + alignItems: 'center', + }, + image: { + flex: 1, + width: '100%', + height: '100%', + backgroundColor: '#41729d', + }, + header: { + width: '100%', + alignItems: 'center', + paddingHorizontal: 20, + flexDirection: 'row', + marginBottom: 20, + ...Platform.select({ + ios: { + marginTop: 10, + }, + android: { + marginTop: 40, + }, + }) + }, + headertextwelcome: { + color: '#fff', + fontSize: 25, + fontWeight: 'bold', + marginLeft: '30%', + }, + headerBtnContainer: { + justifyContent: 'space-between', + flexDirection: 'row' + }, + profileImg: { + width: 160, + height: 160, + borderRadius: 80, + borderWidth: 2, + borderColor: '#fff', + marginBottom: "1%", + alignSelf: 'center', + }, + bookTrip:{ + alignSelf: 'center', + paddingVertical: 15, + paddingHorizontal: 25, + marginEnd:'10%', + backgroundColor: '#5880A2', + borderRadius: 45, + alignSelf: 'flex-end', + ...Platform.select({ + ios: { + shadowColor: '#000', + shadowOffset: { width: 0, height: 1 }, + shadowOpacity: 0.25, + shadowRadius: 4, + }, + android: { + elevation: 10, + }, + }) + }, + Text1:{ + color: "#ffffff", + fontSize: 14, + fontWeight: "bold", + + }, + hscroll: { + width: "100%", + marginTop: 10, + paddingVertical: 10, + }, + hscrollContainer: { + paddingBottom: 20, + }, + + +} +) \ No newline at end of file diff --git a/frontend/infix/views/ProfileScreen.js b/frontend/infix/views/ProfileScreen.js index 296bd60..80731a7 100644 --- a/frontend/infix/views/ProfileScreen.js +++ b/frontend/infix/views/ProfileScreen.js @@ -1,283 +1,295 @@ -import {View, Text, TouchableOpacity, SafeAreaView, StyleSheet, ImageBackground, Image, ScrollView} from 'react-native'; -import React from "react"; -import {authContext} from "../context/AuthContext"; -import bg from "../assets/home_bg.png"; -import profile from "../assets/profile.png"; -import earth from "../assets/card2.jpg"; -import Ionicons from "@expo/vector-icons/Ionicons"; -import Card from "../components/card"; +import { + View, + Text, + TouchableOpacity, + SafeAreaView, + StyleSheet, + ImageBackground, + Image, + ScrollView, +} from "react-native" +import React from "react" +import { authContext } from "../context/AuthContext" +import bg from "../assets/home_bg.png" +import profile from "../assets/profile.png" +import earth from "../assets/card2.jpg" +import Ionicons from "@expo/vector-icons/Ionicons" +import Card from "../components/card" -const ProfileScreen = ({navigation}) => { +const ProfileScreen = ({ navigation }) => { + const { isAuthenticated, logout, user } = React.useContext(authContext) + const onLogoutPressed = () => { + logout() + } - const {isAuthenticated, logout} = React.useContext(authContext); - const onLogoutPressed = () => { - logout(); - } + const gotoNotifications = () => { + navigation.navigate("Notifications") + } + const gotoSettings = () => { + navigation.navigate("Settings") + } + return ( + + + + + + {user} + + + + + + + + + + + + + + + + 101 Memories + + + + 58 Points + + + - const gotoNotifications = () => { - navigation.navigate('Notifications'); - } - const gotoSettings = () => { - navigation.navigate('Settings'); - } - return ( - - - - - - Josh Peter - - - - - - - - - - - - - - - - 101 Memories - - - - 58 Points - - - + - + + + + Current Memory + Jupiter + + + + + + Add memory + + + - - - - Current Memory - Jupiter - - - - - - Add memory - - - + - + + You Memories + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - You Memories - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Logout - - - - - - ) + + + Logout + + + + + + ) } const styles = StyleSheet.create({ - container: { - flex: 1, - width: '100%', - height: '100%', - alignItems: 'center', - }, - image: { - flex: 1, - width: '100%', - height: '100%', - backgroundColor: '#41729d', - }, - header: { - width: '100%', - alignItems: 'center', - paddingHorizontal: 20, - marginTop: 30, - flexDirection: 'row', - justifyContent: 'space-between', - - }, - headertextwelcome: { - color: '#fff', - fontSize: 30, - fontWeight: 'bold', - }, - headertext: { - color: '#fff', - fontSize: 20, - fontWeight: 'bold', - }, - headerBtnContainer: { - width: "22%", - justifyContent: 'space-between', - flexDirection: 'row' - }, - detailSection: { - width: '100%', - alignItems: 'center', - paddingHorizontal: 20, - marginTop: 30, - flexDirection: 'row', - justifyContent: 'space-between', - }, - profileImg: { - width: 100, - height: 100, - borderRadius: 50, - borderWidth: 2, - borderColor: '#fff' - }, - profileDetailsContainer: { - width: '60%', - justifyContent: 'space-between', - alignItems: 'center', - flexDirection: 'column', - }, - profileDetails: { - width: '100%', - justifyContent: 'flex-start', - alignItems: 'center', - flexDirection: 'row', - marginVertical: 5 - }, - profileDetailsText: { - color: '#fff', - fontSize: 20, - fontWeight: 'bold', - marginLeft: 10 - }, - divider: { - width: '100%', - height: 1, - backgroundColor: 'rgba(219,233,245,0.7)', - marginTop: 30 - }, - memoryContainer: { - width: '90%', - height: 100, - alignItems: 'center', - paddingHorizontal: 20, - paddingVertical: 10, - marginTop: 30, - flexDirection: 'row', - backgroundColor: 'rgba(219,233,245,0.5)', - justifyContent: 'space-between', - borderRadius: 20, - }, - memoryImage: { - width: 60, - height: 60, - borderRadius: 50, - }, - memoryDetailsContainer: { - flexDirection: 'column', - justifyContent: 'space-evenly', - alignItems: 'flex-start', - width: '60%', - height: '100%', - - }, - memoryText: { - color: '#fff', - fontSize: 16, - fontWeight: 'bold', - - }, - addMemoryBtn: { - width: '90%', - alignItems: 'center', - justifyContent: 'flex-end', - flexDirection: 'row', - marginTop: 20 - }, - addMemoryBtnText: { - color: '#fff', - fontSize: 16, - fontWeight: 'bold', - marginRight: 10 - }, - youMemoriesContainer: { - width: '100%', - alignItems: 'center', - marginTop: 20, - }, - yourMemoriesHeading: { - color: '#fff', - fontSize: 25, - fontWeight: 'bold', - marginBottom: 10, - alignSelf: 'flex-start', - paddingHorizontal: 20 - }, - yourMemories: { - width: '100%', - alignItems: 'center', - paddingVertical: 10, - flexDirection: 'row', - justifyContent: 'space-between', - }, - yourMemoriesCard: { - marginVertical: 10, - }, - logoutBtnContainer: { - width: '100%', - alignItems: 'center', - marginTop: 20, - marginBottom: 20 - }, - logoutBtnText: { - color: '#fff', - fontSize: 16, - fontWeight: 'bold', - }, - logoutBtn: { - width: '60%', - alignItems: 'center', - justifyContent: 'center', - flexDirection: 'row', - backgroundColor: '#941111', - paddingVertical: 15, - borderRadius: 10, - } - - -}); -export default ProfileScreen; \ No newline at end of file + container: { + flex: 1, + width: "100%", + height: "100%", + alignItems: "center", + }, + image: { + flex: 1, + width: "100%", + height: "100%", + backgroundColor: "#41729d", + }, + header: { + width: "100%", + alignItems: "center", + paddingHorizontal: 20, + marginTop: 30, + flexDirection: "row", + justifyContent: "space-between", + }, + headertextwelcome: { + color: "#fff", + fontSize: 30, + fontWeight: "bold", + }, + headertext: { + color: "#fff", + fontSize: 20, + fontWeight: "bold", + }, + headerBtnContainer: { + width: "22%", + justifyContent: "space-between", + flexDirection: "row", + }, + detailSection: { + width: "100%", + alignItems: "center", + paddingHorizontal: 20, + marginTop: 30, + flexDirection: "row", + justifyContent: "space-between", + }, + profileImg: { + width: 100, + height: 100, + borderRadius: 50, + borderWidth: 2, + borderColor: "#fff", + }, + profileDetailsContainer: { + width: "60%", + justifyContent: "space-between", + alignItems: "center", + flexDirection: "column", + }, + profileDetails: { + width: "100%", + justifyContent: "flex-start", + alignItems: "center", + flexDirection: "row", + marginVertical: 5, + }, + profileDetailsText: { + color: "#fff", + fontSize: 20, + fontWeight: "bold", + marginLeft: 10, + }, + divider: { + width: "100%", + height: 1, + backgroundColor: "rgba(219,233,245,0.7)", + marginTop: 30, + }, + memoryContainer: { + width: "90%", + height: 100, + alignItems: "center", + paddingHorizontal: 20, + paddingVertical: 10, + marginTop: 30, + flexDirection: "row", + backgroundColor: "rgba(219,233,245,0.5)", + justifyContent: "space-between", + borderRadius: 20, + }, + memoryImage: { + width: 60, + height: 60, + borderRadius: 50, + }, + memoryDetailsContainer: { + flexDirection: "column", + justifyContent: "space-evenly", + alignItems: "flex-start", + width: "60%", + height: "100%", + }, + memoryText: { + color: "#fff", + fontSize: 16, + fontWeight: "bold", + }, + addMemoryBtn: { + width: "90%", + alignItems: "center", + justifyContent: "flex-end", + flexDirection: "row", + marginTop: 20, + }, + addMemoryBtnText: { + color: "#fff", + fontSize: 16, + fontWeight: "bold", + marginRight: 10, + }, + youMemoriesContainer: { + width: "100%", + alignItems: "center", + marginTop: 20, + }, + yourMemoriesHeading: { + color: "#fff", + fontSize: 25, + fontWeight: "bold", + marginBottom: 10, + alignSelf: "flex-start", + paddingHorizontal: 20, + }, + yourMemories: { + width: "100%", + alignItems: "center", + paddingVertical: 10, + flexDirection: "row", + justifyContent: "space-between", + }, + yourMemoriesCard: { + marginVertical: 10, + }, + logoutBtnContainer: { + width: "100%", + alignItems: "center", + marginTop: 20, + marginBottom: 20, + }, + logoutBtnText: { + color: "#fff", + fontSize: 16, + fontWeight: "bold", + }, + logoutBtn: { + width: "60%", + alignItems: "center", + justifyContent: "center", + flexDirection: "row", + backgroundColor: "#941111", + paddingVertical: 15, + borderRadius: 10, + }, +}) +export default ProfileScreen diff --git a/frontend/infix/views/Settings.js b/frontend/infix/views/Settings.js index 92033d9..c8d6789 100644 --- a/frontend/infix/views/Settings.js +++ b/frontend/infix/views/Settings.js @@ -6,7 +6,7 @@ import bg from "../assets/settings_bg.png"; import profile from "../assets/profile.png"; import Ionicons from "@expo/vector-icons/Ionicons"; -export default HelpCenter = ({ navigation }) => { +export default SettingsScreen = ({ navigation }) => { const [UID, setUID] = useState('123456789ABCD'); diff --git a/frontend/infix/views/Tickets.js b/frontend/infix/views/Tickets.js new file mode 100644 index 0000000..91ce1fa --- /dev/null +++ b/frontend/infix/views/Tickets.js @@ -0,0 +1,99 @@ +import {View, Text, TouchableOpacity,LayoutAnimation, SafeAreaView, StyleSheet, ImageBackground, Image, ScrollView, TouchableWithoutFeedback, Animated, Platform} from 'react-native'; +import React, {useState} from 'react'; + +import bg from "../assets/Notifications_bg.png"; +import Ionicons from "@expo/vector-icons/Ionicons"; +import planetPic from "../assets/card2.jpg"; +import TicketCard from '../components/TicketCard'; + +const Tickets = ({ navigation }) => { + + const [your_tickets, set_your_tickets] = useState([ + {id: 1, travelTo: "Moon 0001", travelFrom:'MZ 0054', ticketCount: '3',shipType: 'Air Bus',ticketID: '2901-9493-2322',date:'2166-02-17', imageSource: require('../assets/card2.jpg')}, + {id: 2, travelTo: "Moon 0001", travelFrom:'MZ 0054', ticketCount: '3',shipType: 'Air Bus',ticketID: '2901-9493-2322',date:'2166-02-17', imageSource: require('../assets/card2.jpg')}, + {id: 3, travelTo: "Moon 0001", travelFrom:'MZ 0054', ticketCount: '3',shipType: 'Air Bus',ticketID: '2901-9493-2322',date:'2166-02-17', imageSource: require('../assets/card2.jpg')}, + {id: 4, travelTo: "Moon 0001", travelFrom:'MZ 0054', ticketCount: '3',shipType: 'Air Bus',ticketID: '2901-9493-2322',date:'2166-02-17', imageSource: require('../assets/card2.jpg')}, + {id: 5, travelTo: "Moon 0001", travelFrom:'MZ 0054', ticketCount: '3',shipType: 'Air Bus',ticketID: '2901-9493-2322',date:'2166-02-17', imageSource: require('../assets/card2.jpg')}, + {id: 6, travelTo: "Moon 0001", travelFrom:'MZ 0054', ticketCount: '3',shipType: 'Air Bus',ticketID: '2901-9493-2322',date:'2166-02-17', imageSource: require('../assets/card2.jpg')}, + ]) + const gotoBack = () => { + navigation.navigate('Home'); + } + return ( + + + + + + + + + + + Your Tickets + + + + + {your_tickets.map((ticket) => ( + + ))} + + + + + ) + } +export default Tickets; + + const styles = StyleSheet.create({ + container: { + flex: 1, + width: '100%', + height: '100%', + alignItems: 'center', + }, + image: { + flex: 1, + width: '100%', + height: '100%', + backgroundColor: '#41729d', + }, + header: { + width: '100%', + alignItems: 'center', + paddingHorizontal: 20, + flexDirection: 'row', + ...Platform.select({ + ios: { + marginTop: 10, + }, + android: { + marginTop: 40, + }, + }) + }, + headertext: { + color: '#fff', + fontSize: 25, + fontWeight: 'bold', + alignSelf: 'center', + }, + headerBtnContainer: { + marginRight: 40, + }, + scrollContainer: { + width: "100%", + marginTop: 10, + }, +} +) \ No newline at end of file diff --git a/frontend/infix/views/TravelScreen.js b/frontend/infix/views/TravelScreen.js index d866382..5cc173f 100644 --- a/frontend/infix/views/TravelScreen.js +++ b/frontend/infix/views/TravelScreen.js @@ -1,14 +1,169 @@ -import { View, Text } from 'react-native'; +import React, {useState} from "react"; +import { + View, + StyleSheet, + Text, + ImageBackground, + SafeAreaView, + TouchableOpacity, +} from "react-native"; +import Ionicons from "@expo/vector-icons/Ionicons"; +import bg from "../assets/home_bg.png"; +import InputTextField from "../components/InputTextField"; +import SingleTrip from "../components/SingleTrip"; +import RoundTrip from "../components/RoundTrip"; +import MultiTrip from "../components/MultiTrip"; + +const TravelScreen = ({navigation}) => { + const [buttonClicked, setButtonClicked] = useState("Single"); + + const handleButtonClickSingle = () => { + setButtonClicked("Single"); + }; + + const handleButtonClickRound = () => { + setButtonClicked("Round"); + }; + + const handleButtonClickMulti = () => { + setButtonClicked("Multi"); + }; -export default TravelScreen = ({ navigation }) => { - - return ( - - Travel Screen - - - ) - } - \ No newline at end of file + + + + navigation.goBack()}> + + + + Spaceship Search + + + + + + + + ONE-WAY + + + ROUND-TRIP + + + MULTI-PLANET + + + + + + + + {buttonClicked === "Single" && ( + + )} + {buttonClicked === "Round" && ( + + )} + {buttonClicked === "Multi" && ( + + )} + + + + ); +}; + +const styles = StyleSheet.create({ + container: { + width: "100%", + height: "100%", + alignItems: "center", + }, + image: { + width: "100%", + height: "100%", + backgroundColor: "#41729d", + }, + header: { + width: "100%", + alignItems: "center", + paddingHorizontal: 20, + marginTop: 10, + flexDirection: "row", + justifyContent: "space-between", + }, + backButton: { + paddingHorizontal: 0, + marginTop: 30, + }, + pageTitleContainer: { + flex: 1, + justifyContent: "center", + alignItems: "center", + marginTop: 30, + }, + headertextpagename: { + fontSize: 20, + color: "#FFFFFF", + alignItems: "center", + justifyContent: "center", + fontWeight: "bold", + }, + buttonContainer: { + flexDirection: "row", + justifyContent: "space-between", + height: 50, + width: "100%", + marginTop: 20, + }, + button: { + flex: 1, + borderRadius: 2, + alignItems: "center", + justifyContent: "center", + marginHorizontal: 5, + paddingVertical: 10, + }, + buttonText: { + fontSize: 16, + fontWeight: "bold", + color: "#DBE9F5", + }, + + divider: { + width: "100%", + height: 1, + backgroundColor: "#dbe9f5", + shadowColor: "#dbe9f5", + shadowOffset: {width: 0, height: 2}, + shadowOpacity: 0.9, + shadowRadius: 5, + elevation: 10, + marginTop: 0, + }, + bodyContainer: { + width: "100%", + height: "100%", + }, + + bodyContainerStyle: { + width: "100%", + height: "100%", + alignItems: "center", + justifyContent: "center", + backgroundColor: "#FFFFFF", + opacity: 0.9, + }, + label: { + fontSize: 18, + marginBottom: 8, + }, + selectedValue: { + marginTop: 16, + fontSize: 16, + fontWeight: "bold", + }, +}); + +export default TravelScreen; diff --git a/frontend/infix/views/WorldSearchScreen.js b/frontend/infix/views/WorldSearchScreen.js index 4efb08f..b90e4f1 100644 --- a/frontend/infix/views/WorldSearchScreen.js +++ b/frontend/infix/views/WorldSearchScreen.js @@ -1,36 +1,51 @@ -import React, {useState} from "react"; +import React, { useState } from "react" import { - View, - StyleSheet, - Text, - ImageBackground, - SafeAreaView, - TouchableOpacity, - TextInput, -} from "react-native"; -import Ionicons from "@expo/vector-icons/Ionicons"; -import bg from "../assets/Search_bg.png"; + View, + StyleSheet, + Text, + ImageBackground, + SafeAreaView, + TouchableOpacity, + TextInput, +} from "react-native" +import Ionicons from "@expo/vector-icons/Ionicons" +import bg from "../assets/Search_bg.png" +import Axios from "axios" +import _debounce from "lodash.debounce" // Import the debounce function export default WorldSearchScreen = ({ navigation }) => { - const [inputText, setInputText] = useState(''); - const placeholderText = 'Search'; + const [inputText, setInputText] = useState("") + const placeholderText = "Search" + const [searchResults, setSearchResults] = useState([]) const handleTextChange = (text) => { - setInputText(text); - console.log(text); - }; + setInputText(text) // Update inputText state + Axios.get("http://192.168.8.165:3002/destination/search", { + params: { + searchEntry: text, // assuming "searchTerm" is the query parameter name expected by the backend + }, + }) + .then((response) => { + console.log(response.data.destinations) + // Handle the response from the backend if needed + setSearchResults(response.data.destinations) + }) + .catch((error) => { + // Handle errors if the login fails + console.error("Login error:", error) + }) + } const gotoBack = () => { - navigation.navigate('Home'); + navigation.navigate("Home") } - return ( - + return ( + - - + @@ -41,149 +56,140 @@ export default WorldSearchScreen = ({ navigation }) => { - - + + handleTextChange(text)} // Update inputText state + // onSubmitEditing={(text) => handleTextChange(inputText)} // Handle text submission + /> - { inputText !== '' && - Search - Search - Search - Search - Search - Search - Search - Search - Search - Search - Search - Search - - } - - - + {inputText !== "" && searchResults.length>0 && ( + + {searchResults.map((result, index) => ( + + + {result.name} + {/* Display the 'name' property */} + + ))} + + )} - ) - } + ) +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + width: "100%", + height: "100%", + alignItems: "center", + }, + image: { + flex: 1, + width: "100%", + height: "100%", + backgroundColor: "#41729d", + }, + header: { + width: "100%", + alignItems: "center", + paddingHorizontal: 20, + flexDirection: "row", + ...Platform.select({ + ios: { + marginTop: 10, + }, + android: { + marginTop: 40, + }, + }), + }, + headertext: { + color: "#fff", + fontSize: 25, + fontWeight: "bold", + alignSelf: "center", + }, + headerBtnContainer: { + justifyContent: "space-between", + flexDirection: "row", + marginRight: 40, + }, + divider: { + width: "100%", + height: 1, + backgroundColor: "#dbe9f5", + shadowColor: "#dbe9f5", + shadowOffset: { width: 0, height: 2 }, + shadowOpacity: 0.9, + shadowRadius: 5, + elevation: 10, + margin: 20, + }, - const styles = StyleSheet.create({ - container: { - flex: 1, - width: '100%', - height: '100%', - alignItems: 'center', - }, - image: { - flex: 1, - width: '100%', - height: '100%', - backgroundColor: '#41729d', - }, - header: { - width: '100%', - alignItems: 'center', - paddingHorizontal: 20, - flexDirection: 'row', - ...Platform.select({ - ios: { - marginTop: 10, - }, - android: { - marginTop: 40, - }, - }) - }, - headertext: { - color: '#fff', - fontSize: 25, - fontWeight: 'bold', - alignSelf: 'center', - }, - headerBtnContainer: { - justifyContent: 'space-between', - flexDirection: 'row', - marginRight: 40, - - }, - divider: { - width: "100%", - height: 1, - backgroundColor: "#dbe9f5", - shadowColor: "#dbe9f5", - shadowOffset: {width: 0, height: 2}, - shadowOpacity: 0.9, - shadowRadius: 5, - elevation: 10, - margin: 20, + box2: { + flexDirection: "row", + justifyContent: "space-between", + alignItems: "center", }, - -box2:{ - flexDirection: 'row', - justifyContent: 'space-between', - alignItems: 'center', -}, -Text2:{ - width: '90%', - color: '#FFFFFF', - fontSize: 16, - marginLeft: 10, -}, -Text3:{ - color: '#FFFFFF', - fontSize: 16, - padding:10, - alignSelf: 'flex-start', -}, -listItems:{ - width: '90%', - padding: 15, - backgroundColor: 'rgba(131, 163, 190, 0.8)', - borderRadius: 10, - ...Platform.select({ + Text2: { + width: "90%", + color: "#FFFFFF", + fontSize: 16, + marginLeft: 10, + }, + Text3: { + color: "#FFFFFF", + fontSize: 16, + padding: 10, + alignSelf: "flex-start", + }, + listItems: { + width: "90%", + padding: 15, + backgroundColor: "rgba(131, 163, 190, 0.8)", + borderRadius: 10, + ...Platform.select({ ios: { - shadowColor: '#000', - shadowOffset: { width: 0, height: 1 }, - shadowOpacity: 0.25, - shadowRadius: 4, + shadowColor: "#000", + shadowOffset: { width: 0, height: 1 }, + shadowOpacity: 0.25, + shadowRadius: 4, }, android: { - //elevation: 10, + //elevation: 10, }, - }), -}, -listItem:{ - flexDirection: 'row', - alignItems: 'center', -}, -select:{ - width: '90%', - margin: 20, - padding: 15, - flexDirection: 'row', - alignItems: 'center', - alignSelf: 'center', - backgroundColor: 'rgba(131, 163, 190, 0.8)', - borderRadius: 10, - ...Platform.select({ + }), + }, + listItem: { + flexDirection: "row", + alignItems: "center", + }, + select: { + width: "90%", + margin: 20, + padding: 15, + flexDirection: "row", + alignItems: "center", + alignSelf: "center", + backgroundColor: "rgba(131, 163, 190, 0.8)", + borderRadius: 10, + ...Platform.select({ ios: { - shadowColor: '#000', - shadowOffset: { width: 0, height: 1 }, - shadowOpacity: 0.25, - shadowRadius: 4, + shadowColor: "#000", + shadowOffset: { width: 0, height: 1 }, + shadowOpacity: 0.25, + shadowRadius: 4, }, android: { - //elevation: 10, + //elevation: 10, }, - }), -}, - -} -) \ No newline at end of file + }), + }, +}) diff --git a/frontend/infix/views/authentication/Login.js b/frontend/infix/views/authentication/Login.js index f79750c..ca7b319 100644 --- a/frontend/infix/views/authentication/Login.js +++ b/frontend/infix/views/authentication/Login.js @@ -68,7 +68,7 @@ const Login = ({ navigation }) => { { secureTextEntry={false} /> - { + const gotoTravel = () => { + navigation.navigate("Travel") + } -const Home = ({navigation}) => { + const { isAuthenticated, login, user} = React.useContext(authContext) - const gotoTravel = () => { - navigation.navigate('Travel'); - } - const gotoSearch = () => { - navigation.navigate('World Search'); - } - const [pop_destinations, set_pop_destinations] = useState([ - {id: 1, title: "Moon", image: require('../../assets/card1.png'),}, - {id: 2, title: "Jupiter", image: require('../../assets/card2.jpg'),}, - {id: 3, title: "Aurora", image: require('../../assets/card3.png'),}, - {id: 4, title: "Venus", image: require('../../assets/card4.png'),}, - {id: 5, title: "Uranus", image: require('../../assets/card5.png'),}, - {id: 6, title: "Venus Station", image: require('../../assets/card6.png'),}, - ]) + const gotoSearch = () => { + navigation.navigate("World Search") + } + const [pop_destinations, set_pop_destinations] = useState([ + { id: 1, title: "Moon", image: require("../../assets/card1.png") }, + { id: 2, title: "Jupiter", image: require("../../assets/card2.jpg") }, + { id: 3, title: "Aurora", image: require("../../assets/card3.png") }, + { id: 4, title: "Venus", image: require("../../assets/card4.png") }, + { id: 5, title: "Uranus", image: require("../../assets/card5.png") }, + { id: 6, title: "Venus Station", image: require("../../assets/card6.png") }, + ]) - const [top_stories, set_top_stories] = useState([ - {id: 1, title: "Earth", image: require('../../assets/card10.png'),}, - {id: 2, title: "Jupiter", image: require('../../assets/card11.png'),}, - {id: 3, title: "Saturn", image: require('../../assets/card13.png'),}, - {id: 4, title: "Venus", image: require('../../assets/card10.png'),}, - ]) + const [top_stories, set_top_stories] = useState([ + { id: 1, title: "Earth", image: require("../../assets/card10.png") }, + { id: 2, title: "Jupiter", image: require("../../assets/card11.png") }, + { id: 3, title: "Saturn", image: require("../../assets/card13.png") }, + { id: 4, title: "Venus", image: require("../../assets/card10.png") }, + ]) - const [latest_offers, set_latest_offers] = useState([ - {id: 1, image: require('../../assets/offer1.jpg'),}, - {id: 2, image: require('../../assets/offer4.png'),}, - {id: 3, image: require('../../assets/offer3.jpg'),}, - ]) + const [latest_offers, set_latest_offers] = useState([ + { id: 1, image: require("../../assets/offer1.jpg") }, + { id: 2, image: require("../../assets/offer4.png") }, + { id: 3, image: require("../../assets/offer3.jpg") }, + ]) + return ( + + + + + Welcome + {user} + + + + + - return ( - - + + + + Flights + + + + Search + + - - Welcome - Josh Peter - - - - - - - - - - Flights - - - - Search - - - - - - Popular destinations - - - {pop_destinations ? pop_destinations.map((item) => { - return - }) : null} - - - - - Top stories - - - {top_stories ? top_stories.map((item) => { - return - }) : null} - - - - - Latest Offers - - - {latest_offers ? latest_offers.map((item) => { - return - }) : null} - - - - - - - ) + + + Popular destinations + + + {pop_destinations + ? pop_destinations.map((item) => { + return ( + + ) + }) + : null} + + + + + Top stories + + + {top_stories + ? top_stories.map((item) => { + return ( + + ) + }) + : null} + + + + + Latest Offers + + {latest_offers + ? latest_offers.map((item) => { + return ( + + ) + }) + : null} + + + + + + ) } const styles = StyleSheet.create({ diff --git a/server/db/data.txt b/server/db/data.txt index 71eb7e7..f359040 100644 --- a/server/db/data.txt +++ b/server/db/data.txt @@ -37,3 +37,42 @@ VALUES (DEFAULT, 'dwarf planet in the Kuiper belt', 'pluto'), (DEFAULT, 'planet with extreme temperatures', 'mercury'), (DEFAULT, 'the ice giant', 'neptune') + + +INSERT INTO public."Booking-spaceship" (ship_type, starting_id, end_id, price) +VALUES + ('HYPER DRIVES'::ship_type, '5a21bf4c-3414-4ec9-b5ca-876d89cd5b02', '6f8b4e36-a14e-4b3a-abc4-5f460321712a', 2200), + ('SPACE BUS'::ship_type, 'f399ba47-c11a-47a2-8fb6-a9c08d609d8a', '5f4c1351-5306-4ff2-80b2-60b46dbdd425', 1800), + ('HELICARRIER'::ship_type, 'b50737a5-f409-4d01-89e5-bce33c62214e', 'dd7377ee-e35b-4888-96bc-733096e6643a', 1400), + ('HYPER DRIVES'::ship_type, '4c09c5ee-fcd3-4c60-a62e-15675ded29d0', '65e70b61-c200-41f7-8622-3ddcf75372ab', 2600), + ('SPACE BUS'::ship_type, '06870e8b-898c-47d1-b7fc-869215417402', '7a0019f4-05bf-48a8-926c-e50329aa4291', 1200), + ('HELICARRIER'::ship_type, '0c169570-f27f-4f6e-87cb-8aa587df086d', 'f399ba47-c11a-47a2-8fb6-a9c08d609d8a', 1700), + ('HYPER DRIVES'::ship_type, '5f4c1351-5306-4ff2-80b2-60b46dbdd425', 'b50737a5-f409-4d01-89e5-bce33c62214e', 2400), + ('SPACE BUS'::ship_type, 'dd7377ee-e35b-4888-96bc-733096e6643a', '4c09c5ee-fcd3-4c60-a62e-15675ded29d0', 1600), + ('HELICARRIER'::ship_type, '65e70b61-c200-41f7-8622-3ddcf75372ab', '06870e8b-898c-47d1-b7fc-869215417402', 2000), + ('HYPER DRIVES'::ship_type, '7a0019f4-05bf-48a8-926c-e50329aa4291', '0c169570-f27f-4f6e-87cb-8aa587df086d', 2100); + + +INSERT INTO public."Booking-spaceship" (ship_type, starting_id, end_id, price) +VALUES + ('SPACE BUS'::ship_type, '7a0019f4-05bf-48a8-926c-e50329aa4291', '0c169570-f27f-4f6e-87cb-8aa587df086d', 1100), + ('HELICARRIER'::ship_type, '5a21bf4c-3414-4ec9-b5ca-876d89cd5b02', '6f8b4e36-a14e-4b3a-abc4-5f460321712a', 1500), + ('HYPER DRIVES'::ship_type, 'f399ba47-c11a-47a2-8fb6-a9c08d609d8a', '5f4c1351-5306-4ff2-80b2-60b46dbdd425', 2000), + ('SPACE BUS'::ship_type, 'b50737a5-f409-4d01-89e5-bce33c62214e', 'dd7377ee-e35b-4888-96bc-733096e6643a', 1300), + ('HELICARRIER'::ship_type, '4c09c5ee-fcd3-4c60-a62e-15675ded29d0', '65e70b61-c200-41f7-8622-3ddcf75372ab', 1800), + ('HYPER DRIVES'::ship_type, '06870e8b-898c-47d1-b7fc-869215417402', '7a0019f4-05bf-48a8-926c-e50329aa4291', 2500), + ('SPACE BUS'::ship_type, '0c169570-f27f-4f6e-87cb-8aa587df086d', 'f399ba47-c11a-47a2-8fb6-a9c08d609d8a', 1400), + ('HELICARRIER'::ship_type, '5f4c1351-5306-4ff2-80b2-60b46dbdd425', 'b50737a5-f409-4d01-89e5-bce33c62214e', 1700), + ('HYPER DRIVES'::ship_type, 'dd7377ee-e35b-4888-96bc-733096e6643a', '4c09c5ee-fcd3-4c60-a62e-15675ded29d0', 2200), + ('SPACE BUS'::ship_type, '65e70b61-c200-41f7-8622-3ddcf75372ab', '06870e8b-898c-47d1-b7fc-869215417402', 1600); + + +INSERT INTO public."Available Booking" (booking_id, ship_id, starting_id, end_id, starting_time, available_seat_count, starting_date) +VALUES + (DEFAULT, '94a0d173-b383-4ba2-9718-f75a1886218e', '7a0019f4-05bf-48a8-926c-e50329aa4291', '5a21bf4c-3414-4ec9-b5ca-876d89cd5b02', '2023-08-20 01:58:06.000000', 20, '2023-08-21'), + (DEFAULT, 'e9c6b619-69cb-4361-80dc-de8f725293a3', '5a21bf4c-3414-4ec9-b5ca-876d89cd5b02', '6f8b4e36-a14e-4b3a-abc4-5f460321712a', '2023-08-22 10:00:00.000000', 15, '2023-08-22'), + (DEFAULT, 'd0618c59-eaf0-4ec6-9670-1e6c55136d1c', 'f399ba47-c11a-47a2-8fb6-a9c08d609d8a', '5f4c1351-5306-4ff2-80b2-60b46dbdd425', '2023-08-24 09:45:00.000000', 18, '2023-08-24'), + (DEFAULT, '07632671-fda3-4295-9a0c-f9570655737e', '5f4c1351-5306-4ff2-80b2-60b46dbdd425', 'b50737a5-f409-4d01-89e5-bce33c62214e', '2023-08-25 15:00:00.000000', 12, '2023-08-25'), + (DEFAULT, '76072b00-a789-4f2c-97e8-e0dff9c9fd23', 'b50737a5-f409-4d01-89e5-bce33c62214e', 'dd7377ee-e35b-4888-96bc-733096e6643a', '2023-08-26 14:30:00.000000', 30, '2023-08-26'), + (DEFAULT, 'fecbcd98-9b61-451b-8539-1e9fe454e75a', 'dd7377ee-e35b-4888-96bc-733096e6643a', '4c09c5ee-fcd3-4c60-a62e-15675ded29d0', '2023-08-27 17:20:00.000000', 22, '2023-08-27'), + (DEFAULT, 'bb55b625-5b48-4871-af82-0cb821ca1699', '06870e8b-898c-47d1-b7fc-869215417402', '5a21bf4c-3414-4ec9-b5ca-876d89cd5b02', '2023-08-28 08:00:00.000000', 10, '2023-08-28') \ No newline at end of file diff --git a/server/prisma/schema.prisma b/server/prisma/schema.prisma index 541fbbb..c4d36c6 100644 --- a/server/prisma/schema.prisma +++ b/server/prisma/schema.prisma @@ -1,5 +1,6 @@ generator client { - provider = "prisma-client-js" + provider = "prisma-client-js" + previewFeatures = ["views"] } datasource db { @@ -12,7 +13,7 @@ model Available_Booking { ship_id String? @db.Uuid starting_id String? @db.Uuid end_id String? @db.Uuid - starting_time DateTime? @db.Timestamp(6) + starting_time DateTime? @db.Time(6) available_seat_count Int starting_date DateTime? @db.Date local_destination_Available_Booking_end_idTolocal_destination local_destination? @relation("Available_Booking_end_idTolocal_destination", fields: [end_id], references: [local_dest_id], onDelete: NoAction, onUpdate: NoAction, map: "FK_Available Booking.end_id") @@ -131,6 +132,21 @@ model stored_cards { Credentials Credentials? @relation(fields: [universal_id], references: [universal_id], onDelete: NoAction, onUpdate: NoAction, map: "stored_cards_Credentials_universal_id_fk") } +/// The underlying view does not contain a valid unique identifier and can therefore currently not be handled by Prisma Client. +view booking_view { + starting_id String? @db.Uuid + end_id String? @db.Uuid + booking_id String? @db.Uuid + ship_id String? @db.Uuid + price Float? + name String? @db.VarChar(20) + ship_type ship_type? + starting_date DateTime? @db.Date + starting_time DateTime? @db.Time(6) + + @@ignore +} + enum ship_type { SPACE_BUS @map("SPACE BUS") HELICARRIER diff --git a/server/prisma/views/public/booking_view.sql b/server/prisma/views/public/booking_view.sql new file mode 100644 index 0000000..41192b3 --- /dev/null +++ b/server/prisma/views/public/booking_view.sql @@ -0,0 +1,24 @@ +SELECT + t1.starting_id, + t1.end_id, + t1.booking_id, + t1.ship_id, + t3.price, + t2.name, + t2.ship_type, + t1.starting_date, + t1.starting_time +FROM + ( + ( + "Available Booking" t1 + LEFT JOIN "Spaceship" t2 ON ((t1.ship_id = t2.ship_id)) + ) + LEFT JOIN "Booking-spaceship" t3 ON ( + ( + (t2.ship_type = t3.ship_type) + AND (t1.starting_id = t3.starting_id) + AND (t1.end_id = t3.end_id) + ) + ) + ); \ No newline at end of file diff --git a/server/src/api/controllers/bookingController.js b/server/src/api/controllers/bookingController.js index a8e3b2f..b739dd1 100644 --- a/server/src/api/controllers/bookingController.js +++ b/server/src/api/controllers/bookingController.js @@ -1,40 +1,38 @@ -const { getAvailableBookings, createNewBooking,AddBooking } = require('../services/bookingService') -const { getLocatioId } = require('../services/locationService') - +const { + getAvailableBookings, + insertOrderAndTicket +} = require("../services/bookingService") +const { getLocatioId } = require("../services/locationService") const booking = async (req, res) => { - console.log("Booking function") const depature = req.body.depature const destination = req.body.destination const starting_date = req.body.starting_date const starting_id = await getLocatioId(depature) const end_id = await getLocatioId(destination) - - const details = await getAvailableBookings(starting_id,end_id,starting_date) - if(details){ + console.log(req.body) + + const details = await getAvailableBookings(starting_id, end_id, starting_date) + if (details) { console.log("details found") + console.log(details) return res.send({ approved: true }) } } -const addbooking= async(req, res)=>{ - console.log("Add Booking function") - const ship_name = req.body.ship_name - const depature = req.body.depature - const destination = req.body.destination - const starting_id = await getLocatioId(depature) - const end_id = await getLocatioId(destination) - const starting_time = req.body.starting_time - const available_seat_count = req.body.available_seat_count - const starting_date = req.body.starting_date +const placeOrder = async (req, res) => { + console.log("placeOrder function") + const {booking_id, universal_id, order_time, order_type, ship_type, ticket_count} = req.body + const result = await insertOrderAndTicket(booking_id, universal_id, order_time, order_type, ship_type, ticket_count) - const bookingEntry = await AddBooking(ship_name,starting_id,end_id,starting_time,available_seat_count,starting_date) - if(bookingEntry){ - console.log("details added") + if (result) { + console.log("confirmed") + console.log(result) return res.send({ approved: true }) } + } -module.exports = { booking, addbooking } +module.exports = { booking,placeOrder } diff --git a/server/src/api/controllers/destinationController.js b/server/src/api/controllers/destinationController.js index 1f73508..8d635c9 100644 --- a/server/src/api/controllers/destinationController.js +++ b/server/src/api/controllers/destinationController.js @@ -1,20 +1,18 @@ -const { - createUser, - comparePassword, - getUserData, -} = require("../services/destinationService.js") +const { getDestination } = require("../services/destinationService.js") -const register = async (req, res) => { - console.log("Registration function") - const universal_id = req.body.universal_id - const username = req.body.username - const password = req.body.password - const userType = req.body.userType - - const newUser = await createUser(username, password, userType, universal_id) - if (newUser) { - console.log("Registration successful") - return res.send({ approved: true }) +const search = async (req, res) => { + const searchEntry = req.query.searchEntry + console.log(searchEntry) + const destinations = await getDestination(searchEntry) + if(searchEntry == ""){ + console.log("Query successful") + console.log(destinations) + return res.send({ destinations: [] }) + } + else if (destinations ) { + console.log("Query successful") + console.log(destinations) + return res.send({ destinations: destinations }) } } diff --git a/server/src/api/index.js b/server/src/api/index.js index d211df6..87118d2 100644 --- a/server/src/api/index.js +++ b/server/src/api/index.js @@ -13,7 +13,6 @@ const BookRoute = require("./routes/BookingRoute.js") const DestinationRoute = require("./routes/DestinationRoutes.js") const CardRoute = require("./routes/CardRoutes.js") - const app = express() const { urlencoded } = pkg const PORT = process.env.PORT || 3002 diff --git a/server/src/api/routes/BookingRoute.js b/server/src/api/routes/BookingRoute.js index c6aa99b..904b2a7 100644 --- a/server/src/api/routes/BookingRoute.js +++ b/server/src/api/routes/BookingRoute.js @@ -1,13 +1,14 @@ const express = require("express") const bookingController = require("../controllers/bookingController.js") -const { booking ,addbooking} = bookingController +const { booking, placeOrder } = bookingController const router = express.Router() // router.get("/") -router.get("/booking", booking) -router.post("/addbooking", addbooking) +router.post("/booking", booking) +router.post("/placeOrder", placeOrder) + //router.post("/register", register) module.exports = router diff --git a/server/src/api/routes/DestinationRoutes.js b/server/src/api/routes/DestinationRoutes.js index 24467e9..0e5c494 100644 --- a/server/src/api/routes/DestinationRoutes.js +++ b/server/src/api/routes/DestinationRoutes.js @@ -1,13 +1,10 @@ const express = require("express") -const orderController = require("../controllers/orderController.js") +const destinationController = require("../controllers/destinationController.js") -const { one_way, round_trip, multi_trip } = orderController +const { search } = destinationController const router = express.Router() router.get("/") -//router.post() -//router.post("/one-way", one_way) -//router.post("/round-trip", round_trip) -//router.post("/multi-planet", multi_trip) +router.get("/search", search) module.exports = router diff --git a/server/src/api/services/bookingService.js b/server/src/api/services/bookingService.js index e7850f3..e3c7f49 100644 --- a/server/src/api/services/bookingService.js +++ b/server/src/api/services/bookingService.js @@ -1,115 +1,54 @@ const { PrismaClient } = require("@prisma/client") -const bcrypt = require("bcrypt") const prisma = new PrismaClient() +const getAvailableBookings = async (starting_id, end_id, starting_date) => { + const rawQuery = prisma.$queryRaw`SELECT name,ship_type,price,EXTRACT(HOUR FROM starting_time) || ':' || EXTRACT(MINUTE FROM starting_time) AS starting_time FROM booking_view WHERE starting_id = ${starting_id}::uuid AND end_id = ${end_id}::uuid AND starting_date = ${starting_date}::date;` -//to create new spaceship booking entry - -const createNewBooking = async (ship_type, starting_id,end_id,price) => { - + const result = await rawQuery + return result +} - const newBooking = await prisma.booking_spaceship.create({ - data: { - ship_type: ship_type, - starting_id: starting_id, - end_id: end_id, - price: price - }, - - }) +async function insertOrderAndTicket( + booking_id, + universal_id, + order_time, + order_type, + ship_type, + ticket_count +) { + try { + const ticketDataArray = new Array(ticket_count).fill({ + booking_id: booking_id, // Use the appropriate booking ID + }) - return newBooking -} + console.log(ticketDataArray) -//to enter new booking to the available booking table -const AddBooking = async ( ship_name,starting_id,end_id,starting_time,available_seat_count,starting_date) => { - -try{ - await prisma.$transaction(async (tx) => { - const spaceship_details = await prisma.spaceship.findFirst({ - where: { - name: ship_name, - }, - select: { - ship_id: true, + const createdOrder = await prisma.order.create({ + data: { + universal_id: universal_id, + order_time: new Date().toISOString(), + order_type: order_type, + mode: ship_type, + ticket_count: ticket_count, }, }) - if (!spaceship_details) { - throw new Error("Spaceship not found") - } - - - const booking = await tx.available_Booking.create({ - data:{ - Spaceship:{ - connect:{ - ship_id: spaceship_details.ship_id, - } - }, - starting_id: starting_id, - end_id: end_id, - starting_time: starting_time, - available_seat_count: available_seat_count, - starting_date: starting_date, - } + const createdTickets = await prisma.ticket.createMany({ + data: ticketDataArray.map((ticketData) => ({ + ...ticketData, + order_id: createdOrder.order_id, + seat_num: 1, + })), }) - - return booking - }) -} -catch (err) { - console.log(err) -} -} -const getAvailableBookings = async (starting_id,end_id,starting_date) => { - try { - await prisma.$transaction(async (tx) => { - const availableBooking = await tx.available_Booking.findMany({ - where: { - starting_id: starting_id, - end_id: end_id, - starting_date: starting_date - }, - select: { - starting_time: true, - spaceship:{ - select:{ - ship_type: true, - name: true, - } - }, - - available_seat_count: true, - - }, - }) - const shipTypes = availableBooking.map((booking) => booking.ship_type); - const shipPrices = await prisma.$queryRaw - `SELECT ship_type, price - FROM booking_spaceship - WHERE ship_type IN (${shipTypes})`; - - const bookingsWithPrices = availableBooking.map((booking) => { - const price = shipPrices.find((price) => price.ship_type === booking.ship_type) - return { - ...booking, - price: price.price, - }} - ) - return bookingsWithPrices - }) - } - catch (err) { - console.log(err) + console.log("Order and tickets created successfully.") + } catch (error) { + console.error("Transaction failed:", error) + } finally { + await prisma.$disconnect() } } - - - - -module.exports = { createNewBooking, AddBooking, getAvailableBookings} +module.exports = { getAvailableBookings, insertOrderAndTicket } diff --git a/server/src/api/services/destinationService.js b/server/src/api/services/destinationService.js new file mode 100644 index 0000000..c8b2b87 --- /dev/null +++ b/server/src/api/services/destinationService.js @@ -0,0 +1,19 @@ +const { PrismaClient } = require("@prisma/client") +const bcrypt = require("bcrypt") + +const prisma = new PrismaClient() + +const getDestination = async (searchEntry) => { + const entries = await prisma.local_destination.findMany({ + where: { + name: { + startsWith: searchEntry, + }, + }, + select: { name: true }, + }) + + return entries ? entries : null +} + +module.exports = { getDestination }