diff --git a/.env b/.env deleted file mode 100644 index 54ecf2a..0000000 --- a/.env +++ /dev/null @@ -1,5 +0,0 @@ -VITE_BASE_URL = localhost/api - -VITE_POST_BASE_URL = localhost/api/post - -VITE_USER_BASE_URL = localhost:80/api/member \ No newline at end of file diff --git a/.gitignore b/.gitignore index 8ee54e8..2a2b7ec 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ yarn-error.log* pnpm-debug.log* lerna-debug.log* +.env node_modules .DS_Store dist diff --git a/index.html b/index.html index 99f583a..5773335 100644 --- a/index.html +++ b/index.html @@ -2,12 +2,14 @@ - + - Vite App + Trively
+ + diff --git a/package-lock.json b/package-lock.json index 6d340a8..6abfc64 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,10 +8,19 @@ "name": "trively-front", "version": "0.0.0", "dependencies": { + "@vueuse/core": "^10.9.0", + "ant-design-vue": "^4.2.1", "axios": "^1.6.8", "bootstrap": "^5.3.3", + "jwt-decode": "^4.0.0", + "openai": "^4.47.1", + "pinia": "^2.1.7", + "pinia-plugin-persistedstate": "^3.2.1", + "sweetalert2": "^11.11.0", "vue": "^3.4.21", - "vue-router": "^4.3.0" + "vue-router": "^4.3.0", + "vue3-kakao-maps": "^2.3.9", + "vuedraggable": "^4.1.0" }, "devDependencies": { "@vitejs/plugin-vue": "^5.0.4", @@ -34,6 +43,31 @@ "node": ">=6.0.0" } }, + "node_modules/@ant-design/colors": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-6.0.0.tgz", + "integrity": "sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==", + "dependencies": { + "@ctrl/tinycolor": "^3.4.0" + } + }, + "node_modules/@ant-design/icons-svg": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.4.2.tgz", + "integrity": "sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==" + }, + "node_modules/@ant-design/icons-vue": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@ant-design/icons-vue/-/icons-vue-7.0.1.tgz", + "integrity": "sha512-eCqY2unfZK6Fe02AwFlDHLfoyEFreP6rBwAZMIJ1LugmfMiVgwWDYlp1YsRugaPtICYOabV1iWxXdP12u9U43Q==", + "dependencies": { + "@ant-design/colors": "^6.0.0", + "@ant-design/icons-svg": "^4.2.1" + }, + "peerDependencies": { + "vue": ">=3.0.3" + } + }, "node_modules/@antfu/utils": { "version": "0.7.8", "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-0.7.8.tgz", @@ -584,6 +618,17 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/runtime": { + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz", + "integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.24.0", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", @@ -642,6 +687,24 @@ "node": ">=6.9.0" } }, + "node_modules/@ctrl/tinycolor": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz", + "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" + }, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", @@ -1427,12 +1490,43 @@ "win32" ] }, + "node_modules/@simonwep/pickr": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@simonwep/pickr/-/pickr-1.8.2.tgz", + "integrity": "sha512-/l5w8BIkrpP6n1xsetx9MWPWlU6OblN5YgZZphxan0Tq4BByTCETL6lyIeY8lagalS2Nbt4F2W034KHLIiunKA==", + "dependencies": { + "core-js": "^3.15.1", + "nanopop": "^2.1.0" + } + }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, + "node_modules/@types/node": { + "version": "18.19.33", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.33.tgz", + "integrity": "sha512-NR9+KrpSajr2qBVp/Yt5TU/rp+b5Mayi3+OlMlcg2cVCfRmcG5PWZ7S4+MG9PZ5gWBoc9Pd0BKSRViuBCRPu0A==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/node-fetch": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", + "dependencies": { + "@types/node": "*", + "form-data": "^4.0.0" + } + }, + "node_modules/@types/web-bluetooth": { + "version": "0.0.20", + "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz", + "integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==" + }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", @@ -1577,13 +1671,13 @@ "integrity": "sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA==" }, "node_modules/@vue/devtools-core": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@vue/devtools-core/-/devtools-core-7.1.3.tgz", - "integrity": "sha512-pVbWi8pf2Z/fZPioYOIgu+cv9pQG55k4D8bL31ec+Wfe+pQR0ImFDu0OhHfch1Ra8uvLLrAZTF4IKeGAkmzD4A==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@vue/devtools-core/-/devtools-core-7.2.1.tgz", + "integrity": "sha512-OyWl455UnJIVgZ6lo5WQ79WbDMoXtSRwyNKp9WzCZ0HhuQywIk4qv59KtLRe75uVmtGBde4hXNaSyRm+x9bY6g==", "dev": true, "dependencies": { - "@vue/devtools-kit": "^7.1.3", - "@vue/devtools-shared": "^7.1.3", + "@vue/devtools-kit": "^7.2.1", + "@vue/devtools-shared": "^7.2.1", "mitt": "^3.0.1", "nanoid": "^3.3.4", "pathe": "^1.1.2", @@ -1591,12 +1685,12 @@ } }, "node_modules/@vue/devtools-kit": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.1.3.tgz", - "integrity": "sha512-NFskFSJMVCBXTkByuk2llzI3KD3Blcm7WqiRorWjD6nClHPgkH5BobDH08rfulqq5ocRt5xV+3qOT1Q9FXJrwQ==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.2.1.tgz", + "integrity": "sha512-Wak/fin1X0Q8LLIfCAHBrdaaB+R6IdpSXsDByPHbQ3BmkCP0/cIo/oEGp9i0U2+gEqD4L3V9RDjNf1S34DTzQQ==", "dev": true, "dependencies": { - "@vue/devtools-shared": "^7.1.3", + "@vue/devtools-shared": "^7.2.1", "hookable": "^5.5.3", "mitt": "^3.0.1", "perfect-debounce": "^1.0.0", @@ -1607,9 +1701,9 @@ } }, "node_modules/@vue/devtools-shared": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.1.3.tgz", - "integrity": "sha512-KJ3AfgjTn3tJz/XKF+BlVShNPecim3G21oHRue+YQOsooW+0s+qXvm09U09aO7yBza5SivL1QgxSrzAbiKWjhQ==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.2.1.tgz", + "integrity": "sha512-PCJF4UknJmOal68+X9XHyVeQ+idv0LFujkTOIW30+GaMJqwFVN9LkQKX4gLqn61KkGMdJTzQ1bt7EJag3TI6AA==", "dev": true, "dependencies": { "rfdc": "^1.3.1" @@ -1659,6 +1753,100 @@ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.27.tgz", "integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==" }, + "node_modules/@vueuse/core": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.9.0.tgz", + "integrity": "sha512-/1vjTol8SXnx6xewDEKfS0Ra//ncg4Hb0DaZiwKf7drgfMsKFExQ+FnnENcN6efPen+1kIzhLQoGSy0eDUVOMg==", + "dependencies": { + "@types/web-bluetooth": "^0.0.20", + "@vueuse/metadata": "10.9.0", + "@vueuse/shared": "10.9.0", + "vue-demi": ">=0.14.7" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/core/node_modules/vue-demi": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", + "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/@vueuse/metadata": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.9.0.tgz", + "integrity": "sha512-iddNbg3yZM0X7qFY2sAotomgdHK7YJ6sKUvQqbvwnf7TmaVPxS4EJydcNsVejNdS8iWCtDk+fYXr7E32nyTnGA==", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.9.0.tgz", + "integrity": "sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw==", + "dependencies": { + "vue-demi": ">=0.14.7" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared/node_modules/vue-demi": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", + "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, "node_modules/acorn": { "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", @@ -1680,6 +1868,17 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/agentkeepalive": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", + "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -1720,21 +1919,70 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/ant-design-vue": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ant-design-vue/-/ant-design-vue-4.2.1.tgz", + "integrity": "sha512-3u6fmfCEJ5AFTsYhogP8lJ/vcqiAJO16o+gGQkWYRGLl0NxmY4hje4cPyv+pcxpeJgcG0vNEmkb1vVHKcnxd+g==", + "dependencies": { + "@ant-design/colors": "^6.0.0", + "@ant-design/icons-vue": "^7.0.0", + "@babel/runtime": "^7.10.5", + "@ctrl/tinycolor": "^3.5.0", + "@emotion/hash": "^0.9.0", + "@emotion/unitless": "^0.8.0", + "@simonwep/pickr": "~1.8.0", + "array-tree-filter": "^2.1.0", + "async-validator": "^4.0.0", + "csstype": "^3.1.1", + "dayjs": "^1.10.5", + "dom-align": "^1.12.1", + "dom-scroll-into-view": "^2.0.0", + "lodash": "^4.17.21", + "lodash-es": "^4.17.15", + "resize-observer-polyfill": "^1.5.1", + "scroll-into-view-if-needed": "^2.2.25", + "shallow-equal": "^1.0.0", + "stylis": "^4.1.3", + "throttle-debounce": "^5.0.0", + "vue-types": "^3.0.0", + "warning": "^4.0.0" + }, + "engines": { + "node": ">=12.22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ant-design-vue" + }, + "peerDependencies": { + "vue": ">=3.2.0" + } + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "node_modules/array-tree-filter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-tree-filter/-/array-tree-filter-2.1.0.tgz", + "integrity": "sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==" + }, + "node_modules/async-validator": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz", + "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==" + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/axios": { - "version": "1.6.8", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", - "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.1.tgz", + "integrity": "sha512-+LV37nQcd1EpFalkXksWNBiA17NZ5m5/WspmHGmZmdx1qBOg/VNq/c4eRJiA9VQQHBOs+N0ZhhdU10h2TyNK7Q==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -1850,9 +2098,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001617", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001617.tgz", - "integrity": "sha512-mLyjzNI9I+Pix8zwcrpxEbGlfqOkF9kM3ptzmKNw5tizSyYwMe+nGLTqMK9cO+0E+Bh6TsBxNAaHWEM8xwSsmA==", + "version": "1.0.30001620", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001620.tgz", + "integrity": "sha512-WJvYsOjd1/BYUY6SNGUosK9DUidBPDTnOARHp3fSmFO1ekdxaY6nKRttEVrfMmYi80ctS0kz1wiWmm14fVc3ew==", "dev": true, "funding": [ { @@ -1914,6 +2162,11 @@ "node": ">= 0.8" } }, + "node_modules/compute-scroll-into-view": { + "version": "1.0.20", + "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz", + "integrity": "sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==" + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1926,6 +2179,16 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, + "node_modules/core-js": { + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.1.tgz", + "integrity": "sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -1957,6 +2220,11 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, + "node_modules/dayjs": { + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz", + "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==" + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -2040,10 +2308,20 @@ "node": ">=6.0.0" } }, + "node_modules/dom-align": { + "version": "1.12.4", + "resolved": "https://registry.npmjs.org/dom-align/-/dom-align-1.12.4.tgz", + "integrity": "sha512-R8LUSEay/68zE5c8/3BDxiTEvgb4xZTF0RKmAHfiEVN3klfIpXfi2/QCoiWPccVQ0J/ZGdz9OjzL4uJEP/MRAw==" + }, + "node_modules/dom-scroll-into-view": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/dom-scroll-into-view/-/dom-scroll-into-view-2.0.1.tgz", + "integrity": "sha512-bvVTQe1lfaUr1oFzZX80ce9KLDlZ3iU+XGNE/bz9HnGdklTieqsbmsLHe+rT2XWqopvL0PckkYqN7ksmm5pe3w==" + }, "node_modules/electron-to-chromium": { - "version": "1.4.762", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.762.tgz", - "integrity": "sha512-rrFvGweLxPwwSwJOjIopy3Vr+J3cIPtZzuc74bmlvmBIgQO3VYJDvVrlj94iKZ3ukXUH64Ex31hSfRTLqvjYJQ==", + "version": "1.4.775", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.775.tgz", + "integrity": "sha512-JpOfl1aNAiZ88wFzjPczTLwYIoPIsij8S9/XQH9lqMpiJOf23kxea68B8wje4f68t4rOIq4Bh+vP4I65njiJBw==", "dev": true }, "node_modules/entities": { @@ -2058,9 +2336,9 @@ } }, "node_modules/error-stack-parser-es": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-0.1.1.tgz", - "integrity": "sha512-g/9rfnvnagiNf+DRMHEVGuGuIBlCIMDFoTA616HaP2l9PlCjGjVhD98PNbVSJvmK4TttqT5mV5tInMhoFgi+aA==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-0.1.4.tgz", + "integrity": "sha512-l0uy0kAoo6toCgVOYaAayqtPa2a1L15efxUMEnQebKwLQX2X0OpS6wMMQdc4juJXmxd9i40DuaUHq+mjIya9TQ==", "dev": true, "funding": { "url": "https://github.com/sponsors/antfu" @@ -2294,6 +2572,14 @@ "node": ">=0.10.0" } }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "engines": { + "node": ">=6" + } + }, "node_modules/execa": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", @@ -2424,6 +2710,31 @@ "node": ">= 6" } }, + "node_modules/form-data-encoder": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", + "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==" + }, + "node_modules/formdata-node": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", + "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", + "dependencies": { + "node-domexception": "1.0.0", + "web-streams-polyfill": "4.0.0-beta.3" + }, + "engines": { + "node": ">= 12.20" + } + }, + "node_modules/formdata-node/node_modules/web-streams-polyfill": { + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", + "engines": { + "node": ">= 14" + } + }, "node_modules/fs-extra": { "version": "11.2.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", @@ -2574,6 +2885,14 @@ "node": ">=16.17.0" } }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "dependencies": { + "ms": "^2.0.0" + } + }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -2687,6 +3006,14 @@ "node": ">=8" } }, + "node_modules/is-plain-object": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz", + "integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", @@ -2723,8 +3050,7 @@ "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/js-yaml": { "version": "4.1.0", @@ -2792,6 +3118,19 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jwt-decode": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz", + "integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==", + "engines": { + "node": ">=18" + } + }, + "node_modules/kakao.maps.d.ts": { + "version": "0.1.39", + "resolved": "https://registry.npmjs.org/kakao.maps.d.ts/-/kakao.maps.d.ts-0.1.39.tgz", + "integrity": "sha512-KXENJ8hHYtjb5G+0vf8TXx/PwWW4j5ndDiQTSMvGtF7EFWu2P3N/+Zivcj9/UKn3j29Iz/sIUaA7WL8Ug3IDGQ==" + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -2838,8 +3177,12 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" }, "node_modules/lodash.merge": { "version": "4.6.2", @@ -2847,6 +3190,17 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -2931,8 +3285,7 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/nanoid": { "version": "3.3.7", @@ -2951,12 +3304,54 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/nanopop": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/nanopop/-/nanopop-2.4.2.tgz", + "integrity": "sha512-NzOgmMQ+elxxHeIha+OG/Pv3Oc3p4RU2aBhwWwAqDpXrdTbtRylbRLQztLy8dMMwfl6pclznBdfUhccEn9ZIzw==" + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/node-releases": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", @@ -3044,6 +3439,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/openai": { + "version": "4.47.1", + "resolved": "https://registry.npmjs.org/openai/-/openai-4.47.1.tgz", + "integrity": "sha512-WWSxhC/69ZhYWxH/OBsLEirIjUcfpQ5+ihkXKp06hmeYXgBBIUCa9IptMzYx6NdkiOCsSGYCnTIsxaic3AjRCQ==", + "dependencies": { + "@types/node": "^18.11.18", + "@types/node-fetch": "^2.6.4", + "abort-controller": "^3.0.0", + "agentkeepalive": "^4.2.1", + "form-data-encoder": "1.7.2", + "formdata-node": "^4.3.2", + "node-fetch": "^2.6.7", + "web-streams-polyfill": "^3.2.1" + }, + "bin": { + "openai": "bin/cli" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -3143,9 +3556,9 @@ "dev": true }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" }, "node_modules/picomatch": { "version": "2.3.1", @@ -3159,6 +3572,64 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pinia": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.1.7.tgz", + "integrity": "sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==", + "dependencies": { + "@vue/devtools-api": "^6.5.0", + "vue-demi": ">=0.14.5" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "@vue/composition-api": "^1.4.0", + "typescript": ">=4.4.4", + "vue": "^2.6.14 || ^3.3.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/pinia-plugin-persistedstate": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/pinia-plugin-persistedstate/-/pinia-plugin-persistedstate-3.2.1.tgz", + "integrity": "sha512-MK++8LRUsGF7r45PjBFES82ISnPzyO6IZx3CH5vyPseFLZCk1g2kgx6l/nW8pEBKxxd4do0P6bJw+mUSZIEZUQ==", + "peerDependencies": { + "pinia": "^2.0.0" + } + }, + "node_modules/pinia/node_modules/vue-demi": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", + "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, "node_modules/postcss": { "version": "8.4.38", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", @@ -3242,6 +3713,16 @@ } ] }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -3352,6 +3833,14 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/scroll-into-view-if-needed": { + "version": "2.2.31", + "resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.31.tgz", + "integrity": "sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==", + "dependencies": { + "compute-scroll-into-view": "^1.0.20" + } + }, "node_modules/semver": { "version": "7.6.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", @@ -3364,6 +3853,11 @@ "node": ">=10" } }, + "node_modules/shallow-equal": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz", + "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -3411,6 +3905,11 @@ "node": ">= 10" } }, + "node_modules/sortablejs": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.14.0.tgz", + "integrity": "sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w==" + }, "node_modules/source-map-js": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", @@ -3464,6 +3963,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/stylis": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", + "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==" + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -3482,12 +3986,29 @@ "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", "dev": true }, + "node_modules/sweetalert2": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.11.0.tgz", + "integrity": "sha512-wKCTtoE6lQVDKaJ5FFq+znk/YykJmJlD8RnLZps8C7DyivctCoRlVeeOwnKfgwKS+QJYon7s++3dmNi3/am1tw==", + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/limonte" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/throttle-debounce": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.0.tgz", + "integrity": "sha512-2iQTSgkkc1Zyk0MeVrt/3BvuOXYPl/R8Z0U2xxo9rjwNciaHDG3R+Lm6dh4EeUci49DanvBnuqI6jshoQQRGEg==", + "engines": { + "node": ">=12.22" + } + }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -3506,6 +4027,11 @@ "node": ">=6" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -3530,6 +4056,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, "node_modules/universalify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", @@ -3540,9 +4071,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.15", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.15.tgz", - "integrity": "sha512-K9HWH62x3/EalU1U6sjSZiylm9C8tgq2mSvshZpqc7QE69RaA2qjhkW2HlNA0tFpEbtyFz7HTqbSdN4MSwUodA==", + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", + "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", "dev": true, "funding": [ { @@ -3560,7 +4091,7 @@ ], "dependencies": { "escalade": "^3.1.2", - "picocolors": "^1.0.0" + "picocolors": "^1.0.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -3683,18 +4214,18 @@ } }, "node_modules/vite-plugin-vue-devtools": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-7.1.3.tgz", - "integrity": "sha512-qv8Z4yok9RYo6TEs89WnIAlmTHby/+XTim8tlSnMs3lAPcQqqcl/wGRY8gAeYrGCANngOqO+VuabW3Jb1HZtyw==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-7.2.1.tgz", + "integrity": "sha512-4k7QNZz0nSojoePQoxnE5fIzi8RU1QJHc0TEg4golv2phZxhBGfjScZD2B8X6bcrRbUQ9CaRKN0dzBs1xtzzNg==", "dev": true, "dependencies": { - "@vue/devtools-core": "^7.1.3", - "@vue/devtools-kit": "^7.1.3", - "@vue/devtools-shared": "^7.1.3", + "@vue/devtools-core": "^7.2.1", + "@vue/devtools-kit": "^7.2.1", + "@vue/devtools-shared": "^7.2.1", "execa": "^8.0.1", "sirv": "^2.0.4", "vite-plugin-inspect": "^0.8.4", - "vite-plugin-vue-inspector": "^5.0.1" + "vite-plugin-vue-inspector": "^5.1.0" }, "engines": { "node": ">=v14.21.3" @@ -3781,6 +4312,69 @@ "vue": "^3.2.0" } }, + "node_modules/vue-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vue-types/-/vue-types-3.0.2.tgz", + "integrity": "sha512-IwUC0Aq2zwaXqy74h4WCvFCUtoV0iSWr0snWnE9TnU18S66GAQyqQbRf2qfJtUuiFsBf6qp0MEwdonlwznlcrw==", + "dependencies": { + "is-plain-object": "3.0.1" + }, + "engines": { + "node": ">=10.15.0" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, + "node_modules/vue3-kakao-maps": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/vue3-kakao-maps/-/vue3-kakao-maps-2.3.9.tgz", + "integrity": "sha512-L+vtpfvmFslXI8nelxyTGfR8mhiJhYVkWyX7jaOLZJgDtj+4VlKoD73xIxEvVzd9qMfVyMDM6x/kNwD9jPuw/w==", + "dependencies": { + "kakao.maps.d.ts": "^0.1.39" + } + }, + "node_modules/vuedraggable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-4.1.0.tgz", + "integrity": "sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==", + "dependencies": { + "sortablejs": "1.14.0" + }, + "peerDependencies": { + "vue": "^3.0.1" + } + }, + "node_modules/warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index 3b0853d..6b2296c 100644 --- a/package.json +++ b/package.json @@ -10,10 +10,19 @@ "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore" }, "dependencies": { + "@vueuse/core": "^10.9.0", + "ant-design-vue": "^4.2.1", "axios": "^1.6.8", "bootstrap": "^5.3.3", + "jwt-decode": "^4.0.0", + "openai": "^4.47.1", + "pinia": "^2.1.7", + "pinia-plugin-persistedstate": "^3.2.1", + "sweetalert2": "^11.11.0", "vue": "^3.4.21", - "vue-router": "^4.3.0" + "vue-router": "^4.3.0", + "vue3-kakao-maps": "^2.3.9", + "vuedraggable": "^4.1.0" }, "devDependencies": { "@vitejs/plugin-vue": "^5.0.4", diff --git a/src/api/user.js b/src/api/user.js new file mode 100644 index 0000000..3bf8fda --- /dev/null +++ b/src/api/user.js @@ -0,0 +1,27 @@ +import { localAxios } from "@/util/http-common"; +import piniaPersistedstate from "pinia-plugin-persistedstate"; +const local = localAxios(); + +async function userConfirm(param, success, fail) { + await local.post(`/member/login`, param).then(success).catch(fail); + // await local.post(`/member/login`,param).then(success).catch(error => { + // console.error('Login request failed:', error.response || error.message); + // fail(error); + // }); +} + +async function findById(success, fail) { + local.defaults.headers["Authorization"] = sessionStorage.getItem("accessToken"); + await local.get(`/member/info`).then(success).catch(fail); +} + +async function tokenRegeneration(user, success, fail) { + local.defaults.headers["refreshToken"] = sessionStorage.getItem("refreshToken"); //axios header에 refresh-token 셋팅 + await local.post(`/member/refresh`, user).then(success).catch(fail); +} + +async function logout(userid, success, fail) { + await local.get(`/member/logout/${userid}`).then(success).catch(fail); +} + +export { userConfirm, findById, tokenRegeneration, logout }; diff --git a/src/assets/ai.png b/src/assets/ai.png new file mode 100644 index 0000000..cb64392 Binary files /dev/null and b/src/assets/ai.png differ diff --git a/src/assets/bloom-messages.png b/src/assets/bloom-messages.png new file mode 100644 index 0000000..6b9ab3b Binary files /dev/null and b/src/assets/bloom-messages.png differ diff --git a/src/assets/group.png b/src/assets/group.png new file mode 100644 index 0000000..ae84498 Binary files /dev/null and b/src/assets/group.png differ diff --git a/src/assets/heart-message.png b/src/assets/heart-message.png new file mode 100644 index 0000000..ad45407 Binary files /dev/null and b/src/assets/heart-message.png differ diff --git a/src/assets/heart.png b/src/assets/heart.png new file mode 100644 index 0000000..ff60943 Binary files /dev/null and b/src/assets/heart.png differ diff --git a/src/assets/lock.png b/src/assets/lock.png new file mode 100644 index 0000000..609ea78 Binary files /dev/null and b/src/assets/lock.png differ diff --git a/src/assets/plane.png b/src/assets/plane.png new file mode 100644 index 0000000..2251617 Binary files /dev/null and b/src/assets/plane.png differ diff --git a/src/assets/share.png b/src/assets/share.png new file mode 100644 index 0000000..a93060b Binary files /dev/null and b/src/assets/share.png differ diff --git a/src/assets/star.png b/src/assets/star.png new file mode 100644 index 0000000..0b77e99 Binary files /dev/null and b/src/assets/star.png differ diff --git a/src/assets/unheart.png b/src/assets/unheart.png new file mode 100644 index 0000000..554c0b4 Binary files /dev/null and b/src/assets/unheart.png differ diff --git a/src/assets/unlock.png b/src/assets/unlock.png new file mode 100644 index 0000000..9c67edf Binary files /dev/null and b/src/assets/unlock.png differ diff --git a/src/assets/unstar.png b/src/assets/unstar.png new file mode 100644 index 0000000..2f9f5ff Binary files /dev/null and b/src/assets/unstar.png differ diff --git a/src/assets/user_icon.png b/src/assets/user_icon.png new file mode 100644 index 0000000..5596c1e Binary files /dev/null and b/src/assets/user_icon.png differ diff --git a/src/components/OpenAi.vue b/src/components/OpenAi.vue new file mode 100644 index 0000000..38a3bac --- /dev/null +++ b/src/components/OpenAi.vue @@ -0,0 +1,186 @@ + + + + + + + \ No newline at end of file diff --git a/src/components/attraction/attractionImg.vue b/src/components/attraction/attractionImg.vue new file mode 100644 index 0000000..70db01d --- /dev/null +++ b/src/components/attraction/attractionImg.vue @@ -0,0 +1,108 @@ + + + + + \ No newline at end of file diff --git a/src/components/comment/CommentForm.vue b/src/components/comment/CommentForm.vue new file mode 100644 index 0000000..49b4a42 --- /dev/null +++ b/src/components/comment/CommentForm.vue @@ -0,0 +1,79 @@ + + + + + diff --git a/src/components/comment/CommentList.vue b/src/components/comment/CommentList.vue new file mode 100644 index 0000000..4be724d --- /dev/null +++ b/src/components/comment/CommentList.vue @@ -0,0 +1,235 @@ + + + + + diff --git a/src/components/comment/CommentListItem.vue b/src/components/comment/CommentListItem.vue new file mode 100644 index 0000000..0fea842 --- /dev/null +++ b/src/components/comment/CommentListItem.vue @@ -0,0 +1,51 @@ + + + + + diff --git a/src/components/layout/TheFooter.vue b/src/components/layout/TheFooter.vue index 8f25314..3d6208e 100644 --- a/src/components/layout/TheFooter.vue +++ b/src/components/layout/TheFooter.vue @@ -1,8 +1,10 @@ diff --git a/src/components/layout/TheHeadingNavbar.vue b/src/components/layout/TheHeadingNavbar.vue index 5946576..8be5ff1 100644 --- a/src/components/layout/TheHeadingNavbar.vue +++ b/src/components/layout/TheHeadingNavbar.vue @@ -1,9 +1,18 @@ + + + + diff --git a/src/components/map/PlanList.vue b/src/components/map/PlanList.vue new file mode 100644 index 0000000..ad99490 --- /dev/null +++ b/src/components/map/PlanList.vue @@ -0,0 +1,552 @@ + + + + + \ No newline at end of file diff --git a/src/components/map/TourList.vue b/src/components/map/TourList.vue new file mode 100644 index 0000000..db85e49 --- /dev/null +++ b/src/components/map/TourList.vue @@ -0,0 +1,379 @@ + + + + + diff --git a/src/components/message/MessageRoomDetail.vue b/src/components/message/MessageRoomDetail.vue new file mode 100644 index 0000000..005817b --- /dev/null +++ b/src/components/message/MessageRoomDetail.vue @@ -0,0 +1,76 @@ + + + + + diff --git a/src/components/message/MessageRoomList.vue b/src/components/message/MessageRoomList.vue new file mode 100644 index 0000000..504b76c --- /dev/null +++ b/src/components/message/MessageRoomList.vue @@ -0,0 +1,649 @@ + + + + + \ No newline at end of file diff --git a/src/components/message/MessageSend.vue b/src/components/message/MessageSend.vue new file mode 100644 index 0000000..18df8bb --- /dev/null +++ b/src/components/message/MessageSend.vue @@ -0,0 +1,181 @@ + + + + + diff --git a/src/components/post/BoardList.vue b/src/components/post/BoardList.vue new file mode 100644 index 0000000..835d476 --- /dev/null +++ b/src/components/post/BoardList.vue @@ -0,0 +1,97 @@ + + + + + diff --git a/src/components/post/PostDetail.vue b/src/components/post/PostDetail.vue new file mode 100644 index 0000000..a588ec7 --- /dev/null +++ b/src/components/post/PostDetail.vue @@ -0,0 +1,299 @@ + + + + + diff --git a/src/components/post/PostList.vue b/src/components/post/PostList.vue new file mode 100644 index 0000000..b8ed710 --- /dev/null +++ b/src/components/post/PostList.vue @@ -0,0 +1,118 @@ + + + + + diff --git a/src/components/post/PostModify.vue b/src/components/post/PostModify.vue new file mode 100644 index 0000000..856b9e0 --- /dev/null +++ b/src/components/post/PostModify.vue @@ -0,0 +1,16 @@ + + + diff --git a/src/components/post/PostWrite.vue b/src/components/post/PostWrite.vue new file mode 100644 index 0000000..a14dcdb --- /dev/null +++ b/src/components/post/PostWrite.vue @@ -0,0 +1,27 @@ + + + + + diff --git a/src/components/post/item/CommentListItem.vue b/src/components/post/item/CommentListItem.vue new file mode 100644 index 0000000..e960cbf --- /dev/null +++ b/src/components/post/item/CommentListItem.vue @@ -0,0 +1,13 @@ + + + + + diff --git a/src/components/post/item/PostFormItem.vue b/src/components/post/item/PostFormItem.vue new file mode 100644 index 0000000..e96c522 --- /dev/null +++ b/src/components/post/item/PostFormItem.vue @@ -0,0 +1,215 @@ + + + + + diff --git a/src/components/post/item/PostListItem.vue b/src/components/post/item/PostListItem.vue new file mode 100644 index 0000000..e1ad172 --- /dev/null +++ b/src/components/post/item/PostListItem.vue @@ -0,0 +1,25 @@ + + + + + diff --git a/src/components/users/UserJoin.vue b/src/components/users/UserJoin.vue index 48551f8..89085e4 100644 --- a/src/components/users/UserJoin.vue +++ b/src/components/users/UserJoin.vue @@ -1,27 +1,81 @@ - - - + }; + + const submitForm = () => { + userRegist(); + }; + + \ No newline at end of file diff --git a/src/components/users/UserMyComment.vue b/src/components/users/UserMyComment.vue new file mode 100644 index 0000000..6133cb2 --- /dev/null +++ b/src/components/users/UserMyComment.vue @@ -0,0 +1,70 @@ + + + + + diff --git a/src/components/users/UserMyInfo.vue b/src/components/users/UserMyInfo.vue new file mode 100644 index 0000000..81c3eb3 --- /dev/null +++ b/src/components/users/UserMyInfo.vue @@ -0,0 +1,189 @@ + + + + + diff --git a/src/components/users/UserMyPage.vue b/src/components/users/UserMyPage.vue new file mode 100644 index 0000000..057819d --- /dev/null +++ b/src/components/users/UserMyPage.vue @@ -0,0 +1,109 @@ + + + + diff --git a/src/components/users/UserMyPost.vue b/src/components/users/UserMyPost.vue new file mode 100644 index 0000000..45cbe1a --- /dev/null +++ b/src/components/users/UserMyPost.vue @@ -0,0 +1,75 @@ + + + + + diff --git a/src/components/users/UserMyScrap.vue b/src/components/users/UserMyScrap.vue new file mode 100644 index 0000000..5566d5c --- /dev/null +++ b/src/components/users/UserMyScrap.vue @@ -0,0 +1,75 @@ + + + + + diff --git a/src/main.js b/src/main.js index 6cf1fc6..b3d9eb3 100644 --- a/src/main.js +++ b/src/main.js @@ -1,14 +1,29 @@ // import './assets/main.css' import { createApp } from 'vue' +import { createPinia } from "pinia"; +import piniaPluginPersistedstate from "pinia-plugin-persistedstate"; import App from './App.vue' import router from './router' +import Antd from 'ant-design-vue'; +import attractionImg from "@/components/attraction/attractionImg.vue" +import 'ant-design-vue/dist/reset.css'; import "bootstrap/dist/css/bootstrap.min.css"; import "bootstrap"; +import { useKakao } from 'vue3-kakao-maps/@utils'; + +useKakao('acd23fc0b913a085a3ad102649e3b5dc'); const app = createApp(App) +const pinia = createPinia(); +pinia.use(piniaPluginPersistedstate); +// app.use(pinia); +app.use(Antd) app.use(router) - -app.mount('#app') +app.use(pinia); +app.component('attractionImg', attractionImg); +router.isReady().then(() => { + app.mount("#app"); + }); \ No newline at end of file diff --git a/src/router/index.js b/src/router/index.js index f209a68..0d183db 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,35 +1,193 @@ import { createRouter, createWebHistory } from 'vue-router' import HomeView from '../views/HomeView.vue' + +import PostView from "@/views/PostView.vue" +import PostList from "@/components/post/PostList.vue" +import PostWrite from "@/components/post/PostWrite.vue" +import PostDetail from '@/components/post/PostDetail.vue' +import PostModify from '@/components/post/PostModify.vue' + import TheUserView from "@/views/TheUserView.vue" import UserLogin from "@/components/users/UserLogin.vue" import UserJoin from "@/components/users/UserJoin.vue" +import UserMyPage from "@/components/users/UserMyPage.vue" +import MapView from "@/views/MapView.vue" + + +import MessageView from "@/views/MessageView.vue" +import MessageSend from '@/components/message/MessageSend.vue' +import MessageRoomList from '@/components/message/MessageRoomList.vue' +import MessageRoomDetail from '@/components/message/MessageRoomDetail.vue' +import { storeToRefs } from "pinia"; + +import { useMemberStore } from "@/stores/member"; +import UserLogout from "@/components/users/UserLogout.vue" +import UserMyScrap from '@/components/users/UserMyScrap.vue' +import UserMyPost from '@/components/users/UserMyPost.vue' +import UserMyComment from '@/components/users/UserMyComment.vue' +import UserMyInfo from '@/components/users/UserMyInfo.vue' + +import MyPlan from '@/views/MyPlan.vue' + +const onlyAuthUser = async (to, from, next) => { + const memberStore = useMemberStore(); + const { userInfo, isValidToken } = storeToRefs(memberStore); + const { getUserInfo } = memberStore; + + let token = sessionStorage.getItem("accessToken"); + + if (userInfo.value != null && token) { + await getUserInfo(token); + } + if (!isValidToken.value || userInfo.value === null) { + next({ name: "login" }); + } else { + next(); + } +}; const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes: [ { path: '/', name: 'home', - component: HomeView + component: HomeView, }, { - path: '/user', - name: 'user', + + path: '/post', + name: 'post', + component: PostView, + children: [ + { + path: '', + name: 'postList', + component: PostList, + }, + { + path: '', + name: 'postWrite', + component: PostWrite, + beforeEnter: onlyAuthUser, + }, + { + path: ':postId', + name: 'postDetail', + component: PostDetail, + beforeEnter: onlyAuthUser, + }, + { + path: ':postId', + name: 'postModify', + component: PostModify, + beforeEnter: onlyAuthUser, + }, + ], + }, + { + path: '/member', + name: 'member', component: TheUserView, children: [ + { + path: "join", + name: "join", + component: UserJoin + }, { path: "login", name: "login", component: UserLogin }, { - path: "join", - name: "join", - component: UserJoin + path: "myPage", + name: "myPage", + component: UserMyPage, + beforeEnter: onlyAuthUser, + children: [ + { + path: "scrap", + name: "myScrap", + component: UserMyScrap, + beforeEnter: onlyAuthUser, + }, + { + path: "post", + name: "myPost", + component: UserMyPost, + beforeEnter: onlyAuthUser, + }, + { + path: "comment", + name: "myComment", + component: UserMyComment, + beforeEnter: onlyAuthUser, + }, + { + path: "info", + name: "info", + component: UserMyInfo, + beforeEnter: onlyAuthUser, + }, + ] + }, + { + path: "logout", + name: "logout", + component: UserLogout + } + ] + + }, + { + path: '/message', + name: 'message', + component: MessageView, + beforeEnter: onlyAuthUser, + children: [ + { + path: ":memberId", + name: "messageSend", + component: MessageSend, + beforeEnter: onlyAuthUser, + }, + { + path: "", + name: "messageRoomList", + component: MessageRoomList, + beforeEnter: onlyAuthUser, + }, + { + path: ":roomId", + name: "messageRoomDetail", + component: MessageRoomDetail, + beforeEnter: onlyAuthUser, } ] + }, + { + path: "/map", + name: "map", + component: MapView, + }, + { + path: "/map/:planListId", + name: "detailPlan", + component: MapView, + }, + { + path: "/myPlan", + name: "myPlan", + component: MyPlan, + }, + { + path: "/map/:planListId:isShare", + name: "sharePlan", + component: MapView, } + ] }) diff --git a/src/stores/mapTour.js b/src/stores/mapTour.js new file mode 100644 index 0000000..147f815 --- /dev/null +++ b/src/stores/mapTour.js @@ -0,0 +1,49 @@ +import { defineStore } from 'pinia' +import { ref } from "vue" + +export const useMapTourList = defineStore('mapTourList',()=> { + // 상태 + const tripList = ref([]) + const markerList = ref([]) + const planList = ref([]) + + const setMarkerList = () => { + const newMarkers = []; + tripList.value.forEach((trip) => { + newMarkers.push({ + attractionId: trip.attractionId, + planned: false, + lat: trip.longitude, + lng: trip.latitude, + infoWindow: { + content: trip.name, + image: trip.image1, + address: trip.address, + visible: false, + }, + }); + }); + markerList.value = newMarkers; + } + + const setPlanToMarkerList = () => { + const newMarkers = []; + planList.value.forEach((trip) => { + newMarkers.push({ + attractionId: trip.attractionId, + planned: false, + lat: trip.longitude, + lng: trip.latitude, + infoWindow: { + content: trip.name, + image: trip.image1, + address: trip.address, + visible: false, + }, + }); + }); + markerList.value = newMarkers; + } + + return { tripList, markerList, planList, setMarkerList, setPlanToMarkerList }; +}) \ No newline at end of file diff --git a/src/stores/member.js b/src/stores/member.js new file mode 100644 index 0000000..2d7baee --- /dev/null +++ b/src/stores/member.js @@ -0,0 +1,148 @@ +import { ref } from "vue" +import { useRouter } from "vue-router" +import { storeToRefs } from "pinia" +import { defineStore } from "pinia" +import { jwtDecode } from "jwt-decode" +import { createPersistedState } from "pinia-plugin-persistedstate"; +import { userConfirm, findById, tokenRegeneration, logout } from "@/api/user" +import { httpStatusCode } from "@/util/http-status" +import Swal from "sweetalert2"; + +export const useMemberStore = defineStore("memberStore", () => { + const router = useRouter() + + const isLogin = ref(false) + const isLoginError = ref(false) + const userInfo = ref(null) + const isValidToken = ref(false) + + const userLogin = async (loginUser) => { + await userConfirm( + loginUser, + (response) => { + if (response.status === httpStatusCode.CREATE) { + console.log("로그인 성공!!!!") + let { data } = response + let accessToken = data["access-token"] + let refreshToken = data["refresh-token"] + isLogin.value = true + isLoginError.value = false + isValidToken.value = true + sessionStorage.setItem("accessToken", accessToken) + sessionStorage.setItem("refreshToken", refreshToken) + + } + }, + (error) => { + Swal.fire({ + title: "아이디와 비밀번호를 확인해주세요.", + icon: "error", + }); + isLogin.value = false + isLoginError.value = true + isValidToken.value = false + console.error(error) + } + ) + } + + const getUserInfo = async (token) => { + let decodeToken = jwtDecode(token) + console.log(decodeToken) + await findById( + (response) => { + if (response.status === httpStatusCode.OK) { + userInfo.value = response.data.userInfo + } else { + console.log("유저 정보 없음!!!!") + } + }, + async (error) => { + console.error( + "[토큰 만료되어 사용 불가능.] : ", + error.response.status, + error.response.statusText + ) + isValidToken.value = false + + await tokenRegenerate() + } + ) + } + + const tokenRegenerate = async () => { + await tokenRegeneration( + JSON.stringify(userInfo.value), + (response) => { + if (response.status === httpStatusCode.CREATE) { + let accessToken = response.data["access-token"] + sessionStorage.setItem("accessToken", accessToken) + isValidToken.value = true + } + }, + async (error) => { + // HttpStatus.UNAUTHORIZE(401) : RefreshToken 기간 만료 >> 다시 로그인!!!! + if (error.response.status === httpStatusCode.UNAUTHORIZED) { + // 다시 로그인 전 DB에 저장된 RefreshToken 제거. + await logout( + userInfo.value.userid, + (response) => { + if (response.status === httpStatusCode.OK) { + console.log("리프레시 토큰 제거 성공") + } else { + console.log("리프레시 토큰 제거 실패") + } + alert("RefreshToken 기간 만료!!! 다시 로그인해 주세요.") + isLogin.value = false + userInfo.value = null + isValidToken.value = false + router.push({ name: "user-login" }) + }, + (error) => { + console.error(error) + isLogin.value = false + userInfo.value = null + } + ) + } + } + ) + } + + const userLogout = async () => { + console.log("로그아웃 아이디 : " + userInfo.value.userId) + await logout( + userInfo.value.userId, + (response) => { + if (response.status === httpStatusCode.OK) { + isLogin.value = false + userInfo.value = null + isValidToken.value = false + + sessionStorage.removeItem("accessToken") + sessionStorage.removeItem("refreshToken") + } else { + console.error("유저 정보 없음!!!!") + } + }, + (error) => { + console.log(error) + } + ) + } + + return { + isLogin, + isLoginError, + userInfo, + isValidToken, + userLogin, + getUserInfo, + tokenRegenerate, + userLogout, + }; +}, { + persist: { + storage: sessionStorage + } +}); diff --git a/src/stores/menu.js b/src/stores/menu.js new file mode 100644 index 0000000..2805c0b --- /dev/null +++ b/src/stores/menu.js @@ -0,0 +1,24 @@ +import { ref } from "vue"; +import { defineStore } from "pinia"; +import { useRouter } from "vue-router"; + + +export const useMenuStore = defineStore("menuStore", () => { + const menuList = ref([ + { name: "로그인", show: true, routeName: "login" }, + { name: "쪽지", show: false, routeName: "messageRoomList" }, + { name: "마이 페이지", show: false, routeName: "myPage" }, + { name: "로그아웃", show: false, routeName: "logout" }, + ]); + + const router = useRouter(); + + + const changeMenuState = () => { + menuList.value = menuList.value.map((item) => ({ ...item, show: !item.show })); + }; + return { + menuList, + changeMenuState, + }; +}); diff --git a/src/stores/postPage.js b/src/stores/postPage.js new file mode 100644 index 0000000..bf0a383 --- /dev/null +++ b/src/stores/postPage.js @@ -0,0 +1,11 @@ +import { defineStore } from 'pinia' +import { ref } from "vue" + +export const usePostPage = defineStore('postPage',()=> { + const pageIndex = ref(1) + const totalCount = ref() + const pageSize = ref(10) + const order = ref("earliest") + const boardId = ref(0) + return { pageIndex, totalCount, order, boardId, pageSize }; +}) \ No newline at end of file diff --git a/src/util/http-common.js b/src/util/http-common.js new file mode 100644 index 0000000..ba55368 --- /dev/null +++ b/src/util/http-common.js @@ -0,0 +1,83 @@ +import axios from "axios"; +// import { httpStatusCode } from "./http-status"; + +const { VITE_BASE_URL } = import.meta.env; + +// local vue api axios instance +function localAxios() { + const instance = axios.create({ + baseURL: 'http://localhost/api', + // withCredentials: true, + // headers: { + // "Content-Type": "application/json;charset=utf-8", + // }, + }); + // Request 발생 시 적용할 내용. + instance.defaults.headers.common["Authorization"] = ""; + instance.defaults.headers.post["Content-Type"] = "application/json"; + instance.defaults.headers.put["Content-Type"] = "application/json"; + + // Request, Response 시 설정한 내용을 적용. + instance.interceptors.request.use((config) => { + const refreshToken = sessionStorage.getItem("refreshToken"); + if (refreshToken) { + config.headers.Authorization = `${refreshToken}`; + } + return config; + }), + (error) => { + return Promise.reject(error); + }; + + // // accessToken의 값이 유효하지 않은 경우, + // // refreshToken을 이용해 재발급 처리. + // // https://maruzzing.github.io/study/rnative/axios-interceptors%EB%A1%9C-%ED%86%A0%ED%81%B0-%EB%A6%AC%ED%94%84%EB%A0%88%EC%8B%9C-%ED%95%98%EA%B8%B0/ + + // let isTokenRefreshing = false; + + // instance.interceptors.response.use( + // (response) => { + // return response; + // }, + // async (error) => { + // const { + // config, + // response: { status }, + // } = error; + + // // 페이지가 새로고침되어 저장된 accessToken이 없어진 경우. + // // 토큰 자체가 만료되어 더 이상 진행할 수 없는 경우. + // if (status == httpStatusCode.UNAUTHORIZED) { + // // 요청 상태 저장 + // const originalRequest = config; + + // // Token을 재발급하는 동안 다른 요청이 발생하는 경우 대기. + // // 다른 요청을 진행하면, 새로 발급 받은 Token이 유효하지 않게 됨. + // if (!isTokenRefreshing) { + // isTokenRefreshing = true; + + // // 에러가 발생했던 컴포넌트의 axios로 이동하고자하는 경우 + // // 반드시 return을 붙여주어야한다. + // return await instance.post("/user/refresh").then((response) => { + // const newAccessToken = response.data.Authorization; + + // instance.defaults.headers.common["Authorization"] = newAccessToken; + // originalRequest.headers.Authorization = newAccessToken; + + // isTokenRefreshing = false; + + // // 에러가 발생했던 원래의 요청을 다시 진행. + // return instance(originalRequest); + // }); + // } + // } else if (status == httpStatusCode.FORBIDDEN) { + // alert(error.response.data.message); + // } + + // return Promise.reject(error); + // } + // ); + return instance; +} + +export { localAxios }; diff --git a/src/util/http-status.js b/src/util/http-status.js new file mode 100644 index 0000000..76ecca4 --- /dev/null +++ b/src/util/http-status.js @@ -0,0 +1,11 @@ +// HTTP Status Code +// https://developer.mozilla.org/en-US/docs/Web/HTTP/Status +export const httpStatusCode = { + OK: 200, + CREATE: 201, + NOCONTENT: 204, + UNAUTHORIZED: 401, + FORBIDDEN: 403, + NOTFOUND: 404, + }; + \ No newline at end of file diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue index 6494dfe..9ebd423 100644 --- a/src/views/HomeView.vue +++ b/src/views/HomeView.vue @@ -1,91 +1,67 @@ - + @@ -103,4 +79,114 @@ body { vertical-align: -0.125em; fill: currentColor; } + + +.animated-char { + display: inline-block; + animation: wave 1s ease-in-out infinite; +} + +.animated-char:nth-child(1) { + animation-delay: 0s; +} +.animated-char:nth-child(2) { + animation-delay: 0.1s; +} +.animated-char:nth-child(3) { + animation-delay: 0.2s; +} +.animated-char:nth-child(4) { + animation-delay: 0.3s; +} +.animated-char:nth-child(5) { + animation-delay: 0.4s; +} +.animated-char:nth-child(6) { + animation-delay: 0.5s; +} +.animated-char:nth-child(7) { + animation-delay: 0.6s; +} +.animated-char:nth-child(8) { + animation-delay: 0.7s; +} +.animated-char:nth-child(9) { + animation-delay: 0.8s; +} +.animated-char:nth-child(10) { + animation-delay: 0.9s; +} +.animated-char:nth-child(11) { + animation-delay: 1s; +} +.animated-char:nth-child(12) { + animation-delay: 1.1s; +} +.animated-char:nth-child(13) { + animation-delay: 1.2s; +} +.animated-char:nth-child(14) { + animation-delay: 1.3s; +} +.animated-char:nth-child(15) { + animation-delay: 1.4s; +} +.animated-char:nth-child(16) { + animation-delay: 1.5s; +} +.animated-char:nth-child(17) { + animation-delay: 1.6s; +} +.animated-char:nth-child(18) { + animation-delay: 1.7s; +} +.animated-char:nth-child(19) { + animation-delay: 1.8s; +} +.animated-char:nth-child(20) { + animation-delay: 1.9s; +} +.animated-char:nth-child(21) { + animation-delay: 2s; +} +.animated-char:nth-child(22) { + animation-delay: 2.1s; +} +.animated-char:nth-child(23) { + animation-delay: 2.2s; +} +.animated-char:nth-child(24) { + animation-delay: 2.3s; +} +.animated-char:nth-child(25) { + animation-delay: 2.4s; +} +.animated-char:nth-child(26) { + animation-delay: 2.5s; +} +.animated-char:nth-child(27) { + animation-delay: 2.6s; +} +.animated-char:nth-child(28) { + animation-delay: 2.7s; +} +.animated-char:nth-child(29) { + animation-delay: 2.8s; +} +/* 추가 글자에 대해서도 nth-child를 추가해줍니다 */ + +@keyframes wave { + 0%, + 100% { + transform: translateY(0); + } + 50% { + transform: translateY(-10px); + } +} + +.carousel-container { + width: 100%; + margin-top: 50px; +} diff --git a/src/views/MapView.vue b/src/views/MapView.vue new file mode 100644 index 0000000..e85bb82 --- /dev/null +++ b/src/views/MapView.vue @@ -0,0 +1,238 @@ + + + + + diff --git a/src/views/MessageView.vue b/src/views/MessageView.vue new file mode 100644 index 0000000..69c4e07 --- /dev/null +++ b/src/views/MessageView.vue @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/src/views/MyPlan.vue b/src/views/MyPlan.vue new file mode 100644 index 0000000..023cf4c --- /dev/null +++ b/src/views/MyPlan.vue @@ -0,0 +1,220 @@ + + + + + diff --git a/src/views/PostView.vue b/src/views/PostView.vue new file mode 100644 index 0000000..e223bcb --- /dev/null +++ b/src/views/PostView.vue @@ -0,0 +1,11 @@ + + + + +