김성연

최종보고서 ,소스코드 제출

Showing 127 changed files with 2028 additions and 351 deletions
...@@ -3,4 +3,7 @@ ...@@ -3,4 +3,7 @@
3 <component name="JavaScriptSettings"> 3 <component name="JavaScriptSettings">
4 <option name="languageLevel" value="JSX" /> 4 <option name="languageLevel" value="JSX" />
5 </component> 5 </component>
6 + <component name="ProjectPlainTextFileTypeManager">
7 + <file url="file://$PROJECT_DIR$/render_server_react_native/components/CardComponent.js" />
8 + </component>
6 </project> 9 </project>
...\ No newline at end of file ...\ No newline at end of file
......
1 <?xml version="1.0" encoding="UTF-8"?> 1 <?xml version="1.0" encoding="UTF-8"?>
2 <project version="4"> 2 <project version="4">
3 <component name="VcsDirectoryMappings"> 3 <component name="VcsDirectoryMappings">
4 - <mapping directory="$PROJECT_DIR$/.." vcs="Git" />
5 <mapping directory="$PROJECT_DIR$/locationTest/expo-location-example" vcs="Git" /> 4 <mapping directory="$PROJECT_DIR$/locationTest/expo-location-example" vcs="Git" />
6 <mapping directory="$PROJECT_DIR$/my-project" vcs="Git" /> 5 <mapping directory="$PROJECT_DIR$/my-project" vcs="Git" />
7 <mapping directory="$PROJECT_DIR$/render_server_react_native" vcs="Git" /> 6 <mapping directory="$PROJECT_DIR$/render_server_react_native" vcs="Git" />
......
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<project version="4">
3 + <component name="WebServers">
4 + <option name="servers">
5 + <webServer id="1b403629-1b05-48f5-aa8c-1b92f496c1d2" name="2019-BigData" url="http://133.186.211.42">
6 + <fileTransfer host="133.186.211.42" port="22" accessType="SFTP">
7 + <advancedOptions>
8 + <advancedOptions dataProtectionLevel="Private" passiveMode="true" shareSSLContext="true" />
9 + </advancedOptions>
10 + <option name="port" value="22" />
11 + </fileTransfer>
12 + </webServer>
13 + </option>
14 + </component>
15 +</project>
...\ No newline at end of file ...\ No newline at end of file
This diff is collapsed. Click to expand it.
1 -PORT=4001
2 -COOKIE_SECRET=test
...\ No newline at end of file ...\ No newline at end of file
This diff is collapsed. Click to expand it.
1 -import React, {useState, useContext, useEffect, useCallback} from 'react';
2 -import {View, Text, Button, TextInput, TouchableOpacity, StyleSheet} from 'react-native';
3 -import {useDispatch, useSelector} from "react-redux";
4 -import {LOG_IN_REQUEST, LOG_OUT_REQUEST} from "../reducers/user";
5 -import {MaterialCommunityIcons} from "@expo/vector-icons";
6 -import {useNavigation} from '@react-navigation/native';
7 -import LoadingComponent from "../components/LoadingComponent";
8 -
9 -const MyProfileComponent = () => {
10 - const navigation = useNavigation();
11 - const [loading, setLoading] = useState(true);
12 -
13 - const {me} = useSelector(state => state.user);
14 - const {isLoggingIn} = useSelector(state => state.user);
15 -
16 - const dispatch = useDispatch();
17 - const onLogout = async () => {
18 - await dispatch({
19 - type: LOG_OUT_REQUEST
20 - });
21 - console.log('onLogout');
22 - };
23 - return (
24 - <View>
25 - <View style={styles.containerStyle}>
26 - <Text style={styles.TextStyle}>마이페이지</Text>
27 - <Text style={styles.TextStyle}>{me.email}</Text>
28 - <Text style={styles.TextStyle}>{me.nickName}</Text>
29 - <TouchableOpacity onPress={onLogout}>
30 - <MaterialCommunityIcons color={'green'} name={'logout'} size={30}/>
31 - </TouchableOpacity>
32 - </View>
33 - </View>
34 - )
35 -};
36 -
37 -const styles = StyleSheet.create({
38 - containerStyle: {
39 - marginTop: 10,
40 - alignItems: 'center',
41 - justifyContent: 'center',
42 - },
43 - TextStyle: {
44 - width: 200,
45 - height: 44,
46 - padding: 10,
47 - borderWidth: 1,
48 - borderColor: '#778899',
49 - marginBottom: 10,
50 - }
51 -});
52 -
53 -export default MyProfileComponent;
...\ No newline at end of file ...\ No newline at end of file
1 -export const host = '172.20.10.3';
2 -export const coordAPIKEY = 'CDCF07BD-2CE4-33D9-BA13-D6CE4360A2B3';
1 -export const initialState = {
2 - startLocation: null,
3 - finishLocation: null,
4 -
5 - settingLocation: false,
6 -
7 - info: '',
8 -};
9 -
10 -export const SET_LOC_REQUEST = 'SET_LOC_REQUEST';
11 -export const SET_LOC_SUCCESS = 'SET_LOC_SUCCESS';
12 -export const SET_LOC_FAILURE = 'SET_LOC_FAILURE';
13 -
14 -export default (state = initialState, action) => {
15 - switch (action.type) {
16 -
17 - case SET_LOC_REQUEST: {
18 - return {
19 - ...state,
20 - settingLocation: true,
21 - }
22 - }
23 -
24 - case SET_LOC_SUCCESS: {
25 - const {startLocation, finishLocation} = action.data;
26 - return {
27 - ...state,
28 - startLocation,
29 - finishLocation,
30 - isLoggingIn: false,
31 - };
32 - }
33 -
34 - case SET_LOC_FAILURE: {
35 - const {info} = action.data;
36 - return {
37 - ...state,
38 - settingLocation: false,
39 - info,
40 - }
41 - }
42 -
43 - default: {
44 - return {
45 - ...state,
46 - };
47 - }
48 - }
49 -};
...\ No newline at end of file ...\ No newline at end of file
1 -import {all, call, fork, delay, put, takeEvery, takeLatest} from 'redux-saga/effects';
2 -import axios from 'axios';
3 -import {coordAPIKEY} from '../env';
4 -import {
5 - SET_LOC_REQUEST,
6 - SET_LOC_SUCCESS,
7 - SET_LOC_FAILURE,
8 -} from "../reducers/location";
9 -
10 -function setLocationAPI(data) {
11 - const {startTextLocation, finishTextLocation} = data;
12 - console.log(startTextLocation, finishTextLocation);
13 - const startRes = axios.get(`http://api.vworld.kr/req/address?service=address&request=getcoord&version=2.0&crs=epsg:4326&address=${startTextLocation}&refine=true&simple=false&format=xml&type=road&key=${coordAPIKEY}`);
14 - const finishRes = axios.get(`http://api.vworld.kr/req/address?service=address&request=getcoord&version=2.0&crs=epsg:4326&address=${finishTextLocation}&refine=true&simple=false&format=xml&type=road&key=${coordAPIKEY}`);
15 -
16 - return {startRes, finishRes};
17 -}
18 -
19 -
20 -function* setLocation(action) {
21 - try {
22 - console.log('saga의 setLocation', action.data);
23 - const res = yield call(setLocationAPI, action.data);
24 - console.log(res.startRes, res.finishRes);
25 - const {result} = res.startRes;
26 - console.log(result);
27 - } catch (e) {
28 - console.error(e);
29 - }
30 -};
31 -
32 -function* watchSetLocation() {
33 - console.log('watchSetLocation');
34 - yield takeLatest(SET_LOC_REQUEST, setLocation);
35 -}
36 -
37 -export default function* locationSaga() {
38 - yield all([
39 - fork(watchSetLocation),
40 - ]);
41 -};
...\ No newline at end of file ...\ No newline at end of file
1 -import React, {useState, useContext, useEffect, useCallback} from 'react';
2 -import {View, Text, Button, TextInput, TouchableOpacity} from 'react-native';
3 -import {useDispatch, useSelector} from "react-redux";
4 -import {LOG_IN_REQUEST, LOG_OUT_REQUEST} from "../reducers/user";
5 -import {MaterialCommunityIcons} from "@expo/vector-icons";
6 -import styled from "styled-components";
7 -import {useNavigation} from '@react-navigation/native';
8 -import LoadingComponent from "../components/LoadingComponent";
9 -import MyProfileComponent from "../components/MyProfileComponent";
10 -import LoginComponent from "../components/LoginComponent";
11 -
12 -const Login = () => {
13 - const navigation = useNavigation();
14 - const [loading, setLoading] = useState(true);
15 -
16 - const {me} = useSelector(state => state.user);
17 - const {isLoggingIn} = useSelector(state => state.user);
18 -
19 -
20 - useEffect(() => {
21 - setLoading(false);
22 - }, [me]);
23 -
24 - return (
25 - <View>
26 - {me ?
27 - <MyProfileComponent/>
28 - :
29 - <LoginComponent/>
30 - }
31 - </View>
32 - )
33 -};
34 -
35 -export default Login;
...\ No newline at end of file ...\ No newline at end of file
1 -import React, {useState, useEffect} from 'react';
2 -import MapView, {Marker} from 'react-native-maps';
3 -import {StyleSheet, Text, View, Dimensions} from 'react-native';
4 -import screen from '../constants/layout';
5 -import StartAndFinishLocationComponent from "../components/CurrentUserLocationComponent";
6 -
7 -
8 -const Maps = () => {
9 - const [initialRegion, setInitialRegion] = useState(
10 - {
11 - latitude: 37.56647,
12 - longitude: 126.977963,
13 - latitudeDelta: 0.3922,
14 - longitudeDelta: 0.3421
15 - });
16 -
17 - return (
18 - <View style={styles.container}>
19 - <Text style={styles.textStyle}>Current User Location</Text>
20 - <StartAndFinishLocationComponent/>
21 - <MapView
22 - style={styles.mapStyle}
23 - initialRegion={initialRegion}
24 - >
25 - <Marker
26 - coordinate={initialRegion}
27 - title="this is a marker"
28 - description="this is a marker example">
29 - </Marker>
30 -
31 - </MapView>
32 - </View>
33 - )
34 -};
35 -
36 -export default Maps;
37 -
38 -const styles = StyleSheet.create({
39 - container: {
40 - flex: 1,
41 - backgroundColor: '#fff',
42 - alignItems: 'center',
43 - },
44 - mapStyle: {
45 - width: screen.width,
46 - height: screen.height / 2,
47 - },
48 - textStyle: {
49 - fontWeight: 'bold',
50 - fontSize: 20,
51 - color: 'grey',
52 - marginBottom: 20,
53 - }
54 -});
...@@ -9,7 +9,8 @@ npm-debug.* ...@@ -9,7 +9,8 @@ npm-debug.*
9 *.orig.* 9 *.orig.*
10 web-build/ 10 web-build/
11 web-report/ 11 web-report/
12 -node_modules/
13 12
14 # macOS 13 # macOS
15 .DS_Store 14 .DS_Store
15 +env.js
16 +.env
......
...@@ -9,7 +9,7 @@ import {NavigationContainer} from "@react-navigation/native"; ...@@ -9,7 +9,7 @@ import {NavigationContainer} from "@react-navigation/native";
9 import store from './store'; 9 import store from './store';
10 import StackNavigation from "./navigations/StackNavigation"; 10 import StackNavigation from "./navigations/StackNavigation";
11 import {AuthProvider} from "./AuthContext"; 11 import {AuthProvider} from "./AuthContext";
12 -import host from './env'; 12 +import {host} from './env';
13 import axios from "axios"; 13 import axios from "axios";
14 14
15 const cacheImages = (images) => { 15 const cacheImages = (images) => {
...@@ -38,6 +38,7 @@ const App = () => { ...@@ -38,6 +38,7 @@ const App = () => {
38 ); 38 );
39 const fonts = cacheFonts([Ionicons.font]); 39 const fonts = cacheFonts([Ionicons.font]);
40 40
41 + // await AsyncStorage.removeItem('cookie');
41 const cookie = await AsyncStorage.getItem('cookie'); 42 const cookie = await AsyncStorage.getItem('cookie');
42 console.log('cookie', cookie); 43 console.log('cookie', cookie);
43 if (cookie) { 44 if (cookie) {
...@@ -66,12 +67,6 @@ const App = () => { ...@@ -66,12 +67,6 @@ const App = () => {
66 <> 67 <>
67 {isReady 68 {isReady
68 ? 69 ?
69 - // <Provider store={store}>
70 - // <NavigationContainer>
71 - // <StatusBar barstyle={'light-content'}/>
72 - // <StackNavigation/>
73 - // </NavigationContainer>
74 - // </Provider>
75 <Provider store={store}> 70 <Provider store={store}>
76 <AuthProvider user={user}> 71 <AuthProvider user={user}>
77 <NavigationContainer> 72 <NavigationContainer>
......
1 +import { Platform, StyleSheet, Dimensions } from "react-native";
2 +
3 +const { width, height } = Dimensions.get("window");
4 +const SCREEN_WIDTH = width < height ? width : height;
5 +const numColumns = 2;
6 +
7 +export const AppStyles = {
8 + color: {
9 + main: "#5ea23a",
10 + text: "#696969",
11 + title: "#464646",
12 + subtitle: "#545454",
13 + categoryTitle: "#161616",
14 + tint: "#ff5a66",
15 + description: "#bbbbbb",
16 + filterTitle: "#8a8a8a",
17 + starRating: "#2bdf85",
18 + location: "#a9a9a9",
19 + white: "white",
20 + facebook: "#4267b2",
21 + grey: "grey",
22 + greenBlue: "#00aea8",
23 + placeholder: "#a0a0a0",
24 + background: "#f2f2f2",
25 + blue: "#3293fe"
26 + },
27 + fontSize: {
28 + title: 30,
29 + content: 20,
30 + normal: 16
31 + },
32 + buttonWidth: {
33 + main: "70%"
34 + },
35 + textInputWidth: {
36 + main: "80%"
37 + },
38 + fontName: {
39 + main: "Noto Sans",
40 + bold: "Noto Sans"
41 + },
42 + borderRadius: {
43 + main: 25,
44 + small: 5
45 + }
46 +};
47 +
48 +export const AppIcon = {
49 + container: {
50 + backgroundColor: "white",
51 + borderRadius: 20,
52 + padding: 8,
53 + marginRight: 10
54 + },
55 + style: {
56 + tintColor: AppStyles.color.tint,
57 + width: 25,
58 + height: 25
59 + },
60 + images: {
61 + home: require("./assets/icons/home.png"),
62 + defaultUser: require("./assets/icons/default_user.jpg"),
63 + logout: require("./assets/icons/shutdown.png")
64 + }
65 +};
66 +
67 +export const HeaderButtonStyle = StyleSheet.create({
68 + multi: {
69 + flexDirection: "row"
70 + },
71 + container: {
72 + padding: 10
73 + },
74 + image: {
75 + justifyContent: "center",
76 + width: 35,
77 + height: 35,
78 + margin: 6
79 + },
80 + rightButton: {
81 + color: AppStyles.color.tint,
82 + marginRight: 10,
83 + fontWeight: "normal",
84 + fontFamily: AppStyles.fontName.main
85 + }
86 +});
87 +
88 +export const ListStyle = StyleSheet.create({
89 + title: {
90 + fontSize: 16,
91 + color: AppStyles.color.subtitle,
92 + fontFamily: AppStyles.fontName.bold,
93 + fontWeight: "bold"
94 + },
95 + subtitleView: {
96 + minHeight: 55,
97 + flexDirection: "row",
98 + paddingTop: 5,
99 + marginLeft: 10
100 + },
101 + leftSubtitle: {
102 + flex: 2
103 + },
104 + avatarStyle: {
105 + height: 80,
106 + width: 80
107 + }
108 +});
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
1 +[{"index":1,"avgSpeed": 53},{"index":2,"avgSpeed":60}]
...\ No newline at end of file ...\ No newline at end of file
1 +import React, {useState, useContext, useEffect, useCallback} from 'react';
2 +import {Text, View, StyleSheet, TouchableOpacity, ScrollView} from 'react-native';
3 +import {useDispatch, useSelector} from "react-redux";
4 +import {useNavigation} from '@react-navigation/native';
5 +import styled from "styled-components";
6 +import {AntDesign, MaterialCommunityIcons} from "@expo/vector-icons";
7 +
8 +
9 +const Banner = styled.View`
10 + flex: 1;
11 + margin-left: 15px;
12 + margin-bottom: 5px;
13 + width: 3px;
14 + height: 3px;
15 + border-radius: 20px;
16 + border: 3px solid #88c600;
17 +
18 +`;
19 +
20 +const BusPathComponent = (props) => {
21 + const navigation = useNavigation();
22 + const [busPath, setBusPath] = useState(null);
23 + const [seeStaList, setSeeStaList] = useState(false);
24 + const {pathDetail} = props;
25 +
26 + const changeSeeStaList = () => {
27 + setSeeStaList(!seeStaList);
28 + console.log(seeStaList)
29 + };
30 +
31 + useEffect(() => {
32 + console.log(props.pathDetail);
33 + setBusPath(props.pathDetail);
34 + }, []);
35 +
36 + return (
37 + <ScrollView>
38 + <View style={{flexDirection: 'row', flex: 5}}>
39 + <View style={styles.pathType}>
40 + <MaterialCommunityIcons style={{flex: 1}} color={'#88c600'} name={'bus'} size={20}/>
41 + <Text style={{flex: 1, fontSize: 13}}>{pathDetail.time}</Text>
42 + </View>
43 + <View style={{flex: 1}}>
44 + <Banner/>
45 + <Banner/>
46 + <Banner/>
47 + <Banner/>
48 + <Banner/>
49 + <Banner/>
50 + <Banner/>
51 + </View>
52 + <View style={styles.inputTile}>
53 + <Text style={styles.stationStyle}>{pathDetail.startName}</Text>
54 + <Text style={styles.idStyle}>{pathDetail.startID}</Text>
55 + {pathDetail.arrivalInfo.map((bus, index) => {
56 + return (
57 + <View>
58 + <Text style={styles.busStyle}>{bus.busNo}</Text>
59 + {bus.msg.msg1.indexOf('undefined') !== -1 ?
60 + null
61 + :
62 + <>
63 + <Text style={styles.busSubStyle}>{bus.msg.msg1}</Text>
64 + </>
65 + }
66 + {bus.msg.msg2.indexOf('undefined') !== -1 ?
67 + null
68 + :
69 + <>
70 + <Text style={styles.busSubStyle}>{bus.msg.msg2}</Text>
71 + </>
72 + }
73 + </View>
74 + )
75 + })}
76 + <View style={styles.stationListStyle}>
77 + <Text style={styles.cntStyle}>{pathDetail.stationCnt} 정류소 이동</Text>
78 + <TouchableOpacity style={{flex: 1, marginTop: 17}} onPress={changeSeeStaList}>
79 + <AntDesign color={'darkgrey'} name={'caretdown'} size={15}/>
80 + </TouchableOpacity>
81 + </View>
82 + <View>
83 + {seeStaList === true ?
84 + <View>
85 + {pathDetail.stationList.map((bus, index) => {
86 + return (
87 + <>
88 + <Text>{bus.stationName}</Text>
89 + </>
90 + )
91 + })}
92 + </View>
93 + :
94 + null
95 + }
96 + </View>
97 + <Text style={styles.stationStyle}>{pathDetail.endName}</Text>
98 + </View>
99 + </View>
100 + </ScrollView>
101 + );
102 +}
103 +export default BusPathComponent;
104 +
105 +const styles = StyleSheet.create({
106 + inputTile: {
107 + marginLeft: 6,
108 + flex: 4,
109 + color: 'grey',
110 + },
111 + inputText: {
112 + fontWeight: 'normal',
113 + fontSize: 15,
114 + },
115 + pathType: {
116 + flexDirection: 'column',
117 + flex: 0.4,
118 + alignItems: 'center',
119 + justifyContent: 'center',
120 + marginLeft: 5,
121 + marginTop: 10,
122 + },
123 + stationStyle: {
124 + fontWeight: 'bold',
125 + fontSize: 15,
126 + },
127 + idStyle: {
128 + marginTop: 3,
129 + marginBottom: 20,
130 + color: 'grey',
131 + fontSize: 14
132 + },
133 + busStyle: {
134 + fontWeight: 'bold',
135 + fontSize: 14,
136 + color: '#88c600'
137 + },
138 + cntStyle: {
139 + flex: 1,
140 + marginTop: 20,
141 + marginBottom: 3,
142 + color: 'grey',
143 + fontSize: 14
144 + },
145 + stationListStyle: {
146 + flexDirection: 'row',
147 + flex: 1,
148 + },
149 + busSubStyle: {
150 + marginTop: 2,
151 + fontSize: 12,
152 + color: 'red',
153 + }
154 +})
...\ No newline at end of file ...\ No newline at end of file
1 +import React, {useState, useContext, useEffect, useCallback} from 'react';
2 +import {View, Text, Button, Image, TouchableOpacity, StyleSheet, Platform} from 'react-native';
3 +import {useDispatch, useSelector} from "react-redux";
4 +import {LOG_IN_REQUEST, LOG_OUT_REQUEST} from "../reducers/user";
5 +import {MaterialCommunityIcons} from "@expo/vector-icons";
6 +import {useNavigation} from '@react-navigation/native';
7 +import DateTimePicker from '@react-native-community/datetimepicker';
8 +import {SET_TIME_SUCCESS} from "../reducers/location";
9 +import moment from "moment";
10 +
11 +const DateTimePickerComponent = (props) => {
12 + const [date, setDate] = useState(new Date());
13 + const [mode, setMode] = useState('time');
14 + const {goToMapsClick} = props;
15 +
16 + const onChange = (event, selectedDate) => {
17 + const currentDate = selectedDate || date;
18 + console.log(currentDate);
19 + setDate(currentDate);
20 + };
21 +
22 + // SET FINISH TIME
23 + const dispatch = useDispatch();
24 + const onSubmit = async () => {
25 + if (!date) {
26 + return
27 + }
28 + console.log('SET_TIME_SUCCESS GO!!', date);
29 + await dispatch({
30 + type: SET_TIME_SUCCESS,
31 + data: {
32 + date
33 + }
34 + });
35 + };
36 +
37 + useEffect(() => {
38 + if (goToMapsClick === true) {
39 + console.log(goToMapsClick);
40 + console.log('goToMapsClick!');
41 + onSubmit();
42 + }
43 + setDate(date);
44 + }, [goToMapsClick, date]);
45 +
46 + return (
47 + <View>
48 + <DateTimePicker
49 + testID="dateTimePicker"
50 + value={date}
51 + mode={mode}
52 + is24Hour={true}
53 + display="default"
54 + onChange={onChange}
55 + style={styles.TextStyle}
56 + />
57 +
58 + </View>
59 + );
60 +};
61 +
62 +const styles = StyleSheet.create({
63 + containerStyle: {
64 + marginTop: 10,
65 + alignItems: 'center',
66 + justifyContent: 'center',
67 + },
68 + TextStyle: {
69 + flex: 1,
70 + marginBottom: 240,
71 + }
72 +});
73 +
74 +export default DateTimePickerComponent;
75 +
1 +import React, {useState, useEffect} from 'react';
2 +import {Text, View, StyleSheet, TouchableOpacity, ScrollView} from 'react-native';
3 +import styled from 'styled-components';
4 +import {MaterialCommunityIcons, AntDesign} from '@expo/vector-icons';
5 +import {useNavigation} from '@react-navigation/native';
6 +
7 +
8 +const ShowDetail = styled.TouchableOpacity`
9 + flex: 2;
10 + position: absolute;
11 + right: 6px;
12 + bottom: 2px;
13 + width: 30px;
14 + height: 30px;
15 + border-radius: 50px;
16 +`;
17 +
18 +const Banner = styled.View`
19 + flex: 1;
20 + margin-left: 15px;
21 + margin-bottom: 5px;
22 + width: 3px;
23 + height: 3px;
24 + border-radius: 20px;
25 + border: 3px solid #273b96;
26 +`;
27 +
28 +
29 +const GoPathSummary = (props) => {
30 + const navigation = useNavigation();
31 + const [pathSummary, setPathSummary] = useState(null);
32 + const goPathDetail = () => {
33 + navigation.navigate('GoPathDetail', {'detail': props.detail});
34 + };
35 +
36 + useEffect
37 + (() => {
38 + console.log(props.summary);
39 + setPathSummary(props.summary);
40 + }, []);
41 +
42 +
43 + return (
44 + <View>
45 + {pathSummary ?
46 + <>
47 + <View style={styles.container}>
48 +
49 + <View style={styles.titleParagraph}>
50 + <Text style={styles.hourStyle}>{pathSummary.hour1} {pathSummary.min1} 출발
51 + <Text style={styles.conditionStyle}>정확</Text>
52 + </Text>
53 + <Text style={styles.hourStyle}>{pathSummary.hour2} {pathSummary.min2} 출발
54 + <Text style={styles.conditionStyle}>여유</Text>
55 + </Text>
56 + </View>
57 + <View style={{flexDirection: 'row', flex: 2, marginLeft: 70}}>
58 + <Text style={{flex: 1, fontSize: 13, fontWeight: 'bold'}}>총소요시간: {pathSummary.totalTime}</Text>
59 + <Text style={{flex: 1, fontSize: 13, fontWeight: 'bold'}}>비용: {pathSummary.payment}</Text>
60 + </View>
61 + <View style={{flexDirection: 'row', flex: 5, marginLeft: 70, marginTop: 20}}>
62 + <View style={styles.pathType}>
63 + <MaterialCommunityIcons style={{flex: 1}} color={'#273b96'} name={'train'} size={20}/>
64 + </View>
65 + <View style={styles.inputTile}>
66 + <Text style={styles.stationStyle}>{pathSummary.firstStartStation}</Text>
67 + <Text style={styles.stationStyle}>{pathSummary.lastEndStation}</Text>
68 + </View>
69 + </View>
70 + <View style={{position: 'absolute', right: 10}}>
71 + <ShowDetail onPress={goPathDetail}>
72 + <AntDesign color={'darkgrey'} name={'caretright'} size={32}/>
73 + </ShowDetail>
74 + </View>
75 +
76 + </View>
77 + </>
78 + :
79 + null
80 + }
81 + </View>
82 + );
83 +}
84 +
85 +const styles = StyleSheet.create({
86 + container: {
87 + flex: 1,
88 + flexDirection: 'column',
89 + paddingTop: 40,
90 + paddingBottom: 30,
91 + backgroundColor: '#ecf0f1',
92 + alignItems: 'center',
93 + justifyContent: 'center',
94 + borderWidth: 1,
95 + borderColor: 'darkgrey',
96 + },
97 + paragraph: {
98 + flex: 1,
99 + fontSize: 14,
100 + fontWeight: 'bold',
101 + textAlign: 'center',
102 + color: '#34495e',
103 + },
104 + titleParagraph: {
105 + flexDirection: 'column',
106 + flex: 1,
107 + },
108 + inputTile: {
109 + marginLeft: 6,
110 + flex: 4,
111 + color: 'grey',
112 + },
113 + inputText: {
114 + fontWeight: 'normal',
115 + fontSize: 15,
116 + },
117 + pathType: {
118 + flexDirection: 'column',
119 + flex: 0.4,
120 + alignItems: 'center',
121 + justifyContent: 'center',
122 + marginLeft: 5,
123 + marginTop: 10,
124 + },
125 + stationStyle: {
126 + fontWeight: 'bold',
127 + fontSize: 15,
128 + },
129 + idStyle: {
130 + marginTop: 3,
131 + marginBottom: 20,
132 + color: 'grey',
133 + fontSize: 14
134 + },
135 + laneStyle: {
136 + fontWeight: 'bold',
137 + fontSize: 15,
138 + color: '#EBA900'
139 + },
140 + cntStyle: {
141 + flex: 1,
142 + marginTop: 20,
143 + marginBottom: 3,
144 + color: 'grey',
145 + fontSize: 14
146 + },
147 + stationListStyle: {
148 + flexDirection: 'row',
149 + flex: 1,
150 + },
151 + hourStyle: {
152 + flexDirection: 'row',
153 + flex: 1,
154 + fontSize: 18,
155 + fontWeight: 'bold',
156 + marginBottom: 20,
157 + },
158 + conditionStyle: {
159 + paddingLeft: 10,
160 + fontSize: 15,
161 + color: 'red',
162 + }
163 +});
164 +
165 +export default GoPathSummary;
...\ No newline at end of file ...\ No newline at end of file
1 +import React, {useState, useContext, useEffect, useCallback} from 'react';
2 +import {Text, View, StyleSheet, TouchableOpacity, ScrollView} from 'react-native';
3 +import {useDispatch, useSelector} from "react-redux";
4 +import {useNavigation} from '@react-navigation/native';
5 +import styled from "styled-components";
6 +import {AntDesign, MaterialCommunityIcons} from "@expo/vector-icons";
7 +
8 +const Banner = styled.View`
9 + flex: 1;
10 + margin-left: 15px;
11 + margin-bottom: 5px;
12 + width: 3px;
13 + height: 3px;
14 + border-radius: 20px;
15 + border: 3px solid #EBA900;
16 +`;
17 +
18 +const LanePathComponent = (props) => {
19 + const navigation = useNavigation();
20 + const [lanePath, setLanePath] = useState(null);
21 + const [seeLaneList, setSeeLaneList] = useState(false);
22 + const {pathDetail} = props;
23 +
24 +
25 + const changeSeeLaneList = () => {
26 + setSeeLaneList(!seeLaneList);
27 + console.log(seeLaneList)
28 + };
29 +
30 + useEffect(() => {
31 + console.log(props.pathDetail);
32 + setLanePath(props.pathDetail);
33 + }, []);
34 +
35 + return (
36 + <ScrollView>
37 + <View style={{flexDirection: 'row', flex: 5}}>
38 + <View style={styles.pathType}>
39 + <MaterialCommunityIcons style={{flex: 1}} color={'#EBA900'} name={'train'} size={20}/>
40 + <Text style={{flex: 1, fontSize: 13}}>{pathDetail.time}</Text>
41 + </View>
42 + <View style={{flex: 1}}>
43 + <Banner/>
44 + <Banner/>
45 + <Banner/>
46 + <Banner/>
47 + <Banner/>
48 + <Banner/>
49 + <Banner/>
50 + </View>
51 + <View style={styles.inputTile}>
52 + <Text style={styles.stationStyle}>{pathDetail.startName}</Text>
53 + <Text style={styles.idStyle}>{pathDetail.startID}</Text>
54 + {pathDetail.laneList.map((lane, index) => {
55 + return (
56 + <Text style={styles.laneStyle}>{lane.name}</Text>
57 + )
58 + })}
59 + <View style={styles.stationListStyle}>
60 + <Text style={styles.cntStyle}>{pathDetail.stationCnt} 정류소 이동</Text>
61 + <TouchableOpacity style={{flex: 1, marginTop: 17}} onPress={changeSeeLaneList}>
62 + <AntDesign color={'darkgrey'} name={'caretdown'} size={15}/>
63 + </TouchableOpacity>
64 + </View>
65 + {seeLaneList === true ?
66 + <View>
67 + {pathDetail.stationList.map((lane, index) => {
68 + return (
69 + <Text>{lane}</Text>
70 + )
71 + })}
72 + </View>
73 + :
74 + null
75 + }
76 + <Text style={styles.stationStyle}>{pathDetail.endName}</Text>
77 + </View>
78 + </View>
79 + </ScrollView>
80 + );
81 +}
82 +export default LanePathComponent;
83 +
84 +const styles = StyleSheet.create({
85 + inputTile: {
86 + marginLeft: 6,
87 + flex: 4,
88 + color: 'grey',
89 + },
90 + inputText: {
91 + fontWeight: 'normal',
92 + fontSize: 15,
93 + },
94 + pathType: {
95 + flexDirection: 'column',
96 + flex: 0.4,
97 + alignItems: 'center',
98 + justifyContent: 'center',
99 + marginLeft: 5,
100 + marginTop: 10,
101 + },
102 + stationStyle: {
103 + fontWeight: 'bold',
104 + fontSize: 15,
105 + },
106 + idStyle: {
107 + marginTop: 3,
108 + marginBottom: 20,
109 + color: 'grey',
110 + fontSize: 14
111 + },
112 + laneStyle: {
113 + fontWeight: 'bold',
114 + fontSize: 15,
115 + color: '#EBA900'
116 + },
117 + cntStyle: {
118 + flex: 1,
119 + marginTop: 20,
120 + marginBottom: 3,
121 + color: 'grey',
122 + fontSize: 14
123 + },
124 + stationListStyle: {
125 + flexDirection: 'row',
126 + flex: 1,
127 + }
128 +})
...\ No newline at end of file ...\ No newline at end of file
...@@ -13,4 +13,6 @@ const LoadingComponent = () => { ...@@ -13,4 +13,6 @@ const LoadingComponent = () => {
13 ) 13 )
14 }; 14 };
15 15
16 +
17 +
16 export default LoadingComponent; 18 export default LoadingComponent;
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -2,11 +2,9 @@ import React, {useState, useContext, useEffect, useCallback} from 'react'; ...@@ -2,11 +2,9 @@ import React, {useState, useContext, useEffect, useCallback} from 'react';
2 import {View, Text, Button, StyleSheet, TextInput, TouchableOpacity} from 'react-native'; 2 import {View, Text, Button, StyleSheet, TextInput, TouchableOpacity} from 'react-native';
3 import {useDispatch, useSelector} from "react-redux"; 3 import {useDispatch, useSelector} from "react-redux";
4 import {LOG_IN_REQUEST, LOG_OUT_REQUEST} from "../reducers/user"; 4 import {LOG_IN_REQUEST, LOG_OUT_REQUEST} from "../reducers/user";
5 -import {MaterialCommunityIcons} from "@expo/vector-icons";
6 import styled from "styled-components"; 5 import styled from "styled-components";
7 import {useNavigation} from '@react-navigation/native'; 6 import {useNavigation} from '@react-navigation/native';
8 -import LoadingComponent from "../components/LoadingComponent"; 7 +import Profile from "../screens/Profile";
9 -import SignUpComponent from "./SignUpComponent";
10 8
11 9
12 const LoginButton = styled.TouchableOpacity` 10 const LoginButton = styled.TouchableOpacity`
...@@ -16,6 +14,20 @@ const LoginButton = styled.TouchableOpacity` ...@@ -16,6 +14,20 @@ const LoginButton = styled.TouchableOpacity`
16 height: 40px; 14 height: 40px;
17 background-color: #e6e6fa; 15 background-color: #e6e6fa;
18 border: 1px; 16 border: 1px;
17 + marginBottom: 10px;
18 + border-radius: 50px;
19 +
20 +`;
21 +
22 +const SignUpButton = styled.TouchableOpacity`
23 + align-items: center;
24 + justify-content: center;
25 + width: 60px;
26 + height: 40px;
27 + background-color: #e6e6fa;
28 + border: 1px;
29 + border-radius: 50px;
30 +
19 `; 31 `;
20 32
21 33
...@@ -49,8 +61,17 @@ const LoginComponent = () => { ...@@ -49,8 +61,17 @@ const LoginComponent = () => {
49 password 61 password
50 } 62 }
51 }); 63 });
64 +
52 }; 65 };
66 + const goSignUp = () => {
67 + navigation.navigate('SignUp');
68 + }
53 69
70 + useEffect(() => {
71 + if (me) {
72 + navigation.navigate('Profile');
73 + }
74 + }, [me]);
54 75
55 useEffect(() => { 76 useEffect(() => {
56 setLoading(false); 77 setLoading(false);
...@@ -77,17 +98,22 @@ const LoginComponent = () => { ...@@ -77,17 +98,22 @@ const LoginComponent = () => {
77 onPress={onSubmit}> 98 onPress={onSubmit}>
78 <Text style={{color: '#696969'}}>Login</Text> 99 <Text style={{color: '#696969'}}>Login</Text>
79 </LoginButton> 100 </LoginButton>
101 + <SignUpButton
102 + title={'Login'}
103 + onPress={goSignUp}>
104 + <Text style={{color: '#696969'}}>SignUp</Text>
105 + </SignUpButton>
80 </View> 106 </View>
81 ) 107 )
82 }; 108 };
83 109
84 const styles = StyleSheet.create({ 110 const styles = StyleSheet.create({
85 containerStyle: { 111 containerStyle: {
86 - flex: 1, 112 + // flex: 1,
87 alignItems: 'center', 113 alignItems: 'center',
88 - justifyContent: 'center', 114 + // justifyContent: 'center',
89 - backgroundColor: '#ecf0f1', 115 + // backgroundColor: '#ecf0f1',
90 - marginTop: 100, 116 + // marginTop: 100,
91 }, 117 },
92 input: { 118 input: {
93 width: 200, 119 width: 200,
......
1 +import React, {useState, useContext, useEffect, useCallback} from 'react';
2 +import {View, Text, Button, Image, TouchableOpacity, StyleSheet, Alert} from 'react-native';
3 +import {useDispatch, useSelector} from "react-redux";
4 +import {LOG_IN_REQUEST, LOG_OUT_REQUEST} from "../reducers/user";
5 +import {MaterialCommunityIcons} from "@expo/vector-icons";
6 +import {useNavigation} from '@react-navigation/native';
7 +import {SET_PERVELOCITY_SUCCESS} from "../reducers/location";
8 +import Login from "../screens/Login";
9 +import Papa from 'papaparse';
10 +
11 +
12 +const MyProfileComponent = () => {
13 + const navigation = useNavigation();
14 + const [loading, setLoading] = useState(true);
15 + const [numRecord, setNumRecord] = useState(0);
16 +
17 + const {me} = useSelector(state => state.user);
18 + const {isLoggingIn} = useSelector(state => state.user);
19 + //
20 + // const downloadFile = async () => {
21 + // const uri = "https://www.mapmyfitness.com/workout/export/csv";
22 + // let fileUri = FileSystem.documentDirectory + "userVelocity.txt";
23 + // FileSystem.downloadAsync(uri, fileUri)
24 + // .then(({uri}) => {
25 + // saveFile(uri);
26 + // })
27 + // .catch(error => {
28 + // console.error(error);
29 + // })
30 + // }
31 + //
32 + // const saveFile = async (fileUri) => {
33 + // const {status} = await Permissions.askAsync(Permissions.CAMERA_ROLL);
34 + // if (status === "granted") {
35 + // const asset = await MediaLibrary.createAssetAsync(fileUri)
36 + // await MediaLibrary.createAlbumAsync("Download", asset, false)
37 + // }
38 + // }
39 + const dispatch = useDispatch();
40 + const loadPersonalVelocity = async () => {
41 + try {
42 +
43 + const userVelocity = require('../assets/userFile/userVelocity');
44 + var allAvgSpeed = 0;
45 + setNumRecord(userVelocity.length);
46 + userVelocity.map((i, index) => {
47 + allAvgSpeed = allAvgSpeed + i.avgSpeed;
48 + });
49 +
50 + var personalVelocity = parseInt(allAvgSpeed / userVelocity.length);
51 + await dispatch({
52 + type: SET_PERVELOCITY_SUCCESS,
53 + data: {
54 + personalVelocity: personalVelocity
55 + }
56 + });
57 +
58 + Alert.alert(
59 + 'MAP 사용자 평균 속도 설정',
60 + ` 사용자 평균 속도를 설정하였습니다. `,
61 + [
62 + {
63 + text: 'Cancel',
64 + onPress: () => console.log('Cancel Pressed'),
65 + style: 'cancel',
66 + },
67 + {text: 'OK', onPress: () => console.log('OK Pressed')},
68 + ],
69 + {cancelable: false}
70 + );
71 +
72 + } catch (e) {
73 + console.log(e);
74 + }
75 +
76 + };
77 +
78 + useEffect(() => {
79 + setNumRecord(0);
80 + }, []);
81 +
82 + useEffect(() => {
83 + console.log(numRecord)
84 + }, [numRecord]);
85 +
86 + const onLogout = async () => {
87 + await dispatch({
88 + type: LOG_OUT_REQUEST
89 + });
90 + console.log('onLogout');
91 + };
92 + return (
93 + <View>
94 + {me ?
95 + <View>
96 + <View style={{flexDirection: 'row', paddingTop: 15}}>
97 + <View style={{flex: 1, alignItems: 'center'}}>
98 + <Image source={{url: 'https://steemitimages.com/u/anpigon/avatar'}}
99 + style={{width: 75, height: 75, borderRadius: 37.5}}/>
100 + </View>
101 + <View style={{flex: 3}}>
102 + <View style={{flexDirection: 'row', justifyContent: 'space-around', marginTop: 12}}>
103 + <View style={{alignItems: 'center'}}>
104 + <Text style={{fontSize: 15, fontWeight: 'bold'}}>{me.email}</Text>
105 + <Text style={{fontSize: 10, color: 'gray'}}>email</Text>
106 + </View>
107 + <View style={{alignItems: 'center'}}>
108 + <Text style={{fontSize: 15, fontWeight: 'bold'}}>{me.nickName}</Text>
109 + <Text style={{fontSize: 10, color: 'gray'}}>nickName</Text>
110 + </View>
111 + <View style={{alignItems: 'center'}}>
112 + <Text style={{fontSize: 15, fontWeight: 'bold'}}>{numRecord}</Text>
113 + <Text style={{fontSize: 10, color: 'gray'}}>numRecord</Text>
114 + </View>
115 + </View>
116 + <View style={{flexDirection: 'row'}}>
117 + <TouchableOpacity
118 + onPress={loadPersonalVelocity}
119 + style={{
120 + flex: 4,
121 + marginLeft: 10,
122 + justifyContent: 'center',
123 + alignItems: 'center',
124 + borderWidth: 1,
125 + borderColor: 'black',
126 + height: 30,
127 + marginTop: 17
128 + }}>
129 + <Text style={{fontSize: 13}}>load personal velocity</Text>
130 + </TouchableOpacity>
131 + <TouchableOpacity
132 + onPress={onLogout}
133 + style={{
134 + borderColor: 'black',
135 + borderWidth: 1,
136 + flex: 1,
137 + marginRight: 10,
138 + marginLeft: 5,
139 + justifyContent: 'center',
140 + alignItems: 'center',
141 + height: 30,
142 + marginTop: 17
143 + }}>
144 + <MaterialCommunityIcons color={'black'} name={'logout'} size={20}/>
145 + </TouchableOpacity>
146 + </View>
147 + </View>
148 + </View>
149 + < View style={{paddingHorizontal: 20, paddingVertical: 10}}>
150 + </View>
151 + </View>
152 + :
153 + <View style={{alignItems: 'center', justifyContent: 'center', marginTop: 200}}>
154 + <Text style={{fontSize: 30, textAlign: 'center', fontWeight: 'bold'}}>유저 정보가 없습니다.</Text>
155 + </View>
156 + }
157 + </View>
158 + )
159 +};
160 +
161 +const styles = StyleSheet.create({
162 + containerStyle: {
163 + marginTop: 10,
164 + alignItems: 'center',
165 + justifyContent: 'center',
166 + },
167 + TextStyle: {
168 + width: 200,
169 + height: 44,
170 + padding: 10,
171 + borderWidth: 1,
172 + borderColor: '#778899',
173 + marginBottom: 10,
174 + }
175 +});
176 +
177 +export default MyProfileComponent;
...\ No newline at end of file ...\ No newline at end of file
1 import React, {useState, useContext, useEffect, useCallback} from 'react'; 1 import React, {useState, useContext, useEffect, useCallback} from 'react';
2 -import {View, Text, Button, TextInput, TouchableOpacity} from 'react-native'; 2 +import {View, Text, Button, TextInput, TouchableOpacity, StyleSheet} from 'react-native';
3 import {useDispatch, useSelector} from "react-redux"; 3 import {useDispatch, useSelector} from "react-redux";
4 import {SIGN_UP_REQUEST} from "../reducers/user"; 4 import {SIGN_UP_REQUEST} from "../reducers/user";
5 -import {MaterialCommunityIcons} from "@expo/vector-icons";
6 import styled from "styled-components"; 5 import styled from "styled-components";
7 import {useNavigation} from '@react-navigation/native'; 6 import {useNavigation} from '@react-navigation/native';
8 -import LoadingComponent from "../components/LoadingComponent"; 7 +import Profile from "../screens/Profile";
9 8
10 9
11 const SignUpButton = styled.TouchableOpacity` 10 const SignUpButton = styled.TouchableOpacity`
12 align-items: center; 11 align-items: center;
13 justify-content: center; 12 justify-content: center;
14 width: 60px; 13 width: 60px;
15 - height: 60px; 14 + height: 40px;
16 - background-color: #ffffff; 15 + background-color: #e6e6fa;
17 border: 1px; 16 border: 1px;
17 + marginBottom: 10px;
18 + border-radius: 50px;
18 `; 19 `;
19 20
21 +const GoLoginButton = styled.TouchableOpacity`
22 + align-items: center;
23 + justify-content: center;
24 + width: 60px;
25 + height: 40px;
26 + background-color: #e6e6fa;
27 + border: 1px;
28 + border-radius: 50px;
29 +`;
30 +
31 +
20 const SignUpComponent = () => { 32 const SignUpComponent = () => {
21 const navigation = useNavigation(); 33 const navigation = useNavigation();
22 const [email, setEmail] = useState(''); 34 const [email, setEmail] = useState('');
...@@ -49,39 +61,59 @@ const SignUpComponent = () => { ...@@ -49,39 +61,59 @@ const SignUpComponent = () => {
49 password 61 password
50 } 62 }
51 }); 63 });
64 + if (me !== null) {
65 + navigation.navigate('Profile');
66 + }
52 }; 67 };
53 68
54 return ( 69 return (
55 - <> 70 + <View styles={styles.containerStyle}>
56 - <View> 71 + <TextInput
57 - <View> 72 + style={styles.input}
58 - <TextInput 73 + placeholder="Type here to Email!"
59 - style={{height: 40, marginLeft: 10}} 74 + onChangeText={onChangeEmail}
60 - placeholder="Type here to Email!" 75 + />
61 - onChangeText={onChangeEmail} 76 + <TextInput
62 - /> 77 + style={styles.input}
63 - </View> 78 + placeholder="Type here to nickname!"
64 - <View> 79 + onChangeText={onChangeNickName}
65 - <TextInput 80 + />
66 - style={{height: 40, marginLeft: 10}} 81 + <TextInput
67 - placeholder="Type here to nickname!" 82 + style={styles.input}
68 - onChangeText={onChangeNickName} 83 + placeholder="Type here to password!"
69 - /> 84 + type="password"
70 - </View> 85 + onChangeText={onChangePassword}
71 - <View> 86 + />
72 - <TextInput 87 + <SignUpButton
73 - style={{height: 40, marginLeft: 10}} 88 + title={'signUp'}
74 - placeholder="Type here to password!" 89 + onPress={onSubmit}>
75 - type="password" 90 + <Text style={{color: '#696969'}}>signUp</Text>
76 - onChangeText={onChangePassword} 91 + </SignUpButton>
77 - /> 92 + <GoLoginButton
78 - </View> 93 + title={'signUp'}
79 - <SignUpButton title={'회원가입'} onPress={onSubmit}> 94 + onPress={onSubmit}>
80 - <Text>회원가입</Text> 95 + <Text style={{color: '#696969'}}>Login</Text>
81 - </SignUpButton> 96 + </GoLoginButton>
82 - </View> 97 + </View>
83 - </>
84 ) 98 )
85 }; 99 };
86 100
87 -export default SignUpComponent;
...\ No newline at end of file ...\ No newline at end of file
101 +export default SignUpComponent;
102 +
103 +const styles = StyleSheet.create({
104 + containerStyle: {
105 + // flex: 1,
106 + alignItems: 'center',
107 + // justifyContent: 'center',
108 + // backgroundColor: '#ecf0f1',
109 + // marginTop: 100,
110 + },
111 + input: {
112 + width: 200,
113 + height: 44,
114 + padding: 10,
115 + borderWidth: 1,
116 + borderColor: '#778899',
117 + marginBottom: 10,
118 + }
119 +});
...\ No newline at end of file ...\ No newline at end of file
......
1 import React, {useState, useEffect} from 'react'; 1 import React, {useState, useEffect} from 'react';
2 import MapView, {Marker} from 'react-native-maps'; 2 import MapView, {Marker} from 'react-native-maps';
3 -import {StyleSheet, Text, TextInput, View, TouchableOpacity} from 'react-native'; 3 +import {StyleSheet, Text, TextInput, View, TouchableOpacity, Alert} from 'react-native';
4 import screen from '../constants/layout'; 4 import screen from '../constants/layout';
5 import {useSelector, useDispatch} from "react-redux"; 5 import {useSelector, useDispatch} from "react-redux";
6 import * as Location from 'expo-location'; 6 import * as Location from 'expo-location';
7 import {set} from "react-native-reanimated"; 7 import {set} from "react-native-reanimated";
8 import {MaterialCommunityIcons} from "@expo/vector-icons"; 8 import {MaterialCommunityIcons} from "@expo/vector-icons";
9 -import {SET_LOC_REQUEST} from "../reducers/location"; 9 +import {SET_ELOC_REQUEST, SET_LOC_REQUEST, SET_SLOC_REQUEST, SET_USER_LOC} from "../reducers/location";
10 - 10 +import axios from 'axios';
11 11
12 const StartAndFinishLocationComponent = () => { 12 const StartAndFinishLocationComponent = () => {
13 const [hasPermission, setHasPermission] = useState(false); 13 const [hasPermission, setHasPermission] = useState(false);
14 const [startTextLocation, setStartTextLocation] = useState(''); 14 const [startTextLocation, setStartTextLocation] = useState('');
15 - const [finishTextLocation, setFinishTextLocation] = useState(''); 15 + const [endTextLocation, setEndTextLocation] = useState('');
16 const [userLocation, setUserLocation] = useState(null); 16 const [userLocation, setUserLocation] = useState(null);
17 + const [errorMsg, setErrorMsg] = useState(null);
17 18
18 - const onChangeStartLocation = async (startTextLocation) => { 19 + const onChangeStartLocation = (startTextLocation) => {
19 setStartTextLocation(startTextLocation); 20 setStartTextLocation(startTextLocation);
20 }; 21 };
21 22
22 - const onChangeFinishLocation = (finishTextLocation) => { 23 + const onChangeFinishLocation = (endTextLocation) => {
23 - setFinishTextLocation(finishTextLocation); 24 + setEndTextLocation(endTextLocation);
24 }; 25 };
25 26
26 const dispatch = useDispatch(); 27 const dispatch = useDispatch();
27 - const setLocation = async () => { 28 + const onSetUserLocation = async () => {
28 - if (!startTextLocation || !finishTextLocation) { 29 + const {status} = await Location.requestPermissionsAsync();
29 - return 30 + if (status !== 'granted') {
31 + setErrorMsg('Permission to access location was denied')
30 } 32 }
31 - console.log(startTextLocation, finishTextLocation); 33 + const location = await Location.getCurrentPositionAsync({});
34 + setStartTextLocation('현위치');
35 + setUserLocation(location);
36 + console.log(location);
32 await dispatch({ 37 await dispatch({
33 - type: SET_LOC_REQUEST, 38 + type: SET_USER_LOC,
39 + data: {
40 + userLocation
41 + }
42 + });
43 + };
44 +
45 + const setLocation = async () => {
46 + if (startTextLocation && startTextLocation !== '현위치') {
47 + console.log(startTextLocation);
48 + await dispatch({
49 + type: SET_SLOC_REQUEST,
34 data: { 50 data: {
35 - startTextLocation, 51 + startTextLocation
36 - finishTextLocation
37 } 52 }
38 - } 53 + })
39 - ) 54 + }
40 55
56 + if (endTextLocation) {
57 + console.log(endTextLocation);
58 + await dispatch({
59 + type: SET_ELOC_REQUEST,
60 + data: {
61 + endTextLocation
62 + }
63 + }
64 + )
65 + }
66 +
67 + Alert.alert(
68 + 'MAP ROUTE 설정',
69 + ` 출발지 ${startTextLocation}, 목적지 ${endTextLocation} 맞습니까? `,
70 + [
71 + {
72 + text: 'Cancel',
73 + onPress: () => console.log('Cancel Pressed'),
74 + style: 'cancel',
75 + },
76 + {text: 'OK', onPress: () => console.log('OK Pressed')},
77 + ],
78 + {cancelable: false}
79 + );
41 }; 80 };
42 81
82 +
43 return ( 83 return (
44 <View style={styles.container}> 84 <View style={styles.container}>
45 <View style={styles.input}> 85 <View style={styles.input}>
46 - <Text style={styles.textStyle}>출발지</Text> 86 + <MaterialCommunityIcons color={'red'} name={'map-marker'} size={26}/>
47 <TextInput 87 <TextInput
48 style={styles.inputText} 88 style={styles.inputText}
49 onChangeText={onChangeStartLocation} 89 onChangeText={onChangeStartLocation}
90 + value={startTextLocation}
50 /> 91 />
51 - <TouchableOpacity> 92 + <TouchableOpacity onPress={onSetUserLocation}>
52 - <MaterialCommunityIcons color={'grey'} name={'map-marker'} size={30}/> 93 + <MaterialCommunityIcons color={'grey'} name={'crosshairs-gps'} size={30}/>
53 </TouchableOpacity> 94 </TouchableOpacity>
54 95
55 </View> 96 </View>
56 <View style={styles.input}> 97 <View style={styles.input}>
57 - <Text style={styles.textStyle}>도착지</Text> 98 + <MaterialCommunityIcons color={'blue'} name={'map-marker'} size={26}/>
58 <TextInput 99 <TextInput
59 style={styles.inputText} 100 style={styles.inputText}
60 onChangeText={onChangeFinishLocation} 101 onChangeText={onChangeFinishLocation}
102 + value={endTextLocation}
61 /> 103 />
62 </View> 104 </View>
63 - <View style={{flexDirection: 'row'}}> 105 + <View style={{flexDirection: 'row', alignItems: 'center'}}>
64 <TouchableOpacity style={styles.buttonStyle} onPress={setLocation}> 106 <TouchableOpacity style={styles.buttonStyle} onPress={setLocation}>
65 - <Text>MAP설정</Text> 107 + <Text>Map설정</Text>
66 - </TouchableOpacity>
67 - <TouchableOpacity style={styles.buttonStyle}>
68 - <Text>사용자최적경로검색</Text>
69 </TouchableOpacity> 108 </TouchableOpacity>
70 </View> 109 </View>
71 </View> 110 </View>
...@@ -76,20 +115,23 @@ export default StartAndFinishLocationComponent; ...@@ -76,20 +115,23 @@ export default StartAndFinishLocationComponent;
76 115
77 const styles = StyleSheet.create({ 116 const styles = StyleSheet.create({
78 container: { 117 container: {
118 + alignItems: 'center',
119 + marginTop: 50,
79 marginLeft: 20, 120 marginLeft: 20,
80 marginRight: 20, 121 marginRight: 20,
122 + opacity: 0.5,
81 }, 123 },
82 input: { 124 input: {
83 borderRadius: 10, 125 borderRadius: 10,
84 - backgroundColor: 'lightgrey', 126 + backgroundColor: '#f0f8ff',
85 paddingLeft: 10, 127 paddingLeft: 10,
86 paddingRight: 10, 128 paddingRight: 10,
87 width: 300, 129 width: 300,
88 - height: 40, 130 + height: 50,
89 alignItems: 'center', 131 alignItems: 'center',
90 flexDirection: 'row', 132 flexDirection: 'row',
91 justifyContent: 'space-between', 133 justifyContent: 'space-between',
92 - borderBottomColor: '#bbb', 134 + borderBottomColor: '#f0f8ff',
93 marginBottom: 10 135 marginBottom: 10
94 // borderBottomWidth: StyleSheet.hairlineWidth, 136 // borderBottomWidth: StyleSheet.hairlineWidth,
95 }, 137 },
...@@ -102,15 +144,15 @@ const styles = StyleSheet.create({ ...@@ -102,15 +144,15 @@ const styles = StyleSheet.create({
102 marginRight: 15, 144 marginRight: 15,
103 }, 145 },
104 buttonStyle: { 146 buttonStyle: {
105 - flex: 1, 147 + flex: 0.5,
106 - backgroundColor: '#ecf0f1', 148 + backgroundColor: '#f0f8ff',
107 alignItems: 'center', 149 alignItems: 'center',
108 justifyContent: 'center', 150 justifyContent: 'center',
109 - width: 30, 151 + width: 10,
110 height: 30, 152 height: 30,
111 borderWidth: 1, 153 borderWidth: 1,
112 - borderColor: 'black', 154 + borderColor: 'grey',
113 - marginBottom: 20 155 + marginBottom: 20,
114 - 156 + borderRadius: 30
115 } 157 }
116 }); 158 });
......
1 +import React, {useState, useContext, useEffect, useCallback} from 'react';
2 +import {Text, View, StyleSheet, TouchableOpacity, ScrollView, TextInput} from 'react-native';
3 +import {useDispatch, useSelector} from "react-redux";
4 +import {useNavigation} from '@react-navigation/native';
5 +import styled from "styled-components";
6 +import {MaterialCommunityIcons, AntDesign} from '@expo/vector-icons';
7 +
8 +
9 +const Banner = styled.View`
10 + flex: 1;
11 + margin-left: 15px;
12 + margin-bottom: 5px;
13 + width: 3px;
14 + height: 3px;
15 + border-radius: 20px;
16 + border: 3px solid grey;
17 +
18 +`;
19 +
20 +
21 +const WalkPathComponent = (props) => {
22 + const navigation = useNavigation();
23 + const [walkPath, setWalkPath] = useState(null);
24 + const {pathDetail} = props;
25 +
26 + useEffect(() => {
27 + console.log(props.pathDetail.distance);
28 + setWalkPath(props.pathDetail);
29 + }, []);
30 +
31 + return (
32 + <ScrollView>
33 + <View style={{flexDirection: 'row', flex: 5}}>
34 + <View style={styles.pathType}>
35 + <MaterialCommunityIcons style={{flex: 1}} color={'darkgrey'} name={'walk'} size={20}/>
36 + <Text style={{flex: 1, fontSize: 13}}>{pathDetail.time}</Text>
37 + </View>
38 + <View style={{flex: 1}}>
39 + <Banner/>
40 + <Banner/>
41 + <Banner/>
42 + <Banner/>
43 + <Banner/>
44 + <Banner/>
45 + <Banner/>
46 + </View>
47 + <View style={styles.inputTile}>
48 + <Text style={styles.inputText}> 도보 {pathDetail.distance}m 이동</Text>
49 + </View>
50 + </View>
51 + </ScrollView>
52 + );
53 +}
54 +export default WalkPathComponent;
55 +
56 +const styles = StyleSheet.create({
57 + inputTile: {
58 + flex: 4,
59 + justifyContent: 'center',
60 + color: 'grey',
61 + },
62 + inputText: {
63 + fontWeight: 'normal',
64 + fontSize: 15,
65 + },
66 + pathType: {
67 + flexDirection: 'column',
68 + flex: 0.4,
69 + alignItems: 'center',
70 + justifyContent: 'center',
71 + marginLeft: 5,
72 + marginTop: 10,
73 + }
74 +})
...\ No newline at end of file ...\ No newline at end of file
1 import React, {userLayoutEffect} from 'react'; 1 import React, {userLayoutEffect} from 'react';
2 import {createStackNavigator} from "@react-navigation/stack"; 2 import {createStackNavigator} from "@react-navigation/stack";
3 -import TabNavigation from "./TabNavigation";
4 import SelectOrTakePhotoTabNavigation from "./SelectOrTakePhotoTabNavigation"; 3 import SelectOrTakePhotoTabNavigation from "./SelectOrTakePhotoTabNavigation";
5 import UploadPhoto from "../screens/UploadPhoto"; 4 import UploadPhoto from "../screens/UploadPhoto";
6 5
7 const Stack = createStackNavigator(); 6 const Stack = createStackNavigator();
8 7
9 -const SelectOrTakePhotoStackNavigation = () =>{ 8 +const SelectOrTakePhotoStackNavigation = () => {
10 return ( 9 return (
11 <Stack.Navigator 10 <Stack.Navigator
12 mode='card' 11 mode='card'
13 - 12 + screenOptions={{
13 + headerShown: false
14 + }}
14 > 15 >
15 <Stack.Screen 16 <Stack.Screen
16 - name='SelectOrTakePhotoTabNavigation' 17 + name='SelectOrTakePhotoTabNavigation'
17 - component={SelectOrTakePhotoTabNavigation} 18 + component={SelectOrTakePhotoTabNavigation}
18 - /> 19 + />
19 <Stack.Screen 20 <Stack.Screen
20 name='UploadPhoto' 21 name='UploadPhoto'
21 component={UploadPhoto} 22 component={UploadPhoto}
......
1 +import React, {userLayoutEffect} from 'react';
2 +import {createStackNavigator} from "@react-navigation/stack";
3 +import SetLocationTabNavigation from "./SetLocationTabNavigation";
4 +import GoPathDetail from "../screens/GoPathDetail";
5 +import OptRoutePath from "../screens/OptRoutePath";
6 +
7 +const Stack = createStackNavigator();
8 +
9 +const SetLocationStackNavigation = () => {
10 + return (
11 + <Stack.Navigator
12 + mode='card'
13 + screenOptions={{
14 + headerShown: false
15 + }}
16 + >
17 + <Stack.Screen
18 + name='SetLocationTabNavigation'
19 + component={SetLocationTabNavigation}
20 + />
21 +
22 + <Stack.Screen
23 + name='GoPathDetail'
24 + component={GoPathDetail}
25 + />
26 +
27 + </Stack.Navigator>
28 +
29 + )
30 +};
31 +
32 +export default SetLocationStackNavigation;
...\ No newline at end of file ...\ No newline at end of file
1 +import React, {useLayoutEffect} from 'react';
2 +import {Ionicons} from "@expo/vector-icons";
3 +import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
4 +import Maps from "../screens/Maps";
5 +import OptRoutePath from "../screens/OptRoutePath";
6 +
7 +const Tab = createBottomTabNavigator();
8 +
9 +const SetLocationTabNavigation = (props) => {
10 + const {navigation, route} = props;
11 + // useLayoutEffect(() => {}, [route]);
12 +
13 + return (
14 + <Tab.Navigator
15 + tabBarOptions={{}}
16 + >
17 + <Tab.Screen
18 + name='Maps'
19 + component={Maps}
20 + />
21 +
22 + <Tab.Screen
23 + name='OptRoutePath'
24 + component={OptRoutePath}
25 + />
26 +
27 + </Tab.Navigator>
28 + )
29 +};
30 +
31 +export default SetLocationTabNavigation;
...\ No newline at end of file ...\ No newline at end of file
1 import React from 'react'; 1 import React from 'react';
2 import {createStackNavigator} from "@react-navigation/stack"; 2 import {createStackNavigator} from "@react-navigation/stack";
3 import Gallery from "../screens/Gallery"; 3 import Gallery from "../screens/Gallery";
4 +import Maps from "../screens/Maps";
4 import Main from "../screens/Main"; 5 import Main from "../screens/Main";
5 import TabNavigation from "./TabNavigation"; 6 import TabNavigation from "./TabNavigation";
6 import {TouchableOpacity} from "react-native"; 7 import {TouchableOpacity} from "react-native";
7 -// import * as WebBrowser from 'expo-web-browser'; 8 +import {MaterialCommunityIcons} from "@expo/vector-icons";
8 -import {Ionicons} from "@expo/vector-icons";
9 import SelectOrTakePhotoStackNavigation from "./SelectOrTakePhotoStackNavigation"; 9 import SelectOrTakePhotoStackNavigation from "./SelectOrTakePhotoStackNavigation";
10 - 10 +import SetLocationStackNavigation from "./SetLocationStackNavigation";
11 +import Profile from "../screens/Profile";
12 +import Login from "../screens/Login";
13 +import SignUp from "../screens/SignUp";
11 14
12 const Stack = createStackNavigator(); 15 const Stack = createStackNavigator();
13 // 16 //
...@@ -15,15 +18,16 @@ const Stack = createStackNavigator(); ...@@ -15,15 +18,16 @@ const Stack = createStackNavigator();
15 // await WebBrowser.openBrowserAsync(url); 18 // await WebBrowser.openBrowserAsync(url);
16 // }; 19 // };
17 20
18 -const StackNavigation = () =>{ 21 +const StackNavigation = () => {
19 return ( 22 return (
20 <Stack.Navigator 23 <Stack.Navigator
21 mode='card' 24 mode='card'
22 - screenOptions = {{ 25 + screenOptions={{
26 + headerTitle: 'SGGO',
23 headerRight: () => { 27 headerRight: () => {
24 return ( 28 return (
25 - <TouchableOpacity> 29 + <TouchableOpacity style={{marginRight: 5}}>
26 - <Ionicons name={'logo-youtube'} color={'red'} size={25}/> 30 + <MaterialCommunityIcons color={'grey'} name={'send'} size={24}/>
27 </TouchableOpacity> 31 </TouchableOpacity>
28 ) 32 )
29 } 33 }
...@@ -38,9 +42,27 @@ const StackNavigation = () =>{ ...@@ -38,9 +42,27 @@ const StackNavigation = () =>{
38 component={SelectOrTakePhotoStackNavigation} 42 component={SelectOrTakePhotoStackNavigation}
39 /> 43 />
40 <Stack.Screen 44 <Stack.Screen
45 + name='SetLocationStackNavigation'
46 + component={SetLocationStackNavigation}
47 + />
48 + <Stack.Screen
49 + name='Maps'
50 + component={Maps}
51 + />
52 + <Stack.Screen
41 name='Gallery' 53 name='Gallery'
42 component={Gallery} 54 component={Gallery}
43 /> 55 />
56 +
57 + <Stack.Screen
58 + name='Login'
59 + component={Login}
60 + />
61 +
62 + <Stack.Screen
63 + name='SignUp'
64 + component={SignUp}
65 + />
44 </Stack.Navigator> 66 </Stack.Navigator>
45 ) 67 )
46 }; 68 };
......
...@@ -4,14 +4,11 @@ import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'; ...@@ -4,14 +4,11 @@ import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
4 import Main from "../screens/Main"; 4 import Main from "../screens/Main";
5 import Login from "../screens/Login"; 5 import Login from "../screens/Login";
6 import Profile from "../screens/Profile"; 6 import Profile from "../screens/Profile";
7 +import LocationTimeSet from "../screens/LocationTimeSet";
7 import Maps from "../screens/Maps"; 8 import Maps from "../screens/Maps";
8 9
9 -
10 const Tab = createBottomTabNavigator(); 10 const Tab = createBottomTabNavigator();
11 11
12 -const getHeaderName = (route) => {
13 -};
14 -
15 const TabNavigation = (props) => { 12 const TabNavigation = (props) => {
16 const {navigation, route} = props; 13 const {navigation, route} = props;
17 // useLayoutEffect(() => {}, [route]); 14 // useLayoutEffect(() => {}, [route]);
...@@ -19,12 +16,8 @@ const TabNavigation = (props) => { ...@@ -19,12 +16,8 @@ const TabNavigation = (props) => {
19 return ( 16 return (
20 <Tab.Navigator 17 <Tab.Navigator
21 // screenOptions = {({route})=>{}} 18 // screenOptions = {({route})=>{}}
22 - tabBarOptions = {{}} 19 + tabBarOptions={{}}
23 > 20 >
24 - <Tab.Screen
25 - name='main'
26 - component={Main}
27 - />
28 21
29 <Tab.Screen 22 <Tab.Screen
30 name='login' 23 name='login'
...@@ -32,8 +25,8 @@ const TabNavigation = (props) => { ...@@ -32,8 +25,8 @@ const TabNavigation = (props) => {
32 /> 25 />
33 26
34 <Tab.Screen 27 <Tab.Screen
35 - name='maps' 28 + name='LocationTimeSet'
36 - component={Maps} 29 + component={LocationTimeSet}
37 /> 30 />
38 31
39 <Tab.Screen 32 <Tab.Screen
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
8 "eject": "expo eject" 8 "eject": "expo eject"
9 }, 9 },
10 "dependencies": { 10 "dependencies": {
11 + "@react-native-community/datetimepicker": "2.2.2",
11 "@react-native-community/masked-view": "0.1.6", 12 "@react-native-community/masked-view": "0.1.6",
12 "@react-navigation/bottom-tabs": "^5.4.1", 13 "@react-navigation/bottom-tabs": "^5.4.1",
13 "@react-navigation/native": "^5.3.0", 14 "@react-navigation/native": "^5.3.0",
...@@ -16,14 +17,21 @@ ...@@ -16,14 +17,21 @@
16 "expo": "~37.0.3", 17 "expo": "~37.0.3",
17 "expo-asset": "^8.1.4", 18 "expo-asset": "^8.1.4",
18 "expo-camera": "~8.2.0", 19 "expo-camera": "~8.2.0",
20 + "expo-file-system": "~8.1.0",
19 "expo-font": "^8.1.1", 21 "expo-font": "^8.1.1",
20 "expo-location": "~8.1.0", 22 "expo-location": "~8.1.0",
21 "expo-media-library": "~8.1.0", 23 "expo-media-library": "~8.1.0",
22 "expo-permissions": "~8.1.0", 24 "expo-permissions": "~8.1.0",
23 "expo-web-browser": "^8.2.1", 25 "expo-web-browser": "^8.2.1",
26 + "moment": "^2.26.0",
27 + "native-base": "^2.13.12",
28 + "node-nikerunclub": "^1.0.0",
29 + "papaparse": "^5.2.0",
24 "react": "~16.9.0", 30 "react": "~16.9.0",
25 "react-dom": "~16.9.0", 31 "react-dom": "~16.9.0",
26 "react-native": "https://github.com/expo/react-native/archive/sdk-37.0.1.tar.gz", 32 "react-native": "https://github.com/expo/react-native/archive/sdk-37.0.1.tar.gz",
33 + "react-native-bottom-action-sheet": "^2.0.1",
34 + "react-native-fast-image": "^8.1.5",
27 "react-native-gesture-handler": "~1.6.0", 35 "react-native-gesture-handler": "~1.6.0",
28 "react-native-maps": "0.26.1", 36 "react-native-maps": "0.26.1",
29 "react-native-reanimated": "~1.7.0", 37 "react-native-reanimated": "~1.7.0",
......
1 +export const initialState = {
2 + startLocation: null,
3 + endLocation: null,
4 + endTime: '',
5 +
6 + optRoute: null,
7 +
8 + settingLocation: false,
9 + settingTime: false,
10 + settingOptRoute: false,
11 + settingVelocity: false,
12 +
13 +
14 + personalVelocity: 60,
15 + info: '',
16 +};
17 +
18 +export const SET_SLOC_REQUEST = 'SET_SLOC_REQUEST';
19 +export const SET_SLOC_SUCCESS = 'SET_SLOC_SUCCESS';
20 +export const SET_SLOC_FAILURE = 'SET_SLOC_FAILURE';
21 +export const SET_ELOC_REQUEST = 'SET_ELOC_REQUEST';
22 +export const SET_ELOC_SUCCESS = 'SET_ELOC_SUCCESS';
23 +export const SET_ELOC_FAILURE = 'SET_ELOC_FAILURE';
24 +export const SET_USER_LOC = 'SET_USER_LOC';
25 +
26 +export const SET_TIME_REQUEST = 'SET_TIME_REQUEST';
27 +export const SET_TIME_SUCCESS = 'SET_TIME_SUCCESS';
28 +export const SET_TIME_FAILURE = 'SET_TIME_FAILURE';
29 +
30 +export const SET_OPTROUTE_REQUEST = 'SET_OPTROUTE_REQUEST';
31 +export const SET_OPTROUTE_SUCCESS = 'SET_OPTROUTE_SUCCESS';
32 +export const SET_OPTROUTE_FAILURE = 'SET_OPTROUTE_FAILURE';
33 +
34 +export const SET_PERVELOCITY_REQUEST = 'SET_PERVELOCITY_REQUEST';
35 +export const SET_PERVELOCITY_SUCCESS = 'SET_PERVELOCITY_SUCCESS';
36 +export const SET_PERVELOCITY_FAILURE = 'SET_PERVELOCITY_FAILURE';
37 +
38 +
39 +export default (state = initialState, action) => {
40 + switch (action.type) {
41 +
42 + case SET_SLOC_REQUEST: {
43 + return {
44 + ...state,
45 + settingLocation: true,
46 + }
47 + }
48 +
49 + case SET_SLOC_SUCCESS: {
50 + const {startLocation} = action.data;
51 + return {
52 + ...state,
53 + startLocation,
54 + isLoggingIn: false,
55 + };
56 + }
57 +
58 + case SET_SLOC_FAILURE: {
59 + const {info} = action.data;
60 + return {
61 + ...state,
62 + settingLocation: false,
63 + info,
64 + }
65 + }
66 +
67 +
68 + case SET_ELOC_REQUEST: {
69 + return {
70 + ...state,
71 + settingLocation: true,
72 + }
73 + }
74 +
75 + case SET_ELOC_SUCCESS: {
76 + const {endLocation} = action.data;
77 + return {
78 + ...state,
79 + endLocation,
80 + isLoggingIn: false,
81 + };
82 + }
83 +
84 + case SET_ELOC_FAILURE: {
85 + const {info} = action.data;
86 + return {
87 + ...state,
88 + settingLocation: false,
89 + info,
90 + }
91 + }
92 +
93 + case SET_USER_LOC: {
94 + var {userLocation} = action.data;
95 + userLocation = {
96 + title: '현위치',
97 + latitude: userLocation.coords.latitude,
98 + longitude: userLocation.coords.longitude,
99 + latitudeDelta: 0.0039,
100 + longitudeDelta: 0.0039,
101 + description: 'start point',
102 +
103 + };
104 + console.log(userLocation.coords);
105 + return {
106 + ...state,
107 + startLocation: userLocation,
108 + settingLocation: false
109 + }
110 + }
111 +
112 + case SET_TIME_REQUEST: {
113 + return {
114 + ...state,
115 + settingTime: true,
116 + }
117 + }
118 + case SET_TIME_SUCCESS: {
119 + const {date} = action.data;
120 + console.log('reducer SET_TIME_SUCCESS', date);
121 + return {
122 + ...state,
123 + endTime: date,
124 + settingTime: false,
125 + }
126 + }
127 + case SET_TIME_FAILURE: {
128 + const {info} = action.data;
129 + return {
130 + ...state,
131 + settingTime: false,
132 + }
133 + }
134 +
135 + case SET_OPTROUTE_REQUEST: {
136 + return {
137 + ...state,
138 + settingOptRoute: true,
139 + }
140 + }
141 +
142 + case SET_OPTROUTE_SUCCESS: {
143 + var {optRoute} = action.data;
144 + console.log('SET_OPTROUTE_SUCCESST', optRoute);
145 + return {
146 + ...state,
147 + optRoute: optRoute,
148 + settingOptRoute: false,
149 + }
150 + }
151 +
152 + case SET_OPTROUTE_FAILURE: {
153 + const {info} = action.data;
154 + return {
155 + ...state,
156 + settingOptRoute: false,
157 + }
158 + }
159 +
160 +
161 + case SET_PERVELOCITY_REQUEST: {
162 + return {
163 + ...state,
164 + settingVelocity: true,
165 + }
166 + }
167 +
168 + case SET_PERVELOCITY_SUCCESS: {
169 + var {personalVelocity} = action.data;
170 + console.log('SET_PERVELOCITY_SUCCESS', personalVelocity);
171 + return {
172 + ...state,
173 + personalVelocity,
174 + settingVelocity: true,
175 + }
176 + }
177 +
178 + case SET_PERVELOCITY_FAILURE: {
179 + const {info} = action.data;
180 + return {
181 + ...state,
182 + settingVelocity: false,
183 + }
184 + }
185 +
186 + default: {
187 + return {
188 + ...state,
189 + };
190 + }
191 + }
192 +};
...\ No newline at end of file ...\ No newline at end of file
1 export const initialState = { 1 export const initialState = {
2 me: null, 2 me: null,
3 + nikeRecord: null,
3 4
4 isLoggingIn: false, 5 isLoggingIn: false,
5 isSigningUp: false, 6 isSigningUp: false,
......
1 +import {all, call, fork, delay, put, takeEvery, takeLatest} from 'redux-saga/effects';
2 +import axios from 'axios';
3 +import {coordAPIKEY, host} from '../env';
4 +
5 +
6 +import {
7 + SET_ELOC_REQUEST,
8 + SET_SLOC_REQUEST,
9 + SET_SLOC_SUCCESS,
10 + SET_ELOC_SUCCESS,
11 + SET_SLOC_FAILURE,
12 + SET_ELOC_FAILURE,
13 + SET_OPTROUTE_REQUEST,
14 + SET_OPTROUTE_SUCCESS,
15 + SET_OPTROUTE_FAILURE,
16 +} from "../reducers/location";
17 +
18 +function setStartLocationAPI(data) {
19 + const {startTextLocation} = data;
20 + console.log(startTextLocation);
21 + return axios.get(`http://api.vworld.kr/req/address?service=address&request=getcoord&version=1.0&crs=epsg:4326&address=${startTextLocation}&refine=true&simple=false&format=json&type=road&key=${coordAPIKEY}`);
22 +}
23 +
24 +function setEndLocationAPI(data) {
25 + const {endTextLocation} = data;
26 + console.log(endTextLocation);
27 + return axios.get(`http://api.vworld.kr/req/address?service=address&request=getcoord&version=1.0&crs=epsg:4326&address=${endTextLocation}&refine=true&simple=false&format=json&type=road&key=${coordAPIKEY}`);
28 +}
29 +
30 +function setOptRouteAPI(data) {
31 + const {startLocation, endLocation, endTime, personalVelocity} = data;
32 + console.log('제발 좀 되라', startLocation, endLocation, endTime, personalVelocity);
33 + return axios.post(`http://${host}:4001/api/setOptRoute`, {
34 + startLocation,
35 + endLocation,
36 + endTime,
37 + personalVelocity
38 + }, {withCredentials: true});
39 +}
40 +
41 +function* setStartLocation(action) {
42 + try {
43 + console.log('saga의 setLocation', action.data);
44 + let res = yield call(setStartLocationAPI, action.data);
45 + let longitude, latitude = null;
46 +
47 + if (res.data.response.status === "OK") {
48 + longitude = parseFloat(res.data.response.result.point.x);
49 + latitude = parseFloat(res.data.response.result.point.y);
50 + }
51 + //
52 + // if (res.data.status === "OK") {
53 + // latitude = res.data.results[0].geometry.location.lat;
54 + // longitude = res.data.results[0].geometry.location.lng;
55 + // console.log(latitude, longitude)
56 + // }
57 +
58 + console.log('startRes: ', longitude, latitude);
59 +
60 + yield put({
61 + type: SET_SLOC_SUCCESS,
62 + data: {
63 + startLocation: {
64 + title: action.data.startTextLocation,
65 + description: 'start point',
66 + longitude: longitude,
67 + latitude: latitude,
68 + latitudeDelta: 1.2,
69 + longitudeDelta: 1.2
70 +
71 + }
72 + }
73 + })
74 + } catch (e) {
75 + console.error(e);
76 + yield put({
77 + type: SET_SLOC_FAILURE,
78 + data: {
79 + info: e.response.data.info
80 + }
81 + });
82 + }
83 +}
84 +
85 +function* setEndLocation(action) {
86 + try {
87 + let res = yield call(setEndLocationAPI, action.data);
88 + let longitude, latitude = null;
89 +
90 + //
91 + // if (res.data.status === "OK") {
92 + // latitude = res.data.results[0].geometry.location.lat;
93 + // longitude = res.data.results[0].geometry.location.lng;
94 + // console.log(latitude, longitude)
95 + // }
96 +
97 + if (res.data.response.status === "OK") {
98 + longitude = parseFloat(res.data.response.result.point.x);
99 + latitude = parseFloat(res.data.response.result.point.y);
100 + }
101 +
102 + console.log('finishRes: ', longitude, latitude);
103 +
104 + yield put({
105 + type: SET_ELOC_SUCCESS,
106 + data: {
107 + endLocation: {
108 + title: action.data.endTextLocation,
109 + description: 'end point',
110 + longitude: longitude,
111 + latitude: latitude,
112 + latitudeDelta: 1.2,
113 + longitudeDelta: 1.2
114 + }
115 + }
116 + });
117 + } catch (e) {
118 + console.error(e);
119 + yield put({
120 + type: SET_ELOC_FAILURE,
121 + data: {
122 + info: e.response.data.info
123 + }
124 + })
125 +
126 + }
127 +}
128 +
129 +function* setOptRoute(action) {
130 + try {
131 + let res = yield call(setOptRouteAPI, action.data);
132 + const {optRoute} = res.data;
133 + yield put({
134 + type: SET_OPTROUTE_SUCCESS,
135 + data: {
136 + optRoute: optRoute
137 + }
138 + });
139 +
140 + } catch (e) {
141 + console.error(e);
142 + yield put({
143 + type: SET_OPTROUTE_FAILURE,
144 + data: {
145 + info: e.response.data.info
146 + }
147 + })
148 + }
149 +}
150 +
151 +
152 +function* watchSetStartLocation() {
153 + console.log('watchSetStartLocation');
154 + yield takeLatest(SET_SLOC_REQUEST, setStartLocation);
155 +}
156 +
157 +function* watchSetEndLocation() {
158 + console.log('watchSetEndLocation');
159 + yield takeLatest(SET_ELOC_REQUEST, setEndLocation)
160 +}
161 +
162 +function* watchSetOptRoute() {
163 + console.log('watchSetOptimalRoute');
164 + yield takeLatest(SET_OPTROUTE_REQUEST, setOptRoute)
165 +}
166 +
167 +export default function* locationSaga() {
168 + yield all([
169 + fork(watchSetStartLocation),
170 + fork(watchSetEndLocation),
171 + fork(watchSetOptRoute),
172 + ]);
173 +};
...\ No newline at end of file ...\ No newline at end of file
1 import {all, call, fork, delay, put, takeEvery, takeLatest} from 'redux-saga/effects'; 1 import {all, call, fork, delay, put, takeEvery, takeLatest} from 'redux-saga/effects';
2 import axios from 'axios'; 2 import axios from 'axios';
3 -import host from '../env'; 3 +import {host} from '../env';
4 import { 4 import {
5 LOG_IN_FAILURE, 5 LOG_IN_FAILURE,
6 LOG_IN_REQUEST, 6 LOG_IN_REQUEST,
...@@ -37,9 +37,7 @@ function loginAPI(data) { ...@@ -37,9 +37,7 @@ function loginAPI(data) {
37 const {email, password} = data; 37 const {email, password} = data;
38 console.log(email, password); 38 console.log(email, password);
39 console.log(`http://${host}:4001/user/login`); 39 console.log(`http://${host}:4001/user/login`);
40 - // const res1 = axios.get(`http://${host}:4001/user/test`, { 40 +
41 - // withCredentials: true
42 - // });
43 return axios.post(`http://${host}:4001/user/login`, { 41 return axios.post(`http://${host}:4001/user/login`, {
44 email, password 42 email, password
45 }, { 43 }, {
......
1 +import React, {useState, useContext, useEffect, useCallback} from 'react';
2 +import {Text, View, StyleSheet, TouchableOpacity, ScrollView, TextInput} from 'react-native';
3 +import {useDispatch, useSelector} from "react-redux";
4 +import {useNavigation} from '@react-navigation/native';
5 +import WalkPathComponent from "../components/WalkPathComponent";
6 +import BusPathComponent from "../components/BusPathComponent";
7 +import LanePathComponent from "../components/LanePathComponent";
8 +import {MaterialCommunityIcons} from "@expo/vector-icons";
9 +
10 +const GoPathDetail = (props) => {
11 + const navigation = useNavigation();
12 + const {route} = props;
13 + const {detail} = route.params;
14 + const [pathDetails, setPathDetails] = useState(null);
15 + const {startLocation, endLocation, optRoute} = useSelector(state => state.location);
16 +
17 +
18 + useEffect(() => {
19 + setPathDetails(detail);
20 + console.log(detail)
21 + }, []);
22 +
23 +
24 + return (
25 + <ScrollView>
26 + <View style={styles.input}>
27 + <MaterialCommunityIcons color={'red'} name={'map-marker'} size={26}/>
28 + <TextInput
29 + style={styles.inputText}
30 + value={startLocation.title}
31 + />
32 + </View>
33 + {pathDetails ?
34 + pathDetails.map((detail, index) => {
35 + if (detail.trafficType === '도보') {
36 + return (
37 + <WalkPathComponent pathDetail={detail}/>
38 + )
39 + } else if (detail.trafficType === '버스') {
40 + return (
41 + <BusPathComponent pathDetail={detail}/>
42 + )
43 + } else (detail.trafficType === '지하철')
44 + {
45 + return (
46 + <LanePathComponent pathDetail={detail}/>
47 + )
48 + }
49 + })
50 + :
51 + null
52 + }
53 + <View style={styles.input}>
54 + <MaterialCommunityIcons color={'blue'} name={'map-marker'} size={26}/>
55 + <TextInput
56 + style={styles.inputText}
57 + value={endLocation.title}
58 + />
59 + </View>
60 + </ScrollView>
61 + );
62 +}
63 +export default GoPathDetail;
64 +
65 +const styles = StyleSheet.create({
66 + input: {
67 + borderRadius: 20,
68 + paddingLeft: 10,
69 + paddingTop: 5,
70 + paddingRight: 10,
71 + width: 350,
72 + height: 30,
73 + alignItems: 'center',
74 + flexDirection: 'row',
75 + justifyContent: 'space-between',
76 + borderBottomColor: '#f0f8ff',
77 + marginBottom: 10,
78 + // borderBottomWidth: StyleSheet.hairlineWidth,
79 + },
80 + inputText: {
81 + flex: 1,
82 + fontWeight: 'bold',
83 + }
84 +})
...\ No newline at end of file ...\ No newline at end of file
1 +import React, {useState, useEffect} from 'react';
2 +import {View, Text, Button, StyleSheet} from 'react-native';
3 +import StartAndFinishLocationComponent from "../components/StartAndFinishLocationComponent";
4 +import DateTimePickerComponent from "../components/DateTimePickerComponent";
5 +import styled from "styled-components";
6 +import {useNavigation} from "@react-navigation/native";
7 +import {useDispatch, useSelector} from "react-redux";
8 +import {SET_OPTROUTE_REQUEST} from "../reducers/location";
9 +
10 +const GoToMaps = styled.TouchableOpacity`
11 + flex: 0.5;
12 + backgroundColor: #f0f8ff;
13 + align-items: center;
14 + justify-content: center;
15 + width: 180px;
16 + height: 30px;
17 + border-radius: 30px;
18 + border-width: 1px;
19 + border-color: #a9a9a9;
20 + position: absolute;
21 + left: 55
22 +`;
23 +
24 +const LocationTimeSet = () => {
25 + const navigation = useNavigation();
26 + const [goToMapsClick, setGoToMapsClick] = useState(false);
27 +
28 + const {startLocation} = useSelector(state => state.location);
29 + const {endLocation} = useSelector(state => state.location);
30 +
31 + const dispatch = useDispatch();
32 + const goToMaps = async () => {
33 + setGoToMapsClick(true);
34 + navigation.navigate('SetLocationStackNavigation');
35 + setTimeout(() => {
36 + setGoToMapsClick(false)
37 + }, 2000)
38 + };
39 +
40 + useEffect(() => {
41 + }, []);
42 +
43 + return (
44 + <View>
45 + <StartAndFinishLocationComponent/>
46 + <DateTimePickerComponent goToMapsClick={goToMapsClick}/>
47 +
48 + <View style={{flexDirection: 'row', marginLeft: 50}}>
49 + <GoToMaps onPress={goToMaps}>
50 + <Text>도착 시간 설정</Text>
51 + </GoToMaps>
52 + </View>
53 + </View>
54 + )
55 +};
56 +
57 +
58 +const styles = StyleSheet.create({
59 + containerStyle: {
60 + flex: 1,
61 + alignItems: 'center',
62 + justifyContent: 'center',
63 + backgroundColor: '#ecf0f1',
64 + marginTop: 100,
65 + },
66 + input: {
67 + width: 200,
68 + height: 44,
69 + padding: 10,
70 + borderWidth: 1,
71 + borderColor: '#778899',
72 + marginBottom: 10,
73 + }
74 +});
75 +
76 +export default LocationTimeSet;
...\ No newline at end of file ...\ No newline at end of file
1 +import React, {useState, useContext, useEffect, useCallback} from 'react';
2 +import {View, Text, Image, TextInput, TouchableOpacity, StyleSheet} from 'react-native';
3 +import {useDispatch, useSelector} from "react-redux";
4 +import {useNavigation} from '@react-navigation/native';
5 +import LoginComponent from "../components/LoginComponent";
6 +import styled from "styled-components";
7 +
8 +
9 +const Login = (props) => {
10 + const navigation = useNavigation();
11 + const [loading, setLoading] = useState(true);
12 + const [isLogin, setIsLogin] = useState(true);
13 +
14 + const {me} = useSelector(state => state.user);
15 + const {isLoggingIn} = useSelector(state => state.user);
16 +
17 + const changeIsLogin = () => {
18 + return setIsLogin(!isLogin);
19 + }
20 +
21 + useEffect(() => {
22 + setLoading(false);
23 + }, [me]);
24 +
25 +
26 + return (
27 + <View style={styles.changeStyle}>
28 + {me ?
29 + <View style={{flex: 2}}>
30 + <Image
31 + style={{width: 500, height: 600, flex: 1}}
32 + source={require('../assets/nike.png')}
33 + />
34 + <TouchableOpacity
35 + title={'SGGO'}
36 + style={{flex: 1, fontSize: 100}}
37 + >
38 + </TouchableOpacity>
39 + </View>
40 + :
41 + <View style={styles.loginStyle}>
42 + <Text style={styles.inputText}>로그인</Text>
43 + <LoginComponent/>
44 + </View>
45 + }
46 + </View>
47 + )
48 +};
49 +
50 +export default Login;
51 +
52 +const styles = StyleSheet.create({
53 + changeStyle: {
54 + flex: 2,
55 + alignItems: 'center',
56 + justifyContent: 'center',
57 + borderColor: 'darkgrey',
58 + },
59 + loginStyle: {
60 + flex: 1,
61 + marginTop: 30,
62 + },
63 + inputText: {
64 + borderColor: 'darkgrey',
65 + fontWeight: 'bold',
66 + fontSize: 20,
67 + marginBottom: 10
68 + }
69 +
70 +});
...\ No newline at end of file ...\ No newline at end of file
...@@ -29,7 +29,6 @@ const Main = () => { ...@@ -29,7 +29,6 @@ const Main = () => {
29 const navigation = useNavigation(); 29 const navigation = useNavigation();
30 30
31 const goToGallery = () => { 31 const goToGallery = () => {
32 - console.log(navigation.navigate);
33 navigation.navigate('Gallery'); 32 navigation.navigate('Gallery');
34 }; 33 };
35 34
......
1 +import React from 'react';
2 +import {View, Text, TouchableOpacity, Image, StyleSheet} from 'react-native';
3 +import styled from "styled-components";
4 +import {useNavigation} from "@react-navigation/native";
5 +import {useSelector} from "react-redux";
6 +
7 +const MainImage = (props) => {
8 + const navigation = useNavigation();
9 +
10 + const {me} = useSelector(state => state.user);
11 +
12 +
13 + return (
14 + <>
15 + <View style={styles.containerStyle}>
16 + <Text>로그인에 성공하였습니다</Text>
17 + </View>
18 + </>
19 + )
20 +};
21 +export default MainImage;
22 +
23 +const styles = StyleSheet.create({
24 + containerStyle: {
25 + flex: 1,
26 + },
27 +});
1 +import React, {useState, useEffect} from 'react';
2 +import MapView, {Marker, Polygon, AnimatedRegion} from 'react-native-maps';
3 +import {StyleSheet, Text, TextInput, TouchableOpacity, View} from 'react-native';
4 +import screen from '../constants/layout';
5 +import {useDispatch, useSelector} from "react-redux";
6 +import {useNavigation} from "@react-navigation/native";
7 +import {AntDesign, MaterialCommunityIcons} from "@expo/vector-icons";
8 +import {SET_OPTROUTE_REQUEST} from "../reducers/location";
9 +import styled from "styled-components";
10 +import OptRoutePath from "./OptRoutePath";
11 +
12 +const GoToOptRoutePath = styled.TouchableOpacity`
13 + flex: 2;
14 + position: absolute;
15 + right: 8px;
16 + bottom: 20px;
17 + width: 30px;
18 + height: 30px;
19 + border-radius: 50px;
20 +`;
21 +
22 +const Maps = (props) => {
23 + const navigation = useNavigation();
24 + const [region, setRegion] = useState(null);
25 + const [markers, setMarkers] = useState([]);
26 + const [pathList, setPathList] = useState([]);
27 + const {startLocation, endLocation, optRoute, endTime, personalVelocity} = useSelector(state => state.location);
28 + const onRegionChange = (region) => {
29 + setRegion(region);
30 + };
31 +
32 + useEffect(() => {
33 + setRegion({
34 + latitude: 37.56647,
35 + longitude: 126.977963,
36 + latitudeDelta: 1.5,
37 + longitudeDelta: 1.5
38 + });
39 + if (startLocation || endLocation) {
40 + setMarkers([startLocation, endLocation]);
41 + }
42 +
43 + }, []);
44 +
45 + const dispatch = useDispatch();
46 + const goToOptRoutePath = async () => {
47 + try {
48 + console.log('set optroute request');
49 + await dispatch({
50 + type: SET_OPTROUTE_REQUEST,
51 + data: {
52 + startLocation,
53 + endLocation,
54 + endTime,
55 + personalVelocity
56 + }
57 + });
58 + setTimeout(() => {
59 + if (optRoute !== null) {
60 + navigation.navigate('OptRoutePath', {optRoute: optRoute})
61 + }
62 + }, 3000);
63 + } catch (e) {
64 + console.error(e);
65 + }
66 + };
67 +
68 + useEffect(() => {
69 + setMarkers([startLocation, endLocation]);
70 + }, [startLocation, endLocation]);
71 +
72 +
73 + return (
74 + <View style={styles.container}>
75 + <View style={styles.input}>
76 + <MaterialCommunityIcons color={'red'} name={'map-marker'} size={26}/>
77 + <TextInput
78 + style={styles.inputText}
79 + value={startLocation.title}
80 + />
81 + </View>
82 + <View style={styles.input}>
83 + <MaterialCommunityIcons color={'blue'} name={'map-marker'} size={26}/>
84 + <TextInput
85 + style={styles.inputText}
86 + value={endLocation.title}
87 + />
88 + </View>
89 + <MapView
90 + style={styles.mapStyle}
91 + initialRegion={region}
92 + onRegionChange={onRegionChange}
93 + textStyle={{color: '#bc8b00'}}
94 + showsUserLocation={true}
95 + >
96 + {markers ?
97 + markers.map((marker, index) => {
98 + return (
99 + <MapView.Marker draggable
100 + key={index}
101 + coordinate={marker}
102 + title={marker.title}
103 + />
104 + )
105 + })
106 + :
107 + null
108 + }
109 + </MapView>
110 + <GoToOptRoutePath onPress={goToOptRoutePath}>
111 + <AntDesign color={'darkgrey'} name={'caretright'} size={32}/>
112 + </GoToOptRoutePath>
113 + </View>
114 + )
115 +};
116 +
117 +const styles = StyleSheet.create({
118 + container: {
119 + flex: 1,
120 + backgroundColor: '#fff',
121 + alignItems: 'center',
122 + },
123 + mapStyle: {
124 + width: screen.width,
125 + height: screen.height,
126 + },
127 + textStyle: {
128 + flex: 1,
129 + fontWeight: 'bold',
130 + fontSize: 20,
131 + color: 'grey',
132 + marginBottom: 20,
133 + },
134 + input: {
135 + borderRadius: 10,
136 + backgroundColor: '#f0f8ff',
137 + paddingLeft: 10,
138 + paddingTop: 5,
139 + paddingRight: 10,
140 + width: 350,
141 + height: 30,
142 + alignItems: 'center',
143 + flexDirection: 'row',
144 + justifyContent: 'space-between',
145 + borderBottomColor: '#f0f8ff',
146 + marginBottom: 10
147 + // borderBottomWidth: StyleSheet.hairlineWidth,
148 + },
149 + inputText: {
150 + flex: 1,
151 + },
152 +});
153 +
154 +export default Maps;
155 +
1 +import React, {useState, useEffect} from 'react';
2 +import {View, Text, Button, ScrollView} from 'react-native';
3 +import {useNavigation} from '@react-navigation/native';
4 +import {useDispatch, useSelector} from "react-redux";
5 +import GoPathSummary from '../components/GoPathSummary';
6 +
7 +const OptRoutePath = (props) => {
8 + const navigation = useNavigation();
9 + const {route} = props;
10 + const {optRoute} = route.params;
11 +
12 + const [pathList, setPathList] = useState([]);
13 + const {startLocation} = useSelector(state => state.location);
14 + const {endLocation} = useSelector(state => state.location);
15 +
16 + const dispatch = useDispatch();
17 + const setOptRouteRequest = async () => {
18 + try {
19 + console.log('set optroute request');
20 + setTimeout(() => {
21 + if (optRoute.pathList) {
22 + for (var i = 0; i < optRoute.pathList.length; i++) {
23 + setPathList(oldPath => [...oldPath, optRoute.pathList[i]]);
24 + }
25 + }
26 + }, 3000);
27 +
28 + } catch (e) {
29 + console.error(e);
30 + }
31 + };
32 +
33 +
34 + useEffect(() => {
35 + setOptRouteRequest();
36 + }, []);
37 +
38 + return (
39 + <ScrollView>
40 + {pathList ?
41 + pathList.map((path, index) => {
42 + return (
43 + <>
44 + <GoPathSummary summary={path.info} detail={path.subPathList}/>
45 + </>
46 + )
47 + })
48 + :
49 + null
50 + }
51 + </ScrollView>
52 + )
53 +};
54 +
55 +export default OptRoutePath;
...\ No newline at end of file ...\ No newline at end of file
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
No preview for this file type
No preview for this file type