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; +`;