front-boilerplate 설정
This commit is contained in:
parent
4f6510a031
commit
3a639e9a38
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"singleQuote": true,
|
||||
"semi": true,
|
||||
"useTabs": false,
|
||||
"tabWidth": 2,
|
||||
"trailingComma": "all",
|
||||
"printWidth": 80
|
||||
}
|
|
@ -1,24 +1,18 @@
|
|||
{
|
||||
"name": "tuya-admin-front-2",
|
||||
"version": "0.1.0",
|
||||
"name": "front-boilerplate",
|
||||
"version": "0.0.1",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "tuya-admin-front-2",
|
||||
"version": "0.1.0",
|
||||
"name": "front-boilerplate",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"@sdt/sdt-ui-kit": "^0.1.17",
|
||||
"@sdt/sdt-ui-kit": "^0.1.20",
|
||||
"@tanstack/react-query": "^4.33.0",
|
||||
"@tanstack/react-query-devtools": "^4.33.0",
|
||||
"@types/lodash": "^4.14.197",
|
||||
"@types/node": "20.5.1",
|
||||
"@types/qs": "^6.9.7",
|
||||
"@types/react": "18.2.20",
|
||||
"@types/react-dom": "18.2.7",
|
||||
"@types/react-modal": "^3.16.0",
|
||||
"autoprefixer": "10.4.15",
|
||||
"axios": "^1.4.0",
|
||||
"cookies-next": "^3.0.0",
|
||||
"eslint": "8.47.0",
|
||||
"eslint-config-next": "13.4.19",
|
||||
"lodash": "^4.17.21",
|
||||
|
@ -36,6 +30,13 @@
|
|||
"zustand": "^4.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tanstack/react-query-devtools": "^4.33.0",
|
||||
"@types/lodash": "^4.14.197",
|
||||
"@types/node": "20.5.1",
|
||||
"@types/qs": "^6.9.7",
|
||||
"@types/react": "18.2.20",
|
||||
"@types/react-dom": "18.2.7",
|
||||
"@types/react-modal": "^3.16.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.4.1",
|
||||
"@typescript-eslint/parser": "^6.4.1",
|
||||
"eslint-config-next": "13.4.19",
|
||||
|
@ -3138,9 +3139,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/@sdt/sdt-ui-kit": {
|
||||
"version": "0.1.17",
|
||||
"resolved": "http://192.168.1.232:8081/repository/npm-hosted/@sdt/sdt-ui-kit/-/sdt-ui-kit-0.1.17.tgz",
|
||||
"integrity": "sha512-jf8xCO+Dlo/pMMXQxmXFzwguCYKEIgsBg1knZ/XWScAKvnQfpABEB3jo9+vAvEQ+gdteg2L+xIcuaCceJk/NAQ==",
|
||||
"version": "0.1.20",
|
||||
"resolved": "http://192.168.1.232:8081/repository/npm-hosted/@sdt/sdt-ui-kit/-/sdt-ui-kit-0.1.20.tgz",
|
||||
"integrity": "sha512-vqRWbeDioEGgvgT2lDsQl13kPT/pX8N0NMk9FqN9W6+UIT/ZNP/uDvmVqnJyjQmC+xd5j/yJ5hwkuP0joVfqEQ==",
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
|
@ -3176,6 +3177,7 @@
|
|||
"version": "8.8.4",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/match-sorter-utils/-/match-sorter-utils-8.8.4.tgz",
|
||||
"integrity": "sha512-rKH8LjZiszWEvmi01NR72QWZ8m4xmXre0OOwlRGnjU01Eqz/QnN+cqpty2PJ0efHblq09+KilvyR7lsbzmXVEw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"remove-accents": "0.4.2"
|
||||
},
|
||||
|
@ -3226,6 +3228,7 @@
|
|||
"version": "4.33.0",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-4.33.0.tgz",
|
||||
"integrity": "sha512-6gegkuDmOoiY5e6ZKj1id48vlCXchjfE/6tIpYO8dFlVMQ7t1bYna/Ce6qQJ69+kfEHbYiTTn2lj+FDjIBH7Hg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@tanstack/match-sorter-utils": "^8.7.0",
|
||||
"superjson": "^1.10.0",
|
||||
|
@ -3326,12 +3329,14 @@
|
|||
"node_modules/@types/lodash": {
|
||||
"version": "4.14.197",
|
||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.197.tgz",
|
||||
"integrity": "sha512-BMVOiWs0uNxHVlHBgzTIqJYmj+PgCo4euloGF+5m4okL3rEYzM2EEv78mw8zWSMM57dM7kVIgJ2QDvwHSoCI5g=="
|
||||
"integrity": "sha512-BMVOiWs0uNxHVlHBgzTIqJYmj+PgCo4euloGF+5m4okL3rEYzM2EEv78mw8zWSMM57dM7kVIgJ2QDvwHSoCI5g==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.1.tgz",
|
||||
"integrity": "sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg=="
|
||||
"integrity": "sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/parse-json": {
|
||||
"version": "4.0.0",
|
||||
|
@ -3346,7 +3351,8 @@
|
|||
"node_modules/@types/qs": {
|
||||
"version": "6.9.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
|
||||
"integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw=="
|
||||
"integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/react": {
|
||||
"version": "18.2.20",
|
||||
|
@ -3362,6 +3368,7 @@
|
|||
"version": "18.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.7.tgz",
|
||||
"integrity": "sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
|
@ -3386,6 +3393,7 @@
|
|||
"version": "3.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-modal/-/react-modal-3.16.0.tgz",
|
||||
"integrity": "sha512-iphdqXAyUfByLbxJn5j6d+yh93dbMgshqGP0IuBeaKbZXx0aO+OXsvEkt6QctRdxjeM9/bR+Gp3h9F9djVWTQQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
|
@ -4262,10 +4270,39 @@
|
|||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/cookies-next": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cookies-next/-/cookies-next-3.0.0.tgz",
|
||||
"integrity": "sha512-VaSrsjQJ8yHnGAGulV9zJxBr7hrKJ/O2mo87evsGIMF7XvJI3AJNguevotx0Gek1MMMBkZvZNWu2JueSNoSKEQ==",
|
||||
"dependencies": {
|
||||
"@types/cookie": "^0.4.1",
|
||||
"@types/node": "^16.10.2",
|
||||
"cookie": "^0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cookies-next/node_modules/@types/cookie": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz",
|
||||
"integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q=="
|
||||
},
|
||||
"node_modules/cookies-next/node_modules/@types/node": {
|
||||
"version": "16.18.48",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.48.tgz",
|
||||
"integrity": "sha512-mlaecDKQ7rIZrYD7iiKNdzFb6e/qD5I9U1rAhq+Fd+DWvYVs+G2kv74UFHmSOlg5+i/vF3XxuR522V4u8BqO+Q=="
|
||||
},
|
||||
"node_modules/cookies-next/node_modules/cookie": {
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
|
||||
"integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/copy-anything": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz",
|
||||
"integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-what": "^4.1.8"
|
||||
},
|
||||
|
@ -6264,6 +6301,7 @@
|
|||
"version": "4.1.15",
|
||||
"resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.15.tgz",
|
||||
"integrity": "sha512-uKua1wfy3Yt+YqsD6mTUEa2zSi3G1oPlqTflgaPJ7z63vUGN5pxFpnQfeSLMFnJDEsdvOtkp1rUWkYjB4YfhgA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12.13"
|
||||
},
|
||||
|
@ -7500,7 +7538,8 @@
|
|||
"node_modules/remove-accents": {
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz",
|
||||
"integrity": "sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA=="
|
||||
"integrity": "sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/resolve": {
|
||||
"version": "1.22.4",
|
||||
|
@ -8041,6 +8080,7 @@
|
|||
"version": "1.13.1",
|
||||
"resolved": "https://registry.npmjs.org/superjson/-/superjson-1.13.1.tgz",
|
||||
"integrity": "sha512-AVH2eknm9DEd3qvxM4Sq+LTCkSXE2ssfh1t11MHMXyYXFQyQ1HLgVvV+guLTsaQnJU3gnaVo34TohHPulY/wLg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"copy-anything": "^3.0.2"
|
||||
},
|
||||
|
@ -10716,9 +10756,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"@sdt/sdt-ui-kit": {
|
||||
"version": "0.1.17",
|
||||
"resolved": "http://192.168.1.232:8081/repository/npm-hosted/@sdt/sdt-ui-kit/-/sdt-ui-kit-0.1.17.tgz",
|
||||
"integrity": "sha512-jf8xCO+Dlo/pMMXQxmXFzwguCYKEIgsBg1knZ/XWScAKvnQfpABEB3jo9+vAvEQ+gdteg2L+xIcuaCceJk/NAQ==",
|
||||
"version": "0.1.20",
|
||||
"resolved": "http://192.168.1.232:8081/repository/npm-hosted/@sdt/sdt-ui-kit/-/sdt-ui-kit-0.1.20.tgz",
|
||||
"integrity": "sha512-vqRWbeDioEGgvgT2lDsQl13kPT/pX8N0NMk9FqN9W6+UIT/ZNP/uDvmVqnJyjQmC+xd5j/yJ5hwkuP0joVfqEQ==",
|
||||
"requires": {
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
|
@ -10749,6 +10789,7 @@
|
|||
"version": "8.8.4",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/match-sorter-utils/-/match-sorter-utils-8.8.4.tgz",
|
||||
"integrity": "sha512-rKH8LjZiszWEvmi01NR72QWZ8m4xmXre0OOwlRGnjU01Eqz/QnN+cqpty2PJ0efHblq09+KilvyR7lsbzmXVEw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"remove-accents": "0.4.2"
|
||||
}
|
||||
|
@ -10771,6 +10812,7 @@
|
|||
"version": "4.33.0",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-4.33.0.tgz",
|
||||
"integrity": "sha512-6gegkuDmOoiY5e6ZKj1id48vlCXchjfE/6tIpYO8dFlVMQ7t1bYna/Ce6qQJ69+kfEHbYiTTn2lj+FDjIBH7Hg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@tanstack/match-sorter-utils": "^8.7.0",
|
||||
"superjson": "^1.10.0",
|
||||
|
@ -10864,12 +10906,14 @@
|
|||
"@types/lodash": {
|
||||
"version": "4.14.197",
|
||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.197.tgz",
|
||||
"integrity": "sha512-BMVOiWs0uNxHVlHBgzTIqJYmj+PgCo4euloGF+5m4okL3rEYzM2EEv78mw8zWSMM57dM7kVIgJ2QDvwHSoCI5g=="
|
||||
"integrity": "sha512-BMVOiWs0uNxHVlHBgzTIqJYmj+PgCo4euloGF+5m4okL3rEYzM2EEv78mw8zWSMM57dM7kVIgJ2QDvwHSoCI5g==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "20.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.1.tgz",
|
||||
"integrity": "sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg=="
|
||||
"integrity": "sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/parse-json": {
|
||||
"version": "4.0.0",
|
||||
|
@ -10884,7 +10928,8 @@
|
|||
"@types/qs": {
|
||||
"version": "6.9.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
|
||||
"integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw=="
|
||||
"integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/react": {
|
||||
"version": "18.2.20",
|
||||
|
@ -10900,6 +10945,7 @@
|
|||
"version": "18.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.7.tgz",
|
||||
"integrity": "sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
|
@ -10924,6 +10970,7 @@
|
|||
"version": "3.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-modal/-/react-modal-3.16.0.tgz",
|
||||
"integrity": "sha512-iphdqXAyUfByLbxJn5j6d+yh93dbMgshqGP0IuBeaKbZXx0aO+OXsvEkt6QctRdxjeM9/bR+Gp3h9F9djVWTQQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
|
@ -11505,10 +11552,38 @@
|
|||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
|
||||
"integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw=="
|
||||
},
|
||||
"cookies-next": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cookies-next/-/cookies-next-3.0.0.tgz",
|
||||
"integrity": "sha512-VaSrsjQJ8yHnGAGulV9zJxBr7hrKJ/O2mo87evsGIMF7XvJI3AJNguevotx0Gek1MMMBkZvZNWu2JueSNoSKEQ==",
|
||||
"requires": {
|
||||
"@types/cookie": "^0.4.1",
|
||||
"@types/node": "^16.10.2",
|
||||
"cookie": "^0.4.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/cookie": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz",
|
||||
"integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q=="
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "16.18.48",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.48.tgz",
|
||||
"integrity": "sha512-mlaecDKQ7rIZrYD7iiKNdzFb6e/qD5I9U1rAhq+Fd+DWvYVs+G2kv74UFHmSOlg5+i/vF3XxuR522V4u8BqO+Q=="
|
||||
},
|
||||
"cookie": {
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
|
||||
"integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"copy-anything": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz",
|
||||
"integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-what": "^4.1.8"
|
||||
}
|
||||
|
@ -12961,7 +13036,8 @@
|
|||
"is-what": {
|
||||
"version": "4.1.15",
|
||||
"resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.15.tgz",
|
||||
"integrity": "sha512-uKua1wfy3Yt+YqsD6mTUEa2zSi3G1oPlqTflgaPJ7z63vUGN5pxFpnQfeSLMFnJDEsdvOtkp1rUWkYjB4YfhgA=="
|
||||
"integrity": "sha512-uKua1wfy3Yt+YqsD6mTUEa2zSi3G1oPlqTflgaPJ7z63vUGN5pxFpnQfeSLMFnJDEsdvOtkp1rUWkYjB4YfhgA==",
|
||||
"dev": true
|
||||
},
|
||||
"is-wsl": {
|
||||
"version": "2.2.0",
|
||||
|
@ -13795,7 +13871,8 @@
|
|||
"remove-accents": {
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz",
|
||||
"integrity": "sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA=="
|
||||
"integrity": "sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA==",
|
||||
"dev": true
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.22.4",
|
||||
|
@ -14157,6 +14234,7 @@
|
|||
"version": "1.13.1",
|
||||
"resolved": "https://registry.npmjs.org/superjson/-/superjson-1.13.1.tgz",
|
||||
"integrity": "sha512-AVH2eknm9DEd3qvxM4Sq+LTCkSXE2ssfh1t11MHMXyYXFQyQ1HLgVvV+guLTsaQnJU3gnaVo34TohHPulY/wLg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"copy-anything": "^3.0.2"
|
||||
}
|
||||
|
|
21
package.json
21
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "tuya-admin-front",
|
||||
"version": "0.1.0",
|
||||
"name": "front-boilerplate",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
@ -9,17 +9,11 @@
|
|||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@sdt/sdt-ui-kit": "^0.1.17",
|
||||
"@sdt/sdt-ui-kit": "^0.1.20",
|
||||
"@tanstack/react-query": "^4.33.0",
|
||||
"@tanstack/react-query-devtools": "^4.33.0",
|
||||
"@types/lodash": "^4.14.197",
|
||||
"@types/node": "20.5.1",
|
||||
"@types/qs": "^6.9.7",
|
||||
"@types/react": "18.2.20",
|
||||
"@types/react-dom": "18.2.7",
|
||||
"@types/react-modal": "^3.16.0",
|
||||
"autoprefixer": "10.4.15",
|
||||
"axios": "^1.4.0",
|
||||
"cookies-next": "^3.0.0",
|
||||
"eslint": "8.47.0",
|
||||
"eslint-config-next": "13.4.19",
|
||||
"lodash": "^4.17.21",
|
||||
|
@ -37,6 +31,13 @@
|
|||
"zustand": "^4.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tanstack/react-query-devtools": "^4.33.0",
|
||||
"@types/lodash": "^4.14.197",
|
||||
"@types/node": "20.5.1",
|
||||
"@types/qs": "^6.9.7",
|
||||
"@types/react": "18.2.20",
|
||||
"@types/react-dom": "18.2.7",
|
||||
"@types/react-modal": "^3.16.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.4.1",
|
||||
"@typescript-eslint/parser": "^6.4.1",
|
||||
"eslint-config-next": "13.4.19",
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
import {
|
||||
ACCESS_TOKEN_NAME,
|
||||
getCookie,
|
||||
REFREASH_TOKEN_NAME,
|
||||
removeCookie,
|
||||
} from '../utils/cookies';
|
||||
import { ACCESS_TOKEN_NAME, REFREASH_TOKEN_NAME } from '@/utils';
|
||||
import { deleteCookie, getCookie } from 'cookies-next';
|
||||
import { setToken } from '../utils/setToken';
|
||||
import axios, { AxiosRequestConfig, Method } from 'axios';
|
||||
import { silentSignInApi } from './oauth';
|
||||
|
@ -55,6 +51,7 @@ export const fetchApi = ({
|
|||
defaultInstance.interceptors.request.use(
|
||||
(req: any) => {
|
||||
// console.log('######## req interceptors', req);
|
||||
// todo fix
|
||||
const SDT_AT = getCookie(ACCESS_TOKEN_NAME);
|
||||
|
||||
if (noToken) {
|
||||
|
@ -101,9 +98,9 @@ export const fetchApi = ({
|
|||
originalRequest.headers['Authorization'] = `Bearer ${accessToken}`;
|
||||
return fetchApi({ ...originalRequest });
|
||||
} else {
|
||||
removeCookie(REFREASH_TOKEN_NAME);
|
||||
removeCookie(ACCESS_TOKEN_NAME);
|
||||
return (window.location.href = `${process.env.NEXT_PUBLIC_CLOUD_CONSOLE_PATH}/login?redirect=${window.location.href}`);
|
||||
deleteCookie(REFREASH_TOKEN_NAME);
|
||||
deleteCookie(ACCESS_TOKEN_NAME);
|
||||
return (window.location.href = `/login`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { getCookie, REFREASH_TOKEN_NAME } from '../../utils/cookies';
|
||||
import { REFREASH_TOKEN_NAME } from '@/utils';
|
||||
import qs from 'qs';
|
||||
import { fetchApi, afterAxios } from '../config';
|
||||
import { getCookie } from 'cookies-next';
|
||||
|
||||
export interface SignInRequestType {
|
||||
email: string;
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
import "./globals.css";
|
||||
import type { Metadata } from "next";
|
||||
import QueryClientProvider from '@/utils/QueryClientProvider';
|
||||
import './globals.css';
|
||||
import type { Metadata } from 'next';
|
||||
import StyledComponentsRegistry from '@/utils/StyledComponentProvider/StyledComponentProvider';
|
||||
import Layout from '@/components/Layout';
|
||||
import { ACCESS_TOKEN_NAME } from '@/utils';
|
||||
import { defaultInstance } from '@/api/config';
|
||||
import { cookies } from 'next/headers';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Create Next App",
|
||||
description: "Generated by create next app",
|
||||
title: 'Create Next App',
|
||||
description: 'Generated by create next app',
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
|
@ -11,9 +17,21 @@ export default function RootLayout({
|
|||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const accessToken = cookies().get(ACCESS_TOKEN_NAME);
|
||||
|
||||
if (accessToken) {
|
||||
defaultInstance.defaults.headers.common.Authorization = `Bearer ${accessToken.value}`;
|
||||
}
|
||||
|
||||
return (
|
||||
<html>
|
||||
<body>{children}</body>
|
||||
<body>
|
||||
<QueryClientProvider>
|
||||
<StyledComponentsRegistry>
|
||||
<Layout>{children}</Layout>
|
||||
</StyledComponentsRegistry>
|
||||
</QueryClientProvider>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
export { default } from './Login';
|
|
@ -1,8 +1,8 @@
|
|||
"use client";
|
||||
import { Button, TextInput } from "@sdt/sdt-ui-kit";
|
||||
import Link from "next/link";
|
||||
import useLogin from "../hooks/useLogin";
|
||||
import { emailRegex, passwordRegex } from "@/utils/reg";
|
||||
'use client';
|
||||
import { Button, TextInput } from '@sdt/sdt-ui-kit';
|
||||
import Link from 'next/link';
|
||||
import useLogin from '../hooks/useLogin';
|
||||
import { emailRegex, passwordRegex } from '@/utils/reg';
|
||||
|
||||
interface LoginPropsType {}
|
||||
|
||||
|
@ -13,38 +13,36 @@ function Login({}: LoginPropsType) {
|
|||
return (
|
||||
<div className="flex justify-center items-center w-full h-screen bg-cover bg-center">
|
||||
<div className="w-[37.5rem] shadow-md border rounded-[16px] px-10 sm:px-14 lg:px-5 py-7 sm:py-9 flex flex-col justify-center">
|
||||
<h1 className="font-title-32 text-center">쿠폰 관리 시스템</h1>
|
||||
<form onSubmit={handleSubmit((data) => console.log(data))}>
|
||||
<div className="mt-5 flex flex-col">
|
||||
<TextInput
|
||||
{...register("email", {
|
||||
required: "이메일을 입력하세요.",
|
||||
{...register('email', {
|
||||
required: '이메일을 입력하세요.',
|
||||
pattern: {
|
||||
value: emailRegex,
|
||||
message: "올바른 이메일을 입력하세요.",
|
||||
message: '올바른 이메일을 입력하세요.',
|
||||
},
|
||||
})}
|
||||
error={!!formState.errors.email}
|
||||
message={(formState.errors.email?.message as string) ?? ""}
|
||||
message={(formState.errors.email?.message as string) ?? ''}
|
||||
maxLength={40}
|
||||
type="text"
|
||||
className={`rounded-t-[6px] text-[20px] w-full`}
|
||||
placeholder="이메일 주소"
|
||||
/>
|
||||
</div>
|
||||
ㄹㅁㄴ어래ㅑㅓㅐ
|
||||
<div className="flex flex-col">
|
||||
<TextInput
|
||||
{...register("password", {
|
||||
required: "비밀번호를 다시 입력하세요.",
|
||||
{...register('password', {
|
||||
required: '비밀번호를 다시 입력하세요.',
|
||||
pattern: {
|
||||
value: passwordRegex,
|
||||
message:
|
||||
"8~16자 영문 대 소문자, 숫자, 특수문자를 사용하세요.",
|
||||
'8~16자 영문 대 소문자, 숫자, 특수문자를 사용하세요.',
|
||||
},
|
||||
})}
|
||||
error={!!formState.errors.password?.message}
|
||||
message={(formState.errors.password?.message as string) ?? ""}
|
||||
message={(formState.errors.password?.message as string) ?? ''}
|
||||
maxLength={16}
|
||||
type="password"
|
||||
className={`rounded-b-[6px] text-[20px] w-full border-t-none`}
|
||||
|
@ -64,9 +62,7 @@ function Login({}: LoginPropsType) {
|
|||
|
||||
<div className="w-full mt-2 flex justify-center">
|
||||
<span className="mr-3 text-[#9e9e9e]">비밀번호를 잊으셨나요?</span>
|
||||
<Link href={"/reset-password"} className="text-teal-500">
|
||||
비밀번호 재설정
|
||||
</Link>
|
||||
<Link href={'/reset-password'}>비밀번호 재설정</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,10 +1,7 @@
|
|||
"use client";
|
||||
import StyledComponentsRegistry from "@/components/__common/StyledComponentProvider/StyledComponentProvider";
|
||||
|
||||
export default function LoginLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return <StyledComponentsRegistry>{children}</StyledComponentsRegistry>;
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
import React from 'react';
|
||||
import Login from './Login/Login';
|
||||
import Login from './components/Login';
|
||||
|
||||
function LoginPage() {
|
||||
return (
|
||||
<Login />
|
||||
);
|
||||
return <Login />;
|
||||
}
|
||||
|
||||
export default LoginPage;
|
|
@ -1,4 +1,4 @@
|
|||
import Image from 'next/image'
|
||||
import Image from 'next/image';
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
|
@ -109,5 +109,5 @@ export default function Home() {
|
|||
</a>
|
||||
</div>
|
||||
</main>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { useCallback, useEffect } from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
|
||||
import { useAlertStore } from '@/stores';
|
||||
import { usePathname } from 'next/navigation';
|
||||
|
||||
export function useAlert() {
|
||||
const {
|
||||
|
@ -10,7 +11,8 @@ export function useAlert() {
|
|||
setAlertClose,
|
||||
alertCallback,
|
||||
} = useAlertStore();
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
|
||||
/**
|
||||
* Alert Close Handler
|
||||
*/
|
||||
|
@ -29,7 +31,7 @@ export function useAlert() {
|
|||
setAlertClose();
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [router]);
|
||||
}, [pathname]);
|
||||
|
||||
return { alertOpen, alertContent, setAlertOpen, setAlertClose, onCloseAlert };
|
||||
}
|
|
@ -1,18 +1,15 @@
|
|||
import Head from 'next/head';
|
||||
'use client';
|
||||
|
||||
import useAlert from '../Alert/hooks/useAlert';
|
||||
import Alert from '../Alert';
|
||||
import useSilentAuth from '@/hooks/useSilentAuth';
|
||||
|
||||
export default function Layout({ children }: { children: React.ReactElement }) {
|
||||
export default function Layout({ children }: { children: React.ReactNode }) {
|
||||
const { alertOpen, alertContent, onCloseAlert } = useAlert();
|
||||
useSilentAuth();
|
||||
|
||||
return (
|
||||
<div className="w-full overflow-hidden">
|
||||
<Head>
|
||||
<title>BlokWorks</title>
|
||||
<meta name="description" content="BlokWorks" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
<div className="flex pt-14">
|
||||
<main className={`w-full p-12`}>{children}</main>
|
||||
</div>
|
|
@ -0,0 +1,46 @@
|
|||
import { useAuthStore } from '@/stores';
|
||||
import { ACCESS_TOKEN_NAME, REFREASH_TOKEN_NAME } from '@/utils';
|
||||
import { getCookie, deleteCookie } from 'cookies-next';
|
||||
import { usePathname, useRouter } from 'next/navigation';
|
||||
import { useCallback, useEffect } from 'react';
|
||||
|
||||
function useSilentAuth() {
|
||||
const router = useRouter();
|
||||
// todo fix
|
||||
const SDT_AT = getCookie(ACCESS_TOKEN_NAME) ?? '';
|
||||
const { loggedIn, setSignIn, setSignOut } = useAuthStore();
|
||||
const pathname = usePathname();
|
||||
|
||||
useEffect(() => {
|
||||
if (SDT_AT && !loggedIn) {
|
||||
setSignIn();
|
||||
}
|
||||
}, [SDT_AT, loggedIn, setSignIn]);
|
||||
|
||||
/**
|
||||
* handle Logout
|
||||
*/
|
||||
const handleLogout = useCallback(async () => {
|
||||
deleteCookie(ACCESS_TOKEN_NAME);
|
||||
deleteCookie(REFREASH_TOKEN_NAME);
|
||||
setSignOut();
|
||||
}, [setSignOut]);
|
||||
|
||||
/**
|
||||
* not Server redirect
|
||||
*/
|
||||
useEffect(() => {
|
||||
if (
|
||||
!loggedIn &&
|
||||
!SDT_AT &&
|
||||
!(pathname.includes('login') || pathname.includes('reset-password'))
|
||||
) {
|
||||
router.push(`/login`);
|
||||
handleLogout();
|
||||
}
|
||||
}, [SDT_AT, handleLogout, loggedIn, pathname, router, setSignOut]);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
export default useSilentAuth;
|
|
@ -1,20 +1,11 @@
|
|||
import { create } from 'zustand';
|
||||
import { devtools } from 'zustand/middleware';
|
||||
|
||||
export interface ProfileType {
|
||||
id: string;
|
||||
sub: string;
|
||||
iat: number;
|
||||
exp: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Auth State Type
|
||||
*/
|
||||
export interface AuthStateType {
|
||||
loggedIn: boolean;
|
||||
email: string | null;
|
||||
profile: ProfileType | null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -22,8 +13,7 @@ export interface AuthStateType {
|
|||
*/
|
||||
|
||||
export interface AuthActionType {
|
||||
setSignIn: (by: ProfileType) => void;
|
||||
setEmail: (by: string) => void;
|
||||
setSignIn: () => void;
|
||||
setSignOut: () => void;
|
||||
}
|
||||
|
||||
|
@ -33,19 +23,14 @@ export const useAuthStore = create<AuthStoreType>()(
|
|||
devtools(
|
||||
(set): AuthStoreType => ({
|
||||
loggedIn: false,
|
||||
email: null,
|
||||
profile: null,
|
||||
|
||||
setSignIn: (by: ProfileType) =>
|
||||
setSignIn: () =>
|
||||
set(() => ({
|
||||
profile: { ...by },
|
||||
loggedIn: true,
|
||||
})),
|
||||
setEmail: (by: string) => set(() => ({ email: by })),
|
||||
setSignOut: () =>
|
||||
set(() => ({
|
||||
loggedIn: false,
|
||||
email: null,
|
||||
})),
|
||||
}),
|
||||
{ name: 'auth' },
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import { QueryClientProvider, QueryClient } from '@tanstack/react-query';
|
||||
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
|
||||
|
||||
function Providers({ children }: React.PropsWithChildren) {
|
||||
const [client] = React.useState(new QueryClient());
|
||||
|
||||
return (
|
||||
<QueryClientProvider client={client}>
|
||||
{children}
|
||||
<ReactQueryDevtools initialIsOpen={false} />
|
||||
</QueryClientProvider>
|
||||
);
|
||||
}
|
||||
|
||||
export default Providers;
|
|
@ -0,0 +1 @@
|
|||
export { default } from './QueryClientProviider';
|
|
@ -1,7 +1,7 @@
|
|||
"use client";
|
||||
import React, { useState } from "react";
|
||||
import { useServerInsertedHTML } from "next/navigation";
|
||||
import { ServerStyleSheet, StyleSheetManager } from "styled-components";
|
||||
'use client';
|
||||
import React, { useState } from 'react';
|
||||
import { useServerInsertedHTML } from 'next/navigation';
|
||||
import { ServerStyleSheet, StyleSheetManager } from 'styled-components';
|
||||
|
||||
export default function StyledComponentsRegistry({
|
||||
children,
|
||||
|
@ -18,7 +18,7 @@ export default function StyledComponentsRegistry({
|
|||
return styles;
|
||||
});
|
||||
|
||||
if (typeof window !== "undefined") return <>{children}</>;
|
||||
if (typeof window !== 'undefined') return <>{children}</>;
|
||||
|
||||
return (
|
||||
<StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
|
|
@ -1,25 +0,0 @@
|
|||
import { Cookies } from 'react-cookie';
|
||||
import { CookieSetOptions } from 'universal-cookie';
|
||||
|
||||
const cookies = new Cookies();
|
||||
|
||||
export const REFREASH_TOKEN_NAME = 'SDT_RT';
|
||||
export const ACCESS_TOKEN_NAME = 'SDT_AT';
|
||||
|
||||
export const setCookie = (
|
||||
name: string,
|
||||
value: string,
|
||||
option: CookieSetOptions | undefined,
|
||||
) => {
|
||||
return cookies.set(name, value, { ...option });
|
||||
};
|
||||
|
||||
export const getCookie = (name: string) => {
|
||||
return cookies.get(name);
|
||||
};
|
||||
|
||||
export const removeCookie = (name: string) => {
|
||||
return cookies.remove(name, {
|
||||
path: '/',
|
||||
});
|
||||
};
|
|
@ -1,3 +1,2 @@
|
|||
export * from './cookies';
|
||||
export * from './setToken';
|
||||
export * from './reg';
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
import { SignInResponseType } from '../api/oauth';
|
||||
import { ACCESS_TOKEN_NAME, REFREASH_TOKEN_NAME, setCookie } from './cookies';
|
||||
import { setCookie } from 'cookies-next';
|
||||
|
||||
// todo fix
|
||||
export const REFREASH_TOKEN_NAME = 'SDT_RT';
|
||||
export const ACCESS_TOKEN_NAME = 'SDT_AT';
|
||||
|
||||
export function setToken(
|
||||
loginResponse: SignInResponseType,
|
||||
|
|
Loading…
Reference in New Issue