moonyeju
2023-10-05
[ADD]g
@48f7947048e6f23aa47aff307a9ba09db4cb7482
--- kogas_app/__tests__/App.test.tsx
... | ... | @@ -1,17 +0,0 @@ |
1 | -/** | |
2 | - * @format | |
3 | - */ | |
4 | - | |
5 | -import 'react-native'; | |
6 | -import React from 'react'; | |
7 | -import App from '../App'; | |
8 | - | |
9 | -// Note: import explicitly to use the types shiped with jest. | |
10 | -import {it} from '@jest/globals'; | |
11 | - | |
12 | -// Note: test renderer must be required after react-native. | |
13 | -import renderer from 'react-test-renderer'; | |
14 | - | |
15 | -it('renders correctly', () => { | |
16 | - renderer.create(<App />); | |
17 | -}); |
--- kogas_app/package-lock.json
+++ kogas_app/package-lock.json
... | ... | @@ -9,6 +9,7 @@ |
9 | 9 |
"version": "0.0.1", |
10 | 10 |
"dependencies": { |
11 | 11 |
"@react-native-community/masked-view": "^0.1.11", |
12 |
+ "@react-native-firebase/messaging": "^18.5.0", |
|
12 | 13 |
"@react-navigation/bottom-tabs": "^6.5.8", |
13 | 14 |
"@react-navigation/native": "^6.1.7", |
14 | 15 |
"@react-navigation/stack": "^6.3.17", |
... | ... | @@ -3478,6 +3479,34 @@ |
3478 | 3479 |
"peerDependencies": { |
3479 | 3480 |
"react": ">=16.0", |
3480 | 3481 |
"react-native": ">=0.57" |
3482 |
+ } |
|
3483 |
+ }, |
|
3484 |
+ "node_modules/@react-native-firebase/app": { |
|
3485 |
+ "version": "18.5.0", |
|
3486 |
+ "resolved": "https://registry.npmjs.org/@react-native-firebase/app/-/app-18.5.0.tgz", |
|
3487 |
+ "integrity": "sha512-AhHQi5KFDlKZn/lH7rEYtLfpsGamEq+P/cXZWcNPcP0WGlmi++abk7Pxnn4MjnG7TNhEyG/C9uq//qb6VhXaZg==", |
|
3488 |
+ "peer": true, |
|
3489 |
+ "dependencies": { |
|
3490 |
+ "opencollective-postinstall": "^2.0.1", |
|
3491 |
+ "superstruct": "^0.6.2" |
|
3492 |
+ }, |
|
3493 |
+ "peerDependencies": { |
|
3494 |
+ "expo": ">=47.0.0", |
|
3495 |
+ "react": "*", |
|
3496 |
+ "react-native": "*" |
|
3497 |
+ }, |
|
3498 |
+ "peerDependenciesMeta": { |
|
3499 |
+ "expo": { |
|
3500 |
+ "optional": true |
|
3501 |
+ } |
|
3502 |
+ } |
|
3503 |
+ }, |
|
3504 |
+ "node_modules/@react-native-firebase/messaging": { |
|
3505 |
+ "version": "18.5.0", |
|
3506 |
+ "resolved": "https://registry.npmjs.org/@react-native-firebase/messaging/-/messaging-18.5.0.tgz", |
|
3507 |
+ "integrity": "sha512-y1FApYxBMcygmbWBqUPFC+fCfvx6Yf6TdZewun7kPwx+S+tkYzoKx1IsXtxOXtqyJjCNEYirjFgNrs5SSd02zA==", |
|
3508 |
+ "peerDependencies": { |
|
3509 |
+ "@react-native-firebase/app": "18.5.0" |
|
3481 | 3510 |
} |
3482 | 3511 |
}, |
3483 | 3512 |
"node_modules/@react-native/assets-registry": { |
... | ... | @@ -7261,6 +7290,27 @@ |
7261 | 7290 |
"is-callable": "^1.1.3" |
7262 | 7291 |
} |
7263 | 7292 |
}, |
7293 |
+ "node_modules/for-in": { |
|
7294 |
+ "version": "1.0.2", |
|
7295 |
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", |
|
7296 |
+ "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", |
|
7297 |
+ "peer": true, |
|
7298 |
+ "engines": { |
|
7299 |
+ "node": ">=0.10.0" |
|
7300 |
+ } |
|
7301 |
+ }, |
|
7302 |
+ "node_modules/for-own": { |
|
7303 |
+ "version": "1.0.0", |
|
7304 |
+ "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", |
|
7305 |
+ "integrity": "sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==", |
|
7306 |
+ "peer": true, |
|
7307 |
+ "dependencies": { |
|
7308 |
+ "for-in": "^1.0.1" |
|
7309 |
+ }, |
|
7310 |
+ "engines": { |
|
7311 |
+ "node": ">=0.10.0" |
|
7312 |
+ } |
|
7313 |
+ }, |
|
7264 | 7314 |
"node_modules/form-data": { |
7265 | 7315 |
"version": "4.0.0", |
7266 | 7316 |
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", |
... | ... | @@ -7938,6 +7988,15 @@ |
7938 | 7988 |
"resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", |
7939 | 7989 |
"integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", |
7940 | 7990 |
"license": "MIT", |
7991 |
+ "engines": { |
|
7992 |
+ "node": ">=0.10.0" |
|
7993 |
+ } |
|
7994 |
+ }, |
|
7995 |
+ "node_modules/is-extendable": { |
|
7996 |
+ "version": "0.1.1", |
|
7997 |
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", |
|
7998 |
+ "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", |
|
7999 |
+ "peer": true, |
|
7941 | 8000 |
"engines": { |
7942 | 8001 |
"node": ">=0.10.0" |
7943 | 8002 |
} |
... | ... | @@ -10315,6 +10374,28 @@ |
10315 | 10374 |
"url": "https://github.com/sponsors/ljharb" |
10316 | 10375 |
} |
10317 | 10376 |
}, |
10377 |
+ "node_modules/mixin-object": { |
|
10378 |
+ "version": "2.0.1", |
|
10379 |
+ "resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz", |
|
10380 |
+ "integrity": "sha512-ALGF1Jt9ouehcaXaHhn6t1yGWRqGaHkPFndtFVHfZXOvkIZ/yoGaSi0AHVTafb3ZBGg4dr/bDwnaEKqCXzchMA==", |
|
10381 |
+ "peer": true, |
|
10382 |
+ "dependencies": { |
|
10383 |
+ "for-in": "^0.1.3", |
|
10384 |
+ "is-extendable": "^0.1.1" |
|
10385 |
+ }, |
|
10386 |
+ "engines": { |
|
10387 |
+ "node": ">=0.10.0" |
|
10388 |
+ } |
|
10389 |
+ }, |
|
10390 |
+ "node_modules/mixin-object/node_modules/for-in": { |
|
10391 |
+ "version": "0.1.8", |
|
10392 |
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.8.tgz", |
|
10393 |
+ "integrity": "sha512-F0to7vbBSHP8E3l6dCjxNOLuSFAACIxFy3UehTUlG7svlXi37HHsDkyVcHo0Pq8QwrE+pXvWSVX3ZT1T9wAZ9g==", |
|
10394 |
+ "peer": true, |
|
10395 |
+ "engines": { |
|
10396 |
+ "node": ">=0.10.0" |
|
10397 |
+ } |
|
10398 |
+ }, |
|
10318 | 10399 |
"node_modules/mkdirp": { |
10319 | 10400 |
"version": "0.5.6", |
10320 | 10401 |
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", |
... | ... | @@ -10666,6 +10747,15 @@ |
10666 | 10747 |
}, |
10667 | 10748 |
"engines": { |
10668 | 10749 |
"node": ">=8" |
10750 |
+ } |
|
10751 |
+ }, |
|
10752 |
+ "node_modules/opencollective-postinstall": { |
|
10753 |
+ "version": "2.0.3", |
|
10754 |
+ "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", |
|
10755 |
+ "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==", |
|
10756 |
+ "peer": true, |
|
10757 |
+ "bin": { |
|
10758 |
+ "opencollective-postinstall": "index.js" |
|
10669 | 10759 |
} |
10670 | 10760 |
}, |
10671 | 10761 |
"node_modules/optionator": { |
... | ... | @@ -12352,6 +12442,54 @@ |
12352 | 12442 |
"integrity": "sha512-Mu7R0g4ig9TUuGSxJavny5Rv0egCEtpZRNMrZaYS1vxkiIxGiGUwoezU3LazIQ+KE04hTrTfNPgxU5gzi7F5Pw==", |
12353 | 12443 |
"license": "MIT" |
12354 | 12444 |
}, |
12445 |
+ "node_modules/superstruct": { |
|
12446 |
+ "version": "0.6.2", |
|
12447 |
+ "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.6.2.tgz", |
|
12448 |
+ "integrity": "sha512-lvA97MFAJng3rfjcafT/zGTSWm6Tbpk++DP6It4Qg7oNaeM+2tdJMuVgGje21/bIpBEs6iQql1PJH6dKTjl4Ig==", |
|
12449 |
+ "peer": true, |
|
12450 |
+ "dependencies": { |
|
12451 |
+ "clone-deep": "^2.0.1", |
|
12452 |
+ "kind-of": "^6.0.1" |
|
12453 |
+ } |
|
12454 |
+ }, |
|
12455 |
+ "node_modules/superstruct/node_modules/clone-deep": { |
|
12456 |
+ "version": "2.0.2", |
|
12457 |
+ "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-2.0.2.tgz", |
|
12458 |
+ "integrity": "sha512-SZegPTKjCgpQH63E+eN6mVEEPdQBOUzjyJm5Pora4lrwWRFS8I0QAxV/KD6vV/i0WuijHZWQC1fMsPEdxfdVCQ==", |
|
12459 |
+ "peer": true, |
|
12460 |
+ "dependencies": { |
|
12461 |
+ "for-own": "^1.0.0", |
|
12462 |
+ "is-plain-object": "^2.0.4", |
|
12463 |
+ "kind-of": "^6.0.0", |
|
12464 |
+ "shallow-clone": "^1.0.0" |
|
12465 |
+ }, |
|
12466 |
+ "engines": { |
|
12467 |
+ "node": ">=0.10.0" |
|
12468 |
+ } |
|
12469 |
+ }, |
|
12470 |
+ "node_modules/superstruct/node_modules/shallow-clone": { |
|
12471 |
+ "version": "1.0.0", |
|
12472 |
+ "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-1.0.0.tgz", |
|
12473 |
+ "integrity": "sha512-oeXreoKR/SyNJtRJMAKPDSvd28OqEwG4eR/xc856cRGBII7gX9lvAqDxusPm0846z/w/hWYjI1NpKwJ00NHzRA==", |
|
12474 |
+ "peer": true, |
|
12475 |
+ "dependencies": { |
|
12476 |
+ "is-extendable": "^0.1.1", |
|
12477 |
+ "kind-of": "^5.0.0", |
|
12478 |
+ "mixin-object": "^2.0.1" |
|
12479 |
+ }, |
|
12480 |
+ "engines": { |
|
12481 |
+ "node": ">=0.10.0" |
|
12482 |
+ } |
|
12483 |
+ }, |
|
12484 |
+ "node_modules/superstruct/node_modules/shallow-clone/node_modules/kind-of": { |
|
12485 |
+ "version": "5.1.0", |
|
12486 |
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", |
|
12487 |
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", |
|
12488 |
+ "peer": true, |
|
12489 |
+ "engines": { |
|
12490 |
+ "node": ">=0.10.0" |
|
12491 |
+ } |
|
12492 |
+ }, |
|
12355 | 12493 |
"node_modules/supports-color": { |
12356 | 12494 |
"version": "7.2.0", |
12357 | 12495 |
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", |
--- kogas_app/package.json
+++ kogas_app/package.json
... | ... | @@ -11,6 +11,7 @@ |
11 | 11 |
}, |
12 | 12 |
"dependencies": { |
13 | 13 |
"@react-native-community/masked-view": "^0.1.11", |
14 |
+ "@react-native-firebase/messaging": "^18.5.0", |
|
14 | 15 |
"@react-navigation/bottom-tabs": "^6.5.8", |
15 | 16 |
"@react-navigation/native": "^6.1.7", |
16 | 17 |
"@react-navigation/stack": "^6.3.17", |
--- kogas_app/src/App.js
... | ... | @@ -1,12 +0,0 @@ |
1 | -import {UserProvider} from './contexts/UserContext'; | |
2 | -import Navigation from './navigations'; | |
3 | - | |
4 | -const App = () => { | |
5 | - return ( | |
6 | - <UserProvider> | |
7 | - <Navigation /> | |
8 | - </UserProvider> | |
9 | - ); | |
10 | -}; | |
11 | - | |
12 | -export default App; |
--- kogas_app/src/color.js
... | ... | @@ -1,14 +0,0 @@ |
1 | -export const WHITE = '#ffffff'; | |
2 | -export const BLACK = '#000000'; | |
3 | -export const GRAY = '#a3a3a3'; | |
4 | - | |
5 | -export const PRIMARY = { | |
6 | - DARK: '#0E56AA', | |
7 | - DEFAULT: '#3E78BB', | |
8 | - LIGHT: '#B7CDE6', | |
9 | -}; | |
10 | - | |
11 | -export const SBTN = { | |
12 | - DEFAULT: '#DBE6F2', | |
13 | - DARK: '#B3BECA', | |
14 | -}; |
--- kogas_app/src/components/Button.js
... | ... | @@ -1,48 +0,0 @@ |
1 | -import {ActivityIndicator, Pressable, StyleSheet, Text} from 'react-native'; | |
2 | -import PropTypes from 'prop-types'; | |
3 | -import {GRAY, PRIMARY, WHITE} from '../color'; | |
4 | - | |
5 | -const Button = ({title, onPress, disabled, isLoading}) => { | |
6 | - return ( | |
7 | - <Pressable | |
8 | - onPress={onPress} | |
9 | - style={({pressed}) => [ | |
10 | - styles.container, | |
11 | - {backgroundColor: PRIMARY.DEFAULT}, | |
12 | - pressed && {backgroundColor: PRIMARY.DARK}, | |
13 | - disabled && {backgroundColor: PRIMARY.LIGHT}, | |
14 | - ]} | |
15 | - disabled={disabled}> | |
16 | - {isLoading ? ( | |
17 | - <ActivityIndicator size={'small'} color={GRAY} /> | |
18 | - ) : ( | |
19 | - <Text style={styles.title}>{title}</Text> | |
20 | - )} | |
21 | - </Pressable> | |
22 | - ); | |
23 | -}; | |
24 | - | |
25 | -Button.propTypes = { | |
26 | - title: PropTypes.string.isRequired, | |
27 | - onPress: PropTypes.func.isRequired, | |
28 | - disabled: PropTypes.bool, | |
29 | - isLoading: PropTypes.bool, | |
30 | -}; | |
31 | - | |
32 | -const styles = StyleSheet.create({ | |
33 | - container: { | |
34 | - backgroundColor: PRIMARY.DEFAULT, | |
35 | - borderRadius: 8, | |
36 | - justifyContent: 'center', | |
37 | - alignItems: 'center', | |
38 | - paddingVertical: 15, | |
39 | - }, | |
40 | - title: { | |
41 | - color: WHITE, | |
42 | - fontSize: 16, | |
43 | - fontWeight: '700', | |
44 | - lineHeight: 20, | |
45 | - }, | |
46 | -}); | |
47 | - | |
48 | -export default Button; |
--- kogas_app/src/components/CircularProgressBar.js
... | ... | @@ -1,71 +0,0 @@ |
1 | -import React from 'react'; | |
2 | -import { View, StyleSheet } from 'react-native'; | |
3 | -import { Circle, G, Svg, Text } from 'react-native-svg'; | |
4 | -import { BLACK } from '../color'; | |
5 | - | |
6 | -const CircularProgressBar = ({ percentage }) => { | |
7 | - // 원의 반지름 | |
8 | - const radius = 30; | |
9 | - | |
10 | - // 원의 중심 좌표 | |
11 | - const centerX = radius + 5; // X 좌표 | |
12 | - const centerY = radius + 5; // Y 좌표 | |
13 | - | |
14 | - // 원의 둘레 | |
15 | - const circumference = 2 * Math.PI * radius; | |
16 | - | |
17 | - // 원의 시작 각도 (12시 방향이 0도) | |
18 | - const startAngle = -Math.PI / 2; | |
19 | - | |
20 | - // 퍼센티지에 따른 끝 각도 계산 | |
21 | - const endAngle = startAngle + (percentage / 100) * (2 * Math.PI); | |
22 | - | |
23 | - return ( | |
24 | - <View style={styles.container}> | |
25 | - <Svg width={2 * (radius + 5)} height={2 * (radius + 5)}> | |
26 | - <G> | |
27 | - {/* 배경 원 */} | |
28 | - <Circle | |
29 | - r={radius} | |
30 | - cx={centerX} | |
31 | - cy={centerY} | |
32 | - fill="none" | |
33 | - stroke="#ddd" | |
34 | - strokeWidth={10} | |
35 | - /> | |
36 | - {/* 원형 그래프 */} | |
37 | - <Circle | |
38 | - r={radius} | |
39 | - cx={centerX} | |
40 | - cy={centerY} | |
41 | - fill="none" | |
42 | - stroke="#007AFF" // 원형 그래프의 색상 | |
43 | - strokeWidth={10} // 원형 그래프의 두께 | |
44 | - strokeDasharray={`${circumference}, ${circumference}`} | |
45 | - strokeDashoffset={circumference - (percentage / 100) * circumference} | |
46 | - /> | |
47 | - {/* 텍스트 */} | |
48 | - <Text | |
49 | - x={centerX - 7} | |
50 | - y={centerY + 5} // 텍스트 위치 조절 | |
51 | - fontSize="15" | |
52 | - textAnchor="middle" | |
53 | - fill={BLACK} // 텍스트 색상 | |
54 | - > | |
55 | - {percentage}% | |
56 | - </Text> | |
57 | - </G> | |
58 | - </Svg> | |
59 | - </View> | |
60 | - ); | |
61 | -}; | |
62 | - | |
63 | -const styles = StyleSheet.create({ | |
64 | - container: { | |
65 | - alignItems: 'center', | |
66 | - justifyContent: 'center', | |
67 | - marginRight:10, | |
68 | - }, | |
69 | -}); | |
70 | - | |
71 | -export default CircularProgressBar; |
--- kogas_app/src/components/DetailListItem.js
... | ... | @@ -1,56 +0,0 @@ |
1 | -import {Pressable, StyleSheet, Text, View} from 'react-native'; | |
2 | -import {memo} from 'react'; | |
3 | -import { useNavigation } from '@react-navigation/native'; | |
4 | -import { useEffect, useState } from 'react'; | |
5 | - | |
6 | -const DetailListItem = memo(({name, item}) => { | |
7 | - const navigation = useNavigation(); | |
8 | - const [statusMessage, setStatusMessage] = useState(''); | |
9 | - | |
10 | - useEffect(() => { | |
11 | - if (item.status === 'Y') { | |
12 | - setStatusMessage("서명완료"); | |
13 | - } else if (item.status === 'N') { | |
14 | - setStatusMessage("진행중"); | |
15 | - } else if (item.status === 'X') { | |
16 | - setStatusMessage("반려"); | |
17 | - } | |
18 | - }, [statusMessage]); | |
19 | - return ( | |
20 | - <Pressable> | |
21 | - <View style={styles.container}> | |
22 | - <View style={styles.left}> | |
23 | - <Text>{item.department}</Text> | |
24 | - <Text> {item.name}</Text> | |
25 | - </View> | |
26 | - | |
27 | - <View style={styles.right}> | |
28 | - <Text>{statusMessage}</Text> | |
29 | - <Text>{item.datetime}</Text> | |
30 | - </View> | |
31 | - </View> | |
32 | - </Pressable> | |
33 | - ); | |
34 | -}); | |
35 | - | |
36 | -DetailListItem.displayName = 'DetailListItem'; | |
37 | - | |
38 | -const styles = StyleSheet.create({ | |
39 | - container: { | |
40 | - flexDirection: 'column', | |
41 | - marginHorizontal: 10, | |
42 | - marginVertical:5, | |
43 | - borderBottomWidth: 0.5, | |
44 | - paddingVertical: 5, | |
45 | - paddingHorizontal: 15, | |
46 | - }, | |
47 | - left: { | |
48 | - flexDirection: 'row', | |
49 | - }, | |
50 | - right: { | |
51 | - flexDirection: 'column', | |
52 | - alignItems: 'flex-end', | |
53 | - } | |
54 | -}); | |
55 | - | |
56 | -export default DetailListItem; |
--- kogas_app/src/components/EmptyList.js
... | ... | @@ -1,24 +0,0 @@ |
1 | -import {Image, StyleSheet, Text, View} from 'react-native'; | |
2 | -import {PRIMARY} from '../color'; | |
3 | - | |
4 | -const EmptyList = () => { | |
5 | - return ( | |
6 | - <View style={styles.container}> | |
7 | - <Text style={styles.title}>기록이 없습니다.</Text> | |
8 | - </View> | |
9 | - ); | |
10 | -}; | |
11 | -const styles = StyleSheet.create({ | |
12 | - container: { | |
13 | - flex: 1, | |
14 | - justifyContent: 'center', | |
15 | - alignItems: 'center', | |
16 | - }, | |
17 | - title: { | |
18 | - fontSize: 18, | |
19 | - marginTop: 10, | |
20 | - fontWeight: '700', | |
21 | - color: PRIMARY.DEFAULT, | |
22 | - }, | |
23 | -}); | |
24 | -export default EmptyList; |
--- kogas_app/src/components/ListItem.js
... | ... | @@ -1,66 +0,0 @@ |
1 | -import {Pressable, StyleSheet, Text, View} from 'react-native'; | |
2 | -import {memo} from 'react'; | |
3 | -import {useNavigation} from '@react-navigation/native'; | |
4 | -import { BLACK } from '../color'; | |
5 | -import { useEffect, useState } from 'react'; | |
6 | - | |
7 | -const ListItem = memo(({name, item}) => { | |
8 | - const navigation = useNavigation(); | |
9 | - const [stageMessage, setStageMessage] = useState(''); | |
10 | - | |
11 | - useEffect(() => { | |
12 | - if (item.stage === 0) { | |
13 | - setStageMessage('서명 진행중'); | |
14 | - } else if (item.stage === -1) { | |
15 | - setStageMessage('반려 처리'); | |
16 | - } else if (item.stage >= 1) { | |
17 | - setStageMessage(`${item.stage}차 서명완료`); | |
18 | - } | |
19 | - }, [stageMessage]); | |
20 | - | |
21 | - return ( | |
22 | - <Pressable | |
23 | - onPress={() => { | |
24 | - navigation.navigate('ListDetail', { | |
25 | - document_id: item.document_id, | |
26 | - document_name: item.document_name, | |
27 | - main_department: item.main_department, | |
28 | - reg_date: item.reg_date, | |
29 | - name: item.name, | |
30 | - stage: stageMessage | |
31 | - }); | |
32 | - }} | |
33 | - hitSlop={10} | |
34 | - > | |
35 | - <View style={styles.container}> | |
36 | - <View> | |
37 | - <Text>{stageMessage}</Text> | |
38 | - <Text>제목: {item.document_name}</Text> | |
39 | - <Text>기안자: {item.main_department} {item.name}</Text> | |
40 | - </View> | |
41 | - | |
42 | - <View> | |
43 | - <Text>기안일자: {item.reg_date}</Text> | |
44 | - </View> | |
45 | - </View> | |
46 | - </Pressable> | |
47 | - ); | |
48 | -}); | |
49 | - | |
50 | -ListItem.displayName = 'ListItem'; | |
51 | - | |
52 | -const styles = StyleSheet.create({ | |
53 | - container: { | |
54 | - flexDirection: 'column', | |
55 | - marginHorizontal: 10, | |
56 | - marginVertical:10, | |
57 | - paddingVertical: 10, | |
58 | - paddingHorizontal: 15, | |
59 | - borderRadius: 20, | |
60 | - borderColor: BLACK, | |
61 | - borderWidth: 1, | |
62 | - | |
63 | - }, | |
64 | -}); | |
65 | - | |
66 | -export default ListItem; |
--- kogas_app/src/components/TextInput.js
... | ... | @@ -1,123 +0,0 @@ |
1 | -import {StyleSheet, Text, TextInput, View} from 'react-native'; | |
2 | -import PropTypes from 'prop-types'; | |
3 | -import {forwardRef, useState} from 'react'; | |
4 | -import {GRAY, BLACK, PRIMARY, WHITE} from '../color'; | |
5 | -import Icon from 'react-native-vector-icons/Ionicons'; | |
6 | - | |
7 | -export const ReturnKeyTypes = { | |
8 | - DONE: 'done', | |
9 | - NEXT: 'next', | |
10 | -}; | |
11 | - | |
12 | -export const IconNames = { | |
13 | - ID: 'mail', | |
14 | - PASSWORD: 'lock-closed', | |
15 | -}; | |
16 | - | |
17 | -const Input = forwardRef(({placeholder, value, iconName, ...props}, ref) => { | |
18 | - const [isFocused, setIsFocused] = useState(false); | |
19 | - | |
20 | - return ( | |
21 | - <View style={styles.container}> | |
22 | - <View> | |
23 | - <TextInput | |
24 | - ref={ref} | |
25 | - {...props} | |
26 | - value={value} | |
27 | - style={[ | |
28 | - styles.input, | |
29 | - iconName && {paddingLeft: 50}, | |
30 | - value && styles.hasValueInput, | |
31 | - isFocused && styles.focusedInput, | |
32 | - ]} | |
33 | - autoCapitalize={'none'} | |
34 | - autoCorrect={false} | |
35 | - autoCompleteType={'off'} | |
36 | - textContentType={'none'} | |
37 | - keyboardAppearance={'light'} | |
38 | - onBlur={() => setIsFocused(false)} | |
39 | - onFocus={() => setIsFocused(true)} | |
40 | - placeholder={placeholder} | |
41 | - /> | |
42 | - | |
43 | - <View style={styles.icon}> | |
44 | - <Icon | |
45 | - name={iconName} | |
46 | - size={20} | |
47 | - color={WHITE} | |
48 | - // color={(() => { | |
49 | - // switch (true) { | |
50 | - // case isFocused: | |
51 | - // return PRIMARY.DEFAULT; | |
52 | - // case !!value: | |
53 | - // return BLACK; | |
54 | - // default: | |
55 | - // return GRAY; | |
56 | - // } | |
57 | - // })()} | |
58 | - /> | |
59 | - </View> | |
60 | - </View> | |
61 | - </View> | |
62 | - ); | |
63 | -}); | |
64 | -Input.displayName = 'Input'; | |
65 | - | |
66 | -Input.defaultProps = { | |
67 | - returnKeyType: ReturnKeyTypes.DONE, | |
68 | -}; | |
69 | - | |
70 | -Input.propTypes = { | |
71 | - title: PropTypes.string, | |
72 | - placeholder: PropTypes.string, | |
73 | - value: PropTypes.string, | |
74 | - iconName: PropTypes.oneOf(Object.values(IconNames)), | |
75 | -}; | |
76 | - | |
77 | -const styles = StyleSheet.create({ | |
78 | - container: { | |
79 | - width: '100%', | |
80 | - paddingHorizontal: 15, | |
81 | - marginVertical: 10, | |
82 | - }, | |
83 | - title: { | |
84 | - marginBottom: 4, | |
85 | - color: GRAY, | |
86 | - }, | |
87 | - focusedTitle: { | |
88 | - fontWeight: '600', | |
89 | - color: PRIMARY.DEFAULT, | |
90 | - }, | |
91 | - hasValueTitle: { | |
92 | - color: BLACK, | |
93 | - }, | |
94 | - input: { | |
95 | - borderWidth: 1, | |
96 | - borderRadius: 10, | |
97 | - borderColor: '#E7EEEE', | |
98 | - // paddingHorizontal: 20, | |
99 | - // height: 42, | |
100 | - // paddingLeft: 5, | |
101 | - }, | |
102 | - focusedInput: { | |
103 | - borderBottomWidth: 2, | |
104 | - borderBottomColor: PRIMARY.DEFAULT, | |
105 | - color: PRIMARY.DEFAULT, | |
106 | - }, | |
107 | - hasValueInput: { | |
108 | - borderColor: BLACK, | |
109 | - color: BLACK, | |
110 | - }, | |
111 | - icon: { | |
112 | - position: 'absolute', | |
113 | - width: 'auto', | |
114 | - height: '100%', | |
115 | - justifyContent: 'center', | |
116 | - backgroundColor: PRIMARY.DEFAULT, | |
117 | - padding: 10, | |
118 | - borderTopLeftRadius: 10, | |
119 | - borderBottomLeftRadius: 10, | |
120 | - }, | |
121 | -}); | |
122 | - | |
123 | -export default Input; |
--- kogas_app/src/contexts/UserContext.js
... | ... | @@ -1,20 +0,0 @@ |
1 | -import {createContext, useContext, useState} from 'react'; | |
2 | -import PropTypes from 'prop-types'; | |
3 | - | |
4 | -const UserContext = createContext(); | |
5 | -export const UserProvider = ({children}) => { | |
6 | - const [user, setUser] = useState(null); | |
7 | - return ( | |
8 | - <UserContext.Provider value={{user, setUser}}> | |
9 | - {children} | |
10 | - </UserContext.Provider> | |
11 | - ); | |
12 | -}; | |
13 | - | |
14 | -UserProvider.propTypes = { | |
15 | - children: PropTypes.node, | |
16 | -}; | |
17 | - | |
18 | -export const useUserContext = () => useContext(UserContext); | |
19 | - | |
20 | -export default UserContext; |
--- kogas_app/src/img/logo.png
Binary file is not shown |
--- kogas_app/src/screens/HomeScreen.js
... | ... | @@ -1,127 +0,0 @@ |
1 | -import { Pressable, StyleSheet, Text, View } from 'react-native'; | |
2 | -import { BLACK, GRAY, WHITE } from '../color'; | |
3 | -import {useNavigation} from '@react-navigation/native'; | |
4 | -import { FlatList } from 'react-native-gesture-handler'; | |
5 | -import ListItem from '../components/ListItem'; | |
6 | -import { useEffect, useState } from 'react'; | |
7 | -import { url } from '../url'; | |
8 | -import CircularProgressBar from '../components/CircularProgressBar'; | |
9 | - | |
10 | -const HomeScreen = () => { | |
11 | - const navigation = useNavigation(); | |
12 | - const [list, setList] = useState([]); | |
13 | - const [signatureAll, setSignatureAll] = useState(0); | |
14 | - const [signatureClear, setSignatureClear] = useState(0); | |
15 | - const [recentAll, setRecentAll] = useState(0); | |
16 | - const [recentClear, setRecentClear] = useState(0); | |
17 | - const myperc = Math.floor((signatureClear / signatureAll) * 100); | |
18 | - const recentperc = Math.floor((recentClear / recentAll) * 100); | |
19 | - | |
20 | -useEffect(() => { | |
21 | - getMainChart(); | |
22 | -}, [signatureAll, signatureClear, recentAll, recentClear]); | |
23 | - | |
24 | -const getMainChart = async () => { | |
25 | - try { | |
26 | - const response = await fetch(`${url}/main_chart`, { | |
27 | - method: 'GET', | |
28 | - headers: { | |
29 | - 'Content-Type': 'application/json', | |
30 | - }, | |
31 | - }) | |
32 | - if (response.ok) { | |
33 | - const data = await response.json(); | |
34 | - //console.log('aalistpage:', data); | |
35 | - setSignatureAll(data.signature_all); | |
36 | - setSignatureClear(data.signature_clear); | |
37 | - setRecentAll(data.now_all); | |
38 | - setRecentClear(data.now_clear); | |
39 | - } else { | |
40 | - console.error('main_chart 데이터를 가져오는 데 실패했습니다.'); | |
41 | - } | |
42 | - }catch (error) { | |
43 | - console.error('데이터를 가져오는 중 오류 발생:', error); | |
44 | - } | |
45 | - }; | |
46 | - useEffect(() => { | |
47 | - getList(); | |
48 | -}, []); | |
49 | -const getList = async () => { | |
50 | - try { | |
51 | - const response = await fetch(`${url}/list`, { | |
52 | - method: 'GET', | |
53 | - headers: { | |
54 | - 'Content-Type': 'application/json', | |
55 | - }, | |
56 | - }) | |
57 | - if (response.ok) { | |
58 | - const data = await response.json(); | |
59 | - //console.log('listpage:', data); | |
60 | - setList(data); | |
61 | - } else { | |
62 | - console.error('list 데이터를 가져오는 데 실패했습니다.'); | |
63 | - } | |
64 | - } catch (error) { | |
65 | - console.error('데이터를 가져오는 중 오류 발생:', error); | |
66 | - } | |
67 | -}; | |
68 | - | |
69 | - | |
70 | - return ( | |
71 | - <View style={styles.container}> | |
72 | - <View style={styles.containerTop}> | |
73 | - <Text style={styles.title}>내 진행 상황</Text> | |
74 | - <View style={styles.mydocs}><CircularProgressBar percentage={myperc} /> | |
75 | - <View style={styles.text}> | |
76 | - <Text>내 문서 진행률</Text> | |
77 | - <Text>서명 대상자 {signatureAll}명 중 {signatureClear}명이 서명을 완료하였습니다.</Text> | |
78 | - </View></View> | |
79 | - <View style={styles.mydocs}><CircularProgressBar percentage={recentperc} /> | |
80 | - <View style={styles.text}> | |
81 | - <Text>내 문서 진행률</Text> | |
82 | - <Text>서명 대상자 {recentAll}명 중 {recentClear}명이 서명을 완료하였습니다.</Text> | |
83 | - </View></View> | |
84 | - </View> | |
85 | - <View style={styles.containerBottom}> | |
86 | - <Text style={styles.title}>서명 이력</Text> | |
87 | - <View> | |
88 | - <FlatList | |
89 | - data={list} | |
90 | - renderItem={({item}) => ( | |
91 | - <ListItem name="HomeScreen" item={item} /> | |
92 | - )} | |
93 | - // windowSize={5} | |
94 | - ListHeaderComponent={View} | |
95 | - /> | |
96 | - </View> | |
97 | - </View> | |
98 | - </View> | |
99 | - ); | |
100 | -}; | |
101 | -const styles = StyleSheet.create({ | |
102 | - container: { | |
103 | - backgroundColor: WHITE, | |
104 | - flex:1, | |
105 | - }, | |
106 | - containerTop: { | |
107 | - | |
108 | - }, | |
109 | - mydocs: { | |
110 | - flexDirection: 'row', | |
111 | - borderWidth: 0.5, | |
112 | - borderColor: GRAY, | |
113 | - borderRadius: 10, | |
114 | - margin: 10, | |
115 | - padding:20, | |
116 | - }, | |
117 | - title: { | |
118 | - color: BLACK, | |
119 | - //marginTop: 5, | |
120 | - fontWeight: '900', | |
121 | - borderBottomWidth: 0.5, | |
122 | - borderBottomColor: BLACK, | |
123 | - paddingVertical: 5, | |
124 | - marginHorizontal:10, | |
125 | - }, | |
126 | -}); | |
127 | -export default HomeScreen; |
--- kogas_app/src/screens/ListDetailScreen.js
... | ... | @@ -1,156 +0,0 @@ |
1 | -import { FlatList, StyleSheet, Text, View, Button, Alert } from 'react-native'; | |
2 | -import { GRAY } from '../color'; | |
3 | -import DetailListItem from '../components/DetailListItem'; | |
4 | -import { useEffect, useState } from 'react'; | |
5 | -import { url } from '../url'; | |
6 | - | |
7 | -const ListDetailScreen = ({ route, navigation }) => { | |
8 | - const { document_id } = route.params; | |
9 | - const { document_name } = route.params; | |
10 | - const { name } = route.params; | |
11 | - const { main_department } = route.params; | |
12 | - const { reg_date } = route.params; | |
13 | - const { stage } = route.params; | |
14 | - const [user, setUser] = useState(''); | |
15 | - const [department, setDepartment] = useState(''); | |
16 | - const [list, setList] = useState([]); | |
17 | - const [actionType, setActionType] = useState(null); // 서명 완료, 승인, 반려 액션 타입 | |
18 | - | |
19 | - useEffect(() => { | |
20 | - // 세션 정보를 가져옴 | |
21 | - getSession(); | |
22 | - }, []); // 여기에서는 세션 정보를 한 번만 가져오도록 수정 | |
23 | - | |
24 | - // 세션 정보를 가져오는 함수 | |
25 | - const getSession = async () => { | |
26 | - try { | |
27 | - const response = await fetch(`${url}/`); // 세션 정보를 가져오는 엔드포인트로 변경 | |
28 | - if (response.ok) { | |
29 | - const data = await response.json(); | |
30 | - console.log('서버에서 받은 세션 정보listdetail:', data); | |
31 | - setUser(data.user); | |
32 | - setDepartment(data.department); | |
33 | - } else { | |
34 | - console.error('세션 정보를 가져오는 데 실패했습니다.'); | |
35 | - } | |
36 | - } catch (error) { | |
37 | - console.error('오류:', error); | |
38 | - } | |
39 | - }; | |
40 | - | |
41 | - useEffect(() => { | |
42 | - getList(); | |
43 | - }, []); | |
44 | - | |
45 | - const getList = async () => { | |
46 | - //await SInfo.getItem('SessionId', {}).then(sessionId => { | |
47 | - //if (sessionId) { | |
48 | - fetch(`${url}/show_sig`, { | |
49 | - method: 'POST', | |
50 | - body: JSON.stringify({ | |
51 | - document_id: document_id | |
52 | - }), | |
53 | - headers: { | |
54 | - 'Content-Type': 'application/json', | |
55 | - //Authorization: `Bearer ${sessionId}`, // 세션 아이디 사용 | |
56 | - }, | |
57 | - }) | |
58 | - .then(response => response.json()) | |
59 | - .then(data => { | |
60 | - console.log('listdetailpage:', data); | |
61 | - setList(data); | |
62 | - }) | |
63 | - .catch(error => { | |
64 | - console.error(error); | |
65 | - }); | |
66 | - //} else { | |
67 | - // console.log('세션 아이디 없음'); | |
68 | - //} | |
69 | - //}); | |
70 | - }; | |
71 | - | |
72 | - // user와 department 정보를 기반으로 stage 정보를 필터링 | |
73 | - const filteredItem = list.find(item => item.name === user && item.department === department); | |
74 | - | |
75 | - // 서명 완료, 승인, 반려 여부에 따라 액션 타입 설정 | |
76 | - useEffect(() => { | |
77 | - if (filteredItem) { | |
78 | - setActionType(filteredItem.status); | |
79 | - } | |
80 | - }, [filteredItem, actionType]); | |
81 | - | |
82 | - // 승인 또는 반려 버튼 클릭 시 | |
83 | - const handleApproveOrReject = (isApprove) => { | |
84 | - const message = isApprove ? '승인하시겠습니까?' : '반려하시겠습니까?'; | |
85 | - Alert.alert( | |
86 | - '알림', | |
87 | - message, | |
88 | - [ | |
89 | - { | |
90 | - text: '예', | |
91 | - onPress: () => { | |
92 | - // 승인 또는 반려 동작 처리 | |
93 | - if (isApprove) { | |
94 | - // 승인 처리 로직 | |
95 | - // ... | |
96 | - console.log('승인 처리'); | |
97 | - } else { | |
98 | - // 반려 처리 로직 | |
99 | - // ... | |
100 | - console.log('반려 처리'); | |
101 | - } | |
102 | - } | |
103 | - }, | |
104 | - { | |
105 | - text: '아니요', | |
106 | - style: 'cancel' | |
107 | - } | |
108 | - ] | |
109 | - ); | |
110 | - }; | |
111 | - | |
112 | - return ( | |
113 | - <View style={styles.container}> | |
114 | - <View> | |
115 | - <Text style={styles.title}>{stage}</Text> | |
116 | - <Text style={styles.title}>{document_name}</Text> | |
117 | - <Text style={styles.date}>기안자: {main_department} {name}</Text> | |
118 | - <Text style={styles.date}>기안일자: {reg_date}</Text> | |
119 | - </View> | |
120 | - <Button title={'문서 보기'} /> | |
121 | - <View> | |
122 | - <Text style={styles.v}>서명 정보</Text> | |
123 | - <FlatList | |
124 | - data={list} | |
125 | - renderItem={({ item }) => ( | |
126 | - <DetailListItem name="ListDetailScreen" item={item} /> | |
127 | - )} | |
128 | - windowSize={5} | |
129 | - ListHeaderComponent={View} | |
130 | - ListHeaderComponentStyle={{ height: 10 }} | |
131 | - /> | |
132 | - {actionType === 'Y' && ( | |
133 | - <Button title={'서명 완료'} /> | |
134 | - )} | |
135 | - {actionType === 'N' && ( | |
136 | - <View> | |
137 | - <Button title={'승인'} onPress={() => handleApproveOrReject(true)} /> | |
138 | - <Button title={'반려'} onPress={() => handleApproveOrReject(false)} /> | |
139 | - </View> | |
140 | - )} | |
141 | - {actionType === 'X' && ( | |
142 | - <Button title={'반려 처리'} /> | |
143 | - )} | |
144 | - </View> | |
145 | - </View> | |
146 | - ); | |
147 | -}; | |
148 | - | |
149 | -const styles = StyleSheet.create({ | |
150 | - v: { | |
151 | - marginTop: 10, | |
152 | - fontWeight: 'bold', | |
153 | - } | |
154 | -}); | |
155 | - | |
156 | -export default ListDetailScreen; |
--- kogas_app/src/screens/SettingsScreen.js
... | ... | @@ -1,102 +0,0 @@ |
1 | -import { Alert, StyleSheet, Switch, Text, View } from 'react-native'; | |
2 | -import PropTypes from 'prop-types'; | |
3 | -import { GRAY, PRIMARY, WHITE } from '../color'; | |
4 | -import { useState } from 'react'; | |
5 | -import Button from '../components/Button'; | |
6 | -import { url } from '../url'; | |
7 | - | |
8 | -const SettingsScreen = ({ navigation }) => { | |
9 | - const [alarm, setAlarm] = useState(false); | |
10 | - const [dark, setDark] = useState(false); | |
11 | - | |
12 | - const toggleSwitchAlarm = () => setAlarm((previousState) => !previousState); | |
13 | - const toggleSwitchDark = () => setDark((previousState) => !previousState); | |
14 | - | |
15 | - const handleLogout = () => { | |
16 | - fetch(`${url}/logout`, { | |
17 | - method: 'POST', | |
18 | - credentials: 'same-origin' | |
19 | - }) | |
20 | - .then((response) => { | |
21 | - console.log(response.status); | |
22 | - if (response.status === 200) { | |
23 | - navigation.navigate('Login'); | |
24 | - } else { | |
25 | - Alert.alert('로그아웃 실패'); | |
26 | - } | |
27 | - }) | |
28 | - .catch((error) => { | |
29 | - console.error('로그아웃 중 오류 발생:', error); | |
30 | - Alert.alert('로그아웃 중 오류가 발생했습니다.'); | |
31 | - }); | |
32 | - }; | |
33 | - | |
34 | - return ( | |
35 | - <View style={styles.container}> | |
36 | - <View style={styles.containerRadius}> | |
37 | - <View style={styles.textContainer}> | |
38 | - <Text style={styles.text}>알림 설정</Text> | |
39 | - <View style={styles.switchStyle}> | |
40 | - <Switch | |
41 | - trackColor={{ false: GRAY, true: PRIMARY.DEFAULT }} | |
42 | - thumbColor={WHITE} | |
43 | - ios_backgroundColor={GRAY} | |
44 | - onValueChange={toggleSwitchAlarm} | |
45 | - value={alarm} | |
46 | - /> | |
47 | - </View> | |
48 | - </View> | |
49 | - {alarm && ( | |
50 | - <View> | |
51 | - <Text>시간대별 알림 설정 여부</Text> | |
52 | - </View> | |
53 | - )} | |
54 | - <View style={styles.view}> | |
55 | - <Button title={'기기 등록'} onPress={() => {}} /> | |
56 | - </View> | |
57 | - <View style={styles.view}> | |
58 | - <Button title={'로그아웃'} onPress={handleLogout} /> | |
59 | - </View> | |
60 | - </View> | |
61 | - </View> | |
62 | - ); | |
63 | -}; | |
64 | - | |
65 | -SettingsScreen.propTypes = {}; | |
66 | - | |
67 | -const styles = StyleSheet.create({ | |
68 | - container: { | |
69 | - flex: 1, | |
70 | - }, | |
71 | - containerRadius: { | |
72 | - backgroundColor: WHITE, | |
73 | - flex: 1, | |
74 | - margin: 25, | |
75 | - borderRadius: 15, | |
76 | - }, | |
77 | - textContainer: { | |
78 | - position: 'relative', | |
79 | - justifyContent: 'center', | |
80 | - borderBottomWidth: 1, | |
81 | - borderColor: GRAY, | |
82 | - paddingVertical: 30, | |
83 | - }, | |
84 | - text: { | |
85 | - position: 'absolute', | |
86 | - left: 0, | |
87 | - fontSize: 20, | |
88 | - fontWeight: '600', | |
89 | - paddingHorizontal: 20, | |
90 | - }, | |
91 | - switchStyle: { | |
92 | - position: 'absolute', | |
93 | - right: 0, | |
94 | - paddingVertical: 20, | |
95 | - paddingHorizontal: 20, | |
96 | - }, | |
97 | - view: { | |
98 | - margin: 15, | |
99 | - }, | |
100 | -}); | |
101 | - | |
102 | -export default SettingsScreen; |
--- kogas_app/src/screens/SignInScreen.js
... | ... | @@ -1,166 +0,0 @@ |
1 | -import React, { useState, useRef, useEffect } from 'react'; | |
2 | -import { | |
3 | - View, | |
4 | - StyleSheet, | |
5 | - Text, | |
6 | - Keyboard, | |
7 | - Alert, | |
8 | - TouchableOpacity, | |
9 | - Image, | |
10 | - TouchableWithoutFeedback, | |
11 | -} from 'react-native'; | |
12 | -import Button from '../components/Button'; | |
13 | -import TextInput, { IconNames, ReturnKeyTypes } from '../components/TextInput'; | |
14 | -import PropTypes from 'prop-types'; | |
15 | -import {url} from '../url'; | |
16 | - | |
17 | -const SignInScreen = ({ navigation }) => { | |
18 | - const [id, setId] = useState(''); | |
19 | - const [password, setPassword] = useState(''); | |
20 | - const passwordRef = useRef(null); | |
21 | - const [disabled, setDisabled] = useState(true); | |
22 | - const [isLoading, setIsLoading] = useState(false); | |
23 | - | |
24 | - useEffect(() => { | |
25 | - setDisabled(!id || !password); | |
26 | - }, [id, password]); | |
27 | - | |
28 | - const handleDismissKeyboard = () => { | |
29 | - Keyboard.dismiss(); | |
30 | - }; | |
31 | - | |
32 | -const onSubmit = async () => { | |
33 | - if (!disabled && !isLoading) { | |
34 | - Keyboard.dismiss(); | |
35 | - setIsLoading(true); | |
36 | - try { | |
37 | - fetch(`${url}/login`, { | |
38 | - method: 'POST', | |
39 | - body: JSON.stringify({ | |
40 | - username: id, | |
41 | - password: password, | |
42 | - }), | |
43 | - headers: { | |
44 | - 'Content-Type': 'application/json', | |
45 | - }, | |
46 | - }) | |
47 | - try { | |
48 | - //await SecureStore.setItemAsync('Token', token); | |
49 | - // 로그인 성공 후 메인 화면으로 이동 | |
50 | - console.log("성공") | |
51 | - Alert.alert('로그인 성공'); | |
52 | - try { | |
53 | - const response = await fetch(`${url}/`); // 세션 정보를 가져오는 엔드포인트로 변경 | |
54 | - if (response.ok) { | |
55 | - console.log('세션성공'); | |
56 | - navigation.navigate('Main'); | |
57 | - } else { | |
58 | - console.error('세션 정보를 가져오는 데 실패했습니다.'); | |
59 | - } | |
60 | - } catch (error) { | |
61 | - console.error('오류:', error); | |
62 | - } | |
63 | - } catch (e) { | |
64 | - console.log("실패") | |
65 | - Alert.alert('로그인 실패'); | |
66 | - setIsLoading(false); | |
67 | - } | |
68 | - } catch (e) { | |
69 | - console.log("실패") | |
70 | - Alert.alert('로그인 실패', e, [ | |
71 | - { | |
72 | - text: 'Ok', | |
73 | - onPress: () => setIsLoading(false), | |
74 | - }, | |
75 | - ]); | |
76 | - } | |
77 | - } | |
78 | - }; | |
79 | - | |
80 | - | |
81 | - return ( | |
82 | - <TouchableWithoutFeedback onPress={handleDismissKeyboard}> | |
83 | - <View style={styles.container}> | |
84 | - <View style={styles.titleContainer}> | |
85 | - <Image source={require('../img/logo.png')} style={styles.image} /> | |
86 | - <Text | |
87 | - style={[styles.textContainer, {alignSelf: 'center'}]}> | |
88 | - 스마트 전자서명 시스템 | |
89 | - </Text> | |
90 | - </View> | |
91 | - <View style={styles.viewContainer}> | |
92 | - <TextInput | |
93 | - value={id} | |
94 | - onChangeText={text => setId(text.trim())} | |
95 | - placeholder={'아이디'} | |
96 | - returnKeyType={ReturnKeyTypes.NEXT} | |
97 | - iconName={IconNames.ID} | |
98 | - onSubmitEditing={() => passwordRef.current.focus()} | |
99 | - /> | |
100 | - <TextInput | |
101 | - ref={passwordRef} | |
102 | - value={password} | |
103 | - onChangeText={text => setPassword(text.trim())} | |
104 | - placeholder={'비밀번호'} | |
105 | - secureTextEntry | |
106 | - iconName={IconNames.PASSWORD} | |
107 | - onSubmitEditing={onSubmit} | |
108 | - /> | |
109 | - <View style={styles.buttonContainer}> | |
110 | - <Button | |
111 | - title={'로그인'} | |
112 | - onPress={onSubmit} | |
113 | - disabled={disabled} | |
114 | - isLoading={isLoading} | |
115 | - /> | |
116 | - </View> | |
117 | - </View> | |
118 | - </View> | |
119 | - </TouchableWithoutFeedback> | |
120 | - ); | |
121 | -}; | |
122 | - | |
123 | -SignInScreen.propTypes = { | |
124 | - navigation: PropTypes.object, | |
125 | -}; | |
126 | - | |
127 | -const styles = StyleSheet.create({ | |
128 | - container: { | |
129 | - flex: 1, | |
130 | - paddingTop: 20, | |
131 | - justifyContent: 'flex-start', | |
132 | - alignItems: 'center', | |
133 | - }, | |
134 | - titleContainer: { | |
135 | - width: '100%', | |
136 | - flex: 1, | |
137 | - justifyContent: 'center', | |
138 | - alignItems: 'center', | |
139 | - marginTop: 50, | |
140 | - }, | |
141 | - image: { | |
142 | - flex: 1, | |
143 | - width: '60%', | |
144 | - resizeMode: 'contain', | |
145 | - justifyContent: 'flex-end', | |
146 | - alignItems: 'center', | |
147 | - }, | |
148 | - viewContainer: { | |
149 | - flex: 2, | |
150 | - width: '90%', | |
151 | - }, | |
152 | - buttonContainer: { | |
153 | - padding: 5, | |
154 | - marginTop: 10, | |
155 | - }, | |
156 | - textContainer: { | |
157 | - flex: 1, | |
158 | - padding: 10, | |
159 | - alignItems: 'center', | |
160 | - fontSize: 30, | |
161 | - justifyContent: 'flex-start', | |
162 | - fontWeight: '900', | |
163 | - }, | |
164 | -}); | |
165 | - | |
166 | -export default SignInScreen; |
--- kogas_app/src/screens/SignatureScreen.js
... | ... | @@ -1,178 +0,0 @@ |
1 | -import React, { useState,useEffect } from 'react'; | |
2 | -import { View, Text, TouchableOpacity } from 'react-native'; | |
3 | -import { FlatList } from 'react-native-gesture-handler'; | |
4 | -import ListItem from '../components/ListItem'; | |
5 | -import { url } from '../url'; | |
6 | - | |
7 | -// 라디오 버튼 컴포넌트 | |
8 | -const RadioButton = ({ options, selectedOption, onSelect }) => { | |
9 | - return ( | |
10 | - <View style={{ flexDirection: 'row'}}> | |
11 | - {options.map((option, index) => ( | |
12 | - <TouchableOpacity | |
13 | - key={index} | |
14 | - onPress={() => { | |
15 | - onSelect(option,index); | |
16 | - }} | |
17 | - > | |
18 | - <View> | |
19 | - {/* 선택된 옵션에 따라 스타일 변경 */} | |
20 | - <Text | |
21 | - style={{ | |
22 | - fontSize: 16, | |
23 | - marginRight: 10, | |
24 | - color: selectedOption === option ? 'blue' : 'black', | |
25 | - }} | |
26 | - > | |
27 | - {option} | |
28 | - </Text> | |
29 | - </View> | |
30 | - </TouchableOpacity> | |
31 | - ))} | |
32 | - </View> | |
33 | - ); | |
34 | -}; | |
35 | - | |
36 | -// 예제 앱 | |
37 | -const SignatureScreen = () => { | |
38 | - //const [myList, setMyList] = useState([]); | |
39 | - //const [proceedingList, setProceedingList] = useState([]); | |
40 | - //const [doneList, setDoneList] = useState([]); | |
41 | - const [user, setUser] = useState(''); | |
42 | - const options = ['내 기안', '진행 문서', '완료 문서']; | |
43 | - const [selectedOption, setSelectedOption] = useState(null); | |
44 | - const [selectedList, setSelectedList] = useState([]); | |
45 | - useEffect(() => { | |
46 | - if (user !== '') { | |
47 | - if (selectedOption === null && options.length > 0) { | |
48 | - getMyDoc(); | |
49 | - setSelectedOption(options[0]); | |
50 | - } | |
51 | - } else { | |
52 | - console.log("user 없음") | |
53 | - } | |
54 | - }, [user,selectedList]); | |
55 | - | |
56 | - // 옵션 선택 시 호출되는 함수 | |
57 | - const handleSelect = (option,index) => { | |
58 | - setSelectedOption(option); | |
59 | - // 선택된 옵션에 따라 다른 리스트 데이터를 설정 | |
60 | - if (index === 0) { | |
61 | - getMyDoc(); | |
62 | - } else if (index === 1) { | |
63 | - getProceedingDoc(); | |
64 | - } else if (index === 2) { | |
65 | - getDoneDoc(); | |
66 | - } | |
67 | - }; | |
68 | - useEffect(() => { | |
69 | - // 세션 정보를 가져옴 | |
70 | - getSession(); | |
71 | - }, []); // 여기에서는 세션 정보를 한 번만 가져오도록 수정 | |
72 | - | |
73 | - // 세션 정보를 가져오는 함수 | |
74 | - const getSession = async () => { | |
75 | - try { | |
76 | - const response = await fetch(`${url}/`); // 세션 정보를 가져오는 엔드포인트로 변경 | |
77 | - if (response.ok) { | |
78 | - const data = await response.json(); | |
79 | - console.log('서버에서 받은 세션 정보signaturelist:', data); | |
80 | - setUser(data.user); | |
81 | - | |
82 | - } else { | |
83 | - console.error('세션 정보를 가져오는 데 실패했습니다.'); | |
84 | - } | |
85 | - } catch (error) { | |
86 | - console.error('오류:', error); | |
87 | - } | |
88 | - }; | |
89 | - | |
90 | -const getMyDoc = async () => { | |
91 | - console.log('mydoc user signaturelist:',user); | |
92 | - try { | |
93 | - const response = await fetch(`${url}/my_doc`, { | |
94 | - method: 'POST', | |
95 | - body: JSON.stringify({ | |
96 | - user_id: user, | |
97 | - }), | |
98 | - headers: { | |
99 | - 'Content-Type': 'application/json', | |
100 | - }, | |
101 | - }); | |
102 | - if (response.ok) { | |
103 | - const data = await response.json(); | |
104 | - console.log("my"+data); | |
105 | - setSelectedList(data); | |
106 | - } else { | |
107 | - console.error('mydoc 데이터를 가져오는 데 실패했습니다.',response); | |
108 | - } | |
109 | - } catch (error) { | |
110 | - console.error('mydoc 데이터를 가져오는 중 오류 발생:', error); | |
111 | - } | |
112 | -}; | |
113 | - | |
114 | -const getProceedingDoc = async () => { | |
115 | - try { | |
116 | - const response = await fetch(`${url}/trying_doc`, { | |
117 | - method: 'POST', | |
118 | - body: JSON.stringify({ | |
119 | - user_id: user, | |
120 | - }), | |
121 | - headers: { | |
122 | - 'Content-Type': 'application/json', | |
123 | - }, | |
124 | - }) | |
125 | - if (response.ok) { | |
126 | - const data = await response.json(); | |
127 | - console.log("proceed"+data); | |
128 | - //console.log('listpage:', data); | |
129 | - setSelectedList(data); | |
130 | - } else { | |
131 | - console.error('proceedingdoc 데이터를 가져오는 데 실패했습니다.'); | |
132 | - } | |
133 | - } catch (error) { | |
134 | - console.error('proceedingdoc 데이터를 가져오는 중 오류 발생:', error); | |
135 | - } | |
136 | - }; | |
137 | - | |
138 | -const getDoneDoc = async () => { | |
139 | - try { | |
140 | - const response = await fetch(`${url}/done_doc`, { | |
141 | - method: 'GET', | |
142 | - headers: { | |
143 | - 'Content-Type': 'application/json', | |
144 | - }, | |
145 | - }) | |
146 | - if (response.ok) { | |
147 | - const data = await response.json(); | |
148 | - //console.log('listpage:', data); | |
149 | - setSelectedList(data); | |
150 | - } else { | |
151 | - console.error('donedoc 데이터를 가져오는 데 실패했습니다.'); | |
152 | - } | |
153 | - } catch (error) { | |
154 | - console.error('donedoc 데이터를 가져오는 중 오류 발생:', error); | |
155 | - } | |
156 | -}; | |
157 | - return ( | |
158 | - <View> | |
159 | - {/* 라디오 버튼 컴포넌트 사용 */} | |
160 | - <RadioButton | |
161 | - options={options} | |
162 | - selectedOption={selectedOption} | |
163 | - onSelect={handleSelect} | |
164 | - /> | |
165 | - <FlatList | |
166 | - data={selectedList} | |
167 | - renderItem={({item}) => ( | |
168 | - <ListItem name="SignatureScreen" item={item} /> | |
169 | - )} | |
170 | - windowSize={5} | |
171 | - ListHeaderComponent={View} | |
172 | - ListHeaderComponentStyle={{height: 10}} | |
173 | - /> | |
174 | - </View> | |
175 | - ); | |
176 | -}; | |
177 | - | |
178 | -export default SignatureScreen; |
--- kogas_app/src/test/PdfOpen.js
... | ... | @@ -1,95 +0,0 @@ |
1 | -/** | |
2 | - * Copyright (c) 2017-present, Wonday (@wonday.org) | |
3 | - * All rights reserved. | |
4 | - * | |
5 | - * This source code is licensed under the MIT-style license found in the | |
6 | - * LICENSE file in the root directory of this source tree. | |
7 | - */ | |
8 | - | |
9 | -import React from 'react'; | |
10 | -import { StyleSheet, Dimensions, View } from 'react-native'; | |
11 | -import Pdf from 'react-native-pdf'; | |
12 | - | |
13 | -export default class PDFOpen extends React.Component { | |
14 | - render() { | |
15 | - const source = { uri: 'file://C:/Users/mycom/Desktop/KOGAS_APP/test.pdf', cache: false }; | |
16 | - //const source = require('./test.pdf'); // ios only | |
17 | - //const source = {uri:'bundle-assets://test.pdf' }; | |
18 | - //const source = {uri:'file:///sdcard/test.pdf'}; | |
19 | - //const source = {uri:"data:application/pdf;base64,JVBERi0xLjcKJc..."}; | |
20 | - //const source = {uri:"content://com.example.blobs/xxxxxxxx-...?offset=0&size=xxx"}; | |
21 | - //const source = {uri:"blob:xxxxxxxx-...?offset=0&size=xxx"}; | |
22 | - | |
23 | - return ( | |
24 | - <View style={styles.container}> | |
25 | ||
26 | - source={source} | |
27 | - onLoadComplete={(numberOfPages,filePath) => { | |
28 | - console.log(`Number of pages: ${numberOfPages}`); | |
29 | - }} | |
30 | - onPageChanged={(page,numberOfPages) => { | |
31 | - console.log(`Current page: ${page}`); | |
32 | - }} | |
33 | - onError={(error) => { | |
34 | - console.log(error); | |
35 | - }} | |
36 | - onPressLink={(uri) => { | |
37 | - console.log(`Link pressed: ${uri}`); | |
38 | - }} | |
39 | - style={styles.pdf}/> | |
40 | - </View> | |
41 | - ) | |
42 | - } | |
43 | -} | |
44 | - | |
45 | -const styles = StyleSheet.create({ | |
46 | - container: { | |
47 | - flex: 1, | |
48 | - justifyContent: 'flex-start', | |
49 | - alignItems: 'center', | |
50 | - marginTop: 25, | |
51 | - }, | |
52 | - pdf: { | |
53 | - flex:1, | |
54 | - width:Dimensions.get('window').width, | |
55 | - height:Dimensions.get('window').height, | |
56 | - } | |
57 | -}); | |
58 | - | |
59 | -// import React from 'react'; | |
60 | -// import { Text, View, Button } from 'react-native'; | |
61 | -// import { WebView } from 'react-native-webview'; | |
62 | - | |
63 | -// export default class PdfOpen extends React.Component { | |
64 | -// constructor(props) { | |
65 | -// super(props); | |
66 | -// this.state = { | |
67 | -// showPdfViewer: false, // 초기에 PDF 뷰어를 숨깁니다. | |
68 | -// }; | |
69 | -// } | |
70 | - | |
71 | -// // 버튼 클릭 시 PDF 뷰어를 보이도록 상태를 변경합니다. | |
72 | -// showPdfViewer = () => { | |
73 | -// this.setState({ showPdfViewer: true }); | |
74 | -// } | |
75 | - | |
76 | -// render() { | |
77 | -// // 상태에 따라 PDF 뷰어를 보이거나 숨깁니다. | |
78 | -// const pdfViewer = this.state.showPdfViewer ? ( | |
79 | -// <WebView | |
80 | -// source={{ uri: 'C:/Users/mycom/Desktop/aa.pdf' }} | |
81 | -// onError={(err) => console.log(err)} | |
82 | -// /> | |
83 | -// ) : null; | |
84 | - | |
85 | -// return ( | |
86 | -// <View> | |
87 | -// <Text>d</Text> | |
88 | -// {pdfViewer} | |
89 | -// {/* 버튼을 누르면 PDF 뷰어를 보이도록 합니다. */} | |
90 | -// <Button title="Show PDF" onPress={this.showPdfViewer} /> | |
91 | -// </View> | |
92 | -// ); | |
93 | -// } | |
94 | -// } | |
95 | - |
--- kogas_app/yarn.lock
+++ kogas_app/yarn.lock
... | ... | @@ -1702,6 +1702,19 @@ |
1702 | 1702 |
resolved "https://registry.npmjs.org/@react-native-community/masked-view/-/masked-view-0.1.11.tgz" |
1703 | 1703 |
integrity sha512-rQfMIGSR/1r/SyN87+VD8xHHzDYeHaJq6elOSCAD+0iLagXkSI2pfA0LmSXP21uw5i3em7GkkRjfJ8wpqWXZNw== |
1704 | 1704 |
|
1705 |
+"@react-native-firebase/[email protected]": |
|
1706 |
+ version "18.5.0" |
|
1707 |
+ resolved "https://registry.npmjs.org/@react-native-firebase/app/-/app-18.5.0.tgz" |
|
1708 |
+ integrity sha512-AhHQi5KFDlKZn/lH7rEYtLfpsGamEq+P/cXZWcNPcP0WGlmi++abk7Pxnn4MjnG7TNhEyG/C9uq//qb6VhXaZg== |
|
1709 |
+ dependencies: |
|
1710 |
+ opencollective-postinstall "^2.0.1" |
|
1711 |
+ superstruct "^0.6.2" |
|
1712 |
+ |
|
1713 |
+"@react-native-firebase/messaging@^18.5.0": |
|
1714 |
+ version "18.5.0" |
|
1715 |
+ resolved "https://registry.npmjs.org/@react-native-firebase/messaging/-/messaging-18.5.0.tgz" |
|
1716 |
+ integrity sha512-y1FApYxBMcygmbWBqUPFC+fCfvx6Yf6TdZewun7kPwx+S+tkYzoKx1IsXtxOXtqyJjCNEYirjFgNrs5SSd02zA== |
|
1717 |
+ |
|
1705 | 1718 |
"@react-native/assets-registry@^0.72.0": |
1706 | 1719 |
version "0.72.0" |
1707 | 1720 |
resolved "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.72.0.tgz" |
... | ... | @@ -2686,6 +2699,16 @@ |
2686 | 2699 |
strip-ansi "^6.0.1" |
2687 | 2700 |
wrap-ansi "^7.0.0" |
2688 | 2701 |
|
2702 |
+clone-deep@^2.0.1: |
|
2703 |
+ version "2.0.2" |
|
2704 |
+ resolved "https://registry.npmjs.org/clone-deep/-/clone-deep-2.0.2.tgz" |
|
2705 |
+ integrity sha512-SZegPTKjCgpQH63E+eN6mVEEPdQBOUzjyJm5Pora4lrwWRFS8I0QAxV/KD6vV/i0WuijHZWQC1fMsPEdxfdVCQ== |
|
2706 |
+ dependencies: |
|
2707 |
+ for-own "^1.0.0" |
|
2708 |
+ is-plain-object "^2.0.4" |
|
2709 |
+ kind-of "^6.0.0" |
|
2710 |
+ shallow-clone "^1.0.0" |
|
2711 |
+ |
|
2689 | 2712 |
clone-deep@^4.0.1: |
2690 | 2713 |
version "4.0.1" |
2691 | 2714 |
resolved "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz" |
... | ... | @@ -3646,6 +3669,23 @@ |
3646 | 3669 |
dependencies: |
3647 | 3670 |
is-callable "^1.1.3" |
3648 | 3671 |
|
3672 |
+for-in@^0.1.3: |
|
3673 |
+ version "0.1.8" |
|
3674 |
+ resolved "https://registry.npmjs.org/for-in/-/for-in-0.1.8.tgz" |
|
3675 |
+ integrity sha512-F0to7vbBSHP8E3l6dCjxNOLuSFAACIxFy3UehTUlG7svlXi37HHsDkyVcHo0Pq8QwrE+pXvWSVX3ZT1T9wAZ9g== |
|
3676 |
+ |
|
3677 |
+for-in@^1.0.1: |
|
3678 |
+ version "1.0.2" |
|
3679 |
+ resolved "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz" |
|
3680 |
+ integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== |
|
3681 |
+ |
|
3682 |
+for-own@^1.0.0: |
|
3683 |
+ version "1.0.0" |
|
3684 |
+ resolved "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz" |
|
3685 |
+ integrity sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg== |
|
3686 |
+ dependencies: |
|
3687 |
+ for-in "^1.0.1" |
|
3688 |
+ |
|
3649 | 3689 |
form-data@^4.0.0: |
3650 | 3690 |
version "4.0.0" |
3651 | 3691 |
resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz" |
... | ... | @@ -4043,6 +4083,11 @@ |
4043 | 4083 |
version "0.3.1" |
4044 | 4084 |
resolved "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz" |
4045 | 4085 |
integrity sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw== |
4086 |
+ |
|
4087 |
+is-extendable@^0.1.1: |
|
4088 |
+ version "0.1.1" |
|
4089 |
+ resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz" |
|
4090 |
+ integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== |
|
4046 | 4091 |
|
4047 | 4092 |
is-extglob@^2.1.1: |
4048 | 4093 |
version "2.1.1" |
... | ... | @@ -4798,7 +4843,12 @@ |
4798 | 4843 |
dependencies: |
4799 | 4844 |
json-buffer "3.0.1" |
4800 | 4845 |
|
4801 |
-kind-of@^6.0.2: |
|
4846 |
+kind-of@^5.0.0: |
|
4847 |
+ version "5.1.0" |
|
4848 |
+ resolved "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz" |
|
4849 |
+ integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== |
|
4850 |
+ |
|
4851 |
+kind-of@^6.0.0, kind-of@^6.0.1, kind-of@^6.0.2: |
|
4802 | 4852 |
version "6.0.3" |
4803 | 4853 |
resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz" |
4804 | 4854 |
integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== |
... | ... | @@ -5527,6 +5577,14 @@ |
5527 | 5577 |
resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" |
5528 | 5578 |
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== |
5529 | 5579 |
|
5580 |
+mixin-object@^2.0.1: |
|
5581 |
+ version "2.0.1" |
|
5582 |
+ resolved "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz" |
|
5583 |
+ integrity sha512-ALGF1Jt9ouehcaXaHhn6t1yGWRqGaHkPFndtFVHfZXOvkIZ/yoGaSi0AHVTafb3ZBGg4dr/bDwnaEKqCXzchMA== |
|
5584 |
+ dependencies: |
|
5585 |
+ for-in "^0.1.3" |
|
5586 |
+ is-extendable "^0.1.1" |
|
5587 |
+ |
|
5530 | 5588 |
mkdirp@^0.5.1: |
5531 | 5589 |
version "0.5.6" |
5532 | 5590 |
resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz" |
... | ... | @@ -5746,6 +5804,11 @@ |
5746 | 5804 |
integrity sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg== |
5747 | 5805 |
dependencies: |
5748 | 5806 |
is-wsl "^1.1.0" |
5807 |
+ |
|
5808 |
+opencollective-postinstall@^2.0.1: |
|
5809 |
+ version "2.0.3" |
|
5810 |
+ resolved "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz" |
|
5811 |
+ integrity sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q== |
|
5749 | 5812 |
|
5750 | 5813 |
optionator@^0.9.3: |
5751 | 5814 |
version "0.9.3" |
... | ... | @@ -6549,6 +6612,15 @@ |
6549 | 6612 |
resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" |
6550 | 6613 |
integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== |
6551 | 6614 |
|
6615 |
+shallow-clone@^1.0.0: |
|
6616 |
+ version "1.0.0" |
|
6617 |
+ resolved "https://registry.npmjs.org/shallow-clone/-/shallow-clone-1.0.0.tgz" |
|
6618 |
+ integrity sha512-oeXreoKR/SyNJtRJMAKPDSvd28OqEwG4eR/xc856cRGBII7gX9lvAqDxusPm0846z/w/hWYjI1NpKwJ00NHzRA== |
|
6619 |
+ dependencies: |
|
6620 |
+ is-extendable "^0.1.1" |
|
6621 |
+ kind-of "^5.0.0" |
|
6622 |
+ mixin-object "^2.0.1" |
|
6623 |
+ |
|
6552 | 6624 |
shallow-clone@^3.0.0: |
6553 | 6625 |
version "3.0.1" |
6554 | 6626 |
resolved "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz" |
... | ... | @@ -6822,6 +6894,14 @@ |
6822 | 6894 |
resolved "https://registry.npmjs.org/sudo-prompt/-/sudo-prompt-9.2.1.tgz" |
6823 | 6895 |
integrity sha512-Mu7R0g4ig9TUuGSxJavny5Rv0egCEtpZRNMrZaYS1vxkiIxGiGUwoezU3LazIQ+KE04hTrTfNPgxU5gzi7F5Pw== |
6824 | 6896 |
|
6897 |
+superstruct@^0.6.2: |
|
6898 |
+ version "0.6.2" |
|
6899 |
+ resolved "https://registry.npmjs.org/superstruct/-/superstruct-0.6.2.tgz" |
|
6900 |
+ integrity sha512-lvA97MFAJng3rfjcafT/zGTSWm6Tbpk++DP6It4Qg7oNaeM+2tdJMuVgGje21/bIpBEs6iQql1PJH6dKTjl4Ig== |
|
6901 |
+ dependencies: |
|
6902 |
+ clone-deep "^2.0.1" |
|
6903 |
+ kind-of "^6.0.1" |
|
6904 |
+ |
|
6825 | 6905 |
supports-color@^5.3.0: |
6826 | 6906 |
version "5.5.0" |
6827 | 6907 |
resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?