diff --git a/FE/error/.env b/FE/error/.env
index fc225431..831688d2 100644
--- a/FE/error/.env
+++ b/FE/error/.env
@@ -1 +1,2 @@
VITE_ERROR_API = 'https://error.econo-calendar.com:8080'
+
diff --git a/FE/error/.eslintrc.cjs b/FE/error/.eslintrc.cjs
index 3e212e1d..6466c328 100644
--- a/FE/error/.eslintrc.cjs
+++ b/FE/error/.eslintrc.cjs
@@ -2,20 +2,20 @@ module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
- 'eslint:recommended',
- 'plugin:react/recommended',
- 'plugin:react/jsx-runtime',
- 'plugin:react-hooks/recommended',
+ "eslint:recommended",
+ "plugin:react/recommended",
+ "plugin:react/jsx-runtime",
+ "plugin:react-hooks/recommended",
],
- ignorePatterns: ['dist', '.eslintrc.cjs'],
- parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
- settings: { react: { version: '18.2' } },
- plugins: ['react-refresh'],
+ ignorePatterns: ["dist", ".eslintrc.cjs"],
+ parserOptions: { ecmaVersion: "latest", sourceType: "module" },
+ settings: { react: { version: "18.2" } },
+ plugins: ["react-refresh"],
rules: {
- 'react/jsx-no-target-blank': 'off',
- 'react-refresh/only-export-components': [
- 'warn',
+ "react/jsx-no-target-blank": "off",
+ "react-refresh/only-export-components": [
+ "warn",
{ allowConstantExport: true },
],
},
-}
+};
diff --git a/FE/error/index.html b/FE/error/index.html
index 129a715b..bf064d65 100644
--- a/FE/error/index.html
+++ b/FE/error/index.html
@@ -3,6 +3,10 @@
+
Vite + React
= 8"
}
},
+ "node_modules/@remix-run/router": {
+ "version": "1.16.0",
+ "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.0.tgz",
+ "integrity": "sha512-Quz1KOffeEf/zwkCBM3kBtH4ZoZ+pT3xIXBG4PPW/XFtDP7EGhtTiC2+gpL9GnR7+Qdet5Oa6cYSvwKYg6kN9Q==",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.13.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.0.tgz",
@@ -1359,6 +1368,11 @@
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
"dev": true
},
+ "node_modules/@types/parse-json": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz",
+ "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw=="
+ },
"node_modules/@types/prop-types": {
"version": "15.7.11",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz",
@@ -1484,7 +1498,6 @@
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "dev": true,
"dependencies": {
"color-convert": "^1.9.0"
},
@@ -1674,6 +1687,36 @@
"proxy-from-env": "^1.1.0"
}
},
+ "node_modules/babel-plugin-macros": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz",
+ "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==",
+ "dependencies": {
+ "@babel/runtime": "^7.12.5",
+ "cosmiconfig": "^7.0.0",
+ "resolve": "^1.19.0"
+ },
+ "engines": {
+ "node": ">=10",
+ "npm": ">=6"
+ }
+ },
+ "node_modules/babel-plugin-macros/node_modules/resolve": {
+ "version": "1.22.8",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
+ "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
+ "dependencies": {
+ "is-core-module": "^2.13.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -1744,7 +1787,6 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
- "dev": true,
"engines": {
"node": ">=6"
}
@@ -1781,7 +1823,6 @@
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "dev": true,
"dependencies": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
@@ -1796,11 +1837,18 @@
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
"integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow=="
},
+ "node_modules/clone": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+ "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
"node_modules/color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "dev": true,
"dependencies": {
"color-name": "1.1.3"
}
@@ -1808,8 +1856,7 @@
"node_modules/color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
- "dev": true
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
},
"node_modules/combined-stream": {
"version": "1.0.8",
@@ -1834,6 +1881,21 @@
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
"dev": true
},
+ "node_modules/cosmiconfig": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
+ "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
+ "dependencies": {
+ "@types/parse-json": "^4.0.0",
+ "import-fresh": "^3.2.1",
+ "parse-json": "^5.0.0",
+ "path-type": "^4.0.0",
+ "yaml": "^1.10.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -1875,7 +1937,6 @@
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz",
"integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==",
- "peer": true,
"funding": {
"type": "github",
"url": "https://github.com/sponsors/kossnocorp"
@@ -1990,6 +2051,14 @@
"integrity": "sha512-LKqhpwJCLhYId2VVwEzFXWrqQI5n5zBppz1W9ehhTlfYU8CUUW6kClbN8LHF/v7flMgRdETS772nqywJ+ckVAw==",
"dev": true
},
+ "node_modules/error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
"node_modules/es-abstract": {
"version": "1.22.5",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.5.tgz",
@@ -2181,7 +2250,6 @@
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
- "dev": true,
"engines": {
"node": ">=0.8.0"
}
@@ -2490,11 +2558,21 @@
"node": ">=0.10.0"
}
},
+ "node_modules/eventemitter3": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz",
+ "integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg=="
+ },
"node_modules/exenv": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz",
"integrity": "sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw=="
},
+ "node_modules/extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+ },
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -2775,6 +2853,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/goober": {
+ "version": "2.1.14",
+ "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.14.tgz",
+ "integrity": "sha512-4UpC0NdGyAFqLNPnhCT2iHpza2q+RAY3GV85a/mRPdzyPQMsj0KmMMuetdIkzWRbJ+Hgau1EZztq8ImmiMGhsg==",
+ "peerDependencies": {
+ "csstype": "^3.0.10"
+ }
+ },
"node_modules/gopd": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
@@ -2805,7 +2891,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
- "dev": true,
"engines": {
"node": ">=4"
}
@@ -2889,7 +2974,6 @@
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
- "dev": true,
"dependencies": {
"parent-module": "^1.0.0",
"resolve-from": "^4.0.0"
@@ -2971,6 +3055,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="
+ },
"node_modules/is-async-function": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz",
@@ -3030,7 +3119,6 @@
"version": "2.13.1",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz",
"integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==",
- "dev": true,
"dependencies": {
"hasown": "^2.0.0"
},
@@ -3335,6 +3423,11 @@
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
"dev": true
},
+ "node_modules/json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
+ },
"node_modules/json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
@@ -3396,6 +3489,11 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
+ },
"node_modules/locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
@@ -3447,6 +3545,25 @@
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
},
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@@ -3678,7 +3795,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
- "dev": true,
"dependencies": {
"callsites": "^3.0.0"
},
@@ -3686,6 +3802,23 @@
"node": ">=6"
}
},
+ "node_modules/parse-json": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
+ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+ "dependencies": {
+ "@babel/code-frame": "^7.0.0",
+ "error-ex": "^1.3.1",
+ "json-parse-even-better-errors": "^2.3.0",
+ "lines-and-columns": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -3716,8 +3849,15 @@
"node_modules/path-parse": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
- "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
- "dev": true
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
+ },
+ "node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "engines": {
+ "node": ">=8"
+ }
},
"node_modules/picocolors": {
"version": "1.0.0",
@@ -3890,6 +4030,21 @@
"react": "^18.2.0"
}
},
+ "node_modules/react-hot-toast": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.4.1.tgz",
+ "integrity": "sha512-j8z+cQbWIM5LY37pR6uZR6D4LfseplqnuAO4co4u8917hBUvXlEqyP1ZzqVLcqoyUesZZv/ImreoCeHVDpE5pQ==",
+ "dependencies": {
+ "goober": "^2.1.10"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "react": ">=16",
+ "react-dom": ">=16"
+ }
+ },
"node_modules/react-icons": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.0.1.tgz",
@@ -3949,6 +4104,36 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-router": {
+ "version": "6.23.0",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.23.0.tgz",
+ "integrity": "sha512-wPMZ8S2TuPadH0sF5irFGjkNLIcRvOSaEe7v+JER8508dyJumm6XZB1u5kztlX0RVq6AzRVndzqcUh6sFIauzA==",
+ "dependencies": {
+ "@remix-run/router": "1.16.0"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8"
+ }
+ },
+ "node_modules/react-router-dom": {
+ "version": "6.23.0",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.23.0.tgz",
+ "integrity": "sha512-Q9YaSYvubwgbal2c9DJKfx6hTNoBp3iJDsl+Duva/DwxoJH+OTXkxGpql4iUK2sla/8z4RpjAm6EWx1qUDuopQ==",
+ "dependencies": {
+ "@remix-run/router": "1.16.0",
+ "react-router": "6.23.0"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8",
+ "react-dom": ">=16.8"
+ }
+ },
"node_modules/react-select": {
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/react-select/-/react-select-5.8.0.tgz",
@@ -4061,7 +4246,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
- "dev": true,
"engines": {
"node": ">=4"
}
@@ -4445,7 +4629,6 @@
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "dev": true,
"dependencies": {
"has-flag": "^3.0.0"
},
@@ -4457,7 +4640,6 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
- "dev": true,
"engines": {
"node": ">= 0.4"
},
@@ -4817,6 +4999,14 @@
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
"dev": true
},
+ "node_modules/yaml": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
+ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
diff --git a/FE/error/package.json b/FE/error/package.json
index ad43683a..b50103b2 100644
--- a/FE/error/package.json
+++ b/FE/error/package.json
@@ -15,13 +15,16 @@
"@fullcalendar/interaction": "^6.1.11",
"@fullcalendar/react": "^6.1.11",
"axios": "^1.6.8",
+ "date-fns": "^3.6.0",
"react": "^18.2.0",
"react-day-picker": "^8.10.0",
"react-dom": "^18.2.0",
+ "react-hot-toast": "^2.4.1",
+ "react-icons": "^5.0.1",
"react-modal": "^3.16.1",
"react-quill": "^2.0.0",
+ "react-router-dom": "^6.23.0",
"react-select": "^5.8.0",
- "react-icons": "^5.0.1",
"react-tooltip": "^5.26.3",
"styled-components": "^6.1.8"
},
diff --git a/FE/error/public/Background.png b/FE/error/public/Background.png
new file mode 100644
index 00000000..4b412ae9
Binary files /dev/null and b/FE/error/public/Background.png differ
diff --git a/FE/error/public/Picture.png b/FE/error/public/Picture.png
new file mode 100644
index 00000000..93eb3f09
Binary files /dev/null and b/FE/error/public/Picture.png differ
diff --git a/FE/error/public/Slack.png b/FE/error/public/Slack.png
new file mode 100644
index 00000000..8433c0f8
Binary files /dev/null and b/FE/error/public/Slack.png differ
diff --git a/FE/error/src/App.css b/FE/error/src/App.css
deleted file mode 100644
index 82935aec..00000000
--- a/FE/error/src/App.css
+++ /dev/null
@@ -1,124 +0,0 @@
-html,
-body,
-div,
-span,
-applet,
-object,
-iframe,
-h1,
-h2,
-h3,
-h4,
-h5,
-h6,
-p,
-blockquote,
-pre,
-a,
-abbr,
-acronym,
-address,
-big,
-cite,
-code,
-del,
-dfn,
-em,
-img,
-ins,
-kbd,
-q,
-s,
-samp,
-small,
-strike,
-strong,
-sub,
-sup,
-tt,
-var,
-b,
-u,
-i,
-center,
-dl,
-dt,
-dd,
-ol,
-ul,
-li,
-fieldset,
-form,
-label,
-legend,
-table,
-caption,
-tbody,
-tfoot,
-thead,
-tr,
-th,
-td,
-article,
-aside,
-canvas,
-details,
-embed,
-figure,
-figcaption,
-footer,
-header,
-hgroup,
-menu,
-nav,
-output,
-ruby,
-section,
-summary,
-time,
-mark,
-audio,
-video {
- margin: 0;
- padding: 0;
- border: 0;
- font-size: 100%;
- font: inherit;
- vertical-align: baseline;
-}
-/* HTML5 display-role reset for older browsers */
-article,
-aside,
-details,
-figcaption,
-figure,
-footer,
-header,
-hgroup,
-menu,
-nav,
-section {
- display: block;
-}
-body {
- line-height: 1;
-}
-ol,
-ul {
- list-style: none;
-}
-blockquote,
-q {
- quotes: none;
-}
-blockquote:before,
-blockquote:after,
-q:before,
-q:after {
- content: "";
- content: none;
-}
-table {
- border-collapse: collapse;
- border-spacing: 0;
-}
diff --git a/FE/error/src/App.jsx b/FE/error/src/App.jsx
index 8a939c86..1c9ab4bb 100644
--- a/FE/error/src/App.jsx
+++ b/FE/error/src/App.jsx
@@ -1,47 +1,16 @@
-import "./App.css";
-import EconoCalendar from "./components/EconoCalendar";
-import styled from "styled-components";
-import CreateModal from "./components/CreateModal";
+import { Routes, Route } from "react-router-dom";
+import MainPage from "./pages/MainPage";
+import LoginPage from "./pages/LoginPage";
+import CalendarModify from "./pages/CalendarModify";
function App() {
return (
-
-
- ERROR
-
-
-
-
+
+ } />
+ } />
+ } />
+
);
}
export default App;
-
-const SideBar = styled.div`
- width: 20vw;
- height: 98.1vh;
- margin-top: 1rem;
-`;
-
-const CalendarPage = styled.div`
- display: flex;
- width: 100%;
-`;
-
-const LineBox = styled.div`
- width: 100%;
- height: 1.25rem;
- border: 1px solid #ddd;
- border-right: none;
-
- margin-top: 1.63em;
-`;
-
-const Logo = styled.div`
- font-size: 2rem;
- font-weight: bold;
- margin-left: 1.5rem;
- margin-top: 0.3rem;
- color: #ff9999;
- margin-bottom: 1rem;
-`;
diff --git a/FE/error/src/components/CheckModal/CheckCalendar.jsx b/FE/error/src/components/CheckModal/CheckCalendar.jsx
index cbb81940..e16df524 100644
--- a/FE/error/src/components/CheckModal/CheckCalendar.jsx
+++ b/FE/error/src/components/CheckModal/CheckCalendar.jsx
@@ -1,4 +1,4 @@
-import React, { useEffect, useState } from "react"; // useState 추가
+import { useEffect, useState, useRef } from "react"; // useState 추가
import Modal from "react-modal";
import "./CheckCalendar.css";
import styled from "styled-components";
@@ -7,17 +7,17 @@ import { IoClose } from "react-icons/io5";
import axios from "axios";
import { MdOutlineLocationOn } from "react-icons/md";
import { MdOutlineAutoAwesomeMotion } from "react-icons/md";
-import DeletEvent from "./DeleteEvent";
+import DeleteEvent from "./DeleteEvent";
+import { Link } from "react-router-dom";
const CheckCalendar = ({
isOpen,
onRequestClose,
selectID,
events,
- setEvents,
+ handleDelete,
}) => {
const [event, setEvent] = useState({});
- const Calendarmodify = () => {};
function createDate(title, startDate, endDate, place, info) {
const specificEvent = {
@@ -29,7 +29,14 @@ const CheckCalendar = ({
};
setEvent(specificEvent);
}
+
+ const isMount = useRef(false);
useEffect(() => {
+ if (!isMount.current) {
+ isMount.current = true;
+ return;
+ }
+
const instance = axios.create({
baseURL: `${import.meta.env.VITE_ERROR_API}`,
});
@@ -44,12 +51,20 @@ const CheckCalendar = ({
});
}, [selectID]);
- /*function date(startDate, endDate) {
- if (startDate.split("T")[0] === endDate.split("T")[0]) return startDate;
- else {
- return `${startDate} - ${endDate}`;
- }
- }*/
+ function date(startDate, endDate) {
+ if (!startDate && !endDate) return "날짜 정보 없음";
+ if (startDate.split("T")[0] === endDate.split("T")[0]) {
+ if (startDate === endDate) {
+ return `${startDate.split("T")[0]} ${startDate.split("T")[1]}`;
+ } else
+ return `${startDate.split("T")[0]} ${startDate.split("T")[1]}~${
+ endDate.split("T")[1]
+ }`;
+ } else
+ return `${startDate.split("T")[0]} ${startDate.split("T")[1]} - ${
+ endDate.split("T")[0]
+ } ${endDate.split("T")[1]}`;
+ }
return (
-
-
+
+
+
+
@@ -73,17 +95,19 @@ const CheckCalendar = ({
{event.title}
- {/*
- {date(event.startDate, event.endDate)}
- */}
-
-
- {event.place}
-
-
-
- {event.info}
-
+ {date(event.startDate, event.endDate)}
+ {event.place && (
+
+
+ {event.place}
+
+ )}
+ {event.info && (
+
+
+ {event.info}
+
+ )}
);
@@ -131,6 +155,7 @@ const Title = styled.div`
display: flex;
`;
-/*const Date = styled.div`
+const Date = styled.p`
margin-left: 1.55rem;
-`;*/
+ font-size: small;
+`;
diff --git a/FE/error/src/components/CheckModal/DeleteEvent.jsx b/FE/error/src/components/CheckModal/DeleteEvent.jsx
index 573f7a46..b9325c39 100644
--- a/FE/error/src/components/CheckModal/DeleteEvent.jsx
+++ b/FE/error/src/components/CheckModal/DeleteEvent.jsx
@@ -1,7 +1,7 @@
import { RiDeleteBinLine } from "react-icons/ri";
import axios from "axios";
-const DeletEvent = ({ events, setEvents, selectID }) => {
+const DeleteEvent = ({ events, selectID, handleDelete, onRequestClose }) => {
const calendarDelete = () => {
const instance = axios.create({
baseURL: `${import.meta.env.VITE_ERROR_API}`,
@@ -10,9 +10,8 @@ const DeletEvent = ({ events, setEvents, selectID }) => {
instance
.delete("/api/calendar/" + selectID)
.then(() => {
- const updatedEvents = events.filter((event) => event.id !== selectID);
- setEvents(updatedEvents);
- window.location.reload();
+ handleDelete();
+ onRequestClose();
})
.catch((error) => {
console.error("Error deleting event:", error);
@@ -20,10 +19,12 @@ const DeletEvent = ({ events, setEvents, selectID }) => {
};
return (
-
+ <>
+
+ >
);
};
-export default DeletEvent;
+export default DeleteEvent;
diff --git a/FE/error/src/components/CreateModal.css b/FE/error/src/components/CreateModal.css
index 1ae9c122..67086e36 100644
--- a/FE/error/src/components/CreateModal.css
+++ b/FE/error/src/components/CreateModal.css
@@ -5,7 +5,7 @@
transform: translate(-50%, -50%);
background-color: white;
z-index: 1000;
- padding: 90px 95px;
+ padding: 55px 100px;
border-radius: 4px;
box-shadow: 2px 2px 20px 2px rgba(0, 0, 0, 0.3);
outline-style: none;
diff --git a/FE/error/src/components/CreateModal.jsx b/FE/error/src/components/CreateModal.jsx
index ccf3997d..50732862 100644
--- a/FE/error/src/components/CreateModal.jsx
+++ b/FE/error/src/components/CreateModal.jsx
@@ -1,27 +1,38 @@
-import React, { useState, useEffect } from "react";
+import { useState, useEffect } from "react";
import Modal from "react-modal";
import "./CreateModal.css";
import styled from "styled-components";
import TimeSelect from "./TimeSelect";
import ReactQuill from "react-quill";
-import axios from "axios";
+import { format, addDays, compareAsc, parseISO } from "date-fns";
-const CreateModal = ({ isOpen, onRequestClose, selectedDate }) => {
+const CreateModal = ({
+ isOpen,
+ onRequestClose,
+ selectedDate,
+ handleUpdateData,
+}) => {
const [eventName, setEventName] = useState("");
- const [eventStartDate, setEventStartDate] = useState("");
- const [eventEndDate, setEventEndDate] = useState("");
+ const [StartDate, setStartDate] = useState("");
+ const [EndDate, setEndDate] = useState("");
const [eventInfo, setEventInfo] = useState("");
const [eventPlace, setEventPlace] = useState("");
const [eventMemo, setEventMemo] = useState("");
+ const [eventStartDate, setNewStartDate] = useState("");
+ const [eventEndDate, setNewEndDate] = useState("");
+ const [eventStartTime, setEventStartTime] = useState("00:00");
+ const [eventEndTime, setEventEndTime] = useState("00:00");
useEffect(() => {
if (isOpen && selectedDate) {
setEventName("");
- setEventStartDate(selectedDate);
- setEventEndDate(selectedDate);
+ setStartDate(selectedDate);
+ setEndDate(selectedDate);
setEventInfo("");
setEventPlace("");
setEventMemo("");
+ setNewStartDate(selectedDate + "T" + eventStartTime);
+ setNewEndDate(selectedDate + "T" + eventEndTime);
}
}, [isOpen, selectedDate]);
@@ -30,19 +41,46 @@ const CreateModal = ({ isOpen, onRequestClose, selectedDate }) => {
};
const handleStartDateChange = (event) => {
- setEventStartDate(event.target.value);
+ setStartDate(event.target.value);
+ const newStartDate = `${event.target.value}T${eventStartTime}`;
+ setNewStartDate(newStartDate);
+ if (new Date(event.target.value) > new Date(EndDate)) {
+ setEndDate(event.target.value);
+ const updatedEndDate = event.target.value;
+ const newEndDate = `${updatedEndDate}T${eventEndTime}`;
+ setNewEndDate(newEndDate);
+ }
};
const handleEndDateChange = (event) => {
- setEventEndDate(event.target.value);
+ setEndDate(event.target.value);
+ const updatedEndDate = addDays(new Date(event.target.value), 1);
+ const newEndDate = `${format(
+ updatedEndDate,
+ "yyyy-MM-dd"
+ )}T${eventEndTime}`;
+
+ setNewEndDate(newEndDate);
};
const handleStartTimeSelect = (time) => {
- setEventStartDate((prev) => `${prev.split("T")[0]}T${time}`);
+ const startDateString = `${StartDate}T${time}`;
+ const endDateString = `${EndDate}T${eventEndTime}`;
+
+ setEventStartTime(time);
+ setNewStartDate(startDateString);
+
+ if (compareAsc(parseISO(startDateString), parseISO(endDateString)) > 0) {
+ setEventEndTime(time);
+ setNewEndDate(startDateString);
+ }
};
const handleEndTimeSelect = (time) => {
- setEventEndDate((prev) => `${prev.split("T")[0]}T${time}`);
+ let updatedEndDate = addDays(new Date(EndDate), 1);
+ const newEndDate = `${format(updatedEndDate, "yyyy-MM-dd")}T${time}`;
+ setEventEndTime(time);
+ setNewEndDate(newEndDate);
};
const handleMemoChange = (e) => {
@@ -76,27 +114,14 @@ const CreateModal = ({ isOpen, onRequestClose, selectedDate }) => {
.then((data) => {
console.log("Success:", data);
onRequestClose();
- window.location.reload();
+ handleUpdateData(data);
+ //window.location.reload();
})
.catch((error) => {
console.error("Error:", error);
});
};
- // const saveData = () => {
- // const instance = axios.create({
- // baseURL: `${import.meta.env.VITE_ERROR_API}`,
- // });
- // instance.post("/api/calendar").then((res) => {
- // const data = {
- // eventName,
- // eventStartDate,
- // eventEndDate,
- // eventInfo: eventMemo,
- // eventPlace,
- // };
- // onRequestClose();
- // });
- // };
+
return (
{
overlayClassName="overlay"
>
-
+
+ 시작일 :
+
+ 마감일 :
-
-
-
+
+
+ 부터
-
+ 까지
+
{
- 저장
+
+ 저장
+
);
@@ -157,10 +185,16 @@ const SaveButton = styled.button`
border-radius: 0.25rem;
margin-top: 3rem;
border: 0.5px solid #858585;
- color: #3e3e3e;
outline: none;
cursor: pointer;
right: 0;
+ background-color: ${(props) => (props.disabled ? "#e0e0e0" : "white")};
+ color: ${(props) => (props.disabled ? "#9e9e9e" : "#3e3e3e")};
+ border: ${(props) => (props.disabled ? "none" : "0.5px solid #858585")};
+
+ &:disabled {
+ cursor: default;
+ }
`;
const EditorBox = styled.div`
@@ -178,4 +212,11 @@ const PlaceSelect = styled.input`
border: none;
width: 100%;
outline: none;
+ margin: 1.1rem 0;
+`;
+
+const DateRow = styled.div`
+ display: flex;
+ align-items: center;
+ gap: 0.7rem;
`;
diff --git a/FE/error/src/components/EconoCalendar.jsx b/FE/error/src/components/EconoCalendar.jsx
index cabc9cad..6d722885 100644
--- a/FE/error/src/components/EconoCalendar.jsx
+++ b/FE/error/src/components/EconoCalendar.jsx
@@ -2,11 +2,12 @@ import FullCalendar from "@fullcalendar/react";
import dayGridPlugin from "@fullcalendar/daygrid";
import interactionPlugin from "@fullcalendar/interaction";
import styled from "styled-components";
-import React, { useEffect } from "react";
+import { useEffect } from "react";
import CreateModal from "./CreateModal";
import { useState } from "react";
import axios from "axios";
import CheckCalendar from "./CheckModal/CheckCalendar";
+import toast, { Toaster } from "react-hot-toast";
const EconoCalendar = () => {
const [events, setEvents] = useState([]);
@@ -15,6 +16,14 @@ const EconoCalendar = () => {
const [createModalIsOpen, setCreateModalIsOpen] = useState(false);
const [selectedDate, setSelectedDate] = useState("");
+ const handleDelete = () => {
+ toast("일정이 삭제되었습니다", {
+ style: {
+ backgroundColor: "#535353",
+ color: "#fff",
+ },
+ });
+ };
const handleEventClick = (info) => {
setSelectID(info.event._def.publicId);
setCheckModalIsOpen(true);
@@ -24,6 +33,14 @@ const EconoCalendar = () => {
setCreateModalIsOpen(true);
};
+ const getCurrentDate = () => {
+ const today = new Date();
+ const year = today.getFullYear();
+ const month = ("0" + (today.getMonth() + 1)).slice(-2);
+ const day = ("0" + today.getDate()).slice(-2);
+ return `${year}-${month}-${day}`;
+ };
+
useEffect(() => {
const instance = axios.create({
baseURL: `${import.meta.env.VITE_ERROR_API}`,
@@ -37,7 +54,7 @@ const EconoCalendar = () => {
id: event.eventId,
start: event.eventStartDate.split("T")[0],
end: event.eventEndDate.split("T")[0],
- color: "#beb9ff",
+ color: "#ffc5bf",
}));
setEvents(fetchedEvents);
})
@@ -46,17 +63,41 @@ const EconoCalendar = () => {
});
}, []);
+ const handleUpdateData = (newData) => {
+ console.log(newData);
+ setEvents([...events, newData]);
+ };
+
return (
<>
{
onRequestClose={() => setCheckModalIsOpen(false)}
selectID={selectID}
events={events}
- setEvents={setEvents}
+ handleDelete={handleDelete}
/>
setCreateModalIsOpen(false)}
selectedDate={selectedDate}
+ handleUpdateData={handleUpdateData}
/>
+
>
);
};
@@ -109,6 +152,9 @@ const CalendarContainer = styled.div`
margin-top: 1rem;
.fc-toolbar-chunk {
display: flex;
+ .fc-toolbar-chunk > :last-child {
+ margin-right: 1rem;
+ }
}
.fc-prev-button {
@@ -131,6 +177,11 @@ const CalendarContainer = styled.div`
border: none;
}
}
+ .fc-prev-button:focus,
+ .fc-next-button:focus {
+ outline: none; /* 기본 아웃라인을 제거합니다. */
+ box-shadow: none; /* 추가적인 그림자가 있다면 제거합니다. */
+ }
.fc-today-button {
background-color: unset;
@@ -156,14 +207,14 @@ const CalendarContainer = styled.div`
margin-left: 0.3rem;
}
.fc-day-today {
- background: #fff !important;
+ background-color: #ffffff !important;
}
.fc-day-today .fc-daygrid-day-top {
background: #ff9999 !important;
border-radius: 50% !important;
color: #fff;
margin-left: 0.5rem;
- width: 1.7rem;
+ width: 1.53rem;
}
.fc-day-today .fc-daygrid-day-frame {
margin-top: 0.2rem;
@@ -185,4 +236,11 @@ const CalendarContainer = styled.div`
border-right: none;
border-left: none;
}
+
+ .fc-createDateButton-button {
+ background-color: #fff;
+ border-color: #cbcbcb;
+ color: #595959;
+ margin-right: 1rem;
+ }
`;
diff --git a/FE/error/src/components/TimeSelect.jsx b/FE/error/src/components/TimeSelect.jsx
index 6a58f4d7..990eaeb6 100644
--- a/FE/error/src/components/TimeSelect.jsx
+++ b/FE/error/src/components/TimeSelect.jsx
@@ -1,4 +1,4 @@
-import React, { useState } from "react";
+import { useState } from "react";
import Select from "react-select";
let hour = [];
diff --git a/FE/error/src/main.jsx b/FE/error/src/main.jsx
index 35a3de08..73efb39e 100644
--- a/FE/error/src/main.jsx
+++ b/FE/error/src/main.jsx
@@ -1,14 +1,14 @@
-import React from "react";
import ReactDOM from "react-dom/client";
import Modal from "react-modal";
import App from "./App.jsx";
+import { BrowserRouter } from "react-router-dom";
import "./fonts/font.css";
const rootElement = document.getElementById("root");
Modal.setAppElement(rootElement);
ReactDOM.createRoot(document.getElementById("root")).render(
-
+
-
+
);
diff --git a/FE/error/src/pages/CalendarModify.jsx b/FE/error/src/pages/CalendarModify.jsx
new file mode 100644
index 00000000..de2d2298
--- /dev/null
+++ b/FE/error/src/pages/CalendarModify.jsx
@@ -0,0 +1,224 @@
+import styled from "styled-components";
+import { useState, useEffect } from "react";
+import { useLocation } from "react-router-dom";
+import axios from "axios";
+import TimeSelect from "../components/TimeSelect";
+import ReactQuill from "react-quill";
+import { IoMdClose } from "react-icons/io";
+import { useNavigate } from "react-router-dom";
+
+const CalendarModify = () => {
+ const navigate = useNavigate();
+ const location = useLocation();
+ const selectID = location.state.selectID;
+
+ const [modifyName, setModifyName] = useState("");
+ const [modifyStartDate, setModifyStartDate] = useState("");
+ const [modifyEndDate, setModifyEndDate] = useState("");
+ const [modifyInfo, setModifyInfo] = useState("");
+ const [modifyStartTime, setModifyStartTime] = useState("");
+ const [modifyEndTime, setModifyEndTime] = useState("");
+ const [modifyPlace, setModifyPlace] = useState("");
+
+ const handleTitleChange = (e) => {
+ setModifyName(e.target.value);
+ };
+ const handleStartDateChange = (e) => {
+ setModifyStartDate(e.target.value);
+ };
+
+ const handleEndDateChange = (e) => {
+ setModifyEndDate(e.target.value);
+ };
+
+ const handleStartTimeSelect = (time) => {
+ setModifyStartTime(time);
+ };
+
+ const handleEndTimeSelect = (time) => {
+ setModifyEndTime(time);
+ };
+
+ const handleInfoChange = (e) => {
+ setModifyInfo(e.replace(/<[^>]*>/g, ""));
+ };
+
+ const handlePlaceChange = (e) => {
+ setModifyPlace(e.target.value);
+ };
+
+ useEffect(() => {
+ const instance = axios.create({
+ baseURL: `${import.meta.env.VITE_ERROR_API}`,
+ });
+ instance.get("/api/calendar/" + selectID).then((res) => {
+ const event = res.data.data;
+ const title = event.eventName;
+ const startDate = event.eventStartDate.split("T")[0];
+ const startTime = event.eventStartDate.split("T")[1];
+ const endDate = event.eventEndDate.split("T")[0];
+ const endTime = event.eventEndDate.split("T")[1];
+ const info = event.eventInfo;
+ const place = event.eventPlace;
+ setModifyName(title);
+ setModifyStartDate(startDate);
+ setModifyEndDate(endDate);
+ setModifyStartTime(startTime);
+ setModifyEndTime(endTime);
+ setModifyInfo(info);
+ setModifyPlace(place);
+ });
+ }, [selectID]);
+
+ const modifyData = () => {
+ const instance = axios.create({
+ baseURL: `${import.meta.env.VITE_ERROR_API}`,
+ });
+
+ const eventData = {
+ eventName: modifyName,
+ eventStartDate: modifyStartDate + "T" + modifyStartTime,
+ eventEndDate: modifyEndDate + "T" + modifyEndTime,
+ eventInfo: modifyInfo,
+ eventPlace: modifyPlace,
+ };
+
+ instance
+ .put("/api/calendar/" + selectID, eventData)
+ .then((res) => {
+ console.log(res.data);
+ goBack();
+ })
+ .catch((error) => {
+ console.error(error);
+ });
+ };
+ const goBack = () => {
+ navigate(-1);
+ };
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 저장
+
+
+
+ );
+};
+
+export default CalendarModify;
+
+const Box = styled.div`
+ width: 50rem;
+`;
+const ModifyFrame = styled.div`
+ margin-left: 4rem;
+`;
+const TitleInput = styled.input`
+ width: 100%;
+ height: 2rem;
+ margin-bottom: 2rem;
+ margin-top: 2rem;
+ margin-left: 0.7rem;
+ font-size: 1.5rem;
+ border: none;
+ border-bottom: 1px solid #495057;
+ outline: none;
+`;
+const Header = styled.div`
+ display: flex;
+ margin-left: 1rem;
+`;
+const SaveButton = styled.button`
+ width: 4rem;
+ height: 2rem;
+ border-radius: 0.25rem;
+ margin-top: 3rem;
+ border: 0.5px solid #858585;
+ outline: none;
+ cursor: pointer;
+ right: 0;
+ background-color: ${(props) => (props.disabled ? "#e0e0e0" : "white")};
+ color: ${(props) => (props.disabled ? "#9e9e9e" : "#3e3e3e")};
+ border: ${(props) => (props.disabled ? "none" : "0.5px solid #858585")};
+
+ &:disabled {
+ cursor: default;
+ }
+`;
+
+const EditorBox = styled.div`
+ .ql-editor {
+ height: 110px;
+ overflow-y: auto;
+ }
+ .ql-editor::before {
+ font-style: normal !important;
+ color: #999 !important;
+ }
+`;
+
+const PlaceSelect = styled.input`
+ border: none;
+ width: 100%;
+ outline: none;
+ margin: 1.1rem 0;
+`;
+
+const DateRow = styled.div`
+ display: flex;
+ align-items: center;
+ gap: 0.7rem;
+`;
diff --git a/FE/error/src/pages/LoginPage.jsx b/FE/error/src/pages/LoginPage.jsx
new file mode 100644
index 00000000..0a47129c
--- /dev/null
+++ b/FE/error/src/pages/LoginPage.jsx
@@ -0,0 +1,77 @@
+import styled from "styled-components";
+
+const LoginPage = () => {
+ return (
+ <>
+
+
+ 에러 캘린더에 떨어질
+
준비 되셨나요?
+
+
+ 에코노베이션 회원이 아니신 경우 로그인이 불가하며
+
+ 공식 일정만 조회 가능합니다.
+
+
+ 슬랙으로 로그인
+
+
+
+
+ >
+ );
+};
+
+export default LoginPage;
+
+const StyledTextArea = styled.div`
+ position: absolute;
+ top: 10rem;
+ left: 11rem;
+
+ h2 {
+ font-family: "Pretendard-bold";
+ font-size: 3rem;
+ font-weight: 900;
+ line-height: 3.7rem;
+ }
+ h3 {
+ line-height: 1.5rem;
+ }
+`;
+
+const StyledSlackButton = styled.button`
+ position: relative;
+ padding: 1rem 8.5rem 1rem 10.5rem;
+ border-radius: 1rem;
+ border: none;
+ background-color: #e1e1e1;
+ font-size: 1rem;
+ color: #6f6f6f;
+ font-weight: 700;
+ cursor: pointer;
+`;
+
+const StyledSlackImage = styled.img`
+ left: 8rem;
+ bottom: 0.9rem;
+ position: absolute;
+`;
+
+const StyledSubTitle = styled.h3`
+ margin-top: 1.7rem;
+ margin-bottom: 10rem;
+`;
+
+const StyledBackground = styled.img`
+ margin-left: 40rem;
+ margin-top: 5rem;
+ height: 35rem;
+`;
+
+const StyledCharacter = styled.img`
+ position: absolute;
+ top: 13rem;
+ left: 55rem;
+`;
diff --git a/FE/error/src/pages/MainPage.jsx b/FE/error/src/pages/MainPage.jsx
new file mode 100644
index 00000000..0b6fdd49
--- /dev/null
+++ b/FE/error/src/pages/MainPage.jsx
@@ -0,0 +1,46 @@
+import styled from "styled-components";
+import EconoCalendar from "../components/EconoCalendar";
+
+const MainPage = () => {
+ return (
+
+
+
+ ERROR
+
+
+
+
+
+ );
+};
+
+export default MainPage;
+
+const SideBar = styled.div`
+ width: 20vw;
+ height: 98.1vh;
+ margin-top: 1rem;
+`;
+
+const CalendarPage = styled.div`
+ display: flex;
+ width: 100%;
+`;
+
+const LineBox = styled.div`
+ width: 100%;
+ height: 1.25rem;
+ border: 1px solid #ddd;
+ border-right: none;
+ margin-top: 1.63em;
+`;
+
+const Logo = styled.div`
+ font-size: 2rem;
+ font-weight: bold;
+ margin-left: 1.5rem;
+ margin-top: 0.3rem;
+ color: #ff9999;
+ margin-bottom: 1rem;
+`;