Showing
118 changed files
with
0 additions
and
5214 deletions
code/.idea/code.iml
deleted
100644 → 0
1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
2 | -<module type="WEB_MODULE" version="4"> | ||
3 | - <component name="NewModuleRootManager"> | ||
4 | - <content url="file://$MODULE_DIR$" /> | ||
5 | - <orderEntry type="inheritedJdk" /> | ||
6 | - <orderEntry type="sourceFolder" forTests="false" /> | ||
7 | - </component> | ||
8 | -</module> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
code/.idea/misc.xml
deleted
100644 → 0
1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
2 | -<project version="4"> | ||
3 | - <component name="JavaScriptSettings"> | ||
4 | - <option name="languageLevel" value="JSX" /> | ||
5 | - </component> | ||
6 | - <component name="ProjectPlainTextFileTypeManager"> | ||
7 | - <file url="file://$PROJECT_DIR$/render_server_react_native/components/CardComponent.js" /> | ||
8 | - </component> | ||
9 | -</project> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
code/.idea/modules.xml
deleted
100644 → 0
1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
2 | -<project version="4"> | ||
3 | - <component name="ProjectModuleManager"> | ||
4 | - <modules> | ||
5 | - <module fileurl="file://$PROJECT_DIR$/.idea/code.iml" filepath="$PROJECT_DIR$/.idea/code.iml" /> | ||
6 | - </modules> | ||
7 | - </component> | ||
8 | -</project> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
code/.idea/vcs.xml
deleted
100644 → 0
1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
2 | -<project version="4"> | ||
3 | - <component name="VcsDirectoryMappings"> | ||
4 | - <mapping directory="$PROJECT_DIR$/.." vcs="Git" /> | ||
5 | - <mapping directory="$PROJECT_DIR$/locationTest/expo-location-example" vcs="Git" /> | ||
6 | - <mapping directory="$PROJECT_DIR$/my-project" vcs="Git" /> | ||
7 | - <mapping directory="$PROJECT_DIR$/render_server_react_native" vcs="Git" /> | ||
8 | - <mapping directory="$PROJECT_DIR$/render_server_react_native/@expo/vector-icons" vcs="Git" /> | ||
9 | - </component> | ||
10 | -</project> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
code/.idea/webServers.xml
deleted
100644 → 0
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 |
code/.idea/workspace.xml
deleted
100644 → 0
1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
2 | -<project version="4"> | ||
3 | - <component name="ChangeListManager"> | ||
4 | - <list default="true" id="940f1aa2-9848-4abc-bd75-a3db12d9e8e1" name="Default Changelist" comment=""> | ||
5 | - <change beforePath="$PROJECT_DIR$/.idea/vcs.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/vcs.xml" afterDir="false" /> | ||
6 | - <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> | ||
7 | - <change beforePath="$PROJECT_DIR$/../보고서/최종보고서.docx" beforeDir="false" afterPath="$PROJECT_DIR$/../보고서/최종보고서.docx" afterDir="false" /> | ||
8 | - </list> | ||
9 | - <option name="SHOW_DIALOG" value="false" /> | ||
10 | - <option name="HIGHLIGHT_CONFLICTS" value="true" /> | ||
11 | - <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" /> | ||
12 | - <option name="LAST_RESOLUTION" value="IGNORE" /> | ||
13 | - </component> | ||
14 | - <component name="FavoritesManager"> | ||
15 | - <favorites_list name="code" /> | ||
16 | - </component> | ||
17 | - <component name="FileTemplateManagerImpl"> | ||
18 | - <option name="RECENT_TEMPLATES"> | ||
19 | - <list> | ||
20 | - <option value="JavaScript File" /> | ||
21 | - </list> | ||
22 | - </option> | ||
23 | - </component> | ||
24 | - <component name="Git.Settings"> | ||
25 | - <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." /> | ||
26 | - </component> | ||
27 | - <component name="ProjectId" id="1baLVrrFUlmMeeq9EFLzndP0zML" /> | ||
28 | - <component name="ProjectLevelVcsManager" settingsEditedManually="true"> | ||
29 | - <ConfirmationsSetting value="2" id="Add" /> | ||
30 | - </component> | ||
31 | - <component name="ProjectViewState"> | ||
32 | - <option name="hideEmptyMiddlePackages" value="true" /> | ||
33 | - <option name="showExcludedFiles" value="true" /> | ||
34 | - <option name="showLibraryContents" value="true" /> | ||
35 | - </component> | ||
36 | - <component name="PropertiesComponent"> | ||
37 | - <property name="ASKED_ADD_EXTERNAL_FILES" value="true" /> | ||
38 | - <property name="RunOnceActivity.ShowReadmeOnStart" value="true" /> | ||
39 | - <property name="WebServerToolWindowFactoryState" value="true" /> | ||
40 | - <property name="WebServerToolWindowPanel.toolwindow.highlight.mappings" value="true" /> | ||
41 | - <property name="WebServerToolWindowPanel.toolwindow.highlight.symlinks" value="true" /> | ||
42 | - <property name="WebServerToolWindowPanel.toolwindow.show.date" value="false" /> | ||
43 | - <property name="WebServerToolWindowPanel.toolwindow.show.permissions" value="false" /> | ||
44 | - <property name="WebServerToolWindowPanel.toolwindow.show.size" value="false" /> | ||
45 | - <property name="last_opened_file_path" value="$PROJECT_DIR$/render_server_react_native/assets/userFile" /> | ||
46 | - <property name="nodejs_package_manager_path" value="npm" /> | ||
47 | - </component> | ||
48 | - <component name="RecentsManager"> | ||
49 | - <key name="MoveFile.RECENT_KEYS"> | ||
50 | - <recent name="$PROJECT_DIR$/render_server_react_native" /> | ||
51 | - <recent name="$PROJECT_DIR$/render_server_react_native/navigations" /> | ||
52 | - <recent name="$PROJECT_DIR$/render_server_react_native/components" /> | ||
53 | - </key> | ||
54 | - <key name="CopyFile.RECENT_KEYS"> | ||
55 | - <recent name="$PROJECT_DIR$/render_server_react_native/assets/userFile" /> | ||
56 | - <recent name="$PROJECT_DIR$/render_server_react_native" /> | ||
57 | - <recent name="$PROJECT_DIR$/render_server_react_native/screens" /> | ||
58 | - <recent name="$PROJECT_DIR$/render_server_react_native/components" /> | ||
59 | - <recent name="$PROJECT_DIR$/user_and_post_server" /> | ||
60 | - </key> | ||
61 | - </component> | ||
62 | - <component name="SvnConfiguration"> | ||
63 | - <configuration /> | ||
64 | - </component> | ||
65 | - <component name="TaskManager"> | ||
66 | - <task active="true" id="Default" summary="Default task"> | ||
67 | - <changelist id="940f1aa2-9848-4abc-bd75-a3db12d9e8e1" name="Default Changelist" comment="" /> | ||
68 | - <created>1588865284571</created> | ||
69 | - <option name="number" value="Default" /> | ||
70 | - <option name="presentableId" value="Default" /> | ||
71 | - <updated>1588865284571</updated> | ||
72 | - <workItem from="1588865285717" duration="748000" /> | ||
73 | - <workItem from="1588875642765" duration="2528000" /> | ||
74 | - <workItem from="1588878826886" duration="6053000" /> | ||
75 | - <workItem from="1588919313007" duration="576000" /> | ||
76 | - <workItem from="1589357475573" duration="2335000" /> | ||
77 | - <workItem from="1589800232399" duration="230000" /> | ||
78 | - <workItem from="1589865778893" duration="5143000" /> | ||
79 | - <workItem from="1589960196464" duration="11230000" /> | ||
80 | - <workItem from="1590036154083" duration="405000" /> | ||
81 | - <workItem from="1590039473513" duration="2083000" /> | ||
82 | - <workItem from="1590082072338" duration="1708000" /> | ||
83 | - <workItem from="1590302730003" duration="745000" /> | ||
84 | - <workItem from="1590304674918" duration="364000" /> | ||
85 | - <workItem from="1590305558438" duration="34000" /> | ||
86 | - <workItem from="1590392477108" duration="7362000" /> | ||
87 | - <workItem from="1590405423629" duration="8216000" /> | ||
88 | - <workItem from="1590427383874" duration="208000" /> | ||
89 | - <workItem from="1590472694480" duration="1558000" /> | ||
90 | - <workItem from="1590510616633" duration="2347000" /> | ||
91 | - <workItem from="1590561746816" duration="2332000" /> | ||
92 | - <workItem from="1590649191412" duration="121000" /> | ||
93 | - <workItem from="1590667953682" duration="5117000" /> | ||
94 | - <workItem from="1590847459903" duration="309000" /> | ||
95 | - <workItem from="1590857450778" duration="161000" /> | ||
96 | - <workItem from="1590938910580" duration="4993000" /> | ||
97 | - <workItem from="1591036634686" duration="2717000" /> | ||
98 | - <workItem from="1591042905280" duration="3848000" /> | ||
99 | - <workItem from="1591241250822" duration="1506000" /> | ||
100 | - <workItem from="1591243317314" duration="1000" /> | ||
101 | - <workItem from="1591257776111" duration="2611000" /> | ||
102 | - <workItem from="1591347046562" duration="4809000" /> | ||
103 | - <workItem from="1591365203105" duration="1624000" /> | ||
104 | - <workItem from="1591368704614" duration="2067000" /> | ||
105 | - <workItem from="1591371675134" duration="1958000" /> | ||
106 | - <workItem from="1591399909349" duration="755000" /> | ||
107 | - <workItem from="1591424440663" duration="3921000" /> | ||
108 | - <workItem from="1591452959431" duration="5762000" /> | ||
109 | - <workItem from="1591498815349" duration="8719000" /> | ||
110 | - <workItem from="1591763504251" duration="1207000" /> | ||
111 | - <workItem from="1591768189989" duration="16032000" /> | ||
112 | - <workItem from="1591807888950" duration="205000" /> | ||
113 | - <workItem from="1591810687526" duration="2491000" /> | ||
114 | - <workItem from="1591814852707" duration="850000" /> | ||
115 | - <workItem from="1592023711264" duration="7962000" /> | ||
116 | - <workItem from="1592034078601" duration="2771000" /> | ||
117 | - <workItem from="1592043154434" duration="5000" /> | ||
118 | - <workItem from="1592120155930" duration="19951000" /> | ||
119 | - <workItem from="1592294228904" duration="12060000" /> | ||
120 | - <workItem from="1592423933838" duration="20743000" /> | ||
121 | - <workItem from="1592460562052" duration="9046000" /> | ||
122 | - <workItem from="1592493681837" duration="17090000" /> | ||
123 | - <workItem from="1592515725392" duration="2907000" /> | ||
124 | - <workItem from="1592528808951" duration="135000" /> | ||
125 | - <workItem from="1592536638207" duration="5384000" /> | ||
126 | - <workItem from="1592659198314" duration="162000" /> | ||
127 | - <workItem from="1592659457606" duration="137000" /> | ||
128 | - <workItem from="1592813189933" duration="12000" /> | ||
129 | - </task> | ||
130 | - <servers /> | ||
131 | - </component> | ||
132 | - <component name="TypeScriptGeneratedFilesManager"> | ||
133 | - <option name="version" value="1" /> | ||
134 | - </component> | ||
135 | - <component name="UnknownFeatures"> | ||
136 | - <option featureType="com.intellij.fileTypeFactory" implementationName="*.csv" /> | ||
137 | - </component> | ||
138 | - <component name="VcsManagerConfiguration"> | ||
139 | - <option name="ADD_EXTERNAL_FILES_SILENTLY" value="true" /> | ||
140 | - </component> | ||
141 | - <component name="WindowStateProjectService"> | ||
142 | - <state x="399" y="127" key="#Deployment" timestamp="1591366165652"> | ||
143 | - <screen x="0" y="23" width="1440" height="877" /> | ||
144 | - </state> | ||
145 | - <state x="399" y="127" key="#Deployment/0.23.1440.877@0.23.1440.877" timestamp="1591366165652" /> | ||
146 | - <state x="368" y="125" key="#com.intellij.execution.impl.EditConfigurationsDialog" timestamp="1591815112224"> | ||
147 | - <screen x="0" y="23" width="1440" height="877" /> | ||
148 | - </state> | ||
149 | - <state x="368" y="125" key="#com.intellij.execution.impl.EditConfigurationsDialog/0.23.1440.877@0.23.1440.877" timestamp="1591815112224" /> | ||
150 | - <state x="710" y="271" key="#com.intellij.fileTypes.FileTypeChooser" timestamp="1588881921466"> | ||
151 | - <screen x="0" y="23" width="1440" height="877" /> | ||
152 | - </state> | ||
153 | - <state x="710" y="271" key="#com.intellij.fileTypes.FileTypeChooser/0.23.1440.877@0.23.1440.877" timestamp="1588881921466" /> | ||
154 | - <state width="784" height="229" key="GridCell.Tab.0.bottom" timestamp="1588878772214"> | ||
155 | - <screen x="0" y="23" width="1440" height="877" /> | ||
156 | - </state> | ||
157 | - <state width="784" height="229" key="GridCell.Tab.0.bottom/0.23.1440.877@0.23.1440.877" timestamp="1588878772214" /> | ||
158 | - <state width="784" height="229" key="GridCell.Tab.0.center" timestamp="1588878772213"> | ||
159 | - <screen x="0" y="23" width="1440" height="877" /> | ||
160 | - </state> | ||
161 | - <state width="784" height="229" key="GridCell.Tab.0.center/0.23.1440.877@0.23.1440.877" timestamp="1588878772213" /> | ||
162 | - <state width="784" height="229" key="GridCell.Tab.0.left" timestamp="1588878772212"> | ||
163 | - <screen x="0" y="23" width="1440" height="877" /> | ||
164 | - </state> | ||
165 | - <state width="784" height="229" key="GridCell.Tab.0.left/0.23.1440.877@0.23.1440.877" timestamp="1588878772212" /> | ||
166 | - <state width="784" height="229" key="GridCell.Tab.0.right" timestamp="1588878772213"> | ||
167 | - <screen x="0" y="23" width="1440" height="877" /> | ||
168 | - </state> | ||
169 | - <state width="784" height="229" key="GridCell.Tab.0.right/0.23.1440.877@0.23.1440.877" timestamp="1588878772213" /> | ||
170 | - <state x="585" y="23" width="552" height="758" key="dock-window-1" timestamp="1592127183020"> | ||
171 | - <screen x="0" y="23" width="1440" height="877" /> | ||
172 | - </state> | ||
173 | - <state x="585" y="23" width="552" height="758" key="dock-window-1/0.23.1440.877@0.23.1440.877" timestamp="1592127183020" /> | ||
174 | - <state x="702" y="213" width="670" height="676" key="search.everywhere.popup" timestamp="1592465069777"> | ||
175 | - <screen x="0" y="23" width="1440" height="877" /> | ||
176 | - </state> | ||
177 | - <state x="702" y="213" width="670" height="676" key="search.everywhere.popup/0.23.1440.877@0.23.1440.877" timestamp="1592465069777" /> | ||
178 | - <state x="767" y="383" key="vcs.readOnlyHandler.ReadOnlyStatusDialog" timestamp="1588882053803"> | ||
179 | - <screen x="0" y="23" width="1440" height="877" /> | ||
180 | - </state> | ||
181 | - <state x="767" y="383" key="vcs.readOnlyHandler.ReadOnlyStatusDialog/0.23.1440.877@0.23.1440.877" timestamp="1588882053803" /> | ||
182 | - </component> | ||
183 | - <component name="XDebuggerManager"> | ||
184 | - <breakpoint-manager> | ||
185 | - <breakpoints> | ||
186 | - <line-breakpoint enabled="true" type="javascript"> | ||
187 | - <url>file://$PROJECT_DIR$/my-project/screens/HomeScreen.js</url> | ||
188 | - <option name="timeStamp" value="1" /> | ||
189 | - </line-breakpoint> | ||
190 | - </breakpoints> | ||
191 | - </breakpoint-manager> | ||
192 | - </component> | ||
193 | -</project> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | -import React, {useState} from 'react'; | ||
2 | -import {StyleSheet, Text, View, Image, StatusBar, AsyncStorage} from 'react-native'; | ||
3 | -import {AppLoading} from "expo"; | ||
4 | -import {Asset} from 'expo-asset'; | ||
5 | -import {Provider} from 'react-redux'; | ||
6 | -import * as Font from 'expo-font' | ||
7 | -import {Ionicons} from "@expo/vector-icons"; | ||
8 | -import {NavigationContainer} from "@react-navigation/native"; | ||
9 | -import store from './store'; | ||
10 | -import StackNavigation from "./navigations/StackNavigation"; | ||
11 | -import {AuthProvider} from "./AuthContext"; | ||
12 | -import {host} from './env'; | ||
13 | -import axios from "axios"; | ||
14 | - | ||
15 | -const cacheImages = (images) => { | ||
16 | - return images.map((image) => { | ||
17 | - if (typeof image === 'string') { | ||
18 | - return Image.prefetch(image); | ||
19 | - } else { | ||
20 | - return Asset.fromModule(image).downloadAsync(); | ||
21 | - } | ||
22 | - }) | ||
23 | -}; | ||
24 | - | ||
25 | -const cacheFonts = (fonts) => { | ||
26 | - return fonts.map((font) => { | ||
27 | - return Font.loadAsync(font); | ||
28 | - }) | ||
29 | -}; | ||
30 | - | ||
31 | -const App = () => { | ||
32 | - const [isReady, setIsReady] = useState(false); | ||
33 | - const [user, setUser] = useState(''); | ||
34 | - | ||
35 | - const loadAssets = async () => { | ||
36 | - const images = cacheImages( | ||
37 | - ['https://images.unsplash.com/photo-1532278951723-545f655c97f9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60'] | ||
38 | - ); | ||
39 | - const fonts = cacheFonts([Ionicons.font]); | ||
40 | - | ||
41 | - // await AsyncStorage.removeItem('cookie'); | ||
42 | - const cookie = await AsyncStorage.getItem('cookie'); | ||
43 | - console.log('cookie', cookie); | ||
44 | - if (cookie) { | ||
45 | - try { | ||
46 | - axios.defaults.headers.Cookie = cookie; | ||
47 | - console.log('user/loadMe 요청보냄', `http://${host}:4001/user/loadMe`); | ||
48 | - const res = await axios.get(`http://${host}:4001/user/loadMe`); | ||
49 | - const {user} = res.data; | ||
50 | - console.log(user); | ||
51 | - setUser(user); | ||
52 | - } catch (e) { | ||
53 | - console.error(e); | ||
54 | - } | ||
55 | - } | ||
56 | - | ||
57 | - return Promise.all([images, fonts]); | ||
58 | - }; | ||
59 | - | ||
60 | - const onFinish = () => { | ||
61 | - setIsReady(true); | ||
62 | - }; | ||
63 | - const onError = (err) => { | ||
64 | - console.error(err) | ||
65 | - }; | ||
66 | - return ( | ||
67 | - <> | ||
68 | - {isReady | ||
69 | - ? | ||
70 | - <Provider store={store}> | ||
71 | - <AuthProvider user={user}> | ||
72 | - <NavigationContainer> | ||
73 | - <StatusBar barstyle={'light-content'}/> | ||
74 | - <StackNavigation/> | ||
75 | - </NavigationContainer> | ||
76 | - </AuthProvider> | ||
77 | - </Provider> | ||
78 | - : | ||
79 | - <AppLoading | ||
80 | - startAsync={loadAssets} | ||
81 | - onFinish={onFinish} | ||
82 | - onError={onError} | ||
83 | - /> | ||
84 | - } | ||
85 | - </> | ||
86 | - ); | ||
87 | -}; | ||
88 | - | ||
89 | - | ||
90 | -export default App; | ||
91 | - | ||
92 | -const styles = StyleSheet.create({ | ||
93 | - container: { | ||
94 | - flex: 1, | ||
95 | - backgroundColor: '#fff', | ||
96 | - alignItems: 'center', | ||
97 | - justifyContent: 'center', | ||
98 | - }, | ||
99 | -}); |
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 | -}); |
1 | -import React, {createContext, useContext, useEffect, useState} from 'react'; | ||
2 | -import {useDispatch, useSelector} from 'react-redux'; | ||
3 | -import {LOAD_ME_SUCCESS} from "./reducers/user"; | ||
4 | - | ||
5 | -export const AuthContext = createContext({}); | ||
6 | -export const AuthProvider = (props) => { | ||
7 | - const {children, user} = props; | ||
8 | - | ||
9 | - const dispatch = useDispatch(); | ||
10 | - | ||
11 | - const onLoadMe = async () => { | ||
12 | - try { | ||
13 | - await dispatch({ | ||
14 | - type: LOAD_ME_SUCCESS, | ||
15 | - data: { | ||
16 | - user | ||
17 | - } | ||
18 | - }); | ||
19 | - } catch (e) { | ||
20 | - console.log(e); | ||
21 | - } | ||
22 | - }; | ||
23 | - | ||
24 | - useEffect(() => { | ||
25 | - onLoadMe(); | ||
26 | - console.log('AuthContext user', user); | ||
27 | - }, [user]); | ||
28 | - | ||
29 | - return ( | ||
30 | - <AuthContext.Provider> | ||
31 | - {children} | ||
32 | - </AuthContext.Provider> | ||
33 | - ) | ||
34 | -}; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | -{ | ||
2 | - "expo": { | ||
3 | - "name": "render_server_react_native", | ||
4 | - "slug": "render_server_react_native", | ||
5 | - "platforms": [ | ||
6 | - "ios", | ||
7 | - "android", | ||
8 | - "web" | ||
9 | - ], | ||
10 | - "version": "1.0.0", | ||
11 | - "orientation": "portrait", | ||
12 | - "icon": "./assets/icon.png", | ||
13 | - "splash": { | ||
14 | - "image": "./assets/splash.png", | ||
15 | - "resizeMode": "contain", | ||
16 | - "backgroundColor": "#ffffff" | ||
17 | - }, | ||
18 | - "updates": { | ||
19 | - "fallbackToCacheTimeout": 0 | ||
20 | - }, | ||
21 | - "assetBundlePatterns": [ | ||
22 | - "**/*" | ||
23 | - ], | ||
24 | - "ios": { | ||
25 | - "supportsTablet": true | ||
26 | - } | ||
27 | - } | ||
28 | -} |
642 Bytes
This diff could not be displayed because it is too large.
1.11 KB
1.6 KB
2.1 KB
825 Bytes
936 Bytes
1.07 KB
1.05 KB
1.37 KB
1.84 KB
2.21 KB
613 Bytes
1.17 KB
4.3 KB
723 Bytes
1.42 KB
7.22 KB
824 Bytes
1.07 KB
2.39 KB
3.7 KB
1.65 KB
1.09 KB
2.35 KB
988 Bytes
619 Bytes
2.34 KB
974 Bytes
2.51 KB
13.3 KB
1.19 KB
892 Bytes
3.06 KB
1.2 KB
2.22 KB
4.14 KB
1.09 KB
973 Bytes
1.89 KB
6.29 KB
4.1 KB
This diff could not be displayed because it is too large.
9.09 KB
148 KB
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 |
1 | -import React from 'react'; | ||
2 | -import {ActivityIndicator, View} from 'react-native'; | ||
3 | - | ||
4 | -const LoadingComponent = () => { | ||
5 | - return ( | ||
6 | - <View style={{ | ||
7 | - flex: 1, | ||
8 | - justifyContent: 'center', | ||
9 | - alignItems: 'center' | ||
10 | - }}> | ||
11 | - <ActivityIndicator color={'grey'}/> | ||
12 | - </View> | ||
13 | - ) | ||
14 | -}; | ||
15 | - | ||
16 | - | ||
17 | - | ||
18 | -export default LoadingComponent; | ||
... | \ 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, StyleSheet, 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 styled from "styled-components"; | ||
6 | -import {useNavigation} from '@react-navigation/native'; | ||
7 | -import Profile from "../screens/Profile"; | ||
8 | - | ||
9 | - | ||
10 | -const LoginButton = styled.TouchableOpacity` | ||
11 | - align-items: center; | ||
12 | - justify-content: center; | ||
13 | - width: 60px; | ||
14 | - height: 40px; | ||
15 | - background-color: #e6e6fa; | ||
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 | - | ||
31 | -`; | ||
32 | - | ||
33 | - | ||
34 | -const LoginComponent = () => { | ||
35 | - const navigation = useNavigation(); | ||
36 | - const [loading, setLoading] = useState(true); | ||
37 | - const [email, setEmail] = useState(''); | ||
38 | - const [password, setPassword] = useState(''); | ||
39 | - | ||
40 | - | ||
41 | - const {me} = useSelector(state => state.user); | ||
42 | - const {isLoggingIn} = useSelector(state => state.user); | ||
43 | - | ||
44 | - const onChangeEmail = (email) => { | ||
45 | - setEmail(email) | ||
46 | - }; | ||
47 | - | ||
48 | - const onChangePassword = (password) => { | ||
49 | - setPassword(password); | ||
50 | - }; | ||
51 | - | ||
52 | - const dispatch = useDispatch(); | ||
53 | - const onSubmit = async () => { | ||
54 | - if (!email || !password) { | ||
55 | - return | ||
56 | - } | ||
57 | - await dispatch({ | ||
58 | - type: LOG_IN_REQUEST, | ||
59 | - data: { | ||
60 | - email, | ||
61 | - password | ||
62 | - } | ||
63 | - }); | ||
64 | - | ||
65 | - }; | ||
66 | - const goSignUp = () => { | ||
67 | - navigation.navigate('SignUp'); | ||
68 | - } | ||
69 | - | ||
70 | - useEffect(() => { | ||
71 | - if (me) { | ||
72 | - navigation.navigate('Profile'); | ||
73 | - } | ||
74 | - }, [me]); | ||
75 | - | ||
76 | - useEffect(() => { | ||
77 | - setLoading(false); | ||
78 | - setEmail(''); | ||
79 | - setPassword(''); | ||
80 | - }, []); | ||
81 | - | ||
82 | - return ( | ||
83 | - <View style={styles.containerStyle}> | ||
84 | - <TextInput | ||
85 | - style={styles.input} | ||
86 | - placeholder="Type here to Email!" | ||
87 | - onChangeText={onChangeEmail} | ||
88 | - defaultValue={email} | ||
89 | - /> | ||
90 | - <TextInput | ||
91 | - style={styles.input} | ||
92 | - placeholder="Type here to password!" | ||
93 | - type="password" | ||
94 | - onChangeText={onChangePassword} | ||
95 | - /> | ||
96 | - <LoginButton | ||
97 | - title={'Login'} | ||
98 | - onPress={onSubmit}> | ||
99 | - <Text style={{color: '#696969'}}>Login</Text> | ||
100 | - </LoginButton> | ||
101 | - <SignUpButton | ||
102 | - title={'Login'} | ||
103 | - onPress={goSignUp}> | ||
104 | - <Text style={{color: '#696969'}}>SignUp</Text> | ||
105 | - </SignUpButton> | ||
106 | - </View> | ||
107 | - ) | ||
108 | -}; | ||
109 | - | ||
110 | -const styles = StyleSheet.create({ | ||
111 | - containerStyle: { | ||
112 | - // flex: 1, | ||
113 | - alignItems: 'center', | ||
114 | - // justifyContent: 'center', | ||
115 | - // backgroundColor: '#ecf0f1', | ||
116 | - // marginTop: 100, | ||
117 | - }, | ||
118 | - input: { | ||
119 | - width: 200, | ||
120 | - height: 44, | ||
121 | - padding: 10, | ||
122 | - borderWidth: 1, | ||
123 | - borderColor: '#778899', | ||
124 | - marginBottom: 10, | ||
125 | - } | ||
126 | -}); | ||
127 | - | ||
128 | -export default LoginComponent; | ||
... | \ 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, 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 | - | ||
40 | - const dispatch = useDispatch(); | ||
41 | - const loadPersonalVelocity = async () => { | ||
42 | - try { | ||
43 | - | ||
44 | - const userVelocity = require('../assets/userFile/userVelocity'); | ||
45 | - var allAvgSpeed = 0; | ||
46 | - setNumRecord(userVelocity.length); | ||
47 | - userVelocity.map((i, index) => { | ||
48 | - allAvgSpeed = allAvgSpeed + i.avgSpeed; | ||
49 | - }); | ||
50 | - | ||
51 | - var personalVelocity = parseInt(allAvgSpeed / userVelocity.length); | ||
52 | - await dispatch({ | ||
53 | - type: SET_PERVELOCITY_SUCCESS, | ||
54 | - data: { | ||
55 | - personalVelocity: personalVelocity | ||
56 | - } | ||
57 | - }); | ||
58 | - | ||
59 | - Alert.alert( | ||
60 | - 'MAP 사용자 평균 속도 설정', | ||
61 | - ` 사용자 평균 속도를 설정하였습니다. `, | ||
62 | - [ | ||
63 | - { | ||
64 | - text: 'Cancel', | ||
65 | - onPress: () => console.log('Cancel Pressed'), | ||
66 | - style: 'cancel', | ||
67 | - }, | ||
68 | - {text: 'OK', onPress: () => console.log('OK Pressed')}, | ||
69 | - ], | ||
70 | - {cancelable: false} | ||
71 | - ); | ||
72 | - | ||
73 | - } catch (e) { | ||
74 | - console.log(e); | ||
75 | - } | ||
76 | - | ||
77 | - }; | ||
78 | - | ||
79 | - useEffect(() => { | ||
80 | - setNumRecord(0); | ||
81 | - }, []); | ||
82 | - | ||
83 | - useEffect(() => { | ||
84 | - console.log(numRecord) | ||
85 | - }, [numRecord]); | ||
86 | - | ||
87 | - const onLogout = async () => { | ||
88 | - await dispatch({ | ||
89 | - type: LOG_OUT_REQUEST | ||
90 | - }); | ||
91 | - console.log('onLogout'); | ||
92 | - }; | ||
93 | - return ( | ||
94 | - <View> | ||
95 | - {me ? | ||
96 | - <View> | ||
97 | - <View style={{flexDirection: 'row', paddingTop: 15}}> | ||
98 | - <View style={{flex: 1, alignItems: 'center'}}> | ||
99 | - <Image source={{url: 'https://steemitimages.com/u/anpigon/avatar'}} | ||
100 | - style={{width: 75, height: 75, borderRadius: 37.5}}/> | ||
101 | - </View> | ||
102 | - <View style={{flex: 3}}> | ||
103 | - <View style={{flexDirection: 'row', justifyContent: 'space-around', marginTop: 12}}> | ||
104 | - <View style={{alignItems: 'center'}}> | ||
105 | - <Text style={{fontSize: 15, fontWeight: 'bold'}}>{me.email}</Text> | ||
106 | - <Text style={{fontSize: 10, color: 'gray'}}>email</Text> | ||
107 | - </View> | ||
108 | - <View style={{alignItems: 'center'}}> | ||
109 | - <Text style={{fontSize: 15, fontWeight: 'bold'}}>{me.nickName}</Text> | ||
110 | - <Text style={{fontSize: 10, color: 'gray'}}>nickName</Text> | ||
111 | - </View> | ||
112 | - <View style={{alignItems: 'center'}}> | ||
113 | - <Text style={{fontSize: 15, fontWeight: 'bold'}}>{numRecord}</Text> | ||
114 | - <Text style={{fontSize: 10, color: 'gray'}}>numRecord</Text> | ||
115 | - </View> | ||
116 | - </View> | ||
117 | - <View style={{flexDirection: 'row'}}> | ||
118 | - <TouchableOpacity | ||
119 | - onPress={loadPersonalVelocity} | ||
120 | - style={{ | ||
121 | - flex: 4, | ||
122 | - marginLeft: 10, | ||
123 | - justifyContent: 'center', | ||
124 | - alignItems: 'center', | ||
125 | - borderWidth: 1, | ||
126 | - borderColor: 'black', | ||
127 | - height: 30, | ||
128 | - marginTop: 17 | ||
129 | - }}> | ||
130 | - <Text style={{fontSize: 13}}>load personal velocity</Text> | ||
131 | - </TouchableOpacity> | ||
132 | - <TouchableOpacity | ||
133 | - onPress={onLogout} | ||
134 | - style={{ | ||
135 | - borderColor: 'black', | ||
136 | - borderWidth: 1, | ||
137 | - flex: 1, | ||
138 | - marginRight: 10, | ||
139 | - marginLeft: 5, | ||
140 | - justifyContent: 'center', | ||
141 | - alignItems: 'center', | ||
142 | - height: 30, | ||
143 | - marginTop: 17 | ||
144 | - }}> | ||
145 | - <MaterialCommunityIcons color={'black'} name={'logout'} size={20}/> | ||
146 | - </TouchableOpacity> | ||
147 | - </View> | ||
148 | - </View> | ||
149 | - </View> | ||
150 | - < View style={{paddingHorizontal: 20, paddingVertical: 10}}> | ||
151 | - </View> | ||
152 | - </View> | ||
153 | - : | ||
154 | - <View style={{alignItems: 'center', justifyContent: 'center', marginTop: 200}}> | ||
155 | - <Text style={{fontSize: 30, textAlign: 'center', fontWeight: 'bold'}}>유저 정보가 없습니다.</Text> | ||
156 | - </View> | ||
157 | - } | ||
158 | - </View> | ||
159 | - ) | ||
160 | -}; | ||
161 | - | ||
162 | -const styles = StyleSheet.create({ | ||
163 | - containerStyle: { | ||
164 | - marginTop: 10, | ||
165 | - alignItems: 'center', | ||
166 | - justifyContent: 'center', | ||
167 | - }, | ||
168 | - TextStyle: { | ||
169 | - width: 200, | ||
170 | - height: 44, | ||
171 | - padding: 10, | ||
172 | - borderWidth: 1, | ||
173 | - borderColor: '#778899', | ||
174 | - marginBottom: 10, | ||
175 | - } | ||
176 | -}); | ||
177 | - | ||
178 | -export default MyProfileComponent; | ||
... | \ 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, StyleSheet} from 'react-native'; | ||
3 | -import {useDispatch, useSelector} from "react-redux"; | ||
4 | -import {SIGN_UP_REQUEST} from "../reducers/user"; | ||
5 | -import styled from "styled-components"; | ||
6 | -import {useNavigation} from '@react-navigation/native'; | ||
7 | -import Profile from "../screens/Profile"; | ||
8 | - | ||
9 | - | ||
10 | -const SignUpButton = styled.TouchableOpacity` | ||
11 | - align-items: center; | ||
12 | - justify-content: center; | ||
13 | - width: 60px; | ||
14 | - height: 40px; | ||
15 | - background-color: #e6e6fa; | ||
16 | - border: 1px; | ||
17 | - marginBottom: 10px; | ||
18 | - border-radius: 50px; | ||
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 | - | ||
32 | -const SignUpComponent = () => { | ||
33 | - const navigation = useNavigation(); | ||
34 | - const [email, setEmail] = useState(''); | ||
35 | - const [nickName, setNickName] = useState(''); | ||
36 | - const [password, setPassword] = useState(''); | ||
37 | - | ||
38 | - | ||
39 | - const {me} = useSelector(state => state.user); | ||
40 | - const {isSigningUp} = useSelector(state => state.user); | ||
41 | - | ||
42 | - const onChangeEmail = (email) => { | ||
43 | - setEmail(email) | ||
44 | - }; | ||
45 | - | ||
46 | - const onChangePassword = (password) => { | ||
47 | - setPassword(password); | ||
48 | - }; | ||
49 | - | ||
50 | - const onChangeNickName = (nickName) => { | ||
51 | - setNickName(nickName) | ||
52 | - }; | ||
53 | - | ||
54 | - const dispatch = useDispatch(); | ||
55 | - const onSubmit = async () => { | ||
56 | - await dispatch({ | ||
57 | - type: SIGN_UP_REQUEST, | ||
58 | - data: { | ||
59 | - email, | ||
60 | - nickName, | ||
61 | - password | ||
62 | - } | ||
63 | - }); | ||
64 | - if (me !== null) { | ||
65 | - navigation.navigate('Profile'); | ||
66 | - } | ||
67 | - }; | ||
68 | - | ||
69 | - return ( | ||
70 | - <View styles={styles.containerStyle}> | ||
71 | - <TextInput | ||
72 | - style={styles.input} | ||
73 | - placeholder="Type here to Email!" | ||
74 | - onChangeText={onChangeEmail} | ||
75 | - /> | ||
76 | - <TextInput | ||
77 | - style={styles.input} | ||
78 | - placeholder="Type here to nickname!" | ||
79 | - onChangeText={onChangeNickName} | ||
80 | - /> | ||
81 | - <TextInput | ||
82 | - style={styles.input} | ||
83 | - placeholder="Type here to password!" | ||
84 | - type="password" | ||
85 | - onChangeText={onChangePassword} | ||
86 | - /> | ||
87 | - <SignUpButton | ||
88 | - title={'signUp'} | ||
89 | - onPress={onSubmit}> | ||
90 | - <Text style={{color: '#696969'}}>signUp</Text> | ||
91 | - </SignUpButton> | ||
92 | - <GoLoginButton | ||
93 | - title={'signUp'} | ||
94 | - onPress={onSubmit}> | ||
95 | - <Text style={{color: '#696969'}}>Login</Text> | ||
96 | - </GoLoginButton> | ||
97 | - </View> | ||
98 | - ) | ||
99 | -}; | ||
100 | - | ||
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'; | ||
2 | -import MapView, {Marker} from 'react-native-maps'; | ||
3 | -import {StyleSheet, Text, TextInput, View, TouchableOpacity, Alert} from 'react-native'; | ||
4 | -import screen from '../constants/layout'; | ||
5 | -import {useSelector, useDispatch} from "react-redux"; | ||
6 | -import * as Location from 'expo-location'; | ||
7 | -import {set} from "react-native-reanimated"; | ||
8 | -import {MaterialCommunityIcons} from "@expo/vector-icons"; | ||
9 | -import {SET_ELOC_REQUEST, SET_LOC_REQUEST, SET_SLOC_REQUEST, SET_USER_LOC} from "../reducers/location"; | ||
10 | -import axios from 'axios'; | ||
11 | - | ||
12 | -const StartAndFinishLocationComponent = () => { | ||
13 | - const [hasPermission, setHasPermission] = useState(false); | ||
14 | - const [startTextLocation, setStartTextLocation] = useState(''); | ||
15 | - const [endTextLocation, setEndTextLocation] = useState(''); | ||
16 | - const [userLocation, setUserLocation] = useState(null); | ||
17 | - const [errorMsg, setErrorMsg] = useState(null); | ||
18 | - | ||
19 | - const onChangeStartLocation = (startTextLocation) => { | ||
20 | - setStartTextLocation(startTextLocation); | ||
21 | - }; | ||
22 | - | ||
23 | - const onChangeFinishLocation = (endTextLocation) => { | ||
24 | - setEndTextLocation(endTextLocation); | ||
25 | - }; | ||
26 | - | ||
27 | - const dispatch = useDispatch(); | ||
28 | - const onSetUserLocation = async () => { | ||
29 | - const {status} = await Location.requestPermissionsAsync(); | ||
30 | - if (status !== 'granted') { | ||
31 | - setErrorMsg('Permission to access location was denied') | ||
32 | - } | ||
33 | - const location = await Location.getCurrentPositionAsync({}); | ||
34 | - setStartTextLocation('현위치'); | ||
35 | - setUserLocation(location); | ||
36 | - console.log(location); | ||
37 | - await dispatch({ | ||
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, | ||
50 | - data: { | ||
51 | - startTextLocation | ||
52 | - } | ||
53 | - }) | ||
54 | - } | ||
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 | - ); | ||
80 | - }; | ||
81 | - | ||
82 | - | ||
83 | - return ( | ||
84 | - <View style={styles.container}> | ||
85 | - <View style={styles.input}> | ||
86 | - <MaterialCommunityIcons color={'red'} name={'map-marker'} size={26}/> | ||
87 | - <TextInput | ||
88 | - style={styles.inputText} | ||
89 | - onChangeText={onChangeStartLocation} | ||
90 | - value={startTextLocation} | ||
91 | - /> | ||
92 | - <TouchableOpacity onPress={onSetUserLocation}> | ||
93 | - <MaterialCommunityIcons color={'grey'} name={'crosshairs-gps'} size={30}/> | ||
94 | - </TouchableOpacity> | ||
95 | - | ||
96 | - </View> | ||
97 | - <View style={styles.input}> | ||
98 | - <MaterialCommunityIcons color={'blue'} name={'map-marker'} size={26}/> | ||
99 | - <TextInput | ||
100 | - style={styles.inputText} | ||
101 | - onChangeText={onChangeFinishLocation} | ||
102 | - value={endTextLocation} | ||
103 | - /> | ||
104 | - </View> | ||
105 | - <View style={{flexDirection: 'row', alignItems: 'center'}}> | ||
106 | - <TouchableOpacity style={styles.buttonStyle} onPress={setLocation}> | ||
107 | - <Text>Map설정</Text> | ||
108 | - </TouchableOpacity> | ||
109 | - </View> | ||
110 | - </View> | ||
111 | - ) | ||
112 | -}; | ||
113 | - | ||
114 | -export default StartAndFinishLocationComponent; | ||
115 | - | ||
116 | -const styles = StyleSheet.create({ | ||
117 | - container: { | ||
118 | - alignItems: 'center', | ||
119 | - marginTop: 50, | ||
120 | - marginLeft: 20, | ||
121 | - marginRight: 20, | ||
122 | - opacity: 0.5, | ||
123 | - }, | ||
124 | - input: { | ||
125 | - borderRadius: 10, | ||
126 | - backgroundColor: '#f0f8ff', | ||
127 | - paddingLeft: 10, | ||
128 | - paddingRight: 10, | ||
129 | - width: 300, | ||
130 | - height: 50, | ||
131 | - alignItems: 'center', | ||
132 | - flexDirection: 'row', | ||
133 | - justifyContent: 'space-between', | ||
134 | - borderBottomColor: '#f0f8ff', | ||
135 | - marginBottom: 10 | ||
136 | - // borderBottomWidth: StyleSheet.hairlineWidth, | ||
137 | - }, | ||
138 | - inputText: { | ||
139 | - flex: 1, | ||
140 | - }, | ||
141 | - textStyle: { | ||
142 | - fontWeight: 'bold', | ||
143 | - fontSize: 17, | ||
144 | - marginRight: 15, | ||
145 | - }, | ||
146 | - buttonStyle: { | ||
147 | - flex: 0.5, | ||
148 | - backgroundColor: '#f0f8ff', | ||
149 | - alignItems: 'center', | ||
150 | - justifyContent: 'center', | ||
151 | - width: 10, | ||
152 | - height: 30, | ||
153 | - borderWidth: 1, | ||
154 | - borderColor: 'grey', | ||
155 | - marginBottom: 20, | ||
156 | - borderRadius: 30 | ||
157 | - } | ||
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'; | ||
2 | -import {createStackNavigator} from "@react-navigation/stack"; | ||
3 | -import SelectOrTakePhotoTabNavigation from "./SelectOrTakePhotoTabNavigation"; | ||
4 | -import UploadPhoto from "../screens/UploadPhoto"; | ||
5 | - | ||
6 | -const Stack = createStackNavigator(); | ||
7 | - | ||
8 | -const SelectOrTakePhotoStackNavigation = () => { | ||
9 | - return ( | ||
10 | - <Stack.Navigator | ||
11 | - mode='card' | ||
12 | - screenOptions={{ | ||
13 | - headerShown: false | ||
14 | - }} | ||
15 | - > | ||
16 | - <Stack.Screen | ||
17 | - name='SelectOrTakePhotoTabNavigation' | ||
18 | - component={SelectOrTakePhotoTabNavigation} | ||
19 | - /> | ||
20 | - <Stack.Screen | ||
21 | - name='UploadPhoto' | ||
22 | - component={UploadPhoto} | ||
23 | - /> | ||
24 | - </Stack.Navigator> | ||
25 | - ) | ||
26 | -}; | ||
27 | - | ||
28 | -export default SelectOrTakePhotoStackNavigation; | ||
... | \ 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 TakePhoto from "../screens/TakePhoto"; | ||
5 | -import SelectPhoto from "../screens/SelectPhoto"; | ||
6 | - | ||
7 | -const Tab = createBottomTabNavigator(); | ||
8 | - | ||
9 | -const SelectOrTakePhotoTabNavigation = (props) => { | ||
10 | - const {navigation, route} = props; | ||
11 | - // useLayoutEffect(() => {}, [route]); | ||
12 | - | ||
13 | - return ( | ||
14 | - <Tab.Navigator | ||
15 | - tabBarOptions = {{}} | ||
16 | - > | ||
17 | - <Tab.Screen | ||
18 | - name='SelectPhoto' | ||
19 | - component={SelectPhoto} | ||
20 | - /> | ||
21 | - | ||
22 | - <Tab.Screen | ||
23 | - name='TakePhoto' | ||
24 | - component={TakePhoto} | ||
25 | - /> | ||
26 | - | ||
27 | - </Tab.Navigator> | ||
28 | - ) | ||
29 | -}; | ||
30 | - | ||
31 | -export default SelectOrTakePhotoTabNavigation; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
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'; | ||
2 | -import {createStackNavigator} from "@react-navigation/stack"; | ||
3 | -import Gallery from "../screens/Gallery"; | ||
4 | -import Maps from "../screens/Maps"; | ||
5 | -import Main from "../screens/Main"; | ||
6 | -import TabNavigation from "./TabNavigation"; | ||
7 | -import {TouchableOpacity} from "react-native"; | ||
8 | -import {MaterialCommunityIcons} from "@expo/vector-icons"; | ||
9 | -import SelectOrTakePhotoStackNavigation from "./SelectOrTakePhotoStackNavigation"; | ||
10 | -import SetLocationStackNavigation from "./SetLocationStackNavigation"; | ||
11 | -import Profile from "../screens/Profile"; | ||
12 | -import Login from "../screens/Login"; | ||
13 | -import SignUp from "../screens/SignUp"; | ||
14 | - | ||
15 | -const Stack = createStackNavigator(); | ||
16 | -// | ||
17 | -// const openBrowser = (url) => async () => { | ||
18 | -// await WebBrowser.openBrowserAsync(url); | ||
19 | -// }; | ||
20 | - | ||
21 | -const StackNavigation = () => { | ||
22 | - return ( | ||
23 | - <Stack.Navigator | ||
24 | - mode='card' | ||
25 | - screenOptions={{ | ||
26 | - headerTitle: 'SGGO', | ||
27 | - headerRight: () => { | ||
28 | - return ( | ||
29 | - <TouchableOpacity style={{marginRight: 5}}> | ||
30 | - <MaterialCommunityIcons color={'grey'} name={'send'} size={24}/> | ||
31 | - </TouchableOpacity> | ||
32 | - ) | ||
33 | - } | ||
34 | - }} | ||
35 | - > | ||
36 | - <Stack.Screen | ||
37 | - name='TabNavigation' | ||
38 | - component={TabNavigation} | ||
39 | - /> | ||
40 | - <Stack.Screen | ||
41 | - name='SelectOrTakePhotoStackNavigation' | ||
42 | - component={SelectOrTakePhotoStackNavigation} | ||
43 | - /> | ||
44 | - <Stack.Screen | ||
45 | - name='SetLocationStackNavigation' | ||
46 | - component={SetLocationStackNavigation} | ||
47 | - /> | ||
48 | - <Stack.Screen | ||
49 | - name='Maps' | ||
50 | - component={Maps} | ||
51 | - /> | ||
52 | - <Stack.Screen | ||
53 | - name='Gallery' | ||
54 | - component={Gallery} | ||
55 | - /> | ||
56 | - | ||
57 | - <Stack.Screen | ||
58 | - name='Login' | ||
59 | - component={Login} | ||
60 | - /> | ||
61 | - | ||
62 | - <Stack.Screen | ||
63 | - name='SignUp' | ||
64 | - component={SignUp} | ||
65 | - /> | ||
66 | - </Stack.Navigator> | ||
67 | - ) | ||
68 | -}; | ||
69 | - | ||
70 | -export default StackNavigation; | ||
... | \ 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 Main from "../screens/Main"; | ||
5 | -import Login from "../screens/Login"; | ||
6 | -import Profile from "../screens/Profile"; | ||
7 | -import LocationTimeSet from "../screens/LocationTimeSet"; | ||
8 | -import Maps from "../screens/Maps"; | ||
9 | - | ||
10 | -const Tab = createBottomTabNavigator(); | ||
11 | - | ||
12 | -const TabNavigation = (props) => { | ||
13 | - const {navigation, route} = props; | ||
14 | - // useLayoutEffect(() => {}, [route]); | ||
15 | - | ||
16 | - return ( | ||
17 | - <Tab.Navigator | ||
18 | - // screenOptions = {({route})=>{}} | ||
19 | - tabBarOptions={{}} | ||
20 | - > | ||
21 | - | ||
22 | - <Tab.Screen | ||
23 | - name='login' | ||
24 | - component={Login} | ||
25 | - /> | ||
26 | - | ||
27 | - <Tab.Screen | ||
28 | - name='LocationTimeSet' | ||
29 | - component={LocationTimeSet} | ||
30 | - /> | ||
31 | - | ||
32 | - <Tab.Screen | ||
33 | - name='Profile' | ||
34 | - component={Profile} | ||
35 | - /> | ||
36 | - | ||
37 | - </Tab.Navigator> | ||
38 | - ) | ||
39 | -}; | ||
40 | - | ||
41 | -export default TabNavigation; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
This diff could not be displayed because it is too large.
1 | -{ | ||
2 | - "main": "node_modules/expo/AppEntry.js", | ||
3 | - "scripts": { | ||
4 | - "start": "expo start", | ||
5 | - "android": "expo start --android", | ||
6 | - "ios": "expo start --ios", | ||
7 | - "web": "expo start --web", | ||
8 | - "eject": "expo eject" | ||
9 | - }, | ||
10 | - "dependencies": { | ||
11 | - "@react-native-community/datetimepicker": "2.2.2", | ||
12 | - "@react-native-community/masked-view": "0.1.6", | ||
13 | - "@react-navigation/bottom-tabs": "^5.4.1", | ||
14 | - "@react-navigation/native": "^5.3.0", | ||
15 | - "@react-navigation/stack": "^5.2.11", | ||
16 | - "axios": "^0.19.2", | ||
17 | - "expo": "~37.0.3", | ||
18 | - "expo-asset": "^8.1.4", | ||
19 | - "expo-camera": "~8.2.0", | ||
20 | - "expo-file-system": "~8.1.0", | ||
21 | - "expo-font": "^8.1.1", | ||
22 | - "expo-location": "~8.1.0", | ||
23 | - "expo-media-library": "~8.1.0", | ||
24 | - "expo-permissions": "~8.1.0", | ||
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", | ||
30 | - "react": "~16.9.0", | ||
31 | - "react-dom": "~16.9.0", | ||
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", | ||
35 | - "react-native-gesture-handler": "~1.6.0", | ||
36 | - "react-native-maps": "0.26.1", | ||
37 | - "react-native-reanimated": "~1.7.0", | ||
38 | - "react-native-safe-area-context": "0.7.3", | ||
39 | - "react-native-screens": "~2.2.0", | ||
40 | - "react-native-web": "~0.11.7", | ||
41 | - "react-redux": "^7.2.0", | ||
42 | - "redux": "^4.0.5", | ||
43 | - "redux-saga": "^1.1.3", | ||
44 | - "styled-components": "^5.1.0" | ||
45 | - }, | ||
46 | - "devDependencies": { | ||
47 | - "@babel/core": "^7.8.6", | ||
48 | - "@expo/vector-icons": "^10.0.6", | ||
49 | - "babel-preset-expo": "~8.1.0" | ||
50 | - }, | ||
51 | - "private": true | ||
52 | -} |
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 = { | ||
2 | - me: null, | ||
3 | - nikeRecord: null, | ||
4 | - | ||
5 | - isLoggingIn: false, | ||
6 | - isSigningUp: false, | ||
7 | - isLoadingMe: false, | ||
8 | - isLoggingOut: false, | ||
9 | - | ||
10 | - info: '', | ||
11 | -}; | ||
12 | - | ||
13 | -export const LOG_IN_REQUEST = 'LOG_IN_REQUEST'; | ||
14 | -export const LOG_IN_SUCCESS = 'LOG_IN_SUCCESS'; | ||
15 | -export const LOG_IN_FAILURE = 'LOG_IN_FAILURE'; | ||
16 | - | ||
17 | -export const SIGN_UP_REQUEST = 'SIGN_UP_REQUEST'; | ||
18 | -export const SIGN_UP_SUCCESS = 'SIGN_UP_SUCCESS'; | ||
19 | -export const SIGN_UP_FAILURE = 'SIGN_UP_FAILURE'; | ||
20 | - | ||
21 | -export const LOAD_ME_REQUEST = 'LOAD_USER_REQUEST'; | ||
22 | -export const LOAD_ME_SUCCESS = 'LOAD_USER_SUCCESS'; | ||
23 | -export const LOAD_ME_FAILURE = 'LOAD_USER_FAILURE'; | ||
24 | - | ||
25 | -export const LOG_OUT_REQUEST = 'LOG_OUT_REQUEST'; | ||
26 | -export const LOG_OUT_SUCCESS = 'LOG_OUT_SUCCESS'; | ||
27 | -export const LOG_OUT_FAILURE = 'LOG_OUT_FAILURE'; | ||
28 | - | ||
29 | -export default (state = initialState, action) => { | ||
30 | - switch (action.type) { | ||
31 | - | ||
32 | - case LOG_IN_REQUEST: { | ||
33 | - return { | ||
34 | - ...state, | ||
35 | - isLoggingIn: true, | ||
36 | - } | ||
37 | - } | ||
38 | - | ||
39 | - case LOG_IN_SUCCESS: { | ||
40 | - const {me} = action.data; | ||
41 | - return { | ||
42 | - ...state, | ||
43 | - me, | ||
44 | - isLoggingIn: false, | ||
45 | - }; | ||
46 | - } | ||
47 | - | ||
48 | - case LOG_IN_FAILURE: { | ||
49 | - const {info} = action.data; | ||
50 | - return { | ||
51 | - ...state, | ||
52 | - isLoggingIn: false, | ||
53 | - info, | ||
54 | - } | ||
55 | - } | ||
56 | - | ||
57 | - case SIGN_UP_REQUEST: { | ||
58 | - return { | ||
59 | - ...state, | ||
60 | - isSigningUp: true | ||
61 | - } | ||
62 | - } | ||
63 | - case SIGN_UP_SUCCESS: { | ||
64 | - const {me} = action.data; | ||
65 | - return { | ||
66 | - ...state, | ||
67 | - me, | ||
68 | - isSigningUp: false, | ||
69 | - }; | ||
70 | - } | ||
71 | - case SIGN_UP_FAILURE: { | ||
72 | - const {info} = action.data; | ||
73 | - return { | ||
74 | - ...state, | ||
75 | - isSigningUp: false, | ||
76 | - info | ||
77 | - }; | ||
78 | - } | ||
79 | - | ||
80 | - case LOAD_ME_REQUEST: { | ||
81 | - return { | ||
82 | - ...state, | ||
83 | - isLoadingMe: true | ||
84 | - } | ||
85 | - } | ||
86 | - case LOAD_ME_SUCCESS: { | ||
87 | - const {user} = action.data; | ||
88 | - console.log(user); | ||
89 | - return { | ||
90 | - ...state, | ||
91 | - me: user, | ||
92 | - isLoadingMe: false | ||
93 | - } | ||
94 | - } | ||
95 | - case LOAD_ME_FAILURE: { | ||
96 | - const {info} = action.data; | ||
97 | - return { | ||
98 | - ...state, | ||
99 | - isLoadingMe: false, | ||
100 | - info | ||
101 | - } | ||
102 | - } | ||
103 | - | ||
104 | - | ||
105 | - case LOG_OUT_REQUEST: { | ||
106 | - return { | ||
107 | - ...state, | ||
108 | - isLoggingOut: true | ||
109 | - } | ||
110 | - } | ||
111 | - | ||
112 | - case LOG_OUT_SUCCESS: { | ||
113 | - console.log('LOG_OUT_SUCCESS 완료'); | ||
114 | - return { | ||
115 | - ...state, | ||
116 | - me: null, | ||
117 | - isLoggingOut: false | ||
118 | - } | ||
119 | - } | ||
120 | - | ||
121 | - case LOG_OUT_FAILURE: { | ||
122 | - const {info} = action.data; | ||
123 | - return { | ||
124 | - ...state, | ||
125 | - isLoggingOut: false, | ||
126 | - info | ||
127 | - } | ||
128 | - } | ||
129 | - | ||
130 | - default: { | ||
131 | - return { | ||
132 | - ...state, | ||
133 | - }; | ||
134 | - } | ||
135 | - } | ||
136 | -}; | ||
... | \ 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, 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'; | ||
2 | -import axios from 'axios'; | ||
3 | -import {host} from '../env'; | ||
4 | -import { | ||
5 | - LOG_IN_FAILURE, | ||
6 | - LOG_IN_REQUEST, | ||
7 | - LOG_IN_SUCCESS, | ||
8 | - | ||
9 | - SIGN_UP_FAILURE, | ||
10 | - SIGN_UP_REQUEST, | ||
11 | - SIGN_UP_SUCCESS, | ||
12 | - | ||
13 | - LOAD_ME_REQUEST, | ||
14 | - LOAD_ME_SUCCESS, | ||
15 | - LOAD_ME_FAILURE, | ||
16 | - | ||
17 | - LOG_OUT_REQUEST, | ||
18 | - LOG_OUT_SUCCESS, | ||
19 | - LOG_OUT_FAILURE, | ||
20 | -} from '../reducers/user'; | ||
21 | -import {AsyncStorage} from 'react-native'; | ||
22 | - | ||
23 | -const parseCookies = (cookies = '') => | ||
24 | - cookies | ||
25 | - .split(';') | ||
26 | - .map(v => | ||
27 | - v.split('=') | ||
28 | - ) | ||
29 | - .reduce((acc, [key, value]) => { | ||
30 | - acc[key.trim()] = decodeURIComponent(value); | ||
31 | - console.log(acc); | ||
32 | - return acc; | ||
33 | - }, {}); | ||
34 | - | ||
35 | -//로그인 | ||
36 | -function loginAPI(data) { | ||
37 | - const {email, password} = data; | ||
38 | - console.log(email, password); | ||
39 | - console.log(`http://${host}:4001/user/login`); | ||
40 | - | ||
41 | - return axios.post(`http://${host}:4001/user/login`, { | ||
42 | - email, password | ||
43 | - }, { | ||
44 | - withCredentials: true | ||
45 | - }); | ||
46 | -} | ||
47 | - | ||
48 | -// # 함수의 동기적인 호출을 할 때 사용 | ||
49 | -// 응답이 다 받아진 후에 실행할 때 사용 | ||
50 | -function* login(action) { | ||
51 | - try { | ||
52 | - console.log('login하러 왔어요'); | ||
53 | - const res = yield call(loginAPI, action.data); | ||
54 | - console.log('서버 login에서 온 응답', res); | ||
55 | - const {user} = res.data; | ||
56 | - const cookieArray = res.headers['set-cookie']; | ||
57 | - console.log(cookieArray); | ||
58 | - yield call(AsyncStorage.setItem, 'cookie', `userChecker=s%3A${cookieArray.map(cookie => parseCookies(cookie)['userChecker'].substring(2))}`); | ||
59 | - yield put({ | ||
60 | - type: LOG_IN_SUCCESS, | ||
61 | - data: { | ||
62 | - me: user | ||
63 | - } | ||
64 | - }) | ||
65 | - } catch (e) { | ||
66 | - console.error(e); | ||
67 | - yield put({ | ||
68 | - type: LOG_IN_FAILURE, | ||
69 | - data: { | ||
70 | - info: e.response.data.info | ||
71 | - } | ||
72 | - }) | ||
73 | - } | ||
74 | -}; | ||
75 | - | ||
76 | -function* watchLogin() { | ||
77 | - yield takeLatest(LOG_IN_REQUEST, login); | ||
78 | -} | ||
79 | - | ||
80 | -// 회원가입 | ||
81 | -function signUpAPI(data) { | ||
82 | - const {email, nickName, password} = data; | ||
83 | - return axios.post(`http://${host}:4001/user/signUp`, { | ||
84 | - email, nickName, password | ||
85 | - }, { | ||
86 | - withCredentials: true | ||
87 | - }); | ||
88 | -} | ||
89 | - | ||
90 | -function* signUp(action) { | ||
91 | - try { | ||
92 | - console.log('signUp 실행원할'); | ||
93 | - const res = yield call(signUpAPI, action.data); | ||
94 | - const {me} = res.data; | ||
95 | - yield put({ | ||
96 | - type: SIGN_UP_SUCCESS, | ||
97 | - data: { | ||
98 | - me | ||
99 | - } | ||
100 | - }); | ||
101 | - } catch (e) { | ||
102 | - console.error(e); | ||
103 | - yield put({ | ||
104 | - type: SIGN_UP_FAILURE, | ||
105 | - data: { | ||
106 | - info: e.response.data.info | ||
107 | - } | ||
108 | - }); | ||
109 | - } | ||
110 | -} | ||
111 | - | ||
112 | -// # generator 함수에서 마지막 액션 하나만 유효하다고 인정 | ||
113 | -// 실수로 회원가입 버튼을 연달아 누를 경우 서버의 요청이 2번 가지 않게함 | ||
114 | -function* watchSignUp() { | ||
115 | - yield takeLatest(SIGN_UP_REQUEST, signUp); | ||
116 | -} | ||
117 | - | ||
118 | - | ||
119 | -function loadMeAPI() { | ||
120 | - return axios.get(`http://${host}:4001/user/loadMe`, {withCredentials: true}) | ||
121 | -}; | ||
122 | - | ||
123 | -function* loadMe(action) { | ||
124 | - try { | ||
125 | - console.log('loadMe 실행원할'); | ||
126 | - const res = yield call(loadMeAPI, action.data); | ||
127 | - const {user} = res.data; | ||
128 | - yield put({ | ||
129 | - type: LOAD_ME_SUCCESS, | ||
130 | - data: { | ||
131 | - user | ||
132 | - } | ||
133 | - }) | ||
134 | - } catch (e) { | ||
135 | - console.error(e); | ||
136 | - yield put({ | ||
137 | - type: LOAD_ME_FAILURE, | ||
138 | - data: { | ||
139 | - info: e.response.data.info | ||
140 | - } | ||
141 | - }) | ||
142 | - } | ||
143 | -}; | ||
144 | - | ||
145 | -function* watchLoadMe() { | ||
146 | - yield takeLatest(LOAD_ME_REQUEST, loadMe); | ||
147 | -} | ||
148 | - | ||
149 | -function logoutAPI() { | ||
150 | - return axios.get(`http://${host}:4001/user/logout`, {withCredentials: true}); | ||
151 | -} | ||
152 | - | ||
153 | -function* logout() { | ||
154 | - try { | ||
155 | - const res = yield call(logoutAPI); | ||
156 | - console.log('logout 완료'); | ||
157 | - yield call(AsyncStorage.removeItem, 'cookie'); | ||
158 | - yield put({ | ||
159 | - type: LOG_OUT_SUCCESS | ||
160 | - }); | ||
161 | - } catch (e) { | ||
162 | - console.error(e); | ||
163 | - yield put({ | ||
164 | - type: LOG_OUT_FAILURE, | ||
165 | - data: { | ||
166 | - info: e.response.data.info | ||
167 | - } | ||
168 | - }) | ||
169 | - } | ||
170 | -} | ||
171 | - | ||
172 | -function* watchLogoutMe() { | ||
173 | - yield takeLatest(LOG_OUT_REQUEST, logout); | ||
174 | -} | ||
175 | - | ||
176 | -// # 모든 액션을 유효하게 인정한다. | ||
177 | -// while(true)로 감싸는 효과 | ||
178 | -// takeEvery | ||
179 | - | ||
180 | -// # 함수의 비동기적인 호출을 사용할 때 | ||
181 | -// call과 다르게 fork는 순서 상관없이 실행할 때 사용 | ||
182 | -export default function* userSaga() { | ||
183 | - yield all([ | ||
184 | - fork(watchLogin), | ||
185 | - fork(watchSignUp), | ||
186 | - fork(watchLoadMe), | ||
187 | - fork(watchLogoutMe), | ||
188 | - ]); | ||
189 | -} | ||
190 | - |
1 | -import React from 'react'; | ||
2 | -import {View, Text, Button} from 'react-native'; | ||
3 | -import {useNavigation} from "@react-navigation/native"; | ||
4 | - | ||
5 | -const Gallery = () => { | ||
6 | - const navigation = useNavigation(); | ||
7 | - | ||
8 | - return ( | ||
9 | - <View> | ||
10 | - <Text> | ||
11 | - 하이하이 | ||
12 | - </Text> | ||
13 | - </View> | ||
14 | - ) | ||
15 | -}; | ||
16 | - | ||
17 | -export default Gallery; | ||
... | \ 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, 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 |
1 | -import React from 'react'; | ||
2 | -import {View, Text, TouchableOpacity} from 'react-native'; | ||
3 | -import styled from "styled-components"; | ||
4 | -import {useNavigation} from "@react-navigation/native"; | ||
5 | -import {useSelector} from "react-redux"; | ||
6 | - | ||
7 | - | ||
8 | -const GoToGalleryButton = styled.TouchableOpacity` | ||
9 | - width: 60px; | ||
10 | - border: 1px; | ||
11 | - | ||
12 | - align-items: center; | ||
13 | - justify-content: center; | ||
14 | - | ||
15 | - flex: 2 | ||
16 | -`; | ||
17 | - | ||
18 | -const GoToSelectOrTakePhotoButton = styled.TouchableOpacity` | ||
19 | - position: absolute; | ||
20 | - right: 20px; | ||
21 | - bottom: 20px; | ||
22 | - width: 30px; | ||
23 | - height: 30px; | ||
24 | - border-radius: 50px; | ||
25 | - border: 15px solid green; | ||
26 | -`; | ||
27 | - | ||
28 | -const Main = () => { | ||
29 | - const navigation = useNavigation(); | ||
30 | - | ||
31 | - const goToGallery = () => { | ||
32 | - navigation.navigate('Gallery'); | ||
33 | - }; | ||
34 | - | ||
35 | - const goToSelectOrTakePhoto = () => { | ||
36 | - navigation.navigate('SelectOrTakePhotoStackNavigation'); | ||
37 | - }; | ||
38 | - | ||
39 | - | ||
40 | - const {me} = useSelector(state => state.user); | ||
41 | - | ||
42 | - | ||
43 | - return ( | ||
44 | - <> | ||
45 | - <View style={{ | ||
46 | - flex: 1, | ||
47 | - alignItems: 'center', | ||
48 | - justifyContent: 'center' | ||
49 | - }}> | ||
50 | - <GoToGalleryButton title={'갤러리로 가보자'} onPress={goToGallery}> | ||
51 | - <Text>갤러리로 가보자</Text> | ||
52 | - </GoToGalleryButton> | ||
53 | - <View style={{ | ||
54 | - flex: 8, | ||
55 | - flexDirection: 'row' | ||
56 | - }}> | ||
57 | - <Text style={{ | ||
58 | - width: '100%', | ||
59 | - flex: 1, | ||
60 | - backgroundColor: 'red' | ||
61 | - }}>메인페이지</Text> | ||
62 | - <Text style={{ | ||
63 | - width: '100%', | ||
64 | - flex: 1, | ||
65 | - backgroundColor: 'grey', | ||
66 | - }}>메인페이지2</Text> | ||
67 | - <GoToSelectOrTakePhotoButton onPress={goToSelectOrTakePhoto}/> | ||
68 | - </View> | ||
69 | - </View> | ||
70 | - </> | ||
71 | - ) | ||
72 | -}; | ||
73 | - | ||
74 | -export default Main; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
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 |
1 | -import React from 'react'; | ||
2 | -import {View, Text, Button} from 'react-native'; | ||
3 | -import MyProfileComponent from "../components/MyProfileComponent"; | ||
4 | - | ||
5 | -const Profile = () => { | ||
6 | - const {me} = (state => state.user); | ||
7 | - return ( | ||
8 | - <View> | ||
9 | - {!me ? | ||
10 | - <MyProfileComponent/> | ||
11 | - : | ||
12 | - null | ||
13 | - } | ||
14 | - </View> | ||
15 | - ) | ||
16 | -}; | ||
17 | - | ||
18 | -export default Profile; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | -import React, {useEffect, useState} from 'react'; | ||
2 | -import * as MediaLibrary from 'expo-media-library'; | ||
3 | -import * as Permission from 'expo-permissions'; | ||
4 | -import {Image, ImageBackground, ScrollView, View, Text, TouchableOpacity} from "react-native"; | ||
5 | -import {useNavigation} from '@react-navigation/native'; | ||
6 | -import LoadingComponent from "../components/LoadingComponent"; | ||
7 | -import screen from '../constants/layout'; | ||
8 | -import {UploadPhoto} from './UploadPhoto'; | ||
9 | - | ||
10 | -const SelectPhoto = (props) => { | ||
11 | - const navigation = useNavigation(); | ||
12 | - const [loading, setLoading] = useState(false); | ||
13 | - const [hasPermission, setHasPermission] = useState(true); | ||
14 | - const [selectedPhoto, setSelectedPhoto] = useState([]); | ||
15 | - const [allPhotos, setAllPhotos] = useState([]); | ||
16 | - | ||
17 | - const getPhotos = async () => { | ||
18 | - try { | ||
19 | - const {assets} = await MediaLibrary.getAssetsAsync(); | ||
20 | - const [firstPhoto] = assets; | ||
21 | - setSelectedPhoto([firstPhoto]); | ||
22 | - setAllPhotos(assets); | ||
23 | - } catch (e) { | ||
24 | - console.error(e) | ||
25 | - } finally { | ||
26 | - setLoading(false); | ||
27 | - } | ||
28 | - }; | ||
29 | - | ||
30 | - const askPermission = async () => { | ||
31 | - try { | ||
32 | - setLoading(true); | ||
33 | - const {status} = await Permission.askAsync(Permission.CAMERA_ROLL); | ||
34 | - console.log(status); | ||
35 | - if (status === 'granted') { | ||
36 | - setHasPermission(true); | ||
37 | - await getPhotos(); | ||
38 | - } | ||
39 | - } catch (e) { | ||
40 | - console.error(e); | ||
41 | - setHasPermission(false); | ||
42 | - } | ||
43 | - }; | ||
44 | - | ||
45 | - const changeSelectedPhoto = (photo) => { | ||
46 | - setSelectedPhoto([photo]); | ||
47 | - }; | ||
48 | - | ||
49 | - const uploadPhoto = () => { | ||
50 | - navigation.navigate('UploadPhoto', {photos: selectedPhoto}) | ||
51 | - }; | ||
52 | - | ||
53 | - useEffect(() => { | ||
54 | - askPermission(); | ||
55 | - return () => { | ||
56 | - setLoading(true); | ||
57 | - setHasPermission(false); | ||
58 | - setSelectedPhoto([]); | ||
59 | - setAllPhotos([]); | ||
60 | - } | ||
61 | - }, []); | ||
62 | - | ||
63 | - return ( | ||
64 | - <View> | ||
65 | - {loading | ||
66 | - ? | ||
67 | - <LoadingComponent/> | ||
68 | - : | ||
69 | - hasPermission | ||
70 | - ? | ||
71 | - selectedPhoto[0] | ||
72 | - ? | ||
73 | - <> | ||
74 | - <ImageBackground | ||
75 | - style={{width: screen.width, height: screen.height / 2}} | ||
76 | - source={{uri: selectedPhoto[0].uri}} | ||
77 | - > | ||
78 | - <TouchableOpacity | ||
79 | - style={{ | ||
80 | - justifyContent: 'center', | ||
81 | - alignItems: 'center', | ||
82 | - }} | ||
83 | - key={selectedPhoto.id} | ||
84 | - onPress={uploadPhoto} | ||
85 | - > | ||
86 | - <Text>선택</Text> | ||
87 | - </TouchableOpacity> | ||
88 | - </ImageBackground> | ||
89 | - | ||
90 | - <ScrollView> | ||
91 | - | ||
92 | - <> | ||
93 | - <ScrollView horizontal contentContainerStyle={{flexDirection: 'row'}}> | ||
94 | - {allPhotos.map(photo => { | ||
95 | - return ( | ||
96 | - <TouchableOpacity | ||
97 | - key={photo.id} | ||
98 | - onPress={() => changeSelectedPhoto(photo)}> | ||
99 | - <Image | ||
100 | - source={{uri: photo.uri}} | ||
101 | - style={{ | ||
102 | - width: screen.width / 3, | ||
103 | - height: screen.height / 4, | ||
104 | - opacity: photo.id === selectedPhoto[0].id ? 0.6 : 1 | ||
105 | - }}/> | ||
106 | - </TouchableOpacity> | ||
107 | - ) | ||
108 | - } | ||
109 | - )} | ||
110 | - </ScrollView> | ||
111 | - </> | ||
112 | - | ||
113 | - </ScrollView> | ||
114 | - </> | ||
115 | - : | ||
116 | - null | ||
117 | - : | ||
118 | - <Text>사용자 권한이 없습니다</Text> | ||
119 | - } | ||
120 | - </View> | ||
121 | - ) | ||
122 | -}; | ||
123 | - | ||
124 | -export default SelectPhoto; | ||
... | \ 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, StyleSheet} from 'react-native'; | ||
3 | -import {useDispatch, useSelector} from "react-redux"; | ||
4 | -import {useNavigation} from '@react-navigation/native'; | ||
5 | -import SignUpComponent from "../components/SignUpComponent"; | ||
6 | - | ||
7 | - | ||
8 | -const SignUp = (props) => { | ||
9 | - const navigation = useNavigation(); | ||
10 | - const [loading, setLoading] = useState(true); | ||
11 | - const [isLogin, setIsLogin] = useState(true); | ||
12 | - | ||
13 | - const {me} = useSelector(state => state.user); | ||
14 | - const {isLoggingIn} = useSelector(state => state.user); | ||
15 | - | ||
16 | - const changeIsLogin = () => { | ||
17 | - return setIsLogin(!isLogin); | ||
18 | - } | ||
19 | - | ||
20 | - useEffect(() => { | ||
21 | - setLoading(false); | ||
22 | - }, [me]); | ||
23 | - | ||
24 | - return ( | ||
25 | - <View style={styles.changeStyle}> | ||
26 | - <View style={styles.loginStyle}> | ||
27 | - <Text style={styles.inputText}>회원가입</Text> | ||
28 | - <SignUpComponent/> | ||
29 | - </View> | ||
30 | - </View> | ||
31 | - ) | ||
32 | -}; | ||
33 | - | ||
34 | -export default SignUp; | ||
35 | - | ||
36 | -const styles = StyleSheet.create({ | ||
37 | - changeStyle: { | ||
38 | - flex: 2, | ||
39 | - alignItems: 'center', | ||
40 | - justifyContent: 'center', | ||
41 | - borderColor: 'darkgrey', | ||
42 | - }, | ||
43 | - loginStyle: { | ||
44 | - flex: 1, | ||
45 | - marginTop: 30, | ||
46 | - }, | ||
47 | - inputText: { | ||
48 | - borderColor: 'darkgrey', | ||
49 | - fontWeight: 'bold', | ||
50 | - fontSize: 20, | ||
51 | - marginBottom: 10 | ||
52 | - } | ||
53 | - | ||
54 | -}); | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | -import React, {useEffect, useState, useRef} from 'react'; | ||
2 | -import * as MediaLibrary from 'expo-media-library'; | ||
3 | -import * as Permission from 'expo-permissions'; | ||
4 | -import {Image, ImageBackground, ScrollView, View, Text, TouchableOpacity} from "react-native"; | ||
5 | -import {useNavigation} from '@react-navigation/native'; | ||
6 | -import LoadingComponent from "../components/LoadingComponent"; | ||
7 | -import screen from '../constants/layout'; | ||
8 | -import { Camera } from 'expo-camera'; | ||
9 | -import styled from "styled-components"; | ||
10 | -import {MaterialCommunityIcons} from "@expo/vector-icons"; | ||
11 | - | ||
12 | -const TakePhotoButton = styled.TouchableOpacity` | ||
13 | - width: 70px; | ||
14 | - height: 70px; | ||
15 | - border-radius: 50px; | ||
16 | - border: 15px solid green; | ||
17 | -`; | ||
18 | - | ||
19 | - | ||
20 | -const TakePhoto = (props) => { | ||
21 | - const navigation = useNavigation(); | ||
22 | - const [loading, setLoading] = useState(false); | ||
23 | - const [hasPermission, setHasPermission] = useState(false); | ||
24 | - const [cameraType, setCameraType] = useState(Camera.Constants.Type.back); | ||
25 | - const [canTakePhoto, setCanTakePhoto] = useState(true); | ||
26 | - const cameraRef = useRef(null); | ||
27 | - | ||
28 | - | ||
29 | - const askPermission = async () => { | ||
30 | - try { | ||
31 | - setLoading(true); | ||
32 | - const {status} = await Permission.askAsync(Permission.CAMERA); | ||
33 | - console.log(status); | ||
34 | - if (status === 'granted') { | ||
35 | - setHasPermission(true); | ||
36 | - } | ||
37 | - } catch (e) { | ||
38 | - console.error(e); | ||
39 | - setHasPermission(false); | ||
40 | - } finally { | ||
41 | - setLoading(false) | ||
42 | - } | ||
43 | - }; | ||
44 | - | ||
45 | - const changeCameraType = () => { | ||
46 | - if (cameraType === Camera.Constants.Type.front) { | ||
47 | - setCameraType(Camera.Constants.Type.back); | ||
48 | - } else { | ||
49 | - setCameraType(Camera.Constants.Type.front); | ||
50 | - } | ||
51 | - }; | ||
52 | - | ||
53 | - const takePhoto = async () => { | ||
54 | - if (!canTakePhoto) { | ||
55 | - return | ||
56 | - } | ||
57 | - try { | ||
58 | - setCanTakePhoto(false); | ||
59 | - const {uri} = await cameraRef.current.takePictureAsync({quality: 1}); | ||
60 | - const asset = await MediaLibrary.createAssetAsync(uri); | ||
61 | - navigation.navigate('UploadPhoto', {photo: asset}); | ||
62 | - } catch (e) { | ||
63 | - console.error(e); | ||
64 | - setCanTakePhoto(true); | ||
65 | - } | ||
66 | - }; | ||
67 | - | ||
68 | - const goUpload = () => { | ||
69 | - navigation.navigate('UploadPhoto'); | ||
70 | - }; | ||
71 | - | ||
72 | - useEffect(() => { | ||
73 | - askPermission(); | ||
74 | - }, []); | ||
75 | - | ||
76 | - return ( | ||
77 | - <View style={{alignItems: 'center'}}> | ||
78 | - {loading | ||
79 | - ? <LoadingComponent/> | ||
80 | - : hasPermission ? | ||
81 | - <View> | ||
82 | - <Camera | ||
83 | - ref={cameraRef} | ||
84 | - type={cameraType} | ||
85 | - style={{ | ||
86 | - justifyContent: 'flex-end', | ||
87 | - padding: 10, | ||
88 | - width: screen.width, | ||
89 | - height: screen.height / 2 | ||
90 | - }}> | ||
91 | - <TouchableOpacity onPress={changeCameraType}> | ||
92 | - <MaterialCommunityIcons color={'green'} name={'camera'} size={24}/> | ||
93 | - </TouchableOpacity> | ||
94 | - </Camera> | ||
95 | - <TakePhotoButton | ||
96 | - onPress={takePhoto} | ||
97 | - disabled={!canTakePhoto} | ||
98 | - /> | ||
99 | - <TakePhotoButton | ||
100 | - onPress={goUpload} | ||
101 | - /> | ||
102 | - </View> | ||
103 | - : | ||
104 | - null | ||
105 | - } | ||
106 | - </View> | ||
107 | - ) | ||
108 | -}; | ||
109 | - | ||
110 | -export default TakePhoto; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | -import React from 'react'; | ||
2 | -import {View, Text, Image, Button, StyleSheet} from 'react-native'; | ||
3 | -import styled from "styled-components"; | ||
4 | - | ||
5 | -const UploadPhoto = (props) => { | ||
6 | - const {route} = props; | ||
7 | - const {photos} = route.params; | ||
8 | - | ||
9 | - | ||
10 | - return ( | ||
11 | - <View> | ||
12 | - <Text> | ||
13 | - 하이하이 | ||
14 | - </Text> | ||
15 | - <View>{photos.map((photo, index) => { | ||
16 | - return ( | ||
17 | - <Image style={{width: 200, height: 200}} source={{uri: photo.uri}} key={photo.id}/>) | ||
18 | - })}</View> | ||
19 | - | ||
20 | - </View> | ||
21 | - ) | ||
22 | -} | ||
23 | -export default UploadPhoto; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | -import createSagaMiddleware from "redux-saga"; | ||
2 | -import {applyMiddleware, compose, createStore} from "redux"; | ||
3 | -import rootReducer from "./reducers"; | ||
4 | -import rootSaga from "./sagas"; | ||
5 | - | ||
6 | -const sagaMiddleware = createSagaMiddleware(); | ||
7 | -const middlewares = [sagaMiddleware]; | ||
8 | -const enhancer = compose( | ||
9 | - applyMiddleware(...middlewares), | ||
10 | - // !options.isServer && typeof window.REDUX_DEVTOOLS_EXTENSION !== 'undefined' ? window.REDUX_DEVTOOLS_EXTENSION() : (f) => f, | ||
11 | -); | ||
12 | -const store = createStore(rootReducer, enhancer); | ||
13 | -sagaMiddleware.run(rootSaga); | ||
14 | - | ||
15 | -export default store; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
This diff could not be displayed because it is too large.
code/user_and_post_server/.gitignore
deleted
100644 → 0
code/user_and_post_server/app.js
deleted
100644 → 0
1 | -const path = require('path'); | ||
2 | -const morgan = require('morgan'); | ||
3 | -const express = require('express'); | ||
4 | -//header Cookie : 쿠키, 해쉬함수 | ||
5 | -//오리지널 >> 해쉬 >> 압축메세지 | ||
6 | - | ||
7 | -const cookieParser = require('cookie-parser'); | ||
8 | -const expressSession = require('express-session'); | ||
9 | -const passport = require('passport'); | ||
10 | -const httpErrors = require('http-errors'); | ||
11 | -const dotenv = require('dotenv'); | ||
12 | -dotenv.config(); | ||
13 | -const MongoStore = require('connect-mongo')(expressSession); | ||
14 | -const MONGO_URL = `mongodb://localhost:27017/admin`; | ||
15 | -const cors = require('cors'); | ||
16 | - | ||
17 | - | ||
18 | -const {sequelize} = require('./models/index'); | ||
19 | -sequelize.sync({force: false}); | ||
20 | -const connect = require('./schemas/index'); | ||
21 | -connect(); | ||
22 | - | ||
23 | -const sessionMiddleware = expressSession({ | ||
24 | - resave: false, | ||
25 | - saveUninitialized: false, | ||
26 | - secret: process.env.COOKIE_SECRET, | ||
27 | - cookie: { | ||
28 | - httpOnly: true, | ||
29 | - secure: false | ||
30 | - }, | ||
31 | - name: 'userChecker', | ||
32 | - store: new MongoStore({ | ||
33 | - url: MONGO_URL, | ||
34 | - collection: "sessions" | ||
35 | - }), | ||
36 | -}); | ||
37 | - | ||
38 | -const passportIndex = require('./passport/index'); | ||
39 | -const userRouter = require('./routes/user'); | ||
40 | -const apiRouter = require('./routes/api'); | ||
41 | - | ||
42 | -passportIndex(passport); | ||
43 | - | ||
44 | - | ||
45 | -// const app = express(); 사용 설명서 | ||
46 | -// app.use(미들웨어) | ||
47 | -// 미들웨어란: (req, res, next) => {req와 res를 분석 및 가공, next로 req와 res를 다음 미들웨어로 전달} | ||
48 | -// 따라서 미들웨어끼리의 순서가 중요하다 | ||
49 | - | ||
50 | -// 어떤 미들웨어에서 req에 변수를 등록하고, 다음 미들웨어에서 그 변수를 가져다가 사용하는 방법 | ||
51 | -// 1. req.set()으로 변수를 등록하고, req.get()으로 전역 변수들을 가져와서 사용할 수 있다 | ||
52 | -// 2. app.set()으로 변수를 등록하고, req.app.get()으로 전역 변수들을 가져와서 사용할 수 있다(req 객체에 app 객체는 자동으로 세팅된다) | ||
53 | -// 3. req.app.set()으로 변수를 등록하고, req.app.get()으로 전역 변수들을 가져와서 사용할 수 있다 | ||
54 | - | ||
55 | -// res 사용법 | ||
56 | -// 오리지날: res.writeHead, res.write, res.end | ||
57 | -// 익스프레스 프레임워크: res.render('view 파일 이름', 자바스크립트 변수 객체), res.send(아무거나), res,json(객체), res.redirect('경로'), res.sendFile, | ||
58 | - | ||
59 | -const app = express(); // 익스프레스 프레임워크를 사용하기 위한 app 객체를 생성 | ||
60 | - | ||
61 | -app.use(morgan('dev')); // 로거를 미들웨어 최상단에 위치시켜서 서버로 들어오는 모든 요청에 대한 로그를 콘솔에서 확인 | ||
62 | - | ||
63 | -app.use(cors({ | ||
64 | - origin: 'http://localhost:3001', | ||
65 | - credentials: true | ||
66 | -})); | ||
67 | -app.use(express.json()); | ||
68 | -app.use(express.urlencoded({extended: false})); | ||
69 | -app.use(cookieParser(process.env.COOKIE_SECRET)); | ||
70 | -app.use(sessionMiddleware); | ||
71 | - | ||
72 | -app.use(passport.initialize()); // 패스포트 작동 시작 | ||
73 | -app.use(passport.session()); // 패스포트 세션 작업 | ||
74 | - | ||
75 | - | ||
76 | -app.use('/public', express.static(path.join(__dirname, 'open'))); // 모두에게 공개된 폴더 설정 | ||
77 | -app.use('/user', userRouter); | ||
78 | -app.use('/api', apiRouter); | ||
79 | - | ||
80 | - | ||
81 | -app.use(function (req, res, next) { | ||
82 | - next(httpErrors(404)); | ||
83 | -}); | ||
84 | -app.use(function (err, req, res, next) { | ||
85 | - // set locals, only providing error in development | ||
86 | - console.log(req); | ||
87 | - res.locals.message = err.message; | ||
88 | - res.locals.error = req.app.get('env') === 'development' ? err : {}; | ||
89 | - | ||
90 | - //render the error pagea | ||
91 | - res.status(err.status || 500); | ||
92 | - res.render('error'); | ||
93 | -}); | ||
94 | - | ||
95 | -module.exports = { | ||
96 | - app, | ||
97 | - sessionMiddleware | ||
98 | -}; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
code/user_and_post_server/bin/www
deleted
100644 → 0
1 | -#!/usr/bin/env node | ||
2 | - | ||
3 | - | ||
4 | -/* | ||
5 | -* Module dependencies | ||
6 | -*/ | ||
7 | - | ||
8 | -const debug = require('debug')('node_study_project_final:server'); | ||
9 | -const http = require('http'); | ||
10 | -const {app} = require('../app'); | ||
11 | - | ||
12 | - | ||
13 | -/* | ||
14 | -* Get port from environment and store in Express. | ||
15 | -*/ | ||
16 | - | ||
17 | -const port = normalizePort(process.env.PORT || '3001'); | ||
18 | -app.set('port', port); | ||
19 | - | ||
20 | -/* | ||
21 | -* Create HTTP server. | ||
22 | -*/ | ||
23 | - | ||
24 | -const server = http.createServer(app); | ||
25 | - | ||
26 | -function normalizePort(val) { | ||
27 | - const port = parseInt(val, 10); | ||
28 | - | ||
29 | - if (isNaN(port)) { | ||
30 | - return val; | ||
31 | - } | ||
32 | - | ||
33 | - if (port >= 0) { | ||
34 | - return port; | ||
35 | - } | ||
36 | - | ||
37 | - return false; | ||
38 | -}; | ||
39 | - | ||
40 | -const onListening = () => { | ||
41 | - const addr = server.address(); | ||
42 | - const bind = typeof addr === 'string' | ||
43 | - ? 'pipe ' + addr | ||
44 | - : 'port ' + addr.port; | ||
45 | - debug('Listening on ' + bind); | ||
46 | -}; | ||
47 | - | ||
48 | -const onError = (error) => { | ||
49 | - if (error.syscall !== 'listen') { | ||
50 | - throw error; | ||
51 | - } | ||
52 | - | ||
53 | - const bind = typeof port === 'string' | ||
54 | - ? 'Pipe ' + port | ||
55 | - : 'Port ' + port; | ||
56 | - | ||
57 | - switch (error.code) { | ||
58 | - case 'EACCES': | ||
59 | - console.error(bind + ' requires elevated privileges'); | ||
60 | - process.exit(1); | ||
61 | - break; | ||
62 | - case 'EADDRINUSE': | ||
63 | - console.error(bind + ' is already in use'); | ||
64 | - process.exit(1); | ||
65 | - break; | ||
66 | - default: | ||
67 | - throw error; | ||
68 | - } | ||
69 | -}; | ||
70 | - | ||
71 | - | ||
72 | -server.listen(port); | ||
73 | -server.on('listening', onListening); | ||
74 | -server.on('error', onError); | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | -{ | ||
2 | - "development": { | ||
3 | - "username": "root", | ||
4 | - "password": "ksy98042!", | ||
5 | - "database": "capstone_design_prj1", | ||
6 | - "host": "127.0.0.1", | ||
7 | - "dialect": "mysql", | ||
8 | - "operatorsAliases": false | ||
9 | - }, | ||
10 | - "test": { | ||
11 | - "username": "root", | ||
12 | - "password": null, | ||
13 | - "database": "database_test", | ||
14 | - "host": "127.0.0.1", | ||
15 | - "dialect": "mysql", | ||
16 | - "operatorsAliases": false | ||
17 | - }, | ||
18 | - "production": { | ||
19 | - "username": "root", | ||
20 | - "password": null, | ||
21 | - "database": "database_production", | ||
22 | - "host": "127.0.0.1", | ||
23 | - "dialect": "mysql", | ||
24 | - "operatorsAliases": false | ||
25 | - } | ||
26 | -} |
1 | -'use strict'; | ||
2 | - | ||
3 | -const fs = require('fs'); | ||
4 | -const path = require('path'); | ||
5 | -const Sequelize = require('sequelize'); | ||
6 | -const basename = path.basename(__filename); | ||
7 | -const env = process.env.NODE_ENV || 'development'; | ||
8 | -const config = require(__dirname + '/../config/config.json')[env]; | ||
9 | -const models = {}; | ||
10 | - | ||
11 | -let sequelize; | ||
12 | -if (config.use_env_variable) { | ||
13 | - sequelize = new Sequelize(process.env[config.use_env_variable], config); | ||
14 | -} else { | ||
15 | - sequelize = new Sequelize(config.database, config.username, config.password, config); | ||
16 | -} | ||
17 | - | ||
18 | -// 반복문을 돌면서 models 내에 있는 파일들을 읽고 그것을 모델로 정의함 | ||
19 | -fs | ||
20 | - .readdirSync(__dirname) | ||
21 | - .filter(file => { | ||
22 | - return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js'); | ||
23 | - }) | ||
24 | - .forEach(file => { | ||
25 | - const model = sequelize['import'](path.join(__dirname, file)); | ||
26 | - models[model.name] = model; | ||
27 | - }); | ||
28 | - | ||
29 | -models.User = require('./user')(sequelize, Sequelize); | ||
30 | - | ||
31 | - | ||
32 | -Object.keys(models).forEach(modelName => { | ||
33 | - if (models[modelName].associate) { | ||
34 | - models[modelName].associate(models); | ||
35 | - } | ||
36 | -}); | ||
37 | - | ||
38 | -models.sequelize = sequelize; | ||
39 | -models.Sequelize = Sequelize; | ||
40 | - | ||
41 | -module.exports = models; |
1 | -module.exports = (sequelize, DataTypes) => { | ||
2 | - const User = sequelize.define("User", { | ||
3 | - email: { | ||
4 | - type: DataTypes.STRING(30), | ||
5 | - allowNull: false, | ||
6 | - unique: true | ||
7 | - }, | ||
8 | - nickName: { | ||
9 | - type: DataTypes.STRING(10), | ||
10 | - allowNull: false, | ||
11 | - unique: true | ||
12 | - }, | ||
13 | - hashedPassword: { | ||
14 | - type: DataTypes.STRING(200), | ||
15 | - allowNull: false | ||
16 | - } | ||
17 | - }, { | ||
18 | - timestamps: true, | ||
19 | - paranoid: true, | ||
20 | - underscored: false, | ||
21 | - charset: 'utf8mb4', | ||
22 | - collate: 'utf8mb4_general_ci' | ||
23 | - }); | ||
24 | - // User.associate = (models) => { | ||
25 | - // models.User.hasMany(models.SnsId, {onDelete: 'CASCADE', foreignKey: 'userId', sourceKey: 'id'}); | ||
26 | - // models.User.hasMany(models.Post, {onDelete: 'CASCADE', foreignKey: 'userId', sourceKey: 'id'}); | ||
27 | - // models.User.hasMany(models.Comment, {onDelete: 'CASCADE', foreignKey: 'userId', sourceKey: 'id'}); | ||
28 | - // }; | ||
29 | - return User; | ||
30 | -} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | -body { | ||
2 | - padding: 50px; | ||
3 | - font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; | ||
4 | -} | ||
5 | - | ||
6 | -.card { | ||
7 | - float: left; | ||
8 | - margin: 10px; | ||
9 | - border: 3px solid #e3e3e3; | ||
10 | - width: 300px; | ||
11 | -} | ||
12 | - | ||
13 | -.post-img { | ||
14 | - width: 300px; | ||
15 | -} | ||
16 | - | ||
17 | -.mine { | ||
18 | - background-color: #808B96 ; | ||
19 | -} | ||
20 | - | ||
21 | -.other { | ||
22 | - background-color: #BFC9CA; | ||
23 | -} | ||
24 | - | ||
25 | -.system { | ||
26 | - text-align: center; | ||
27 | -} |
This diff could not be displayed because it is too large.
1 | -{ | ||
2 | - "name": "capstone_design_prj1", | ||
3 | - "version": "0.0.0", | ||
4 | - "private": true, | ||
5 | - "scripts": { | ||
6 | - "start": "nodemon ./bin/www" | ||
7 | - }, | ||
8 | - "dependencies": { | ||
9 | - "axios": "^0.19.2", | ||
10 | - "bcrypt": "^3.0.6", | ||
11 | - "connect-mongo": "^3.2.0", | ||
12 | - "cookie-parser": "~1.4.4", | ||
13 | - "cookie-signature": "^1.1.0", | ||
14 | - "cors": "^2.8.5", | ||
15 | - "debug": "~2.6.9", | ||
16 | - "dotenv": "^8.1.0", | ||
17 | - "express": "~4.16.1", | ||
18 | - "express-session": "^1.16.2", | ||
19 | - "fs": "0.0.1-security", | ||
20 | - "http-errors": "~1.6.3", | ||
21 | - "moment": "^2.26.0", | ||
22 | - "mongoose": "^5.9.2", | ||
23 | - "morgan": "^1.9.1", | ||
24 | - "multer": "^1.4.2", | ||
25 | - "mysql": "^2.18.1", | ||
26 | - "mysql2": "^1.7.0", | ||
27 | - "nodemon": "^1.19.4", | ||
28 | - "passport": "^0.4.0", | ||
29 | - "passport-local": "^1.0.0", | ||
30 | - "path": "^0.12.7", | ||
31 | - "pug": "2.0.0-beta11", | ||
32 | - "sequelize": "^5.21.5", | ||
33 | - "sequelize-cli": "^5.5.1", | ||
34 | - "socket.io": "^2.3.0", | ||
35 | - "xml-js": "^1.6.11", | ||
36 | - "xml2json": "^0.12.0", | ||
37 | - "xmlhttprequest": "^1.8.0" | ||
38 | - } | ||
39 | -} |
1 | -const models = require('../models/index'); | ||
2 | -const localStrategy = require('./localStrategy'); | ||
3 | - | ||
4 | -module.exports = (passport) => { | ||
5 | - passport.serializeUser((user, done) => { | ||
6 | - done(null, user.email); | ||
7 | - }); | ||
8 | - passport.deserializeUser(async (email, done) => { | ||
9 | - try { | ||
10 | - const user = await models.User.findOne({ | ||
11 | - where: {email}, | ||
12 | - attributes: ['id', 'email', 'nickName'] | ||
13 | - }); | ||
14 | - | ||
15 | - if (!user) { | ||
16 | - console.error('유저 데이터가 존재하지 않습니다.'); | ||
17 | - done(null, false, {message: '유저 데이터가 존재하지 않습니다.'}); | ||
18 | - } | ||
19 | - | ||
20 | - return done(null, user); | ||
21 | - } catch (e) { | ||
22 | - console.error(e); | ||
23 | - done(e); | ||
24 | - } | ||
25 | - }); | ||
26 | - localStrategy(passport); | ||
27 | -}; |
1 | -const LocalStrategy = require('passport-local').Strategy; | ||
2 | -const models = require('../models/index'); | ||
3 | -const bcrypt = require("bcrypt"); | ||
4 | - | ||
5 | -module.exports = (passport) => { | ||
6 | - passport.use(new LocalStrategy({ | ||
7 | - usernameField: 'email', | ||
8 | - passwordField: 'password' | ||
9 | - }, async (email, password, done) => { | ||
10 | - try { | ||
11 | - let user = await models.User.findOne({ | ||
12 | - where: {email} | ||
13 | - }); | ||
14 | - if (!user) { | ||
15 | - return done(null, false, {message: "유저 데이터가 존재하지 않습니다."}); | ||
16 | - } | ||
17 | - | ||
18 | - let resultOfPasswordCheck = await bcrypt.compare(password, user.hashedPassword); | ||
19 | - if (!resultOfPasswordCheck) { | ||
20 | - return done(null, false, {message: '비밀번호 에러입니다'}); | ||
21 | - } | ||
22 | - user = await models.User.findOne({ | ||
23 | - where:{email}, | ||
24 | - attributes: ['id', 'email', 'nickName'] | ||
25 | - }); | ||
26 | - return done(null, user); | ||
27 | - } catch (e) { | ||
28 | - console.error(e); | ||
29 | - return done(e); | ||
30 | - } | ||
31 | - }) | ||
32 | - ); | ||
33 | -}; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | -var express = require('express'); | ||
2 | -const axios = require('axios'); | ||
3 | -const convert = require('xml-js'); | ||
4 | -var router = express.Router(); | ||
5 | -let xmlParser = require('xml2json'); | ||
6 | -var searchPubTransPath = require('../setPath'); | ||
7 | -const moment = require('moment'); | ||
8 | - | ||
9 | -/* GET home page. */ | ||
10 | -router.get('/', function (req, res, next) { | ||
11 | - return res.json({title: 'Express'}); | ||
12 | -}); | ||
13 | - | ||
14 | -router.post('/setOptRoute', async (req, res, next) => { | ||
15 | - var {startLocation, endLocation, endTime, personalVelocity} = req.body; | ||
16 | - try { | ||
17 | - const startLocationX = startLocation.longitude; | ||
18 | - const startLocationY = startLocation.latitude; | ||
19 | - const endLocationX = endLocation.longitude; | ||
20 | - const endLocationY = endLocation.latitude; | ||
21 | - var avgSpeed = personalVelocity; | ||
22 | - if(!avgSpeed){ | ||
23 | - avgSpeed = 60; | ||
24 | - } | ||
25 | - console.log('endTime 은? ', endTime, personalVelocity); | ||
26 | - const path = await searchPubTransPath(startLocationX, startLocationY, endLocationX, endLocationY, avgSpeed, endTime); | ||
27 | - const optRoute = path; | ||
28 | - console.log(path); | ||
29 | - return res.json({optRoute: optRoute}); | ||
30 | - } catch (e) { | ||
31 | - console.error(e); | ||
32 | - // next(e); | ||
33 | - } | ||
34 | -}); | ||
35 | - | ||
36 | -module.exports = router; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | -const express = require('express'); | ||
2 | -const router = express.Router(); | ||
3 | -const models = require('../models/index'); | ||
4 | - | ||
5 | -router.get('/', async (req, res, next) => { | ||
6 | - try { | ||
7 | - if (!req.isAuthenticated()) { | ||
8 | - return res.render('index', { | ||
9 | - title: '홈', | ||
10 | - user: null, | ||
11 | - posts: [], | ||
12 | - } | ||
13 | - ); | ||
14 | - } | ||
15 | - | ||
16 | - return res.render('index', { | ||
17 | - title: '홈', | ||
18 | - user: req.user, | ||
19 | - } | ||
20 | - ); | ||
21 | - } catch (e) { | ||
22 | - console.error(e); | ||
23 | - next(e); | ||
24 | - } | ||
25 | -}); | ||
26 | - | ||
27 | -module.exports = router; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | -const isLoggedIn = (req, res, next) => { | ||
2 | - if (req.isAuthenticated()) { | ||
3 | - next(); | ||
4 | - } else { | ||
5 | - res.redirect('/'); | ||
6 | - } | ||
7 | -}; | ||
8 | - | ||
9 | -let isNotLoggedIn = (req, res, next) => { | ||
10 | - if (!req.isAuthenticated()) { | ||
11 | - next(); | ||
12 | - } else { | ||
13 | - res.redirect('/'); | ||
14 | - } | ||
15 | -}; | ||
16 | - | ||
17 | - | ||
18 | -module.exports = { | ||
19 | - isLoggedIn, | ||
20 | - isNotLoggedIn, | ||
21 | -}; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | -const express = require('express'); | ||
2 | -const router = express.Router(); | ||
3 | -const bcrypt = require('bcrypt'); | ||
4 | -const passport = require('passport'); | ||
5 | -const {isLoggedIn, isNotLoggedIn} = require("./middleware"); | ||
6 | -const models = require('../models/index'); | ||
7 | - | ||
8 | -router.get('/loadMe', isLoggedIn, (req, res, next) => { | ||
9 | - // console.log('loadMe요청옴', req.user); | ||
10 | - return res.json({user: req.user}); | ||
11 | -}); | ||
12 | - | ||
13 | -router.get('/signUp', isNotLoggedIn, (req, res, next) => { | ||
14 | - return res.render('SignUpComponent.vue', { | ||
15 | - title: '회원가입' | ||
16 | - }); | ||
17 | -}); | ||
18 | - | ||
19 | -router.post('/signUp', isNotLoggedIn, async (req, res, next) => { | ||
20 | - let {email, nickName, password} = req.body; | ||
21 | - try { | ||
22 | - let user = await models.User.findOne({ | ||
23 | - where: {email} | ||
24 | - }); | ||
25 | - if (user) { | ||
26 | - return res.json({user}); | ||
27 | - } | ||
28 | - | ||
29 | - const hashedPassword = await bcrypt.hash(password, 10); | ||
30 | - const signupComplete = await models.User.create({ | ||
31 | - email, nickName, hashedPassword | ||
32 | - }); | ||
33 | - | ||
34 | - user = await models.User.findOne({ | ||
35 | - where: {email}, | ||
36 | - attributes: ['id', 'email', 'nickName'] | ||
37 | - }); | ||
38 | - | ||
39 | - return req.login(user, (err) => { | ||
40 | - if (err) { | ||
41 | - console.error(err); | ||
42 | - return next(err); | ||
43 | - } | ||
44 | - return res.json({me: user}); | ||
45 | - }); | ||
46 | - } catch (e) { | ||
47 | - console.error(e); | ||
48 | - next(e); | ||
49 | - } | ||
50 | -}); | ||
51 | - | ||
52 | -router.post('/login', isNotLoggedIn, (req, res, next) => { | ||
53 | - passport.authenticate('local', {}, (err, user, info) => { | ||
54 | - if (err) { | ||
55 | - console.error(err); | ||
56 | - return next(err); | ||
57 | - } | ||
58 | - if (info) { | ||
59 | - console.error(info.message); | ||
60 | - return res.status(401).send(info.message); | ||
61 | - } | ||
62 | - req.login(user, (err) => { | ||
63 | - if (err) { | ||
64 | - console.error(err); | ||
65 | - return next(err); | ||
66 | - } | ||
67 | - ///////////////////////// req.session.returnURL | ||
68 | - // nuxt | ||
69 | - // return res.json({user: req.user}); | ||
70 | - return res.json({user: req.user}); | ||
71 | - }); | ||
72 | - })(req, res, next); | ||
73 | -}); | ||
74 | - | ||
75 | -router.get('/profile', isLoggedIn, (req, res, next) => { | ||
76 | - return res.render('profile', {title: '프로필', user: req.user}); | ||
77 | -}); | ||
78 | - | ||
79 | -router.post('/updateProfile', isLoggedIn, async (req, res, next) => { | ||
80 | - let {newNickName} = req.body; | ||
81 | - await models.User.update({ | ||
82 | - nickName: newNickName | ||
83 | - }, { | ||
84 | - where: {email: req.user.email} | ||
85 | - }); | ||
86 | - | ||
87 | - let user = await models.User.findOne({ | ||
88 | - where: {email: req.user.email} | ||
89 | - }); | ||
90 | - if (!user) { | ||
91 | - return res.redirect('/'); | ||
92 | - } | ||
93 | - | ||
94 | - return res.render('profile', { | ||
95 | - title: 'profile', | ||
96 | - user | ||
97 | - }) | ||
98 | -}); | ||
99 | - | ||
100 | -router.get('/deleteProfile', async (req, res, next) => { | ||
101 | - let email = {email: req.user.email}; | ||
102 | - let User = await models.User.destroy({ | ||
103 | - where: {email} | ||
104 | - }); | ||
105 | - return res.redirect('/'); | ||
106 | -}); | ||
107 | - | ||
108 | - | ||
109 | -router.get('/logout', (req, res, next) => { | ||
110 | - console.log('로그아웃 요청이 들어옴'); | ||
111 | - req.logout(); | ||
112 | - req.session.destroy(); | ||
113 | - return res.send(); | ||
114 | -}); | ||
115 | - | ||
116 | -router.get('/test', (req, res, next) => { | ||
117 | - searchPubTransPathAJAX(); | ||
118 | -}); | ||
119 | - | ||
120 | -module.exports = router; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | -const mongoose = require('mongoose'); | ||
2 | -const {MONGO_ID, MONGO_PASSWORD, NODE_ENV} = process.env; | ||
3 | -const MONGO_URL = `mongodb://localhost:27017/admin`; | ||
4 | -const connect = () => { | ||
5 | - if (process.env.NODE_VIEW !== 'production') { | ||
6 | - mongoose.set('debug', true); | ||
7 | - } | ||
8 | - mongoose.connect(MONGO_URL, { | ||
9 | - dbName: 'chat', | ||
10 | - useUnifiedTopology: true | ||
11 | - }, (err) => { | ||
12 | - if (err) { | ||
13 | - console.error('몽고디비 연결 에러', err); | ||
14 | - } else { | ||
15 | - console.log('몽고디비 연결 성공'); | ||
16 | - } | ||
17 | - }); | ||
18 | -}; | ||
19 | - | ||
20 | -module.exports = () => { | ||
21 | - connect(); | ||
22 | - mongoose.connection.on('error', (err) => { | ||
23 | - console.log('연결 종료'); | ||
24 | - }); | ||
25 | - mongoose.connection.on('disconnected', (err) => { | ||
26 | - console.error('연결이 끊어졌습니다. 재접속 시도중'); | ||
27 | - connect(); | ||
28 | - }); | ||
29 | -}; | ||
30 | -// 몽고디비는 데이터의 형식조건에서 자유롭다 | ||
31 | -// json객체 형태라면 무엇이든 저장이 가능하다 | ||
32 | -// 이러한 자유도에 제약을 걸고(형태에 제약) 안정성을 높이는 몽구스를 사용할 수 있다 | ||
33 | -// 몽고디비는 sql이 아닌 자바스크립트를 쓰기 때문에 노드와 궁합이 좋다 | ||
34 | -// 마이에스큐엘도 시퀄라이즈를 쓰면 자바스크립트로 제어할 수는 있다 | ||
35 | -// 몽고디비서버 실행 명령어: mongod --dbpath C:\Users\kimseoyoung\mongodb_data --auth | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | -<경희대학교 우정원 -> 영통역> | ||
2 | -{ | ||
3 | - "result": { //최상위 노드 | ||
4 | - "searchType": 0, //결과구분 0:도시내 | ||
5 | - "outTrafficCheck": 1, //환승 | ||
6 | - "busCount": 6, //버스6개 | ||
7 | - "subwayCount": 0,//지하철 0개 | ||
8 | - "subwayBusCount": 0, //버스&지하철 0 개 | ||
9 | - "pointDistance": 792, //출발지와 도착지의 직선거리 (필요없음) | ||
10 | - "startRadius": 700, //출발지 반경(필요없음) | ||
11 | - "endRadius": 700,//도착지 반경(필요없음) | ||
12 | - "path": [ //결과 리스트 확장 노드 | ||
13 | -{ | ||
14 | - "pathType": 2, //결과종류 2:버스 | ||
15 | - "info": { //요약정보 확장 노드 | ||
16 | - "trafficDistance": 934, //총이동거리 – 도보거리(필요없음) | ||
17 | - "totalWalk": 462, //총도보 이동거리 | ||
18 | - "totalTime": 14, //총소요시간 (분) | ||
19 | - "payment": 1050, //요금 (필요없음) | ||
20 | - "busTransitCount": 1, //버스환승 횟수 | ||
21 | - "subwayTransitCount": 0,//지하철 환승 횟수 | ||
22 | - "mapObj": "11235:1:13:16", //보간점 api를 호출하기 위한 파라미터값 | ||
23 | - "firstStartStation": "SK아파트", //최초 출발역 | ||
24 | - "lastEndStation": "동수원세무소.영통역2번출구", //최종 도착역 | ||
25 | - "totalStationCount": 3, //총 정류장 합 | ||
26 | - "busStationCount": 3,//버스 정류장 합 | ||
27 | - "subwayStationCount": 0, //총 지하철 정류장 합 | ||
28 | - "totalDistance": 1396, //총 거리 | ||
29 | - "totalWalkTime": -1// | ||
30 | -}, | ||
31 | - "subPath": [ //이동 교통수단 정보 확장 노드 | ||
32 | -{ | ||
33 | - "trafficType": 3, //도보 이동 | ||
34 | - "distance": 296, //도보 이동 거리 | ||
35 | - "sectionTime": 4 //도보 이동 소요시간-> 사용자 최적화 시키기 | ||
36 | -}, | ||
37 | -{ | ||
38 | - "trafficType": 2, | ||
39 | - "distance": 934, | ||
40 | - "sectionTime": 8, | ||
41 | - "stationCount": 3, | ||
42 | - "lane": [ | ||
43 | -{ | ||
44 | - "busNo": "55", | ||
45 | - "type": 3, | ||
46 | - "busID": 11235 | ||
47 | -} | ||
48 | - ], | ||
49 | - "startName": "SK아파트", | ||
50 | - "startX": 127.073755, | ||
51 | - "startY": 37.245495, | ||
52 | - "endName": "동수원세무소.영통역2번출구", | ||
53 | - "endX": 127.072699, | ||
54 | - "endY": 37.250704, | ||
55 | - "startID": 211483, | ||
56 | - "endID": 83255, | ||
57 | - "passStopList": { | ||
58 | - "stations": [ | ||
59 | -{ | ||
60 | - "index": 0, | ||
61 | - "stationID": 211483, | ||
62 | - "stationName": "SK아파트", | ||
63 | - "x": "127.073755", | ||
64 | - "y": "37.245495" | ||
65 | -}, | ||
66 | -{ | ||
67 | - "index": 1, | ||
68 | - "stationID": 184510, | ||
69 | - "stationName": "서그내", | ||
70 | - "x": "127.073454", | ||
71 | - "y": "37.247034" | ||
72 | -}, | ||
73 | -{ | ||
74 | - "index": 2, | ||
75 | - "stationID": 184509, | ||
76 | - "stationName": "영일중학교.수원출입국외국인청", | ||
77 | - "x": "127.075096", | ||
78 | - "y": "37.249227" | ||
79 | -}, | ||
80 | -{ | ||
81 | - "index": 3, | ||
82 | - "stationID": 83255, | ||
83 | - "stationName": "동수원세무소.영통역2번출구", | ||
84 | - "x": "127.072699", | ||
85 | - "y": "37.250704" | ||
86 | -} | ||
87 | - ] | ||
88 | -} | ||
89 | -}, | ||
90 | -{ | ||
91 | - "trafficType": 3, | ||
92 | - "distance": 166, | ||
93 | - "sectionTime": 2 | ||
94 | -} | ||
95 | - ] | ||
96 | -}, | ||
97 | -{ | ||
98 | - "pathType": 2, | ||
99 | - "info": { | ||
100 | - "trafficDistance": 610, | ||
101 | - "totalWalk": 363, | ||
102 | - "totalTime": 12, | ||
103 | - "payment": 1450, | ||
104 | - "busTransitCount": 1, | ||
105 | - "subwayTransitCount": 0, | ||
106 | - "mapObj": "9576:1:50:52", | ||
107 | - "firstStartStation": "경희대학교", | ||
108 | - "lastEndStation": "동수원세무소.영통역2번출구", | ||
109 | - "totalStationCount": 2, | ||
110 | - "busStationCount": 2, | ||
111 | - "subwayStationCount": 0, | ||
112 | - "totalDistance": 973, | ||
113 | - "totalWalkTime": -1 | ||
114 | -}, | ||
115 | - "subPath": [ | ||
116 | -{ | ||
117 | - "trafficType": 3, | ||
118 | - "distance": 197, | ||
119 | - "sectionTime": 3 | ||
120 | -}, | ||
121 | -{ | ||
122 | - "trafficType": 2, | ||
123 | - "distance": 610, | ||
124 | - "sectionTime": 7, | ||
125 | - "stationCount": 2, | ||
126 | - "lane": [ | ||
127 | -{ | ||
128 | - "busNo": "5", | ||
129 | - "type": 1, | ||
130 | - "busID": 9576 | ||
131 | -}, | ||
132 | -{ | ||
133 | - "busNo": "310", | ||
134 | - "type": 1, | ||
135 | - "busID": 9516 | ||
136 | -}, | ||
137 | -{ | ||
138 | - "busNo": "900", | ||
139 | - "type": 1, | ||
140 | - "busID": 9660 | ||
141 | -}, | ||
142 | -{ | ||
143 | - "busNo": "9", | ||
144 | - "type": 1, | ||
145 | - "busID": 9598 | ||
146 | -}, | ||
147 | -{ | ||
148 | - "busNo": "9-1", | ||
149 | - "type": 1, | ||
150 | - "busID": 9517 | ||
151 | -}, | ||
152 | -{ | ||
153 | - "busNo": "18", | ||
154 | - "type": 1, | ||
155 | - "busID": 9584 | ||
156 | -} | ||
157 | - ], | ||
158 | - "startName": "경희대학교", | ||
159 | - "startX": 127.077671, | ||
160 | - "startY": 37.247878, | ||
161 | - "endName": "동수원세무소.영통역2번출구", | ||
162 | - "endX": 127.072699, | ||
163 | - "endY": 37.250704, | ||
164 | - "startID": 184499, | ||
165 | - "endID": 83255, | ||
166 | - "passStopList": { | ||
167 | - "stations": [ | ||
168 | -{ | ||
169 | - "index": 0, | ||
170 | - "stationID": 184499, | ||
171 | - "stationName": "경희대학교", | ||
172 | - "x": "127.077671", | ||
173 | - "y": "37.247878" | ||
174 | -}, | ||
175 | -{ | ||
176 | - "index": 1, | ||
177 | - "stationID": 184509, | ||
178 | - "stationName": "영일중학교.수원출입국외국인청", | ||
179 | - "x": "127.075096", | ||
180 | - "y": "37.249227" | ||
181 | -}, | ||
182 | -{ | ||
183 | - "index": 2, | ||
184 | - "stationID": 83255, | ||
185 | - "stationName": "동수원세무소.영통역2번출구", | ||
186 | - "x": "127.072699", | ||
187 | - "y": "37.250704" | ||
188 | -} | ||
189 | - ] | ||
190 | -} | ||
191 | -}, | ||
192 | -{ | ||
193 | - "trafficType": 3, | ||
194 | - "distance": 166, | ||
195 | - "sectionTime": 2 | ||
196 | -} | ||
197 | - ] | ||
198 | -}, | ||
199 | -{ | ||
200 | - "pathType": 2, | ||
201 | - "info": { | ||
202 | - "trafficDistance": 1944, | ||
203 | - "totalWalk": 541, | ||
204 | - "totalTime": 16, | ||
205 | - "payment": 2800, | ||
206 | - "busTransitCount": 1, | ||
207 | - "subwayTransitCount": 0, | ||
208 | - "mapObj": "10501:1:3:6", | ||
209 | - "firstStartStation": "경희대학교", | ||
210 | - "lastEndStation": "영통역", | ||
211 | - "totalStationCount": 2, | ||
212 | - "busStationCount": 2, | ||
213 | - "subwayStationCount": 0, | ||
214 | - "totalDistance": 2485, | ||
215 | - "totalWalkTime": -1 | ||
216 | -}, | ||
217 | - "subPath": [ | ||
218 | -{ | ||
219 | - "trafficType": 3, | ||
220 | - "distance": 197, | ||
221 | - "sectionTime": 3 | ||
222 | -}, | ||
223 | -{ | ||
224 | - "trafficType": 2, | ||
225 | - "distance": 1944, | ||
226 | - "sectionTime": 8, | ||
227 | - "stationCount": 2, | ||
228 | - "lane": [ | ||
229 | -{ | ||
230 | - "busNo": "M5107", | ||
231 | - "type": 14, | ||
232 | - "busID": 10501 | ||
233 | -} | ||
234 | - ], | ||
235 | - "startName": "경희대학교", | ||
236 | - "startX": 127.077671, | ||
237 | - "startY": 37.247878, | ||
238 | - "endName": "영통역", | ||
239 | - "endX": 127.074057, | ||
240 | - "endY": 37.25395, | ||
241 | - "startID": 184499, | ||
242 | - "endID": 184643, | ||
243 | - "passStopList": { | ||
244 | - "stations": [ | ||
245 | -{ | ||
246 | - "index": 0, | ||
247 | - "stationID": 184499, | ||
248 | - "stationName": "경희대학교", | ||
249 | - "x": "127.077671", | ||
250 | - "y": "37.247878" | ||
251 | -}, | ||
252 | -{ | ||
253 | - "index": 1, | ||
254 | - "stationID": 88099, | ||
255 | - "stationName": "외서천삼거리", | ||
256 | - "x": "127.072291", | ||
257 | - "y": "37.247187" | ||
258 | -}, | ||
259 | -{ | ||
260 | - "index": 2, | ||
261 | - "stationID": 184641, | ||
262 | - "stationName": "살구골동아아파트", | ||
263 | - "x": "127.068013", | ||
264 | - "y": "37.247685" | ||
265 | -}, | ||
266 | -{ | ||
267 | - "index": 3, | ||
268 | - "stationID": 184643, | ||
269 | - "stationName": "영통역", | ||
270 | - "x": "127.074057", | ||
271 | - "y": "37.25395" | ||
272 | -} | ||
273 | - ] | ||
274 | -} | ||
275 | -}, | ||
276 | -{ | ||
277 | - "trafficType": 3, | ||
278 | - "distance": 344, | ||
279 | - "sectionTime": 5 | ||
280 | -} | ||
281 | - ] | ||
282 | -}, | ||
283 | -{ | ||
284 | - "pathType": 2, | ||
285 | - "info": { | ||
286 | - "trafficDistance": 454, | ||
287 | - "totalWalk": 705, | ||
288 | - "totalTime": 17, | ||
289 | - "payment": 2800, | ||
290 | - "busTransitCount": 1, | ||
291 | - "subwayTransitCount": 0, | ||
292 | - "mapObj": "10049:1:70:71", | ||
293 | - "firstStartStation": "경희대학교", | ||
294 | - "lastEndStation": "살구골.서광아파트", | ||
295 | - "totalStationCount": 1, | ||
296 | - "busStationCount": 1, | ||
297 | - "subwayStationCount": 0, | ||
298 | - "totalDistance": 1159, | ||
299 | - "totalWalkTime": -1 | ||
300 | -}, | ||
301 | - "subPath": [ | ||
302 | -{ | ||
303 | - "trafficType": 3, | ||
304 | - "distance": 197, | ||
305 | - "sectionTime": 3 | ||
306 | -}, | ||
307 | -{ | ||
308 | - "trafficType": 2, | ||
309 | - "distance": 454, | ||
310 | - "sectionTime": 6, | ||
311 | - "stationCount": 1, | ||
312 | - "lane": [ | ||
313 | -{ | ||
314 | - "busNo": "1550-1", | ||
315 | - "type": 4, | ||
316 | - "busID": 10049 | ||
317 | -} | ||
318 | - ], | ||
319 | - "startName": "경희대학교", | ||
320 | - "startX": 127.077671, | ||
321 | - "startY": 37.247878, | ||
322 | - "endName": "살구골.서광아파트", | ||
323 | - "endX": 127.07264, | ||
324 | - "endY": 37.24728, | ||
325 | - "startID": 184499, | ||
326 | - "endID": 184495, | ||
327 | - "passStopList": { | ||
328 | - "stations": [ | ||
329 | -{ | ||
330 | - "index": 0, | ||
331 | - "stationID": 184499, | ||
332 | - "stationName": "경희대학교", | ||
333 | - "x": "127.077671", | ||
334 | - "y": "37.247878" | ||
335 | -}, | ||
336 | -{ | ||
337 | - "index": 1, | ||
338 | - "stationID": 184495, | ||
339 | - "stationName": "살구골.서광아파트", | ||
340 | - "x": "127.07264", | ||
341 | - "y": "37.24728" | ||
342 | -} | ||
343 | - ] | ||
344 | -} | ||
345 | -}, | ||
346 | -{ | ||
347 | - "trafficType": 3, | ||
348 | - "distance": 508, | ||
349 | - "sectionTime": 8 | ||
350 | -} | ||
351 | - ] | ||
352 | -}, | ||
353 | -{ | ||
354 | - "pathType": 2, | ||
355 | - "info": { | ||
356 | - "trafficDistance": 1416, | ||
357 | - "totalWalk": 385, | ||
358 | - "totalTime": 14, | ||
359 | - "payment": 2800, | ||
360 | - "busTransitCount": 1, | ||
361 | - "subwayTransitCount": 0, | ||
362 | - "mapObj": "10052:1:4:7", | ||
363 | - "firstStartStation": "경희대학교", | ||
364 | - "lastEndStation": "살구골현대아파트.영통역4번출구", | ||
365 | - "totalStationCount": 3, | ||
366 | - "busStationCount": 3, | ||
367 | - "subwayStationCount": 0, | ||
368 | - "totalDistance": 1801, | ||
369 | - "totalWalkTime": -1 | ||
370 | -}, | ||
371 | - "subPath": [ | ||
372 | -{ | ||
373 | - "trafficType": 3, | ||
374 | - "distance": 197, | ||
375 | - "sectionTime": 3 | ||
376 | -}, | ||
377 | -{ | ||
378 | - "trafficType": 2, | ||
379 | - "distance": 1416, | ||
380 | - "sectionTime": 8, | ||
381 | - "stationCount": 3, | ||
382 | - "lane": [ | ||
383 | -{ | ||
384 | - "busNo": "1112", | ||
385 | - "type": 4, | ||
386 | - "busID": 10052 | ||
387 | -}, | ||
388 | -{ | ||
389 | - "busNo": "5100", | ||
390 | - "type": 4, | ||
391 | - "busID": 9564 | ||
392 | -} | ||
393 | - ], | ||
394 | - "startName": "경희대학교", | ||
395 | - "startX": 127.077671, | ||
396 | - "startY": 37.247878, | ||
397 | - "endName": "살구골현대아파트.영통역4번출구", | ||
398 | - "endX": 127.070462, | ||
399 | - "endY": 37.250191, | ||
400 | - "startID": 184499, | ||
401 | - "endID": 184689, | ||
402 | - "passStopList": { | ||
403 | - "stations": [ | ||
404 | -{ | ||
405 | - "index": 0, | ||
406 | - "stationID": 184499, | ||
407 | - "stationName": "경희대학교", | ||
408 | - "x": "127.077671", | ||
409 | - "y": "37.247878" | ||
410 | -}, | ||
411 | -{ | ||
412 | - "index": 1, | ||
413 | - "stationID": 184495, | ||
414 | - "stationName": "살구골.서광아파트", | ||
415 | - "x": "127.07264", | ||
416 | - "y": "37.24728" | ||
417 | -}, | ||
418 | -{ | ||
419 | - "index": 2, | ||
420 | - "stationID": 184641, | ||
421 | - "stationName": "살구골동아아파트", | ||
422 | - "x": "127.068013", | ||
423 | - "y": "37.247685" | ||
424 | -}, | ||
425 | -{ | ||
426 | - "index": 3, | ||
427 | - "stationID": 184689, | ||
428 | - "stationName": "살구골현대아파트.영통역4번출구", | ||
429 | - "x": "127.070462", | ||
430 | - "y": "37.250191" | ||
431 | -} | ||
432 | - ] | ||
433 | -} | ||
434 | -}, | ||
435 | -{ | ||
436 | - "trafficType": 3, | ||
437 | - "distance": 188, | ||
438 | - "sectionTime": 3 | ||
439 | -} | ||
440 | - ] | ||
441 | -}, | ||
442 | -{ | ||
443 | - "pathType": 2, | ||
444 | - "info": { | ||
445 | - "trafficDistance": 2784, | ||
446 | - "totalWalk": 337, | ||
447 | - "totalTime": 16, | ||
448 | - "payment": 2800, | ||
449 | - "busTransitCount": 1, | ||
450 | - "subwayTransitCount": 0, | ||
451 | - "mapObj": "9592:1:3:8", | ||
452 | - "firstStartStation": "경희대학교", | ||
453 | - "lastEndStation": "영통역6번출구.영덕고등학교", | ||
454 | - "totalStationCount": 5, | ||
455 | - "busStationCount": 5, | ||
456 | - "subwayStationCount": 0, | ||
457 | - "totalDistance": 3121, | ||
458 | - "totalWalkTime": -1 | ||
459 | -}, | ||
460 | - "subPath": [ | ||
461 | -{ | ||
462 | - "trafficType": 3, | ||
463 | - "distance": 197, | ||
464 | - "sectionTime": 3 | ||
465 | -}, | ||
466 | -{ | ||
467 | - "trafficType": 2, | ||
468 | - "distance": 2784, | ||
469 | - "sectionTime": 11, | ||
470 | - "stationCount": 5, | ||
471 | - "lane": [ | ||
472 | -{ | ||
473 | - "busNo": "7000", | ||
474 | - "type": 4, | ||
475 | - "busID": 9592 | ||
476 | -} | ||
477 | - ], | ||
478 | - "startName": "경희대학교", | ||
479 | - "startX": 127.077671, | ||
480 | - "startY": 37.247878, | ||
481 | - "endName": "영통역6번출구.영덕고등학교", | ||
482 | - "endX": 127.069841, | ||
483 | - "endY": 37.252142, | ||
484 | - "startID": 184499, | ||
485 | - "endID": 184508, | ||
486 | - "passStopList": { | ||
487 | - "stations": [ | ||
488 | -{ | ||
489 | - "index": 0, | ||
490 | - "stationID": 184499, | ||
491 | - "stationName": "경희대학교", | ||
492 | - "x": "127.077671", | ||
493 | - "y": "37.247878" | ||
494 | -}, | ||
495 | -{ | ||
496 | - "index": 1, | ||
497 | - "stationID": 184495, | ||
498 | - "stationName": "살구골.서광아파트", | ||
499 | - "x": "127.07264", | ||
500 | - "y": "37.24728" | ||
501 | -}, | ||
502 | -{ | ||
503 | - "index": 2, | ||
504 | - "stationID": 113705, | ||
505 | - "stationName": "영통롯데아파트", | ||
506 | - "x": "127.061285", | ||
507 | - "y": "37.246695" | ||
508 | -}, | ||
509 | -{ | ||
510 | - "index": 3, | ||
511 | - "stationID": 184503, | ||
512 | - "stationName": "벽적골태영아파트", | ||
513 | - "x": "127.062669", | ||
514 | - "y": "37.24958" | ||
515 | -}, | ||
516 | -{ | ||
517 | - "index": 4, | ||
518 | - "stationID": 184501, | ||
519 | - "stationName": "신나무실아파트", | ||
520 | - "x": "127.06605", | ||
521 | - "y": "37.252445" | ||
522 | -}, | ||
523 | -{ | ||
524 | - "index": 5, | ||
525 | - "stationID": 184508, | ||
526 | - "stationName": "영통역6번출구.영덕고등학교", | ||
527 | - "x": "127.069841", | ||
528 | - "y": "37.252142" | ||
529 | -} | ||
530 | - ] | ||
531 | -} | ||
532 | -}, | ||
533 | -{ | ||
534 | - "trafficType": 3, | ||
535 | - "distance": 140, | ||
536 | - "sectionTime": 2 | ||
537 | -} | ||
538 | - ] | ||
539 | -} | ||
540 | - ] | ||
541 | -} | ||
542 | -} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
code/user_and_post_server/setPath.js
deleted
100644 → 0
1 | -const axios = require('axios'); | ||
2 | -const convert = require('xml-js'); | ||
3 | -const moment = require('moment'); | ||
4 | - | ||
5 | -const apiKey = ''; | ||
6 | - | ||
7 | -const reverseGeocoding = async (_x, _y) => { | ||
8 | - try { | ||
9 | - var result = await axios.get("http://apis.vworld.kr/coord2jibun.do?x=" + _x + "&y=" + _y + "&output=xml&epsg=epsg:4326&apiKey="); | ||
10 | - result = convert.xml2js(result.data, {compact: true, spaces: 4}); | ||
11 | - result = JSON.parse(JSON.stringify(result)); | ||
12 | - var cityName = result.result.ADDR._cdata.split(" ")[0]; | ||
13 | - return cityName | ||
14 | - } catch (e) { | ||
15 | - console.error(e); | ||
16 | - } | ||
17 | - | ||
18 | -}; | ||
19 | - | ||
20 | -const subwayArrivalTime = async (stationID, wayCode) => { | ||
21 | - try { | ||
22 | - let today = new Date(); | ||
23 | - let day = today.getDay();//요일 | ||
24 | - let hours = today.getHours();//시 | ||
25 | - let minutes = today.getMinutes();//분 | ||
26 | - var result = await axios.get("https://api.odsay.com/v1/api/subwayTimeTable?lang=0&stationID=" + stationID + "&wayCode=" + wayCode + `&showExpressTime=1&apiKey=${apiKey}`); | ||
27 | - } catch (e) { | ||
28 | - console.error(e); | ||
29 | - } | ||
30 | - | ||
31 | -} | ||
32 | -//subwayArrivalTime(216,1); | ||
33 | -const seoulBusStationID = async (stationID) => { | ||
34 | - try { | ||
35 | - var result = await axios.get("https://api.odsay.com/v1/api/busStationInfo?lang=0&stationID=" + parseInt(stationID) + `&apiKey=${apiKey}`); | ||
36 | - result = result.data; | ||
37 | - var _stationID = result.result.arsID; | ||
38 | - _stationID = _stationID.replace("-", ""); | ||
39 | - return _stationID; | ||
40 | - } catch (e) { | ||
41 | - console.error(e); | ||
42 | - } | ||
43 | -} | ||
44 | - | ||
45 | -const seoulBusArrivalTime = async (stationID, busNum) => { | ||
46 | - try { | ||
47 | - | ||
48 | - var _stationID = await seoulBusStationID(stationID); | ||
49 | - | ||
50 | - var result = await axios.get('http://ws.bus.go.kr/api/rest/stationinfo/getStationByUid?serviceKey' + _stationID); | ||
51 | - //console.log(res.data); | ||
52 | - result = convert.xml2js(result.data, {compact: true, spaces: 4}); | ||
53 | - result = JSON.parse(JSON.stringify(result)); | ||
54 | - //console.log(result.ServiceResult.msgBody.itemList); | ||
55 | - var arrList = result.ServiceResult.msgBody.itemList; | ||
56 | - //console.log(arrList); | ||
57 | - for (var i = 0; i < arrList.length; i++) { | ||
58 | - if (arrList[i].rtNm._text == busNum) { | ||
59 | - var msg = new Object(); | ||
60 | - msg.msg1 = arrList[i].arrmsg1._text; | ||
61 | - msg.msg2 = arrList[i].arrmsg2._text; | ||
62 | - msg.timeInterval = 7; | ||
63 | - return msg; | ||
64 | - } | ||
65 | - } | ||
66 | - var msg = new Object(); | ||
67 | - msg.msg1 = "도착예정 없음"; | ||
68 | - msg.msg2 = "도착예정 없음"; | ||
69 | - msg.timeInterval = 7; | ||
70 | - return msg; | ||
71 | - | ||
72 | - | ||
73 | - } catch (e) { | ||
74 | - console.error(e); | ||
75 | - } | ||
76 | -}; | ||
77 | - | ||
78 | -const gyeonggiLocalData = async (stationID, busID) => { | ||
79 | - try { | ||
80 | - var result = await axios.get("https://api.odsay.com/v1/api/busStationInfo?lang=0&stationID=" + parseInt(stationID) + `&apiKey=${apiKey}`); | ||
81 | - result = result.data; | ||
82 | - var stationLocalId = result.result.localStationID; | ||
83 | - for (var i = 0; i < result.result.lane.length; i++) { | ||
84 | - if (result.result.lane[i].busID == busID) { | ||
85 | - busLocalId = result.result.lane[i].busLocalBlID; | ||
86 | - | ||
87 | - return [stationLocalId, busLocalId]; | ||
88 | - } | ||
89 | - } | ||
90 | - } catch (e) { | ||
91 | - console.error(e); | ||
92 | - } | ||
93 | -}; | ||
94 | -const gyeonggiBusArrivalTime = async (stationID, busID) => { | ||
95 | - try { | ||
96 | - var localData = await gyeonggiLocalData(stationID, busID); | ||
97 | - var stationLocalID = localData[0]; | ||
98 | - var busLocalID = localData[1]; | ||
99 | - var result = await axios.get('http://openapi.gbis.go.kr/ws/rest/busarrivalservice/station?&stationId=' + stationLocalID); | ||
100 | - result = convert.xml2js(result.data, {compact: true, spaces: 4}); | ||
101 | - result = JSON.parse(JSON.stringify(result)); | ||
102 | - | ||
103 | - var msg = new Object(); | ||
104 | - if (result.response.msgHeader.resultMessage._text == "결과가 존재하지 않습니다.") { | ||
105 | - msg.msg1 = "도착 정보 없음"; | ||
106 | - msg.msg2 = "도착 정보 없음"; | ||
107 | - msg.timeInterval = 7; | ||
108 | - console.log(msg); | ||
109 | - return msg; | ||
110 | - | ||
111 | - } else if (result.response.msgHeader.resultMessage._text == '정상적으로 처리되었습니다.') { | ||
112 | - | ||
113 | - var arrList = result.response.msgBody.busArrivalList; | ||
114 | - for (var i = 0; i < arrList.length; i++) { | ||
115 | - var item = arrList[i]; | ||
116 | - if (item.routeId._text == busLocalID) { | ||
117 | - msg.msg1 = item.predictTime1._text + "분 남음" + "(" + item.locationNo1._text + "개 역 전에 도착)"; | ||
118 | - if (parseInt(item.predictTime2._text) > 0) { | ||
119 | - msg.msg2= msg.msg2 = item.predictTime2._text + "분 남음" + "(" + item.locationNo2._text + "개 역 전에 도착)"; | ||
120 | - msg.timeInterval = (parseInt(item.predictTime2._text) - parseInt(item.predictTime1._text))/60;//초 | ||
121 | - console.log("time interval,",msg.timeInterval); | ||
122 | - } else { | ||
123 | - msg.msg2="도착 정보 없음"; | ||
124 | - msg.timeInterval = parseInt(item.predictTime1._text); | ||
125 | - } | ||
126 | - console.log(msg); | ||
127 | - return msg;//JSON타입 데이터 | ||
128 | - | ||
129 | - } | ||
130 | - } | ||
131 | - msg.msg1 = "도착 정보 없음"; | ||
132 | - msg.msg2 = "도착 정보 없음"; | ||
133 | - msg.timeInterval = 7; | ||
134 | - console.log(msg); | ||
135 | - return msg; | ||
136 | - | ||
137 | - } | ||
138 | - | ||
139 | - } catch (e) { | ||
140 | - console.error(e); | ||
141 | - } | ||
142 | -} | ||
143 | - | ||
144 | -function printSubwayInfo(subPath) { | ||
145 | - console.log("-------지하철 이동---------"); | ||
146 | - console.log("소요시간:", subPath.time); | ||
147 | - console.log("총 정거장수:", subPath.stationCnt); | ||
148 | - console.log("지하철 정보:"); | ||
149 | - for (var i = 0; i < subPath.laneList.length; i++) { | ||
150 | - console.log(subPath.laneList[i].name); | ||
151 | - } | ||
152 | - console.log("출발역:", subPath.startName); | ||
153 | - console.log("도착역:", subPath.endName); | ||
154 | - console.log("station 리스트"); | ||
155 | - console.log("------노선-------"); | ||
156 | - for (var i = 0; i < subPath.stationList.length; i++) { | ||
157 | - console.log("|") | ||
158 | - console.log(subPath.stationList[i]); | ||
159 | - } | ||
160 | - | ||
161 | - | ||
162 | -} | ||
163 | - | ||
164 | -function printBusInfo(subPath) { | ||
165 | - console.log("--------버스 이동----------"); | ||
166 | - console.log("소요시간:", subPath.time); | ||
167 | - console.log(subPath.stationCnt, "개 정류장 이동"); | ||
168 | - for (var i = 0; i < subPath.arrivalInfo.length; i++) { | ||
169 | - console.log("버스 번호:", subPath.arrivalInfo[i].busNo); | ||
170 | - console.log(subPath.arrivalInfo[i].msg); | ||
171 | - console.log("-----------------------"); | ||
172 | - } | ||
173 | - //console.log("대체버스:",subPath.busNumberList); | ||
174 | - console.log("출발역:", subPath.startName); | ||
175 | - console.log("도착역:", subPath.endName); | ||
176 | - console.log("-------노선--------"); | ||
177 | - for (var i = 0; i < subPath.stationList.length; i++) { | ||
178 | - console.log("|"); | ||
179 | - console.log(subPath.stationList[i].stationName); | ||
180 | - } | ||
181 | - | ||
182 | - | ||
183 | -} | ||
184 | - | ||
185 | -function printWalkInfo(subPath) { | ||
186 | - console.log("--------도보 이동----------"); | ||
187 | - console.log("도보 이동 시간:", subPath.time); | ||
188 | - console.log("도보 이동 거리:", subPath.distance); | ||
189 | - | ||
190 | - | ||
191 | -} | ||
192 | - | ||
193 | -const searchPubTransPath = async (sx, sy, ex, ey, avgSpeed, endTime) => { | ||
194 | - //출발지점x좌표, 출발지점 y좌표, 도착지점 x좌표, 도착지점 y좌표, 보행자 평균 속도, 희망 도착시간(stringtype 2digit->hour, 2digit->min) | ||
195 | - try { | ||
196 | - var result = await axios.get("https://api.odsay.com/v1/api/searchPubTransPath?SX=" + sx + "&SY=" + sy + "&EX=" + ex + "&EY=" + ey + `&apiKey=${apiKey}`); | ||
197 | - result = result.data; | ||
198 | - var endTime = moment(endTime).format('HH:mm').split(':'); | ||
199 | - console.log(endTime); | ||
200 | - | ||
201 | - var arrivalTime = parseInt(endTime[0]) * 60 + parseInt(endTime[1]);//endTime의 시각을 minute단위로 바꿈 | ||
202 | - if (result.result.searchType == 0) {//도시내 이동 | ||
203 | - var pathList = new Array(); | ||
204 | - for (var i = 0; i < result.result.path.length; i++) { | ||
205 | - var path = result.result.path[i]; | ||
206 | - console.log("========================================================================================"); | ||
207 | - console.log("========================================================================================"); | ||
208 | - console.log(i + 1, "번째 경로"); | ||
209 | - var pathObj = new Object(); | ||
210 | - if (path.pathType == 1) { | ||
211 | - pathObj.pathType = "지하철"; | ||
212 | - } else if (path.pathType == 2) { | ||
213 | - pathObj.pathType = "버스"; | ||
214 | - } else { | ||
215 | - pathObj.pathType = "지하철&버스"; | ||
216 | - } | ||
217 | - pathObj.walkTime = 0; | ||
218 | - pathObj.info = path.info; | ||
219 | - pathObj.walkDistance = 0; | ||
220 | - pathObj.busTimeInterval = 0; | ||
221 | - console.log(pathObj.pathType); | ||
222 | - console.log("총소요시간:", pathObj.info.totalTime); | ||
223 | - console.log("비용:", pathObj.info.payment); | ||
224 | - console.log("출발역:", pathObj.info.firstStartStation); | ||
225 | - console.log("도착역:", pathObj.info.lastEndStation); | ||
226 | - console.log("도보:", pathObj.info.totalWalk, " 이동"); | ||
227 | - console.log("총", pathObj.info.totalStationCount, "개 역 이동"); | ||
228 | - console.log("버스:", pathObj.info.busStationCount, "개 역 이동"); | ||
229 | - console.log("지하철:", pathObj.info.subwayStationCount, "개 역 이동"); | ||
230 | - console.log("=======경로 상세정보========"); | ||
231 | - pathObj.subPathList = new Array(); | ||
232 | - //console.log(pathObj.info); | ||
233 | - for (var j = 0; j < path.subPath.length; j++) { | ||
234 | - var subPath = new Object(); | ||
235 | - if (path.subPath[j].trafficType == 1) {//지하철 환승 | ||
236 | - subPath.trafficType = "지하철"; | ||
237 | - subPath.time = path.subPath[j].sectionTime; | ||
238 | - subPath.stationCnt = path.subPath[j].stationCount; | ||
239 | - subPath.laneList = path.subPath[j].lane; | ||
240 | - subPath.startName = path.subPath[j].startName; | ||
241 | - subPath.startID = path.subPath[j].startID; | ||
242 | - subPath.endName = path.subPath[j].endName; | ||
243 | - subPath.endID = path.subPath[j].endID; | ||
244 | - subPath.stationList = new Array(); | ||
245 | - for (var k = 0; k < path.subPath[j].passStopList.stations.length; k++) { | ||
246 | - subPath.stationList.push(path.subPath[j].passStopList.stations[k].stationName); | ||
247 | - } | ||
248 | - printSubwayInfo(subPath); | ||
249 | - } else if (path.subPath[j].trafficType == 2) {//버스=>실시간 정보! | ||
250 | - subPath.trafficType = "버스"; | ||
251 | - subPath.time = path.subPath[j].sectionTime;//총소요시간 | ||
252 | - subPath.stationCnt = path.subPath[j].stationCount; | ||
253 | - subPath.startName = path.subPath[j].startName; | ||
254 | - subPath.startID = path.subPath[j].startID; | ||
255 | - subPath.endName = path.subPath[j].endName; | ||
256 | - subPath.endID = path.subPath[j].endID; | ||
257 | - subPath.stationList = path.subPath[j].passStopList.stations; | ||
258 | - subPath.arrivalInfo = new Array(); | ||
259 | - var cityName = await reverseGeocoding(path.subPath[j].passStopList.stations[0].x, path.subPath[j].passStopList.stations[0].y); | ||
260 | - if (cityName == "서울특별시") {//stationID와 busNo로 도착 예정시간 추출 | ||
261 | - //seoulBusArrivalTime(path.subPath[j].passStopList.stations[0].stationID,busNumberList); | ||
262 | - for (var a = 0; a < path.subPath[j].lane.length; a++) { | ||
263 | - var busArrivalInfoItem = new Object(); | ||
264 | - var _msg = await seoulBusArrivalTime(subPath.startID, path.subPath[j].lane[a].busNo); | ||
265 | - busArrivalInfoItem.busID = path.subPath[j].lane[a].busID; | ||
266 | - busArrivalInfoItem.busNo = path.subPath[j].lane[a].busNo; | ||
267 | - busArrivalInfoItem.msg = _msg; | ||
268 | - subPath.arrivalInfo.push(busArrivalInfoItem); | ||
269 | - pathObj.busTimeInterval = _msg.timeInterval; //초->분단위로 바꿈 | ||
270 | - console.log(_msg.timeInterval); | ||
271 | - if (a == 2)//버스 최대 3개까지만 출력시킴 | ||
272 | - break; | ||
273 | - } | ||
274 | - printBusInfo(subPath); | ||
275 | - } else if (cityName == "경기도") { | ||
276 | - for (var a = 0; a < path.subPath[j].lane.length; a++) { | ||
277 | - var busArrivalInfoItem = new Object(); | ||
278 | - var _msg = await gyeonggiBusArrivalTime(subPath.startID, path.subPath[j].lane[a].busID); | ||
279 | - busArrivalInfoItem.busID = path.subPath[j].lane[a].busID; | ||
280 | - busArrivalInfoItem.busNo = path.subPath[j].lane[a].busNo; | ||
281 | - busArrivalInfoItem.msg = _msg; | ||
282 | - subPath.arrivalInfo.push(busArrivalInfoItem); | ||
283 | - console.log("----------메시지메시지-----------", _msg); | ||
284 | - pathObj.busTimeInterval = _msg.timeInterval; | ||
285 | - | ||
286 | - if (a == 2)//버스 최대 3개까지만 출력 | ||
287 | - break; | ||
288 | - } | ||
289 | - printBusInfo(subPath); | ||
290 | - } else { | ||
291 | - //서울, 경기를 제외한 지역은 실시간 정보 제공 불가 | ||
292 | - printBusInfo(subPath); | ||
293 | - } | ||
294 | - } else {//도보이동 | ||
295 | - pathObj.walkTime += path.subPath[j].sectionTime; | ||
296 | - pathObj.walkDistance += path.subPath[j].distance; | ||
297 | - subPath.trafficType = "도보"; | ||
298 | - subPath.time = path.subPath[j].sectionTime; | ||
299 | - subPath.distance = path.subPath[j].distance; | ||
300 | - printWalkInfo(subPath); | ||
301 | - } | ||
302 | - pathObj.subPathList.push(subPath); | ||
303 | - | ||
304 | - } | ||
305 | - | ||
306 | - pathList.push(pathObj); | ||
307 | - var optTotalTime = pathObj.info.totalTime - pathObj.walkTime + pathObj.walkDistance / avgSpeed;//사용자의 보행속도를 고려한 이동시간 | ||
308 | - console.log("arrrrrrrrrrr",arrivalTime) | ||
309 | - var departureTime1 = parseInt(arrivalTime - optTotalTime); | ||
310 | - | ||
311 | - if(departureTime1<0){ | ||
312 | - departureTime1+=1440; | ||
313 | - } | ||
314 | - if(path.pathType==1){//지하철의 경우 시간간격 4분으로 | ||
315 | - pathObj.busTimeInterval=4; | ||
316 | - } | ||
317 | - var departureTime2 = parseInt(arrivalTime - optTotalTime - pathObj.busTimeInterval); | ||
318 | - if(departureTime2<0){ | ||
319 | - departureTime2+=1440; | ||
320 | - } | ||
321 | - console.log(pathObj.busTimeInterval); | ||
322 | - console.log("dp1",departureTime1); | ||
323 | - console.log("dp2",departureTime2); | ||
324 | - | ||
325 | - console.log("pathType",path.pathType); | ||
326 | - console.log("departure time 1",departureTime1); | ||
327 | - console.log("departure time 2",departureTime2); | ||
328 | - var hour1 = departureTime1 / 60; | ||
329 | - var min1 = departureTime1 % 60; | ||
330 | - var hour2 = departureTime2 / 60; | ||
331 | - var min2 =departureTime2 % 60; | ||
332 | - pathObj.info.hour1=parseInt(hour1).toString(); | ||
333 | - pathObj.info.min1=parseInt(min1).toString(); | ||
334 | - pathObj.info.hour2=parseInt(hour2).toString(); | ||
335 | - pathObj.info.min2=parseInt(min2).toString(); | ||
336 | - console.log(pathObj.info.hour1,"시 ",pathObj.info.min1,"분"); | ||
337 | - console.log(pathObj.info.hour2,"시 ",pathObj.info.min2,"분"); | ||
338 | - if (i == 2)//경로 3개까지만 출력 | ||
339 | - break; | ||
340 | - | ||
341 | - | ||
342 | - } | ||
343 | - return {pathList}; | ||
344 | - } else if (result.result.searchType == 1) {//도시간 이동 | ||
345 | - var path = new Object(); | ||
346 | - path.trainList = new Array(); | ||
347 | - for (var j = 0; j < result.result.trainRequest.count; j++) { | ||
348 | - var train = new Object(); | ||
349 | - train = result.result.trainRequest.OBJ[j]; | ||
350 | - path.trainList.push(train); | ||
351 | - if (j == 2) | ||
352 | - break; | ||
353 | - } | ||
354 | - path.exBusList = new Array(); | ||
355 | - for (var j = 0; j < result.result.exBusRequest.count; j++) { | ||
356 | - var exBus = new Object(); | ||
357 | - exBus = reuslt.result.exBusRequest.OBJ[j]; | ||
358 | - path.exBusList.push(exBus); | ||
359 | - if (j == 2) | ||
360 | - break; | ||
361 | - } | ||
362 | - path.outBusList = new Array(); | ||
363 | - for (var j = 0; j < result.result.outBusRequest.count; j++) { | ||
364 | - var outBus = new Object(); | ||
365 | - outBus = result.result.outBusRequest.OBJ[j]; | ||
366 | - path.outBusList.push(outBus); | ||
367 | - if (j == 2) | ||
368 | - break; | ||
369 | - } | ||
370 | - return path; | ||
371 | - | ||
372 | - } | ||
373 | - | ||
374 | - } catch (e) { | ||
375 | - console.error(e); | ||
376 | - } | ||
377 | -}; | ||
378 | -searchPubTransPath(126.999451,37.266670, 126.986990,37.541386,60,"00:10"); | ||
379 | -module.exports = searchPubTransPath; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
-
Please register or login to post a comment