├── .babelrc
├── .eslintrc.js
├── .github
├── ISSUE_TEMPLATE
│ ├── bug-template.md
│ ├── feature-template.md
│ └── refactor-template.md
└── pull_request_template.md
├── .gitignore
├── .pnp.cjs
├── .pnp.loader.mjs
├── .prettierrc
├── .vscode
├── extensions.json
└── settings.json
├── .yarn
├── cache
│ ├── @emotion-hash-npm-0.9.1-650576c2b1-716e17e48b.zip
│ ├── @emotion-memoize-npm-0.8.1-9b1e35ff15-a19cc01a29.zip
│ ├── @emotion-weak-memoize-npm-0.3.1-bfc18213af-b2be47caa2.zip
│ ├── @nodelib-fs.stat-npm-2.0.5-01f4dd3030-012480b5ca.zip
│ ├── @types-istanbul-lib-coverage-npm-2.0.4-734954bb56-a25d7589ee.zip
│ ├── @types-istanbul-reports-npm-3.0.1-770e825002-f1ad54bc68.zip
│ ├── @types-prop-types-npm-15.7.5-2aa48aa177-5b43b8b154.zip
│ ├── @types-scheduler-npm-0.16.3-887bfc0086-2b0aec39c2.zip
│ ├── @types-stack-utils-npm-2.0.1-867718ab70-205fdbe332.zip
│ ├── ansi-regex-npm-5.0.1-c963a48615-2aa4bb54ca.zip
│ ├── ansi-styles-npm-3.2.1-8cb8107983-d85ade01c1.zip
│ ├── ansi-styles-npm-5.2.0-72fc7003e3-d7f4e97ce0.zip
│ ├── array-buffer-byte-length-npm-1.0.0-331671f28a-044e101ce1.zip
│ ├── array-union-npm-2.1.0-4e4852b221-5bee12395c.zip
│ ├── astral-regex-npm-2.0.0-f30d866aab-876231688c.zip
│ ├── balanced-match-npm-1.0.2-a53c126459-9706c088a2.zip
│ ├── brace-expansion-npm-1.1.11-fb95eb05ad-faf34a7bb0.zip
│ ├── bundle-name-npm-3.0.0-d7e52ba2a3-edf2b1fbe6.zip
│ ├── callsites-npm-3.1.0-268f989910-072d17b6ab.zip
│ ├── client-only-npm-0.0.1-07d3e9505c-0c16bf660d.zip
│ ├── color-name-npm-1.1.3-728b7b5d39-09c5d3e33d.zip
│ ├── color-name-npm-1.1.4-025792b0ea-b044585952.zip
│ ├── convert-source-map-npm-1.9.0-e294555f4b-dc55a1f28d.zip
│ ├── default-browser-id-npm-3.0.0-f65ceaa214-279c7ad492.zip
│ ├── default-browser-npm-4.0.0-e9e9c8aba0-40c5af9847.zip
│ ├── define-properties-npm-1.2.0-3547cd0fd2-e60aee6a19.zip
│ ├── dir-glob-npm-3.0.1-1aea628b1b-fa05e18324.zip
│ ├── emotion-npm-11.0.0-37796da599-ab160e7378.zip
│ ├── emotion-reset-npm-3.0.1-061e1e27b7-788cfbf6f3.zip
│ ├── es-set-tostringtag-npm-2.0.1-c87b5de872-ec416a1294.zip
│ ├── escape-string-regexp-npm-1.0.5-3284de402f-6092fda75c.zip
│ ├── escape-string-regexp-npm-2.0.0-aef69d2a25-9f8a2d5743.zip
│ ├── escape-string-regexp-npm-4.0.0-4b531d8d59-98b48897d9.zip
│ ├── eslint-config-next-npm-13.0.0-5b02624f35-69f04df8d8.zip
│ ├── eslint-config-next-npm-13.3.4-f39f791450-f87ef8ade3.zip
│ ├── fast-deep-equal-npm-3.1.3-790edcfcf5-e21a9d8d84.zip
│ ├── find-up-npm-5.0.0-e03e9b796d-07955e3573.zip
│ ├── flatted-npm-3.2.7-0da10b7c56-427633049d.zip
│ ├── glob-parent-npm-6.0.2-2cbef12738-c13ee97978.zip
│ ├── has-flag-npm-3.0.0-16ac11fe05-4a15638b45.zip
│ ├── has-flag-npm-4.0.0-32af9f0536-261a135703.zip
│ ├── has-property-descriptors-npm-1.0.0-56289b918d-a6d3f0a266.zip
│ ├── import-fresh-npm-3.3.0-3e34265ca9-2cacfad06e.zip
│ ├── is-array-buffer-npm-3.0.2-0dec897785-dcac9dda66.zip
│ ├── is-docker-npm-2.2.1-3f18a53aff-3fef7ddbf0.zip
│ ├── is-docker-npm-3.0.0-1570e32177-b698118f04.zip
│ ├── is-extglob-npm-2.1.1-0870ea68b5-df033653d0.zip
│ ├── is-fullwidth-code-point-npm-3.0.0-1ecf4ebee5-44a30c2945.zip
│ ├── is-inside-container-npm-1.0.0-f2c9e9bb96-c50b75a2ab.zip
│ ├── is-path-inside-npm-3.0.3-2ea0ef44fd-abd50f0618.zip
│ ├── is-stream-npm-2.0.1-c802db55e7-b8e05ccdf9.zip
│ ├── is-stream-npm-3.0.0-a77ac9a62e-172093fe99.zip
│ ├── is-wsl-npm-2.2.0-2ba10d6393-20849846ae.zip
│ ├── jest-get-type-npm-29.4.3-790eefdb01-6ac7f2dde1.zip
│ ├── json-schema-traverse-npm-0.4.1-4759091693-7486074d3b.zip
│ ├── json-schema-traverse-npm-1.0.0-fb3684f4f0-02f2f466cd.zip
│ ├── lines-and-columns-npm-1.2.4-d6c7cc5799-0c37f9f7fa.zip
│ ├── locate-path-npm-6.0.0-06a1e4c528-72eb661788.zip
│ ├── loose-envify-npm-1.4.0-6307b72ccf-6517e24e0c.zip
│ ├── merge-stream-npm-2.0.0-2ac83efea5-6fa4dcc8d8.zip
│ ├── merge2-npm-1.4.1-a2507bd06c-7268db63ed.zip
│ ├── mimic-fn-npm-2.1.0-4fbeb3abb4-d2421a3444.zip
│ ├── mimic-fn-npm-4.0.0-feaeda79f7-995dcece15.zip
│ ├── ms-npm-2.1.2-ec0c1512ff-673cdb2c31.zip
│ ├── ms-npm-2.1.3-81ff3cfac1-aa92de6080.zip
│ ├── natural-compare-lite-npm-1.4.0-12b6b308ed-5222ac3986.zip
│ ├── natural-compare-npm-1.4.0-97b75b362d-23ad088b08.zip
│ ├── npm-run-path-npm-4.0.1-7aebd8bab3-5374c0cea4.zip
│ ├── npm-run-path-npm-5.1.0-79c0668d42-dc184eb5ec.zip
│ ├── object-assign-npm-4.1.1-1004ad6dec-fcc6e4ea8c.zip
│ ├── once-npm-1.4.0-ccf03ef07a-cd0a885013.zip
│ ├── onetime-npm-6.0.0-4f3684e29a-0846ce78e4.zip
│ ├── p-limit-npm-3.1.0-05d2ede37f-7c3690c4db.zip
│ ├── p-locate-npm-5.0.0-92cc7c7a3e-1623088f36.zip
│ ├── parent-module-npm-1.0.1-1fae11b095-6ba8b25514.zip
│ ├── parse-json-npm-5.2.0-00a63b1199-62085b17d6.zip
│ ├── path-exists-npm-4.0.0-e9e4f63eb0-505807199d.zip
│ ├── path-is-absolute-npm-1.0.1-31bc695ffd-060840f92c.zip
│ ├── path-key-npm-3.1.1-0e66ea8321-55cd7a9dd4.zip
│ ├── path-key-npm-4.0.0-2bce99f089-8e6c314ae6.zip
│ ├── path-parse-npm-1.0.7-09564527b7-49abf3d811.zip
│ ├── path-type-npm-4.0.0-10d47fc86a-5b1e2daa24.zip
│ ├── picocolors-npm-1.0.0-d81e0b1927-a2e8092dd8.zip
│ ├── reset-npm-0.1.0-f1733b9137-cf7dc9c876.zip
│ ├── run-applescript-npm-5.0.0-ea4b8840dd-d00c2dbfa5.zip
│ ├── run-parallel-npm-1.2.0-3f47ff2034-cb4f97ad25.zip
│ ├── shebang-command-npm-2.0.0-eb2b01921d-6b52fe8727.zip
│ ├── shebang-regex-npm-3.0.0-899a0cd65e-1a2bcae50d.zip
│ ├── signal-exit-npm-3.0.7-bd270458a3-a2f098f247.zip
│ ├── slash-npm-3.0.0-b87de2279a-94a93fff61.zip
│ ├── slash-npm-4.0.0-ce4bbc4a80-da8e4af737.zip
│ ├── slice-ansi-npm-4.0.0-6eeca1d10e-4a82d7f085.zip
│ ├── string-width-npm-4.2.3-2c27177bae-e52c10dc3f.zip
│ ├── strip-bom-npm-3.0.0-71e8f81ff9-8d50ff27b7.zip
│ ├── strip-final-newline-npm-2.0.0-340c4f7c66-69412b5e25.zip
│ ├── strip-final-newline-npm-3.0.0-7972cbec8b-23ee263adf.zip
│ ├── strip-json-comments-npm-3.1.1-dcb2324823-492f73e272.zip
│ ├── titleize-npm-3.0.0-7deac2f3a3-71fbbeabbf.zip
│ ├── to-fast-properties-npm-2.0.0-0dc60cc481-be2de62fe5.zip
│ ├── untildify-npm-4.0.0-4a8b569825-39ced9c418.zip
│ ├── wrappy-npm-1.0.2-916de4d4b3-159da4805f.zip
│ └── yocto-queue-npm-0.1.0-c6c9a7db29-f77b3d8d00.zip
├── releases
│ └── yarn-4.6.0.cjs
└── sdks
│ ├── eslint
│ ├── bin
│ │ └── eslint.js
│ ├── lib
│ │ └── api.js
│ └── package.json
│ ├── integrations.yml
│ ├── prettier
│ ├── index.js
│ └── package.json
│ └── typescript
│ ├── bin
│ ├── tsc
│ └── tsserver
│ ├── lib
│ ├── tsc.js
│ ├── tsserver.js
│ ├── tsserverlibrary.js
│ └── typescript.js
│ └── package.json
├── .yarnrc.yml
├── README.md
├── apps
├── admin
│ ├── .gitignore
│ ├── README.md
│ ├── next.config.js
│ ├── package.json
│ ├── public
│ │ ├── admin-favicon.svg
│ │ ├── favicon.ico
│ │ ├── next.svg
│ │ ├── og-admin.jpeg
│ │ └── vercel.svg
│ ├── src
│ │ ├── assets
│ │ │ ├── Arrow
│ │ │ │ └── index.tsx
│ │ │ ├── CEOS
│ │ │ │ └── index.tsx
│ │ │ ├── CloseBtn
│ │ │ │ └── index.tsx
│ │ │ ├── Loading
│ │ │ │ └── index.tsx
│ │ │ ├── MoreVert
│ │ │ │ └── index.tsx
│ │ │ ├── Plus
│ │ │ │ └── index.tsx
│ │ │ ├── Sidebar
│ │ │ │ └── index.tsx
│ │ │ └── data
│ │ │ │ ├── dropDownList.tsx
│ │ │ │ └── sidebarMenuList.tsx
│ │ ├── components
│ │ │ ├── Alert
│ │ │ │ └── index.tsx
│ │ │ ├── Common
│ │ │ │ ├── BackButton
│ │ │ │ │ └── index.tsx
│ │ │ │ └── PageTitle
│ │ │ │ │ └── index.tsx
│ │ │ ├── DataGrid
│ │ │ │ ├── Pagination.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── Dropdown
│ │ │ │ └── index.tsx
│ │ │ ├── ImageUploader
│ │ │ │ └── index.tsx
│ │ │ ├── Layout
│ │ │ │ └── index.tsx
│ │ │ ├── Loading
│ │ │ │ └── index.tsx
│ │ │ ├── Modals
│ │ │ │ ├── applicationModal.tsx
│ │ │ │ └── interviewTimeModal.tsx
│ │ │ ├── Sidebar
│ │ │ │ └── index.tsx
│ │ │ ├── activity
│ │ │ │ └── ActivityCardContainer
│ │ │ │ │ └── indext.tsx
│ │ │ ├── cookie.ts
│ │ │ ├── project
│ │ │ │ └── ProjectCardContainer
│ │ │ │ │ └── index.tsx
│ │ │ ├── reward
│ │ │ │ └── RewardCardContainer
│ │ │ │ │ └── index.tsx
│ │ │ └── sponsoredBy
│ │ │ │ └── SponsoredByContainer
│ │ │ │ └── index.tsx
│ │ ├── hooks
│ │ │ ├── useAlert.tsx
│ │ │ ├── useInfiniteQueries.tsx
│ │ │ └── usePresignedUrl.ts
│ │ ├── pages
│ │ │ ├── _app.tsx
│ │ │ ├── _document.tsx
│ │ │ ├── activity
│ │ │ │ └── [[...]].tsx
│ │ │ ├── api
│ │ │ │ └── hello.ts
│ │ │ ├── application
│ │ │ │ └── index.tsx
│ │ │ ├── applyStatement
│ │ │ │ └── index.tsx
│ │ │ ├── auth
│ │ │ │ ├── findID
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── findPW
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ └── signUp
│ │ │ │ │ └── index.tsx
│ │ │ ├── faq
│ │ │ │ └── index.tsx
│ │ │ ├── index.tsx
│ │ │ ├── manageUser
│ │ │ │ └── index.tsx
│ │ │ ├── management
│ │ │ │ ├── add
│ │ │ │ │ └── [[...id]].tsx
│ │ │ │ └── index.tsx
│ │ │ ├── project
│ │ │ │ ├── edit
│ │ │ │ │ └── [[...id]].tsx
│ │ │ │ └── index.tsx
│ │ │ ├── recruit
│ │ │ │ └── index.tsx
│ │ │ ├── reward
│ │ │ │ ├── add
│ │ │ │ │ └── [[...id]].tsx
│ │ │ │ └── index.tsx
│ │ │ └── sponsoredby
│ │ │ │ └── [[...]].tsx
│ │ ├── store
│ │ │ └── recoil
│ │ │ │ └── index.tsx
│ │ ├── styles
│ │ │ ├── Home.module.css
│ │ │ ├── common.tsx
│ │ │ └── globals.css
│ │ └── utils
│ │ │ ├── date.ts
│ │ │ └── dropdown.ts
│ └── tsconfig.json
└── ceos
│ ├── .gitignore
│ ├── README.md
│ ├── next.config.js
│ ├── package.json
│ ├── public
│ ├── 404-desktop.png
│ ├── 404-mobile.png
│ ├── banner-graphic-mobile.png
│ ├── banner-graphic-web.png
│ ├── ceos-favicon.svg
│ ├── footer
│ │ ├── background-desktop.png
│ │ └── background-mobile.png
│ ├── header
│ │ ├── activity.svg
│ │ ├── faq.svg
│ │ ├── project.svg
│ │ └── recruit.svg
│ ├── mobileShortcuts.svg
│ ├── next.svg
│ ├── og-ceos.jpeg
│ ├── recruit
│ │ ├── banner-desktop.png
│ │ ├── banner-mobile.png
│ │ ├── pass-desktop.png
│ │ └── pass-mobile.png
│ ├── shortcuts.svg
│ └── vercel.svg
│ ├── src
│ ├── assets
│ │ ├── ArrowUpRight.tsx
│ │ ├── Diamond.tsx
│ │ ├── FAQIcon.tsx
│ │ ├── apply
│ │ │ ├── ModalBgImage.tsx
│ │ │ └── modalBackground.svg
│ │ ├── bgImage
│ │ │ └── index.tsx
│ │ ├── constant.tsx
│ │ ├── header
│ │ │ └── menuBtn.tsx
│ │ ├── landing
│ │ │ ├── glassButtonText.tsx
│ │ │ ├── shortcutBackground.tsx
│ │ │ └── title.tsx
│ │ └── logo
│ │ │ └── index.tsx
│ ├── components
│ │ ├── FAQBox
│ │ │ └── index.tsx
│ │ ├── Footer
│ │ │ └── index.tsx
│ │ ├── FooterText
│ │ │ └── index.tsx
│ │ ├── GlassBox
│ │ │ └── index.tsx
│ │ ├── Header
│ │ │ └── index.tsx
│ │ ├── Landing
│ │ │ ├── buttons.tsx
│ │ │ ├── rewards.tsx
│ │ │ ├── sponsor.tsx
│ │ │ └── subHeader.tsx
│ │ ├── Layout
│ │ │ └── index.tsx
│ │ ├── MenuBar
│ │ │ └── index.tsx
│ │ ├── Modals
│ │ │ ├── checkModal.tsx
│ │ │ ├── dropModal.tsx
│ │ │ ├── emailModal.tsx
│ │ │ └── timeModal.tsx
│ │ ├── Shortcut
│ │ │ └── index.tsx
│ │ ├── Title
│ │ │ └── index.tsx
│ │ ├── project
│ │ │ ├── DetailModal
│ │ │ │ └── index.tsx
│ │ │ └── ProjectCardContainer
│ │ │ │ └── index.tsx
│ │ ├── recruit
│ │ │ ├── Common.tsx
│ │ │ ├── Information.tsx
│ │ │ ├── Part.tsx
│ │ │ ├── Schedule.tsx
│ │ │ ├── docpass
│ │ │ │ └── index.tsx
│ │ │ ├── finpass
│ │ │ │ └── index.tsx
│ │ │ ├── interface.tsx
│ │ │ ├── nonpass
│ │ │ │ └── index.tsx
│ │ │ ├── recruitBox.tsx
│ │ │ ├── recruitBtn.tsx
│ │ │ ├── recruitSubHeader.tsx
│ │ │ └── style
│ │ │ │ └── index.tsx
│ │ └── recruitModal
│ │ │ ├── ErrorModal.tsx
│ │ │ ├── SubmitModal.tsx
│ │ │ └── SuccessModal.tsx
│ ├── hooks
│ │ ├── useInfiniteQueries.tsx
│ │ └── useWindoSize.ts
│ ├── pages
│ │ ├── 404.tsx
│ │ ├── FAQ
│ │ │ └── index.tsx
│ │ ├── _app.tsx
│ │ ├── _document.tsx
│ │ ├── activity
│ │ │ └── index.tsx
│ │ ├── index.tsx
│ │ ├── management
│ │ │ └── index.tsx
│ │ ├── project
│ │ │ └── index.tsx
│ │ ├── recruit
│ │ │ ├── apply
│ │ │ │ └── index.tsx
│ │ │ └── index.tsx
│ │ └── rewards
│ │ │ └── index.tsx
│ ├── state
│ │ └── index.tsx
│ └── styles
│ │ ├── Home.module.css
│ │ ├── globals.css
│ │ ├── landing
│ │ └── index.tsx
│ │ └── recruit
│ │ └── index.tsx
│ └── tsconfig.json
├── package.json
├── packages
├── eslint-config-custom
│ ├── index.js
│ └── package.json
├── tsconfig
│ ├── README.md
│ ├── base.json
│ ├── nextjs.json
│ ├── package.json
│ └── react-library.json
├── ui
│ ├── custom.d.ts
│ ├── index.tsx
│ ├── package.json
│ ├── src
│ │ ├── assets
│ │ │ ├── Arrow
│ │ │ │ └── index.tsx
│ │ │ ├── Calender
│ │ │ │ └── index.tsx
│ │ │ ├── CheckIcon
│ │ │ │ └── index.tsx
│ │ │ ├── CloseIcon
│ │ │ │ ├── WhiteCloseIcon.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── FloatingButton
│ │ │ │ ├── Email
│ │ │ │ │ └── index.tsx
│ │ │ │ └── Instagram
│ │ │ │ │ └── index.tsx
│ │ │ ├── RewardCheck
│ │ │ │ └── index.tsx
│ │ │ └── SubTextFieldIcon
│ │ │ │ └── index.tsx
│ │ ├── components
│ │ │ ├── Button
│ │ │ │ └── index.tsx
│ │ │ ├── Card
│ │ │ │ ├── ActivityCard.tsx
│ │ │ │ ├── ManagementCard.tsx
│ │ │ │ ├── ProjectCard.tsx
│ │ │ │ ├── RewardCard.tsx
│ │ │ │ ├── SponsorCard.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── Checkbox
│ │ │ │ └── index.tsx
│ │ │ ├── DatePicker
│ │ │ │ └── index.tsx
│ │ │ ├── FloatingButton
│ │ │ │ └── index.tsx
│ │ │ ├── SelectButton
│ │ │ │ └── index.tsx
│ │ │ ├── TextField
│ │ │ │ └── index.tsx
│ │ │ └── common
│ │ │ │ ├── Text.tsx
│ │ │ │ ├── Wrapper.tsx
│ │ │ │ └── index.tsx
│ │ ├── custom.d.ts
│ │ └── styles
│ │ │ ├── GlobalStyles.ts
│ │ │ ├── emotion.d.ts
│ │ │ ├── glass.tsx
│ │ │ ├── index.tsx
│ │ │ ├── mediaQuery.ts
│ │ │ ├── palette.tsx
│ │ │ ├── shadow.tsx
│ │ │ ├── theme.tsx
│ │ │ └── typo.tsx
│ └── tsconfig.json
└── utils
│ ├── README.md
│ ├── index.tsx
│ ├── package.json
│ ├── src
│ ├── apis
│ │ ├── admin
│ │ │ ├── adminActivityApi.ts
│ │ │ ├── adminApplicationApi.ts
│ │ │ ├── adminApplyStatementApi.tsx
│ │ │ ├── adminAuthApi.tsx
│ │ │ ├── adminFaqApi.ts
│ │ │ ├── adminInterviewAvailabilityApi.tsx
│ │ │ ├── adminManageUserApi.tsx
│ │ │ ├── adminManagementApi.ts
│ │ │ ├── adminProjectApi.ts
│ │ │ ├── adminRecruitApi.ts
│ │ │ ├── adminRewardApi.ts
│ │ │ ├── adminSponsoredByApi.tsx
│ │ │ ├── imageApi.ts
│ │ │ ├── index.ts
│ │ │ └── sendEmailApi.ts
│ │ ├── axiosConfig.ts
│ │ ├── ceos
│ │ │ ├── activityApi.ts
│ │ │ ├── awardApi.ts
│ │ │ ├── emailApi.ts
│ │ │ ├── faqApi.ts
│ │ │ ├── index.ts
│ │ │ ├── managementApi.ts
│ │ │ ├── projectApi.ts
│ │ │ ├── recruitApi.ts
│ │ │ └── sponsorApi.ts
│ │ └── index.ts
│ ├── hooks
│ │ ├── useModal.ts
│ │ └── useWindowResize.ts
│ └── utils
│ │ ├── index.ts
│ │ └── portal.tsx
│ └── tsconfig.json
├── tsconfig.base.json
├── turbo.json
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["next/babel"],
3 | "plugins": ["emotion"]
4 | }
5 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | // This tells ESLint to load the config from the package `eslint-config-custom`
4 | extends: ['custom'],
5 | settings: {
6 | next: {
7 | rootDir: ['apps/*/'],
8 | },
9 | },
10 | };
11 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug-template.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug Template
3 | about: Bug 발생 시 사용해주세요
4 | title: "[Bug]"
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | ### 🐞 버그 개요
11 |
12 |
13 | ### 📌 설명
14 |
15 |
16 | ### ✅ TODO
17 |
18 | - [ ] todo
19 | - [ ] todo
20 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature-template.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature Template
3 | about: Feature 작업 시 사용해주세요
4 | title: "[Feat]"
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | ### ✏️ 기능 개요
11 |
12 |
13 | ### ✅ TODO
14 |
15 | - [ ] todo
16 | - [ ] todo
17 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/refactor-template.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Refactor Template
3 | about: 리팩토링 시 사용해주세요
4 | title: "[Refactor]"
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | ### ⚒️ 리팩토링 개요
11 |
12 |
13 | ### ✅ TODO
14 |
15 | - [ ] todo
16 | - [ ] todo
17 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | ## 🛠 관련 이슈
2 |
3 | ## 📝 수정 사항
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | node_modules
5 | .pnp
6 | .pnp.js
7 |
8 | # testing
9 | coverage
10 |
11 | # next.js
12 | .next/
13 | out/
14 | build
15 |
16 | # misc
17 | .DS_Store
18 | *.pem
19 |
20 | # debug
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 | .pnpm-debug.log*
25 |
26 | # Ignore all .env files in the apps directory and its subdirectories
27 | apps/**/.env
28 |
29 | # local env files
30 | .env.local
31 | .env.development.local
32 | .env.test.local
33 | .env.production.local
34 |
35 | # turbo
36 | .turbo
37 | .yarn/cache
38 | .yarn/install-state.gz
39 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "semi": true,
4 | "useTabs": false,
5 | "tabWidth": 2,
6 | "trailingComma": "all",
7 | "printWidth": 80
8 | }
9 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "arcanis.vscode-zipfs",
4 | "dbaeumer.vscode-eslint",
5 | "esbenp.prettier-vscode"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "search.exclude": {
3 | "**/.yarn": true,
4 | "**/.pnp.*": true
5 | },
6 | "eslint.nodePath": ".yarn/sdks",
7 | "prettier.prettierPath": ".yarn/sdks/prettier/index.js",
8 | "typescript.tsdk": ".yarn/sdks/typescript/lib",
9 | "typescript.enablePromptUseWorkspaceTsdk": true,
10 | "editor.defaultFormatter": "esbenp.prettier-vscode",
11 | "editor.formatOnSave": true,
12 | "editor.rulers": [120],
13 | "svn.ignoreMissingSvnWarning": true
14 | }
15 |
--------------------------------------------------------------------------------
/.yarn/cache/@emotion-hash-npm-0.9.1-650576c2b1-716e17e48b.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/@emotion-hash-npm-0.9.1-650576c2b1-716e17e48b.zip
--------------------------------------------------------------------------------
/.yarn/cache/@emotion-memoize-npm-0.8.1-9b1e35ff15-a19cc01a29.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/@emotion-memoize-npm-0.8.1-9b1e35ff15-a19cc01a29.zip
--------------------------------------------------------------------------------
/.yarn/cache/@emotion-weak-memoize-npm-0.3.1-bfc18213af-b2be47caa2.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/@emotion-weak-memoize-npm-0.3.1-bfc18213af-b2be47caa2.zip
--------------------------------------------------------------------------------
/.yarn/cache/@nodelib-fs.stat-npm-2.0.5-01f4dd3030-012480b5ca.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/@nodelib-fs.stat-npm-2.0.5-01f4dd3030-012480b5ca.zip
--------------------------------------------------------------------------------
/.yarn/cache/@types-istanbul-lib-coverage-npm-2.0.4-734954bb56-a25d7589ee.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/@types-istanbul-lib-coverage-npm-2.0.4-734954bb56-a25d7589ee.zip
--------------------------------------------------------------------------------
/.yarn/cache/@types-istanbul-reports-npm-3.0.1-770e825002-f1ad54bc68.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/@types-istanbul-reports-npm-3.0.1-770e825002-f1ad54bc68.zip
--------------------------------------------------------------------------------
/.yarn/cache/@types-prop-types-npm-15.7.5-2aa48aa177-5b43b8b154.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/@types-prop-types-npm-15.7.5-2aa48aa177-5b43b8b154.zip
--------------------------------------------------------------------------------
/.yarn/cache/@types-scheduler-npm-0.16.3-887bfc0086-2b0aec39c2.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/@types-scheduler-npm-0.16.3-887bfc0086-2b0aec39c2.zip
--------------------------------------------------------------------------------
/.yarn/cache/@types-stack-utils-npm-2.0.1-867718ab70-205fdbe332.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/@types-stack-utils-npm-2.0.1-867718ab70-205fdbe332.zip
--------------------------------------------------------------------------------
/.yarn/cache/ansi-regex-npm-5.0.1-c963a48615-2aa4bb54ca.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/ansi-regex-npm-5.0.1-c963a48615-2aa4bb54ca.zip
--------------------------------------------------------------------------------
/.yarn/cache/ansi-styles-npm-3.2.1-8cb8107983-d85ade01c1.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/ansi-styles-npm-3.2.1-8cb8107983-d85ade01c1.zip
--------------------------------------------------------------------------------
/.yarn/cache/ansi-styles-npm-5.2.0-72fc7003e3-d7f4e97ce0.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/ansi-styles-npm-5.2.0-72fc7003e3-d7f4e97ce0.zip
--------------------------------------------------------------------------------
/.yarn/cache/array-buffer-byte-length-npm-1.0.0-331671f28a-044e101ce1.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/array-buffer-byte-length-npm-1.0.0-331671f28a-044e101ce1.zip
--------------------------------------------------------------------------------
/.yarn/cache/array-union-npm-2.1.0-4e4852b221-5bee12395c.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/array-union-npm-2.1.0-4e4852b221-5bee12395c.zip
--------------------------------------------------------------------------------
/.yarn/cache/astral-regex-npm-2.0.0-f30d866aab-876231688c.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/astral-regex-npm-2.0.0-f30d866aab-876231688c.zip
--------------------------------------------------------------------------------
/.yarn/cache/balanced-match-npm-1.0.2-a53c126459-9706c088a2.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/balanced-match-npm-1.0.2-a53c126459-9706c088a2.zip
--------------------------------------------------------------------------------
/.yarn/cache/brace-expansion-npm-1.1.11-fb95eb05ad-faf34a7bb0.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/brace-expansion-npm-1.1.11-fb95eb05ad-faf34a7bb0.zip
--------------------------------------------------------------------------------
/.yarn/cache/bundle-name-npm-3.0.0-d7e52ba2a3-edf2b1fbe6.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/bundle-name-npm-3.0.0-d7e52ba2a3-edf2b1fbe6.zip
--------------------------------------------------------------------------------
/.yarn/cache/callsites-npm-3.1.0-268f989910-072d17b6ab.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/callsites-npm-3.1.0-268f989910-072d17b6ab.zip
--------------------------------------------------------------------------------
/.yarn/cache/client-only-npm-0.0.1-07d3e9505c-0c16bf660d.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/client-only-npm-0.0.1-07d3e9505c-0c16bf660d.zip
--------------------------------------------------------------------------------
/.yarn/cache/color-name-npm-1.1.3-728b7b5d39-09c5d3e33d.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/color-name-npm-1.1.3-728b7b5d39-09c5d3e33d.zip
--------------------------------------------------------------------------------
/.yarn/cache/color-name-npm-1.1.4-025792b0ea-b044585952.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/color-name-npm-1.1.4-025792b0ea-b044585952.zip
--------------------------------------------------------------------------------
/.yarn/cache/convert-source-map-npm-1.9.0-e294555f4b-dc55a1f28d.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/convert-source-map-npm-1.9.0-e294555f4b-dc55a1f28d.zip
--------------------------------------------------------------------------------
/.yarn/cache/default-browser-id-npm-3.0.0-f65ceaa214-279c7ad492.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/default-browser-id-npm-3.0.0-f65ceaa214-279c7ad492.zip
--------------------------------------------------------------------------------
/.yarn/cache/default-browser-npm-4.0.0-e9e9c8aba0-40c5af9847.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/default-browser-npm-4.0.0-e9e9c8aba0-40c5af9847.zip
--------------------------------------------------------------------------------
/.yarn/cache/define-properties-npm-1.2.0-3547cd0fd2-e60aee6a19.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/define-properties-npm-1.2.0-3547cd0fd2-e60aee6a19.zip
--------------------------------------------------------------------------------
/.yarn/cache/dir-glob-npm-3.0.1-1aea628b1b-fa05e18324.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/dir-glob-npm-3.0.1-1aea628b1b-fa05e18324.zip
--------------------------------------------------------------------------------
/.yarn/cache/emotion-npm-11.0.0-37796da599-ab160e7378.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/emotion-npm-11.0.0-37796da599-ab160e7378.zip
--------------------------------------------------------------------------------
/.yarn/cache/emotion-reset-npm-3.0.1-061e1e27b7-788cfbf6f3.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/emotion-reset-npm-3.0.1-061e1e27b7-788cfbf6f3.zip
--------------------------------------------------------------------------------
/.yarn/cache/es-set-tostringtag-npm-2.0.1-c87b5de872-ec416a1294.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/es-set-tostringtag-npm-2.0.1-c87b5de872-ec416a1294.zip
--------------------------------------------------------------------------------
/.yarn/cache/escape-string-regexp-npm-1.0.5-3284de402f-6092fda75c.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/escape-string-regexp-npm-1.0.5-3284de402f-6092fda75c.zip
--------------------------------------------------------------------------------
/.yarn/cache/escape-string-regexp-npm-2.0.0-aef69d2a25-9f8a2d5743.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/escape-string-regexp-npm-2.0.0-aef69d2a25-9f8a2d5743.zip
--------------------------------------------------------------------------------
/.yarn/cache/escape-string-regexp-npm-4.0.0-4b531d8d59-98b48897d9.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/escape-string-regexp-npm-4.0.0-4b531d8d59-98b48897d9.zip
--------------------------------------------------------------------------------
/.yarn/cache/eslint-config-next-npm-13.0.0-5b02624f35-69f04df8d8.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/eslint-config-next-npm-13.0.0-5b02624f35-69f04df8d8.zip
--------------------------------------------------------------------------------
/.yarn/cache/eslint-config-next-npm-13.3.4-f39f791450-f87ef8ade3.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/eslint-config-next-npm-13.3.4-f39f791450-f87ef8ade3.zip
--------------------------------------------------------------------------------
/.yarn/cache/fast-deep-equal-npm-3.1.3-790edcfcf5-e21a9d8d84.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/fast-deep-equal-npm-3.1.3-790edcfcf5-e21a9d8d84.zip
--------------------------------------------------------------------------------
/.yarn/cache/find-up-npm-5.0.0-e03e9b796d-07955e3573.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/find-up-npm-5.0.0-e03e9b796d-07955e3573.zip
--------------------------------------------------------------------------------
/.yarn/cache/flatted-npm-3.2.7-0da10b7c56-427633049d.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/flatted-npm-3.2.7-0da10b7c56-427633049d.zip
--------------------------------------------------------------------------------
/.yarn/cache/glob-parent-npm-6.0.2-2cbef12738-c13ee97978.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/glob-parent-npm-6.0.2-2cbef12738-c13ee97978.zip
--------------------------------------------------------------------------------
/.yarn/cache/has-flag-npm-3.0.0-16ac11fe05-4a15638b45.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/has-flag-npm-3.0.0-16ac11fe05-4a15638b45.zip
--------------------------------------------------------------------------------
/.yarn/cache/has-flag-npm-4.0.0-32af9f0536-261a135703.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/has-flag-npm-4.0.0-32af9f0536-261a135703.zip
--------------------------------------------------------------------------------
/.yarn/cache/has-property-descriptors-npm-1.0.0-56289b918d-a6d3f0a266.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/has-property-descriptors-npm-1.0.0-56289b918d-a6d3f0a266.zip
--------------------------------------------------------------------------------
/.yarn/cache/import-fresh-npm-3.3.0-3e34265ca9-2cacfad06e.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/import-fresh-npm-3.3.0-3e34265ca9-2cacfad06e.zip
--------------------------------------------------------------------------------
/.yarn/cache/is-array-buffer-npm-3.0.2-0dec897785-dcac9dda66.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/is-array-buffer-npm-3.0.2-0dec897785-dcac9dda66.zip
--------------------------------------------------------------------------------
/.yarn/cache/is-docker-npm-2.2.1-3f18a53aff-3fef7ddbf0.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/is-docker-npm-2.2.1-3f18a53aff-3fef7ddbf0.zip
--------------------------------------------------------------------------------
/.yarn/cache/is-docker-npm-3.0.0-1570e32177-b698118f04.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/is-docker-npm-3.0.0-1570e32177-b698118f04.zip
--------------------------------------------------------------------------------
/.yarn/cache/is-extglob-npm-2.1.1-0870ea68b5-df033653d0.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/is-extglob-npm-2.1.1-0870ea68b5-df033653d0.zip
--------------------------------------------------------------------------------
/.yarn/cache/is-fullwidth-code-point-npm-3.0.0-1ecf4ebee5-44a30c2945.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/is-fullwidth-code-point-npm-3.0.0-1ecf4ebee5-44a30c2945.zip
--------------------------------------------------------------------------------
/.yarn/cache/is-inside-container-npm-1.0.0-f2c9e9bb96-c50b75a2ab.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/is-inside-container-npm-1.0.0-f2c9e9bb96-c50b75a2ab.zip
--------------------------------------------------------------------------------
/.yarn/cache/is-path-inside-npm-3.0.3-2ea0ef44fd-abd50f0618.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/is-path-inside-npm-3.0.3-2ea0ef44fd-abd50f0618.zip
--------------------------------------------------------------------------------
/.yarn/cache/is-stream-npm-2.0.1-c802db55e7-b8e05ccdf9.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/is-stream-npm-2.0.1-c802db55e7-b8e05ccdf9.zip
--------------------------------------------------------------------------------
/.yarn/cache/is-stream-npm-3.0.0-a77ac9a62e-172093fe99.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/is-stream-npm-3.0.0-a77ac9a62e-172093fe99.zip
--------------------------------------------------------------------------------
/.yarn/cache/is-wsl-npm-2.2.0-2ba10d6393-20849846ae.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/is-wsl-npm-2.2.0-2ba10d6393-20849846ae.zip
--------------------------------------------------------------------------------
/.yarn/cache/jest-get-type-npm-29.4.3-790eefdb01-6ac7f2dde1.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/jest-get-type-npm-29.4.3-790eefdb01-6ac7f2dde1.zip
--------------------------------------------------------------------------------
/.yarn/cache/json-schema-traverse-npm-0.4.1-4759091693-7486074d3b.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/json-schema-traverse-npm-0.4.1-4759091693-7486074d3b.zip
--------------------------------------------------------------------------------
/.yarn/cache/json-schema-traverse-npm-1.0.0-fb3684f4f0-02f2f466cd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/json-schema-traverse-npm-1.0.0-fb3684f4f0-02f2f466cd.zip
--------------------------------------------------------------------------------
/.yarn/cache/lines-and-columns-npm-1.2.4-d6c7cc5799-0c37f9f7fa.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/lines-and-columns-npm-1.2.4-d6c7cc5799-0c37f9f7fa.zip
--------------------------------------------------------------------------------
/.yarn/cache/locate-path-npm-6.0.0-06a1e4c528-72eb661788.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/locate-path-npm-6.0.0-06a1e4c528-72eb661788.zip
--------------------------------------------------------------------------------
/.yarn/cache/loose-envify-npm-1.4.0-6307b72ccf-6517e24e0c.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/loose-envify-npm-1.4.0-6307b72ccf-6517e24e0c.zip
--------------------------------------------------------------------------------
/.yarn/cache/merge-stream-npm-2.0.0-2ac83efea5-6fa4dcc8d8.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/merge-stream-npm-2.0.0-2ac83efea5-6fa4dcc8d8.zip
--------------------------------------------------------------------------------
/.yarn/cache/merge2-npm-1.4.1-a2507bd06c-7268db63ed.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/merge2-npm-1.4.1-a2507bd06c-7268db63ed.zip
--------------------------------------------------------------------------------
/.yarn/cache/mimic-fn-npm-2.1.0-4fbeb3abb4-d2421a3444.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/mimic-fn-npm-2.1.0-4fbeb3abb4-d2421a3444.zip
--------------------------------------------------------------------------------
/.yarn/cache/mimic-fn-npm-4.0.0-feaeda79f7-995dcece15.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/mimic-fn-npm-4.0.0-feaeda79f7-995dcece15.zip
--------------------------------------------------------------------------------
/.yarn/cache/ms-npm-2.1.2-ec0c1512ff-673cdb2c31.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/ms-npm-2.1.2-ec0c1512ff-673cdb2c31.zip
--------------------------------------------------------------------------------
/.yarn/cache/ms-npm-2.1.3-81ff3cfac1-aa92de6080.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/ms-npm-2.1.3-81ff3cfac1-aa92de6080.zip
--------------------------------------------------------------------------------
/.yarn/cache/natural-compare-lite-npm-1.4.0-12b6b308ed-5222ac3986.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/natural-compare-lite-npm-1.4.0-12b6b308ed-5222ac3986.zip
--------------------------------------------------------------------------------
/.yarn/cache/natural-compare-npm-1.4.0-97b75b362d-23ad088b08.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/natural-compare-npm-1.4.0-97b75b362d-23ad088b08.zip
--------------------------------------------------------------------------------
/.yarn/cache/npm-run-path-npm-4.0.1-7aebd8bab3-5374c0cea4.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/npm-run-path-npm-4.0.1-7aebd8bab3-5374c0cea4.zip
--------------------------------------------------------------------------------
/.yarn/cache/npm-run-path-npm-5.1.0-79c0668d42-dc184eb5ec.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/npm-run-path-npm-5.1.0-79c0668d42-dc184eb5ec.zip
--------------------------------------------------------------------------------
/.yarn/cache/object-assign-npm-4.1.1-1004ad6dec-fcc6e4ea8c.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/object-assign-npm-4.1.1-1004ad6dec-fcc6e4ea8c.zip
--------------------------------------------------------------------------------
/.yarn/cache/once-npm-1.4.0-ccf03ef07a-cd0a885013.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/once-npm-1.4.0-ccf03ef07a-cd0a885013.zip
--------------------------------------------------------------------------------
/.yarn/cache/onetime-npm-6.0.0-4f3684e29a-0846ce78e4.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/onetime-npm-6.0.0-4f3684e29a-0846ce78e4.zip
--------------------------------------------------------------------------------
/.yarn/cache/p-limit-npm-3.1.0-05d2ede37f-7c3690c4db.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/p-limit-npm-3.1.0-05d2ede37f-7c3690c4db.zip
--------------------------------------------------------------------------------
/.yarn/cache/p-locate-npm-5.0.0-92cc7c7a3e-1623088f36.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/p-locate-npm-5.0.0-92cc7c7a3e-1623088f36.zip
--------------------------------------------------------------------------------
/.yarn/cache/parent-module-npm-1.0.1-1fae11b095-6ba8b25514.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/parent-module-npm-1.0.1-1fae11b095-6ba8b25514.zip
--------------------------------------------------------------------------------
/.yarn/cache/parse-json-npm-5.2.0-00a63b1199-62085b17d6.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/parse-json-npm-5.2.0-00a63b1199-62085b17d6.zip
--------------------------------------------------------------------------------
/.yarn/cache/path-exists-npm-4.0.0-e9e4f63eb0-505807199d.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/path-exists-npm-4.0.0-e9e4f63eb0-505807199d.zip
--------------------------------------------------------------------------------
/.yarn/cache/path-is-absolute-npm-1.0.1-31bc695ffd-060840f92c.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/path-is-absolute-npm-1.0.1-31bc695ffd-060840f92c.zip
--------------------------------------------------------------------------------
/.yarn/cache/path-key-npm-3.1.1-0e66ea8321-55cd7a9dd4.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/path-key-npm-3.1.1-0e66ea8321-55cd7a9dd4.zip
--------------------------------------------------------------------------------
/.yarn/cache/path-key-npm-4.0.0-2bce99f089-8e6c314ae6.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/path-key-npm-4.0.0-2bce99f089-8e6c314ae6.zip
--------------------------------------------------------------------------------
/.yarn/cache/path-parse-npm-1.0.7-09564527b7-49abf3d811.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/path-parse-npm-1.0.7-09564527b7-49abf3d811.zip
--------------------------------------------------------------------------------
/.yarn/cache/path-type-npm-4.0.0-10d47fc86a-5b1e2daa24.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/path-type-npm-4.0.0-10d47fc86a-5b1e2daa24.zip
--------------------------------------------------------------------------------
/.yarn/cache/picocolors-npm-1.0.0-d81e0b1927-a2e8092dd8.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/picocolors-npm-1.0.0-d81e0b1927-a2e8092dd8.zip
--------------------------------------------------------------------------------
/.yarn/cache/reset-npm-0.1.0-f1733b9137-cf7dc9c876.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/reset-npm-0.1.0-f1733b9137-cf7dc9c876.zip
--------------------------------------------------------------------------------
/.yarn/cache/run-applescript-npm-5.0.0-ea4b8840dd-d00c2dbfa5.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/run-applescript-npm-5.0.0-ea4b8840dd-d00c2dbfa5.zip
--------------------------------------------------------------------------------
/.yarn/cache/run-parallel-npm-1.2.0-3f47ff2034-cb4f97ad25.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/run-parallel-npm-1.2.0-3f47ff2034-cb4f97ad25.zip
--------------------------------------------------------------------------------
/.yarn/cache/shebang-command-npm-2.0.0-eb2b01921d-6b52fe8727.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/shebang-command-npm-2.0.0-eb2b01921d-6b52fe8727.zip
--------------------------------------------------------------------------------
/.yarn/cache/shebang-regex-npm-3.0.0-899a0cd65e-1a2bcae50d.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/shebang-regex-npm-3.0.0-899a0cd65e-1a2bcae50d.zip
--------------------------------------------------------------------------------
/.yarn/cache/signal-exit-npm-3.0.7-bd270458a3-a2f098f247.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/signal-exit-npm-3.0.7-bd270458a3-a2f098f247.zip
--------------------------------------------------------------------------------
/.yarn/cache/slash-npm-3.0.0-b87de2279a-94a93fff61.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/slash-npm-3.0.0-b87de2279a-94a93fff61.zip
--------------------------------------------------------------------------------
/.yarn/cache/slash-npm-4.0.0-ce4bbc4a80-da8e4af737.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/slash-npm-4.0.0-ce4bbc4a80-da8e4af737.zip
--------------------------------------------------------------------------------
/.yarn/cache/slice-ansi-npm-4.0.0-6eeca1d10e-4a82d7f085.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/slice-ansi-npm-4.0.0-6eeca1d10e-4a82d7f085.zip
--------------------------------------------------------------------------------
/.yarn/cache/string-width-npm-4.2.3-2c27177bae-e52c10dc3f.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/string-width-npm-4.2.3-2c27177bae-e52c10dc3f.zip
--------------------------------------------------------------------------------
/.yarn/cache/strip-bom-npm-3.0.0-71e8f81ff9-8d50ff27b7.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/strip-bom-npm-3.0.0-71e8f81ff9-8d50ff27b7.zip
--------------------------------------------------------------------------------
/.yarn/cache/strip-final-newline-npm-2.0.0-340c4f7c66-69412b5e25.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/strip-final-newline-npm-2.0.0-340c4f7c66-69412b5e25.zip
--------------------------------------------------------------------------------
/.yarn/cache/strip-final-newline-npm-3.0.0-7972cbec8b-23ee263adf.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/strip-final-newline-npm-3.0.0-7972cbec8b-23ee263adf.zip
--------------------------------------------------------------------------------
/.yarn/cache/strip-json-comments-npm-3.1.1-dcb2324823-492f73e272.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/strip-json-comments-npm-3.1.1-dcb2324823-492f73e272.zip
--------------------------------------------------------------------------------
/.yarn/cache/titleize-npm-3.0.0-7deac2f3a3-71fbbeabbf.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/titleize-npm-3.0.0-7deac2f3a3-71fbbeabbf.zip
--------------------------------------------------------------------------------
/.yarn/cache/to-fast-properties-npm-2.0.0-0dc60cc481-be2de62fe5.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/to-fast-properties-npm-2.0.0-0dc60cc481-be2de62fe5.zip
--------------------------------------------------------------------------------
/.yarn/cache/untildify-npm-4.0.0-4a8b569825-39ced9c418.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/untildify-npm-4.0.0-4a8b569825-39ced9c418.zip
--------------------------------------------------------------------------------
/.yarn/cache/wrappy-npm-1.0.2-916de4d4b3-159da4805f.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/wrappy-npm-1.0.2-916de4d4b3-159da4805f.zip
--------------------------------------------------------------------------------
/.yarn/cache/yocto-queue-npm-0.1.0-c6c9a7db29-f77b3d8d00.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/.yarn/cache/yocto-queue-npm-0.1.0-c6c9a7db29-f77b3d8d00.zip
--------------------------------------------------------------------------------
/.yarn/sdks/eslint/bin/eslint.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const {existsSync} = require(`fs`);
4 | const {createRequire} = require(`module`);
5 | const {resolve} = require(`path`);
6 |
7 | const relPnpApiPath = "../../../../.pnp.cjs";
8 |
9 | const absPnpApiPath = resolve(__dirname, relPnpApiPath);
10 | const absRequire = createRequire(absPnpApiPath);
11 |
12 | if (existsSync(absPnpApiPath)) {
13 | if (!process.versions.pnp) {
14 | // Setup the environment to be able to require eslint/bin/eslint.js
15 | require(absPnpApiPath).setup();
16 | }
17 | }
18 |
19 | // Defer to the real eslint/bin/eslint.js your application uses
20 | module.exports = absRequire(`eslint/bin/eslint.js`);
21 |
--------------------------------------------------------------------------------
/.yarn/sdks/eslint/lib/api.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const {existsSync} = require(`fs`);
4 | const {createRequire} = require(`module`);
5 | const {resolve} = require(`path`);
6 |
7 | const relPnpApiPath = "../../../../.pnp.cjs";
8 |
9 | const absPnpApiPath = resolve(__dirname, relPnpApiPath);
10 | const absRequire = createRequire(absPnpApiPath);
11 |
12 | if (existsSync(absPnpApiPath)) {
13 | if (!process.versions.pnp) {
14 | // Setup the environment to be able to require eslint
15 | require(absPnpApiPath).setup();
16 | }
17 | }
18 |
19 | // Defer to the real eslint your application uses
20 | module.exports = absRequire(`eslint`);
21 |
--------------------------------------------------------------------------------
/.yarn/sdks/eslint/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "eslint",
3 | "version": "8.40.0-sdk",
4 | "main": "./lib/api.js",
5 | "type": "commonjs"
6 | }
7 |
--------------------------------------------------------------------------------
/.yarn/sdks/integrations.yml:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by @yarnpkg/sdks.
2 | # Manual changes might be lost!
3 |
4 | integrations:
5 | - vscode
6 |
--------------------------------------------------------------------------------
/.yarn/sdks/prettier/index.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const {existsSync} = require(`fs`);
4 | const {createRequire} = require(`module`);
5 | const {resolve} = require(`path`);
6 |
7 | const relPnpApiPath = "../../../.pnp.cjs";
8 |
9 | const absPnpApiPath = resolve(__dirname, relPnpApiPath);
10 | const absRequire = createRequire(absPnpApiPath);
11 |
12 | if (existsSync(absPnpApiPath)) {
13 | if (!process.versions.pnp) {
14 | // Setup the environment to be able to require prettier/index.js
15 | require(absPnpApiPath).setup();
16 | }
17 | }
18 |
19 | // Defer to the real prettier/index.js your application uses
20 | module.exports = absRequire(`prettier/index.js`);
21 |
--------------------------------------------------------------------------------
/.yarn/sdks/prettier/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "prettier",
3 | "version": "2.8.8-sdk",
4 | "main": "./index.js",
5 | "type": "commonjs"
6 | }
7 |
--------------------------------------------------------------------------------
/.yarn/sdks/typescript/bin/tsc:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const {existsSync} = require(`fs`);
4 | const {createRequire} = require(`module`);
5 | const {resolve} = require(`path`);
6 |
7 | const relPnpApiPath = "../../../../.pnp.cjs";
8 |
9 | const absPnpApiPath = resolve(__dirname, relPnpApiPath);
10 | const absRequire = createRequire(absPnpApiPath);
11 |
12 | if (existsSync(absPnpApiPath)) {
13 | if (!process.versions.pnp) {
14 | // Setup the environment to be able to require typescript/bin/tsc
15 | require(absPnpApiPath).setup();
16 | }
17 | }
18 |
19 | // Defer to the real typescript/bin/tsc your application uses
20 | module.exports = absRequire(`typescript/bin/tsc`);
21 |
--------------------------------------------------------------------------------
/.yarn/sdks/typescript/bin/tsserver:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const {existsSync} = require(`fs`);
4 | const {createRequire} = require(`module`);
5 | const {resolve} = require(`path`);
6 |
7 | const relPnpApiPath = "../../../../.pnp.cjs";
8 |
9 | const absPnpApiPath = resolve(__dirname, relPnpApiPath);
10 | const absRequire = createRequire(absPnpApiPath);
11 |
12 | if (existsSync(absPnpApiPath)) {
13 | if (!process.versions.pnp) {
14 | // Setup the environment to be able to require typescript/bin/tsserver
15 | require(absPnpApiPath).setup();
16 | }
17 | }
18 |
19 | // Defer to the real typescript/bin/tsserver your application uses
20 | module.exports = absRequire(`typescript/bin/tsserver`);
21 |
--------------------------------------------------------------------------------
/.yarn/sdks/typescript/lib/tsc.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const {existsSync} = require(`fs`);
4 | const {createRequire} = require(`module`);
5 | const {resolve} = require(`path`);
6 |
7 | const relPnpApiPath = "../../../../.pnp.cjs";
8 |
9 | const absPnpApiPath = resolve(__dirname, relPnpApiPath);
10 | const absRequire = createRequire(absPnpApiPath);
11 |
12 | if (existsSync(absPnpApiPath)) {
13 | if (!process.versions.pnp) {
14 | // Setup the environment to be able to require typescript/lib/tsc.js
15 | require(absPnpApiPath).setup();
16 | }
17 | }
18 |
19 | // Defer to the real typescript/lib/tsc.js your application uses
20 | module.exports = absRequire(`typescript/lib/tsc.js`);
21 |
--------------------------------------------------------------------------------
/.yarn/sdks/typescript/lib/typescript.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const {existsSync} = require(`fs`);
4 | const {createRequire} = require(`module`);
5 | const {resolve} = require(`path`);
6 |
7 | const relPnpApiPath = "../../../../.pnp.cjs";
8 |
9 | const absPnpApiPath = resolve(__dirname, relPnpApiPath);
10 | const absRequire = createRequire(absPnpApiPath);
11 |
12 | if (existsSync(absPnpApiPath)) {
13 | if (!process.versions.pnp) {
14 | // Setup the environment to be able to require typescript/lib/typescript.js
15 | require(absPnpApiPath).setup();
16 | }
17 | }
18 |
19 | // Defer to the real typescript/lib/typescript.js your application uses
20 | module.exports = absRequire(`typescript/lib/typescript.js`);
21 |
--------------------------------------------------------------------------------
/.yarn/sdks/typescript/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "typescript",
3 | "version": "5.0.4-sdk",
4 | "main": "./lib/typescript.js",
5 | "type": "commonjs"
6 | }
7 |
--------------------------------------------------------------------------------
/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | compressionLevel: mixed
2 |
3 | enableGlobalCache: false
4 |
5 | nodeLinker: pnp
6 |
7 | yarnPath: .yarn/releases/yarn-4.6.0.cjs
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## 프로젝트 구성 설명
2 |
3 | 본 프로젝트는 유령 의존성을 피하기 위한 `yarn berry` 패키지 매니저와 ceos 웹 페이지와 어드민을 동시에 관리하기 위한 모노레포 툴로서 `turbo`를 이용하고 있습니다. [참고 링크](https://toss.tech/article/node-modules-and-yarn-berry).
4 | 이에 따라 두 프로젝트는 `apps` 디렉터리에, 그리고 이들이 공통적으로 활용하는 UI 컴포넌트 및 유틸 함수는 `package` 디렉터리에 위치합니다.
5 |
6 | ### 환경 설치
7 |
8 | ```
9 | yarn install
10 | ```
11 |
12 | ### 환경 변수 파일 설정
13 |
14 | > 프로젝트 인수인계자로부터 .env 관련 파일 내용을 전달 받아 `apps/ceos`와 `apps/admin` 디렉터리에 만들어 넣습니다.
15 |
16 | ### 실행 및 빌드
17 |
18 | 모노 레포인만큼 `yarn dev` 명령어를 통해 package.json의 scripts 필드에 적힌 명령어를 실행하면 두 3000, 3001번의 두 포트에서 각각의 프로젝트가 실행될 것입니다. 개별적으로 실행하고 싶다면 `yarn workspace` 명령어를 이용하거나 이를 활용한 스크립트를 만들어서 실행하십시오.
19 |
20 | ```
21 | # 실행
22 | yarn turbo run dev
23 |
24 | # admin 실행
25 | yarn admin
26 |
27 | # ceos 실행
28 | yarn ceos
29 | ```
30 |
31 | ### Typescript 버전 맞춰주기
32 |
33 | 여러분의 로컬 환경 혹은 vscode와 같은 편집기가 가지고 있는 타입스크립트 버전이 본 프로젝트의 것과 호환되지 않을 수도 있습니다. 따라서 이를 맞춰줄 필요가 있습니다.
34 |
35 | 1. 루트 경로에서 `.pnp.cjs ` 파일에 포커싱 합니다.
36 | 2. cmd + shift + p 를 누르고 setting 설정 창을 킨 뒤 `Select Typescript version` 을 누릅니다.
37 | 3. vscode 의 타입 스크립트 버전이 아니라, 본 프로젝트 workspace 의 버전을 이용합니다.
38 |
39 | > 이 설정을 안 해주면 typescript와 린팅 에러가 많이 날겁니다.
40 |
41 | ### 프로젝트 구성
42 |
43 | 1. 본 프로젝트는 메타 프레임워크로는 nextJS를 이용합니다. 루트 package.json에 기술된 버전은 13 메이저 버전(app route 방식)이지만, 실제 프로젝트의 라우팅 구성을 보면 app 디렉터리가 아닌, page 디렉터리를 이용하는 페이지 라우팅 구성을 활용하고 있습니다. 본 문서를 보시는 운영진 분들께서 원하신다면 app routing으로 마이그레이션하는 작업을 진행하셔도 좋습니다(As you wish...)
44 |
45 | ### 참고 문헌
46 |
47 | 1. [yarn berry와 turbo로 모노 레포 구성하기](https://medium.com/lbox-team/humans-in-lbox-%EC%97%98%EB%B0%95%EC%8A%A4%EC%9D%98-%EC%9D%B8%ED%84%B4%EC%9D%80-%EB%AC%B4%EC%8A%A8-%EC%9D%BC%EC%9D%84-%ED%95%A0%EA%B9%8C-8d4d008da2ca)
48 | 2. [nextJS를 turbo로 구성하기](https://www.youtube.com/watch?v=9RSNWt3AU-M&t=1599s)
49 | 3. [nextJS migration from page router to app router way](https://nextjs.org/docs/app/building-your-application/upgrading/app-router-migration#nextjs-version)
50 |
51 |
52 |
53 | ---
54 |
55 |
Written by Seungwan Kim, Tonkatsu Lover
56 |
--------------------------------------------------------------------------------
/apps/admin/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env*.local
29 |
30 | # vercel
31 | .vercel
32 |
33 | # typescript
34 | *.tsbuildinfo
35 | next-env.d.ts
36 |
--------------------------------------------------------------------------------
/apps/admin/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ```bash
8 | npm run dev
9 | # or
10 | yarn dev
11 | # or
12 | pnpm dev
13 | ```
14 |
15 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
16 |
17 | You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file.
18 |
19 | [API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`.
20 |
21 | The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
22 |
23 | This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
24 |
25 | ## Learn More
26 |
27 | To learn more about Next.js, take a look at the following resources:
28 |
29 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
30 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
31 |
32 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
33 |
34 | ## Deploy on Vercel
35 |
36 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
37 |
38 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
39 |
--------------------------------------------------------------------------------
/apps/admin/next.config.js:
--------------------------------------------------------------------------------
1 | // @ceos-fe/ui, @ceos-fe/utils 패키지를 tranpile 시킨다.
2 | const withTM = require('next-transpile-modules')([
3 | '@ceos-fe/ui',
4 | '@ceos-fe/utils',
5 | ]);
6 |
7 | const nextConfig = {
8 | reactStrictMode: true,
9 | swcMinify: true,
10 | images: {
11 | domains: [
12 | 'ceos-web-20.s3.ap-northeast-2.amazonaws.com',
13 | 's3.ap-northeast-2.amazonaws.com',
14 | 'github.com',
15 | ],
16 | },
17 | };
18 |
19 | module.exports = withTM(nextConfig);
20 |
--------------------------------------------------------------------------------
/apps/admin/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@ceos-fe/admin",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "@ceos-fe/ui": "workspace:packages/ui",
13 | "@ceos-fe/utils": "workspace:packages/utils",
14 | "@tanstack/react-query": "^4.29.15",
15 | "@tanstack/react-query-devtools": "^4.29.23",
16 | "@types/node": "18.16.3",
17 | "@types/react": "18.2.3",
18 | "@types/react-dom": "18.2.3",
19 | "antd": "^5.5.2",
20 | "axios": "^1.4.0",
21 | "eslint": "8.39.0",
22 | "eslint-config-next": "13.3.4",
23 | "next": "13.3.4",
24 | "next-transpile-modules": "^10.0.0",
25 | "react": "18.2.0",
26 | "react-bootstrap-icons": "^1.10.3",
27 | "react-cookie": "^4.1.1",
28 | "react-dom": "18.2.0",
29 | "react-hook-form": "^7.43.9",
30 | "react-intersection-observer": "^9.5.2",
31 | "react-modal": "^3.16.1",
32 | "recoil": "^0.7.7",
33 | "typescript": "5.0.4"
34 | },
35 | "devDependencies": {
36 | "@emotion/react": "^11.11.0",
37 | "@emotion/styled": "^11.11.0",
38 | "@types/eslint": "^8",
39 | "@types/react-modal": "^3"
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/apps/admin/public/admin-favicon.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/apps/admin/public/next.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/apps/admin/public/og-admin.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/apps/admin/public/og-admin.jpeg
--------------------------------------------------------------------------------
/apps/admin/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/apps/admin/src/assets/CEOS/index.tsx:
--------------------------------------------------------------------------------
1 | import { KeyOfPalette } from '@ceos-fe/ui';
2 |
3 | export const CEOS = ({
4 | width = 56,
5 | height = 17,
6 | color = 'White',
7 | }: {
8 | width?: number;
9 | height?: number;
10 | color?: KeyOfPalette;
11 | }) => {
12 | return (
13 |
27 | );
28 | };
29 |
--------------------------------------------------------------------------------
/apps/admin/src/assets/CloseBtn/index.tsx:
--------------------------------------------------------------------------------
1 | export const CloseBtn = () => {
2 | return (
3 |
17 | );
18 | };
19 |
--------------------------------------------------------------------------------
/apps/admin/src/assets/Loading/index.tsx:
--------------------------------------------------------------------------------
1 | export const LoadingIcon = () => {
2 | return (
3 |
15 | );
16 | };
17 |
--------------------------------------------------------------------------------
/apps/admin/src/assets/MoreVert/index.tsx:
--------------------------------------------------------------------------------
1 | export const MoreVert = () => {
2 | return (
3 |
16 | );
17 | };
18 |
--------------------------------------------------------------------------------
/apps/admin/src/assets/Plus/index.tsx:
--------------------------------------------------------------------------------
1 | // Plus
2 | export const Plus = () => {
3 | return (
4 |
26 | );
27 | };
28 |
--------------------------------------------------------------------------------
/apps/admin/src/assets/data/dropDownList.tsx:
--------------------------------------------------------------------------------
1 | import { DropdownItemInterface } from '@admin/utils/dropdown';
2 |
3 | export const PartDropdownList: DropdownItemInterface[] = [
4 | {
5 | label: '선택안함',
6 | value: '',
7 | },
8 | {
9 | label: '기획',
10 | value: 'product',
11 | },
12 | {
13 | label: '디자인',
14 | value: 'design',
15 | },
16 | {
17 | label: '프론트엔드',
18 | value: 'frontend',
19 | },
20 | {
21 | label: '백엔드',
22 | value: 'backend',
23 | },
24 | ];
25 |
26 | export const PassDropdownList: DropdownItemInterface[] = [
27 | {
28 | label: '선택안함',
29 | value: '',
30 | },
31 | {
32 | label: '합격',
33 | value: 'pass',
34 | },
35 | {
36 | label: '불합격',
37 | value: 'fail',
38 | },
39 | ];
40 |
41 | export const ColorPassDropdownList = [
42 | {
43 | label: '합격',
44 | value: 'pass',
45 | background: '#D4FFF7',
46 | color: '#01D1A8',
47 | },
48 | {
49 | label: '불합격',
50 | value: 'fail',
51 | background: '#FFE7E7',
52 | color: '#FF6262',
53 | },
54 | ];
55 |
56 | export const ManagementDropdownList: DropdownItemInterface[] = [
57 | {
58 | label: '임시',
59 | value: 'guest',
60 | },
61 | {
62 | label: '운영진',
63 | value: 'management',
64 | },
65 | ];
66 |
--------------------------------------------------------------------------------
/apps/admin/src/assets/data/sidebarMenuList.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | SidebarApply,
3 | SidebarPageEdit,
4 | SidebarRecruiting,
5 | SidebarUser,
6 | } from '@admin/assets/Sidebar';
7 | import { sidebarInterface } from '@admin/components/Sidebar';
8 |
9 | export const SidebarMenuList: sidebarInterface[] = [
10 | {
11 | icon: ,
12 | menu: '지원현황',
13 | path: '/applyStatement',
14 | submenuopen: false,
15 | submenu: [],
16 | },
17 | {
18 | icon: ,
19 | menu: '페이지 수정',
20 | path: '',
21 | submenuopen: false,
22 | submenu: [
23 | { subMenuName: 'PROJECT', path: '/project' },
24 | { subMenuName: 'REWARD', path: '/reward' },
25 | { subMenuName: 'ACTIVITY', path: '/activity' },
26 | { subMenuName: 'MANAGEMENT', path: '/management' },
27 | { subMenuName: 'SPONSORED BY', path: '/sponsoredby' },
28 | ],
29 | },
30 | {
31 | icon: ,
32 | menu: '리쿠르팅',
33 | path: '',
34 | submenuopen: false,
35 | submenu: [
36 | { subMenuName: 'RECRUIT', path: '/recruit' },
37 | { subMenuName: '지원서 제출', path: '/application' },
38 | { subMenuName: 'FAQ', path: '/faq' },
39 | ],
40 | },
41 | {
42 | icon: ,
43 | menu: '유저관리',
44 | path: '/manageUser',
45 | submenuopen: false,
46 | submenu: [],
47 | },
48 | ];
49 |
--------------------------------------------------------------------------------
/apps/admin/src/components/Alert/index.tsx:
--------------------------------------------------------------------------------
1 | import { Alert as AntdAlert } from 'antd';
2 | import styled from '@emotion/styled';
3 |
4 | interface AlertProps {
5 | type: 'success' | 'error';
6 | message: string;
7 | }
8 |
9 | /**
10 | * @param {'success' | 'error'} type: alert type
11 | * @param {string} message: alert message
12 | */
13 | export const Alert = ({ message, type }: AlertProps) => {
14 | return (
15 |
16 |
17 |
18 | );
19 | };
20 |
21 | const Container = styled.div`
22 | position: fixed;
23 | bottom: 60px;
24 | left: 50%;
25 | transform: translate(-50%, 0);
26 | `;
27 |
--------------------------------------------------------------------------------
/apps/admin/src/components/Common/BackButton/index.tsx:
--------------------------------------------------------------------------------
1 | import { Flex, Text } from '@ceos-fe/ui';
2 | import { BackArrow } from '../../../assets/Arrow/index';
3 | import { css } from '@emotion/react';
4 |
5 | interface BackButtonProps {
6 | title: string;
7 | onClick: () => void;
8 | }
9 |
10 | export const BackButton = ({ title, onClick }: BackButtonProps) => {
11 | return (
12 |
21 |
22 |
23 | {title}
24 |
25 |
26 | );
27 | };
28 |
--------------------------------------------------------------------------------
/apps/admin/src/components/Common/PageTitle/index.tsx:
--------------------------------------------------------------------------------
1 | import { Flex, Space, Text } from '@ceos-fe/ui';
2 |
3 | interface PageTitleProps {
4 | title: string;
5 | description: string;
6 | }
7 |
8 | export const PageTitle = ({ title, description }: PageTitleProps) => {
9 | return (
10 |
11 |
12 | {title}
13 |
14 |
15 |
16 | {description}
17 |
18 |
19 | );
20 | };
21 |
--------------------------------------------------------------------------------
/apps/admin/src/components/DataGrid/index.tsx:
--------------------------------------------------------------------------------
1 | import styled from '@emotion/styled';
2 | import { Table } from 'antd';
3 | import { Pagination, PageInterface } from './Pagination';
4 | import { Space } from 'packages/ui';
5 |
6 | interface ColumnsInterface {
7 | title: string;
8 | dataIndex: string;
9 | }
10 | interface DataGridProps {
11 | pagination: PageInterface;
12 | columns: ColumnsInterface[];
13 | dataSource: object[];
14 | onChangePage: (newPage: number) => void;
15 | }
16 |
17 | /**
18 | * @param {{ page: number; pageSize: number; total: number }} pagination: 페이지 정보 객체
19 | * @param {{ title: string; dataIndex: string; }[]} columns: Table에 들어갈 column 정보
20 | * @param {object[]} dataSource: 현재 페이지의 데이터
21 | * @param {Function} onChangePage: 페이지 넘버 수정
22 | */
23 | export const DataGrid = ({
24 | pagination,
25 | columns,
26 | dataSource,
27 | onChangePage,
28 | }: DataGridProps) => {
29 | return (
30 |
31 |
37 |
38 |
39 |
40 | );
41 | };
42 |
43 | const Container = styled.div`
44 | width: 100%;
45 | `;
46 |
47 | const StyledTable = styled(Table)`
48 | .ant-table-thead .ant-table-cell {
49 | background-color: #f3f5f8;
50 | height: 45px;
51 | padding: 12px 10px 10px 10px;
52 |
53 | font-family: 'Pretendard', 'Apple SD Gothic Neo';
54 | font-weight: 600;
55 | font-size: 14px;
56 | line-height: 150%;
57 |
58 | border-start-start-radius: 0 !important;
59 | border-start-end-radius: 0 !important;
60 | }
61 |
62 | tbody {
63 | font-family: 'Pretendard';
64 | font-style: normal;
65 | font-weight: 400;
66 | font-size: 15px;
67 | line-height: 160%;
68 |
69 | white-space: nowrap;
70 | text-overflow: ellipsis;
71 | }
72 | .ant-table-row .ant-table-cell {
73 | padding: 10px;
74 | }
75 | .ant-table-row .ant-table-cell button {
76 | margin: -10px;
77 | }
78 | `;
79 |
--------------------------------------------------------------------------------
/apps/admin/src/components/Loading/index.tsx:
--------------------------------------------------------------------------------
1 | import { Text } from '@ceos-fe/ui';
2 | import styled from '@emotion/styled';
3 | import { LoadingIcon } from '@admin/assets/Loading';
4 |
5 | export const Loading = () => {
6 | return (
7 |
8 |
9 |
10 | 로딩중입니다
11 |
12 |
13 | );
14 | };
15 |
16 | const Container = styled.div`
17 | display: flex;
18 | flex-direction: column;
19 | justify-content: center;
20 | align-items: center;
21 | gap: 50px;
22 | position: fixed;
23 |
24 | width: 100vw;
25 | height: 100vh;
26 | `;
27 |
--------------------------------------------------------------------------------
/apps/admin/src/components/activity/ActivityCardContainer/indext.tsx:
--------------------------------------------------------------------------------
1 | import { ActivityCardProps } from '@ceos-fe/ui';
2 | import { useRouter } from 'next/router';
3 | import { useMutation, useQueryClient } from '@tanstack/react-query';
4 | import { adminActivityApi } from '@ceos-fe/utils';
5 | import { AdminActivityCard } from '../../../../../../packages/ui/src/components/Card/ActivityCard';
6 |
7 | export const ActivityCardContainer = (props: ActivityCardProps) => {
8 | const router = useRouter();
9 | const queryClient = useQueryClient();
10 |
11 | // 활동 삭제 api
12 | const activityDeleteMutation = useMutation(adminActivityApi.DELETE_ACTIVITY, {
13 | onSuccess: async () => {
14 | alert('삭제 완료');
15 | queryClient.invalidateQueries([['activity']]);
16 | router.push('/activity');
17 | },
18 | });
19 |
20 | const onClickRemoveHandler = (id: number) => {
21 | activityDeleteMutation.mutate(id);
22 | };
23 |
24 | const onClickUpdateHandler = (id: number) => {
25 | router.push(`/activity/${id}`);
26 | };
27 |
28 | return (
29 | onClickUpdateHandler(props.id)}
31 | onClickRemove={() => onClickRemoveHandler(props.id)}
32 | {...props}
33 | />
34 | );
35 | };
36 |
--------------------------------------------------------------------------------
/apps/admin/src/components/cookie.ts:
--------------------------------------------------------------------------------
1 | import { Cookies } from 'react-cookie';
2 |
3 | const cookies = new Cookies();
4 |
5 | export const setCookie = (name: string, value: string, option?: any) => {
6 | return cookies.set(name, value, { ...option });
7 | };
8 |
9 | export const getCookie = (name: string) => {
10 | return cookies.get(name);
11 | };
12 |
--------------------------------------------------------------------------------
/apps/admin/src/components/project/ProjectCardContainer/index.tsx:
--------------------------------------------------------------------------------
1 | import { AdminProjectCard, ProjectCardProps } from '@ceos-fe/ui';
2 | import { useRouter } from 'next/router';
3 | import { useMutation, useQueryClient } from '@tanstack/react-query';
4 | import { adminProjectApi } from '@ceos-fe/utils';
5 |
6 | export const ProjectCardContainer = (props: ProjectCardProps) => {
7 | const router = useRouter();
8 | const queryClient = useQueryClient();
9 |
10 | // 프로젝트 삭제 api
11 | const projectDeleteMutation = useMutation(adminProjectApi.DELETE_PROJECT, {
12 | onSuccess: async () => {
13 | alert('삭제 완료');
14 | queryClient.invalidateQueries([['project']]);
15 | router.push('/project');
16 | },
17 | });
18 |
19 | const onClickRemoveHandler = (id: number) => {
20 | projectDeleteMutation.mutate(id);
21 | };
22 |
23 | const onClickUpdateHandler = (id: number) => {
24 | router.push(`/project/edit/${id}`);
25 | };
26 |
27 | return (
28 | onClickUpdateHandler(props.id)}
30 | onClickRemove={() => onClickRemoveHandler(props.id)}
31 | {...props}
32 | />
33 | );
34 | };
35 |
--------------------------------------------------------------------------------
/apps/admin/src/components/reward/RewardCardContainer/index.tsx:
--------------------------------------------------------------------------------
1 | import { AdminRewardCard, RewardCardProps } from '@ceos-fe/ui';
2 | import { useRouter } from 'next/router';
3 | import { useMutation, useQueryClient } from '@tanstack/react-query';
4 | import { adminRewardApi } from '@ceos-fe/utils';
5 |
6 | export const RewardCardContainer = (props: RewardCardProps) => {
7 | const router = useRouter();
8 | const queryClient = useQueryClient();
9 |
10 | // 이력 삭제 api
11 | const rewardDeleteMutation = useMutation(adminRewardApi.DELETE_REWARD, {
12 | onSuccess: async () => {
13 | alert('삭제 완료');
14 | queryClient.invalidateQueries();
15 | },
16 | });
17 |
18 | const onClickRemoveHandler = (generation: number) => {
19 | rewardDeleteMutation.mutate(generation);
20 | };
21 |
22 | const onClickUpdateHandler = (generation: number) => {
23 | router.push(`/reward/add/${generation}`);
24 | };
25 |
26 | return (
27 | onClickUpdateHandler(props.generation)}
29 | onClickRemove={() => onClickRemoveHandler(props.generation)}
30 | {...props}
31 | />
32 | );
33 | };
34 |
--------------------------------------------------------------------------------
/apps/admin/src/components/sponsoredBy/SponsoredByContainer/index.tsx:
--------------------------------------------------------------------------------
1 | import { AdminSponsorCard, SponsorCardProps } from '@ceos-fe/ui';
2 | import { useRouter } from 'next/router';
3 | import { useMutation, useQueryClient } from '@tanstack/react-query';
4 | import { adminSponsoredByApi } from '@ceos-fe/utils';
5 |
6 | export const SponsoredByContainer = (props: SponsorCardProps) => {
7 | const router = useRouter();
8 | const queryClient = useQueryClient();
9 |
10 | // 스폰서 삭제 api
11 | const sponsorDeleteMutation = useMutation(
12 | adminSponsoredByApi.DELETE_SPONSOR,
13 | {
14 | onSuccess: async () => {
15 | alert('삭제 완료');
16 | queryClient.invalidateQueries([['sponsor']]);
17 | router.push('/sponsoredby');
18 | },
19 | },
20 | );
21 |
22 | const onClickRemoveHandler = (id: number) => {
23 | sponsorDeleteMutation.mutate(id);
24 | };
25 |
26 | const onClickUpdateHandler = (id: number) => {
27 | router.push(`/sponsoredby/${id}`);
28 | };
29 |
30 | return (
31 | onClickUpdateHandler(props.id)}
33 | onClickRemove={() => onClickRemoveHandler(props.id)}
34 | {...props}
35 | />
36 | );
37 | };
38 |
--------------------------------------------------------------------------------
/apps/admin/src/hooks/useAlert.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from 'react';
2 |
3 | export type AlertType = 'success' | 'error';
4 |
5 | export const useAlert = () => {
6 | const [isOpen, setIsOpen] = useState(false);
7 | const [type, setType] = useState('success');
8 |
9 | useEffect(() => {
10 | const timer = setTimeout(() => setIsOpen(false), 5000);
11 |
12 | return () => clearTimeout(timer);
13 | }, [isOpen]);
14 |
15 | const openAlert = (type: AlertType) => {
16 | setType(type);
17 | setIsOpen(true);
18 | };
19 |
20 | return { isOpen, type, openAlert };
21 | };
22 |
--------------------------------------------------------------------------------
/apps/admin/src/hooks/useInfiniteQueries.tsx:
--------------------------------------------------------------------------------
1 | import { ReactNode, useEffect, useState } from 'react';
2 | import { QueryKey, useInfiniteQuery } from '@tanstack/react-query';
3 | import { useInView } from 'react-intersection-observer';
4 |
5 | // 인덱스 시그니처
6 | export interface InfiniteResponse {
7 | content: T[];
8 | pageInfo: {
9 | pageNum: number;
10 | limit: number;
11 | totalPages: number;
12 | totalElements: number;
13 | };
14 | }
15 |
16 | export interface InfiniteRequestProps {
17 | queryKey: QueryKey;
18 | queryFunction: (param: any) => Promise>;
19 | PageItem: (props: any) => JSX.Element;
20 | }
21 |
22 | const useInfiniteQueries = ({
23 | queryKey,
24 | queryFunction,
25 | PageItem,
26 | ...props
27 | }: InfiniteRequestProps) => {
28 | const [results, setResults] = useState(0);
29 | const [currentPage, setCurrentPage] = useState(0);
30 | const [ref, inView] = useInView();
31 |
32 | const getNextData = async ({ pageParam = 0, limit }: any) => {
33 | const param = {
34 | pageNum: currentPage,
35 | limit: limit,
36 | };
37 |
38 | const res = await queryFunction(param);
39 |
40 | return {
41 | board_page: res,
42 | current_page: pageParam,
43 | isLast: pageParam === res.pageInfo.totalPages,
44 | };
45 | };
46 |
47 | const {
48 | data: getBoard,
49 | fetchNextPage: getNextPage,
50 | isSuccess: getBoardIsSuccess,
51 | hasNextPage: getNextPageIsPossible,
52 | isLoading: isLoading,
53 | } = useInfiniteQuery([queryKey, currentPage], queryFunction, {
54 | getNextPageParam: (lastPage: any) => {
55 | if (!lastPage.pageInfo.isLast) return lastPage.pageInfo.pageNum + 1;
56 | return undefined;
57 | },
58 | });
59 |
60 | useEffect(() => {
61 | if (!getBoard) return;
62 |
63 | const totalPage = getBoard.pages[currentPage].pageInfo.totalPages - 1;
64 | const isLast = getBoard.pages[currentPage].pageInfo.pageNum === totalPage;
65 |
66 | if (inView) {
67 | console.log('next');
68 | }
69 |
70 | if (inView && !isLast) {
71 | getNextPage();
72 | }
73 | }, [inView, currentPage, ref]);
74 |
75 | const pageData: ReactNode[] | undefined = getBoard?.pages.map((page_data) => {
76 | return page_data.content.map((data: any, index: number) => (
77 |
78 | ));
79 | });
80 |
81 | return {
82 | getBoard,
83 | getNextPage,
84 | getBoardIsSuccess,
85 | getNextPageIsPossible,
86 | isLoading,
87 | results,
88 | currentPage,
89 | ref,
90 | infiniteData: <>{pageData}>,
91 | };
92 | };
93 |
94 | export default useInfiniteQueries;
95 |
--------------------------------------------------------------------------------
/apps/admin/src/hooks/usePresignedUrl.ts:
--------------------------------------------------------------------------------
1 | import { imageApi } from '@ceos-fe/utils';
2 | import { useMutation } from '@tanstack/react-query';
3 | import { useEffect, useState } from 'react';
4 |
5 | export type ImageApiType = 'ACTIVITY' | 'SPONSOR' | 'MANAGEMENT' | 'PROJECTS';
6 |
7 | const usePresignedUrl = (apiType: ImageApiType) => {
8 | const [image, setImage] = useState();
9 | const [pUrl, setPUrl] = useState('');
10 | const [url, setUrl] = useState('');
11 |
12 | useEffect(() => {
13 | if (image) {
14 | getPresignedUrlMutation.mutate();
15 | }
16 | }, [image]);
17 |
18 | const getPresignedUrlMutation = useMutation(
19 | imageApi[`GET_${apiType}_IMAGE`],
20 | {
21 | onSuccess: async (data: string) => {
22 | uploadImageMutation.mutate({ url: data, file: image! });
23 | setPUrl(data.slice(0, data.indexOf('?X-Amz')));
24 | },
25 | onError: (error: any) => {
26 | console.log(error);
27 | },
28 | },
29 | );
30 |
31 | const uploadImageMutation = useMutation(imageApi.PUT_IMAGE, {
32 | onSuccess: async (data: any) => {
33 | setUrl(pUrl);
34 | },
35 | onError: (error: any) => {
36 | console.log(error);
37 | },
38 | });
39 |
40 | return {
41 | presignedUrl: url,
42 | setUrl,
43 | image,
44 | setImage,
45 | };
46 | };
47 |
48 | export default usePresignedUrl;
49 |
--------------------------------------------------------------------------------
/apps/admin/src/pages/_app.tsx:
--------------------------------------------------------------------------------
1 | import { Layout } from '@admin/components/Layout';
2 | import '@admin/styles/globals.css';
3 | import { globalStyle, theme } from '@ceos-fe/ui';
4 | import { Global, ThemeProvider } from '@emotion/react';
5 | import type { AppProps } from 'next/app';
6 | import { useState } from 'react';
7 | import {
8 | Hydrate,
9 | QueryClient,
10 | QueryClientProvider,
11 | } from '@tanstack/react-query';
12 | import { RecoilRoot } from 'recoil';
13 |
14 | export default function App({ Component, pageProps }: AppProps) {
15 | const [queryClient] = useState(
16 | () =>
17 | new QueryClient({
18 | defaultOptions: {
19 | queries: {
20 | refetchOnWindowFocus: false,
21 | },
22 | },
23 | }),
24 | );
25 |
26 | return (
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | );
41 | }
42 |
--------------------------------------------------------------------------------
/apps/admin/src/pages/_document.tsx:
--------------------------------------------------------------------------------
1 | import { Html, Head, Main, NextScript } from 'next/document';
2 |
3 | export default function Document() {
4 | return (
5 |
6 |
7 | CEOS ADMIN
8 |
9 |
13 |
19 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | );
31 | }
32 |
--------------------------------------------------------------------------------
/apps/admin/src/pages/api/hello.ts:
--------------------------------------------------------------------------------
1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2 | import type { NextApiRequest, NextApiResponse } from 'next'
3 |
4 | type Data = {
5 | name: string
6 | }
7 |
8 | export default function handler(
9 | req: NextApiRequest,
10 | res: NextApiResponse
11 | ) {
12 | res.status(200).json({ name: 'John Doe' })
13 | }
14 |
--------------------------------------------------------------------------------
/apps/admin/src/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import { useRouter } from 'next/router';
2 | import { useEffect } from 'react';
3 |
4 | export default function Home() {
5 | const router = useRouter();
6 |
7 | useEffect(() => {
8 | router.push('/auth');
9 | }, []);
10 |
11 | return null;
12 | }
13 |
--------------------------------------------------------------------------------
/apps/admin/src/pages/project/index.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | AdminProjectCard,
3 | Button,
4 | Flex,
5 | ProjectCard,
6 | Space,
7 | Text,
8 | } from '@ceos-fe/ui';
9 | import {
10 | QueryClient,
11 | dehydrate,
12 | useInfiniteQuery,
13 | useMutation,
14 | } from '@tanstack/react-query';
15 | import { ProjectListInterface, adminProjectApi } from '@ceos-fe/utils';
16 | import styled from '@emotion/styled';
17 | import { useRouter } from 'next/router';
18 | import useInfiniteQueries from '@admin/hooks/useInfiniteQueries';
19 | import { ProjectCardContainer } from '../../components/project/ProjectCardContainer/index';
20 | import { css } from '@emotion/react';
21 | import { PageTitle } from '@admin/components/Common/PageTitle';
22 |
23 | export default function Project() {
24 | const router = useRouter();
25 |
26 | const { infiniteData, ref } = useInfiniteQueries({
27 | queryKey: ['project'],
28 | queryFunction: ({ pageParam = 0 }) =>
29 | adminProjectApi.GET_PROJECTS({ pageNum: pageParam, limit: 12 }),
30 | PageItem: ProjectCardContainer,
31 | });
32 |
33 | return (
34 | <>
35 |
36 |
40 |
47 |
48 |
49 |
50 |
51 |
52 |
62 | {infiniteData}
63 |
64 |
65 |
66 | >
67 | );
68 | }
69 |
70 | export const getStaticProps = async () => {
71 | try {
72 | const queryClient = new QueryClient();
73 |
74 | await queryClient.prefetchInfiniteQuery(['admin', 'projects'], () =>
75 | adminProjectApi.GET_PROJECTS({ pageNum: 0, limit: 24 }),
76 | );
77 |
78 | return {
79 | props: {
80 | dehydratedProps: JSON.parse(JSON.stringify(dehydrate(queryClient))),
81 | },
82 | };
83 | } catch (err) {
84 | console.error(err);
85 | }
86 | };
87 |
88 | const GridContainer = styled.div`
89 | display: grid;
90 | grid-template-columns: repeat(3, 1fr);
91 | column-gap: 24px;
92 | row-gap: 24px;
93 |
94 | margin-top: 48px;
95 | `;
96 |
--------------------------------------------------------------------------------
/apps/admin/src/pages/reward/index.tsx:
--------------------------------------------------------------------------------
1 | import { useRouter } from 'next/router';
2 | import { Flex, Button, Space } from '@ceos-fe/ui';
3 | import { PageTitle } from '@admin/components/Common/PageTitle';
4 | import { RewardResponse, adminRewardApi } from '@ceos-fe/utils';
5 | import useInfiniteQueries from '@admin/hooks/useInfiniteQueries';
6 | import styled from '@emotion/styled';
7 | import { RewardCardContainer } from '@admin/components/reward/RewardCardContainer';
8 |
9 | export default function Reward() {
10 | const router = useRouter();
11 | const { infiniteData, ref } = useInfiniteQueries({
12 | queryKey: ['reward'],
13 | queryFunction: ({ pageParam = 0 }) =>
14 | adminRewardApi.GET_REWARD({ pageNum: pageParam, limit: 12 }),
15 | PageItem: RewardCardContainer,
16 | });
17 |
18 | return (
19 |
20 |
21 |
25 |
26 |
27 |
28 |
29 |
35 |
41 | {infiniteData}
42 |
43 |
49 | {infiniteData}
50 |
51 |
52 |
53 |
54 | );
55 | }
56 |
57 | const InfiniteElement = styled(Flex)<{
58 | isLeft: boolean;
59 | }>`
60 | height: auto;
61 |
62 | & > :nth-child(even) {
63 | display: ${({ isLeft }) => (isLeft ? 'none' : '')};
64 | }
65 |
66 | & > :nth-child(odd) {
67 | display: ${({ isLeft }) => (isLeft ? '' : 'none')};
68 | }
69 | `;
70 |
--------------------------------------------------------------------------------
/apps/admin/src/store/recoil/index.tsx:
--------------------------------------------------------------------------------
1 | import { atom } from 'recoil';
2 |
3 | export const loginState = atom({ key: 'loginState', default: false });
4 |
5 | export const accessTokenState = atom({
6 | key: 'accessToken',
7 | default: '',
8 | });
9 |
--------------------------------------------------------------------------------
/apps/admin/src/styles/Home.module.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/apps/admin/src/styles/Home.module.css
--------------------------------------------------------------------------------
/apps/admin/src/styles/common.tsx:
--------------------------------------------------------------------------------
1 | import styled from '@emotion/styled';
2 |
3 | export const StyledForm = styled.form<{ webGap?: number; padding?: string }>`
4 | display: flex;
5 | flex-direction: column;
6 | align-items: center;
7 | gap: ${({ webGap }) => (webGap ? webGap : 36)}px;
8 | padding: ${({ padding }) => (padding ? padding : '0px')};
9 |
10 | .button-container {
11 | padding: 24px 0 0 0;
12 | }
13 | `;
14 |
--------------------------------------------------------------------------------
/apps/admin/src/styles/globals.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/apps/admin/src/styles/globals.css
--------------------------------------------------------------------------------
/apps/admin/src/utils/date.ts:
--------------------------------------------------------------------------------
1 | export const getFormattedDate = (date: Date) => {
2 | const year = date.getFullYear();
3 | const month = String(date.getMonth() + 1).padStart(2, '0');
4 | const day = String(date.getDate()).padStart(2, '0');
5 |
6 | return `${year}-${month}-${day}`;
7 | };
8 |
--------------------------------------------------------------------------------
/apps/admin/src/utils/dropdown.ts:
--------------------------------------------------------------------------------
1 | import { theme } from '@ceos-fe/ui';
2 |
3 | export interface DropdownItemInterface {
4 | label: string;
5 | value: string;
6 | color?: string;
7 | background?: string;
8 | }
9 |
10 | export const setColor = (
11 | value: DropdownItemInterface,
12 | isOpen: boolean,
13 | ): string => {
14 | if ((!value || value.value === '') && !isOpen) {
15 | return theme.palette.Gray4;
16 | } else if (value && value.color && !isOpen) {
17 | return value.color;
18 | }
19 | return theme.palette.Admin.DeepNavy;
20 | };
21 |
22 | export const setBackgroundColor = (
23 | value: DropdownItemInterface,
24 | isOpen: boolean,
25 | ): string => {
26 | if (value && value.background && !isOpen) {
27 | return value.background;
28 | }
29 | return theme.palette.White;
30 | };
31 |
--------------------------------------------------------------------------------
/apps/admin/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "compilerOptions": {
4 | "target": "es5",
5 | "lib": ["dom", "dom.iterable", "esnext"],
6 | "allowJs": true,
7 | "skipLibCheck": true,
8 | "strict": true,
9 | "forceConsistentCasingInFileNames": false,
10 | "noEmit": true,
11 | "esModuleInterop": true,
12 | "module": "esnext",
13 | "moduleResolution": "node",
14 | "resolveJsonModule": true,
15 | "isolatedModules": true,
16 | "jsx": "preserve",
17 | "incremental": true,
18 | "paths": {
19 | "@admin/*": ["./apps/admin/src/*"]
20 | }
21 | },
22 | "include": [
23 | "next-env.d.ts",
24 | "**/*.ts",
25 | "**/*.tsx",
26 | "../../**/*.d.ts",
27 | "../../packages/utils/src/hooks/useInfiniteQueries.tsx"
28 | ],
29 | "exclude": ["node_modules"]
30 | }
31 |
--------------------------------------------------------------------------------
/apps/ceos/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env*.local
29 |
30 | # vercel
31 | .vercel
32 |
33 | # typescript
34 | *.tsbuildinfo
35 | next-env.d.ts
36 | */.install-state.gz
37 |
--------------------------------------------------------------------------------
/apps/ceos/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ```bash
8 | npm run dev
9 | # or
10 | yarn dev
11 | # or
12 | pnpm dev
13 | ```
14 |
15 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
16 |
17 | You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file.
18 |
19 | [API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`.
20 |
21 | The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
22 |
23 | This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
24 |
25 | ## Learn More
26 |
27 | To learn more about Next.js, take a look at the following resources:
28 |
29 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
30 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
31 |
32 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
33 |
34 | ## Deploy on Vercel
35 |
36 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
37 |
38 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
39 |
--------------------------------------------------------------------------------
/apps/ceos/next.config.js:
--------------------------------------------------------------------------------
1 | // @ceos-fe/ui, @ceos-fe/utils 패키지를 tranpile 시킨다.
2 | const withTM = require('next-transpile-modules')([
3 | '@ceos-fe/ui',
4 | '@ceos-fe/utils',
5 | ]);
6 |
7 | /** @type {import('next').NextConfig} */
8 | const nextConfig = {
9 | reactStrictMode: false,
10 | swcMinify: true,
11 | compiler: {
12 | emotion: true,
13 | },
14 | images: {
15 | domains: ['ceos-web-20.s3.ap-northeast-2.amazonaws.com'],
16 | },
17 | async redirects() {
18 | return [
19 | // {
20 | // source: '/recruit/apply',
21 | // destination: '/',
22 | // permanent: false,
23 | // },
24 | {
25 | source: '/recruit/docpass',
26 | destination: '/',
27 | permanent: false,
28 | },
29 | {
30 | source: '/recruit/finpass',
31 | destination: '/',
32 | permanent: false,
33 | },
34 | {
35 | source: '/recruit/nonpass',
36 | destination: '/',
37 | permanent: false,
38 | },
39 | ];
40 | },
41 | };
42 |
43 | module.exports = withTM(nextConfig);
44 |
--------------------------------------------------------------------------------
/apps/ceos/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@ceos-fe/ceos",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "@ceos-fe/ui": "workspace:packages/ui",
13 | "@ceos-fe/utils": "workspace:packages/utils",
14 | "@emotion/babel-plugin": "^11.11.0",
15 | "@tanstack/react-query": "^4.29.15",
16 | "@types/node": "18.16.3",
17 | "@types/react": "18.2.3",
18 | "@types/react-dom": "18.2.3",
19 | "axios": "^1.4.0",
20 | "date-fns": "^2.30.0",
21 | "eslint": "8.39.0",
22 | "eslint-config-next": "13.3.4",
23 | "next": "13.3.4",
24 | "next-transpile-modules": "^10.0.0",
25 | "react": "18.2.0",
26 | "react-dom": "18.2.0",
27 | "react-hook-form": "^7.43.9",
28 | "react-intersection-observer": "^9.5.2",
29 | "recoil": "^0.7.7",
30 | "typescript": "5.0.4"
31 | },
32 | "devDependencies": {
33 | "@emotion/react": "^11.11.0",
34 | "@emotion/styled": "^11.11.0",
35 | "@types/eslint": "^8",
36 | "@types/recoil": "^0.0.9",
37 | "emotion": "^11.0.0",
38 | "reset": "^0.1.0"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/apps/ceos/public/404-desktop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/apps/ceos/public/404-desktop.png
--------------------------------------------------------------------------------
/apps/ceos/public/404-mobile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/apps/ceos/public/404-mobile.png
--------------------------------------------------------------------------------
/apps/ceos/public/banner-graphic-mobile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/apps/ceos/public/banner-graphic-mobile.png
--------------------------------------------------------------------------------
/apps/ceos/public/banner-graphic-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/apps/ceos/public/banner-graphic-web.png
--------------------------------------------------------------------------------
/apps/ceos/public/ceos-favicon.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/apps/ceos/public/footer/background-desktop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/apps/ceos/public/footer/background-desktop.png
--------------------------------------------------------------------------------
/apps/ceos/public/footer/background-mobile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/apps/ceos/public/footer/background-mobile.png
--------------------------------------------------------------------------------
/apps/ceos/public/header/activity.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/apps/ceos/public/header/faq.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/apps/ceos/public/header/project.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/apps/ceos/public/header/recruit.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/apps/ceos/public/next.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/apps/ceos/public/og-ceos.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/apps/ceos/public/og-ceos.jpeg
--------------------------------------------------------------------------------
/apps/ceos/public/recruit/banner-desktop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/apps/ceos/public/recruit/banner-desktop.png
--------------------------------------------------------------------------------
/apps/ceos/public/recruit/banner-mobile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/apps/ceos/public/recruit/banner-mobile.png
--------------------------------------------------------------------------------
/apps/ceos/public/recruit/pass-desktop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/apps/ceos/public/recruit/pass-desktop.png
--------------------------------------------------------------------------------
/apps/ceos/public/recruit/pass-mobile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/apps/ceos/public/recruit/pass-mobile.png
--------------------------------------------------------------------------------
/apps/ceos/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/apps/ceos/src/assets/ArrowUpRight.tsx:
--------------------------------------------------------------------------------
1 | interface ArrowProps {
2 | color?: string;
3 | }
4 |
5 | export const ArrowUpRight = (props: ArrowProps) => {
6 | return (
7 |
27 | );
28 | };
29 |
--------------------------------------------------------------------------------
/apps/ceos/src/assets/Diamond.tsx:
--------------------------------------------------------------------------------
1 | import { css } from '@emotion/react';
2 |
3 | export const Diamond = ({
4 | width = 20,
5 | height = 20,
6 | }: {
7 | width?: number;
8 | height?: number;
9 | }) => {
10 | return (
11 |
35 | );
36 | };
37 |
--------------------------------------------------------------------------------
/apps/ceos/src/assets/FAQIcon.tsx:
--------------------------------------------------------------------------------
1 | import { css } from '@emotion/react';
2 |
3 | export const FAQIcon = ({
4 | width = 20,
5 | height = 20,
6 | }: {
7 | width?: number;
8 | height?: number;
9 | }) => {
10 | return (
11 |
36 | );
37 | };
38 |
--------------------------------------------------------------------------------
/apps/ceos/src/assets/constant.tsx:
--------------------------------------------------------------------------------
1 | export const notionUrl = {
2 | 기획: 'https://www.notion.so/ceos17th/CEOS-17-5465f0fa21044180b6326d8cb3482f9f',
3 | 디자인:
4 | 'https://www.notion.so/ceos17th/CEOS-17-20c1f5c1bbf742cebca6f155b4778978',
5 | 개발: 'https://www.notion.so/ceos17th/CEOS-17-3c96efbb9289417681a60bf4adb9050d',
6 | };
7 |
--------------------------------------------------------------------------------
/apps/ceos/src/assets/header/menuBtn.tsx:
--------------------------------------------------------------------------------
1 | import { KeyOfPalette, theme } from '@ceos-fe/ui';
2 | import { css } from '@emotion/react';
3 |
4 | export interface MenuProps {
5 | backColor: KeyOfPalette;
6 | onClick: () => void;
7 | }
8 |
9 | export const MenuBtn = (props: MenuProps) => {
10 | const { backColor, onClick } = props;
11 |
12 | return (
13 |
23 |
49 |
50 | );
51 | };
52 |
--------------------------------------------------------------------------------
/apps/ceos/src/assets/landing/title.tsx:
--------------------------------------------------------------------------------
1 | import { Desktop, Flex, Mobile, Text } from '@ceos-fe/ui';
2 | import styled from '@emotion/styled';
3 |
4 | export const BigTitle = ({
5 | title,
6 | explain,
7 | }: {
8 | title: string;
9 | explain: string[];
10 | }) => {
11 | let webString = '';
12 | explain.forEach((ex, idx) => {
13 | if (idx >= 1) {
14 | webString += ` ${ex}`;
15 | } else {
16 | webString += ex;
17 | }
18 | });
19 |
20 | return (
21 |
22 |
27 | {title}
28 |
29 |
30 |
31 | {webString}
32 |
33 |
34 |
35 |
36 | {explain.map((ex, idx) => (
37 |
38 | {ex}
39 |
40 | ))}
41 |
42 |
43 |
44 | );
45 | };
46 |
47 | const Container = styled(Flex)`
48 | flex-direction: column;
49 | margin-top: 80px;
50 |
51 | @media (max-width: 1023px) {
52 | margin-top: 36px;
53 | }
54 | `;
55 |
--------------------------------------------------------------------------------
/apps/ceos/src/components/FAQBox/index.tsx:
--------------------------------------------------------------------------------
1 | import { KeyOfPalette, theme } from '@ceos-fe/ui';
2 | import { css } from '@emotion/react';
3 |
4 | // const colors = ['Green', 'Skyblue', 'Yellow'];
5 | //api로 answer을 받아오고 거기서 줄바꿈을 하고,
6 | //줄바꿈 한 애들을 중앙 정렬 하려면 받아온 텍스트 사이사이에 태그를 추가해야함
7 | //api나오면 map돌리면 될듯!
8 | //사용할 부분에서 colors 선언!
9 |
10 | // export const wrapperCss = () => css`
11 | // display: flex;
12 | // flex-direction: column;
13 | // align-items: center;
14 | // typo: ${theme.typo.Web.Heading3};
15 | // `;
16 |
17 | export interface FAQProps {
18 | color?: KeyOfPalette;
19 | isAnswer: boolean;
20 | children: string | React.ReactNode;
21 | }
22 |
23 | //typo => Q : web/mobile_heading4
24 | //typo => A : web/mobile_body2
25 |
26 | export const FAQBox = (props: FAQProps) => {
27 | const { color, isAnswer, children } = props;
28 | return (
29 |
30 | {!isAnswer ? 'Q. ' : ''}
31 | {children}
32 |
33 | );
34 | };
35 |
36 | const boxCss = ({
37 | color = 'Gray9',
38 | isAnswer,
39 | }: {
40 | color?: KeyOfPalette;
41 | isAnswer: boolean;
42 | }) => css`
43 | background-color: ${isAnswer ? theme.palette.Gray9 : theme.palette[color]};
44 | typo: ${isAnswer ? theme.typo.Web.Body2 : theme.typo.Web.Heading4};
45 | width: 680px;
46 | display: flex;
47 | flex-direction: column;
48 | justify-content: center;
49 | align-items: center;
50 | padding: 18px;
51 | box-sizing: border-box;
52 | border-radius: 16px;
53 | word-break: keep-all;
54 | text-align: center;
55 | margin: ${!isAnswer ? '36px 0px 20px 0px' : '0px'};
56 |
57 | @media (max-width: 1023px) {
58 | width: 100%;
59 | ${isAnswer ? theme.typo.Mobile.Body2 : theme.typo.Mobile.Heading4};
60 | margin: ${!isAnswer ? '24px 0px 14px 0px' : '0px'};
61 | }
62 | `;
63 |
--------------------------------------------------------------------------------
/apps/ceos/src/components/FooterText/index.tsx:
--------------------------------------------------------------------------------
1 | import { Text } from '@ceos-fe/ui';
2 | import { css } from '@emotion/react';
3 |
4 | export const FooterText = () => {
5 | return (
6 |
14 | © 2015-2025 CEOS ALL RIGHTS RESERVED.
15 |
16 | );
17 | };
18 |
19 | export const FooterTextCss = css`
20 | margin-bottom: 80px;
21 |
22 | @media (max-width: 1023px) {
23 | margin-bottom: 30px;
24 | }
25 | `;
26 |
--------------------------------------------------------------------------------
/apps/ceos/src/components/Landing/buttons.tsx:
--------------------------------------------------------------------------------
1 | import { GlassShortcut } from '../Shortcut';
2 | import styled from '@emotion/styled';
3 | import { Flex, Space, media, theme } from '@ceos-fe/ui';
4 | import { useRouter } from 'next/router';
5 | import useWindowSize from '@ceos/hooks/useWindoSize';
6 | import {
7 | MobileShortcut,
8 | WebShortcut,
9 | } from '@ceos/assets/landing/shortcutBackground';
10 |
11 | interface ButtonsProps {
12 | className?: string;
13 | dataSection?: string;
14 | }
15 |
16 | export const Buttons = (props: ButtonsProps) => {
17 | const router = useRouter();
18 | const windowSize = useWindowSize();
19 |
20 | return (
21 |
22 |
23 |
24 |
25 | {windowSize.width < 1023 && windowSize.width !== 0 ? (
26 |
27 | ) : (
28 |
29 | )}
30 |
31 |
32 | router.push('/project')}>
33 | 프로젝트 확인하기
34 |
35 | router.push('/management')}>
36 | 운영진 보러가기
37 |
38 | router.push('/recruit')}>
39 | 지원하기
40 |
41 |
42 |
43 |
44 | );
45 | };
46 |
47 | const Wrapper = styled.div`
48 | position: relative;
49 | width: 100vw;
50 | overflow: hidden;
51 | user-select: none;
52 |
53 | .shortcut-image {
54 | overflow: hidden;
55 |
56 | background-color: ${theme.palette.Blue};
57 | height: 319px;
58 |
59 | ${media.mobile} {
60 | height: 372px;
61 | }
62 | }
63 |
64 | .buttons {
65 | position: absolute;
66 | top: 0;
67 |
68 | ${media.mobile} {
69 | flex-direction: column;
70 |
71 | padding: 0px 22px;
72 | }
73 | }
74 | `;
75 |
--------------------------------------------------------------------------------
/apps/ceos/src/components/Landing/sponsor.tsx:
--------------------------------------------------------------------------------
1 | import { Text, SponsorCard, media, Space } from '@ceos-fe/ui';
2 | import { css } from '@emotion/react';
3 | import { sponsorApi } from '@ceos-fe/utils';
4 | import { useQuery } from '@tanstack/react-query';
5 |
6 | interface SponsorInterface {
7 | id: number;
8 | name: string;
9 | imageUrl: string;
10 | }
11 |
12 | interface SponsorResponse {
13 | content: SponsorInterface[];
14 | pageInfo: {
15 | pageNum: number;
16 | limit: number;
17 | totalPages: number;
18 | totalElements: number;
19 | };
20 | }
21 |
22 | export const Sponsors = () => {
23 | const { data } = useQuery(
24 | ['ceos', 'sponsor'],
25 | async () =>
26 | await sponsorApi.GET_SPONSORS({
27 | pageNum: 0,
28 | limit: 20,
29 | }),
30 | );
31 |
32 | const sponsorList = data?.content;
33 | return (
34 |
41 |
42 |
47 | Sponsored by
48 |
49 |
56 | CEOS 활동에 도움을 주시는 공식 파트너 단체입니다.
57 |
58 |
59 |
76 | {sponsorList &&
77 | sponsorList.map((s: SponsorInterface) => (
78 |
79 | ))}
80 |
81 |
82 |
83 |
84 | );
85 | };
86 |
--------------------------------------------------------------------------------
/apps/ceos/src/components/Layout/index.tsx:
--------------------------------------------------------------------------------
1 | import { Header } from '@ceos/components/Header';
2 | import { Flex, media } from '@ceos-fe/ui';
3 | import { useRecoilValue, useSetRecoilState } from 'recoil';
4 | import { HeaderState, projectId } from '@ceos/state';
5 | import { useQuery } from '@tanstack/react-query';
6 | import { recruitApi } from '@ceos-fe/utils';
7 | import { useEffect } from 'react';
8 | import { generationState } from '../../state/index';
9 | import { css } from '@emotion/react';
10 | import styled from '@emotion/styled';
11 |
12 | export const Layout = ({ children }: { children: React.ReactNode }) => {
13 | const { data, isFetching, isSuccess } = useQuery(['generation'], () =>
14 | recruitApi.GET_RECRUITMENTS(),
15 | );
16 |
17 | const setGeneration = useSetRecoilState(generationState);
18 | const backColor = useRecoilValue(HeaderState);
19 | const modalNumber = useRecoilValue(projectId);
20 |
21 | const isLoaded = !isFetching && isSuccess;
22 |
23 | useEffect(() => {
24 | if (isLoaded) {
25 | setGeneration(data.generation);
26 | }
27 | }, [isLoaded]);
28 |
29 | return (
30 |
31 |
32 | {/* backColor = White */}
33 | {isLoaded && children}
34 |
35 | );
36 | };
37 |
38 | const Wrapper = styled(Flex)<{
39 | projectId: number;
40 | }>`
41 | overflow-x: hidden;
42 |
43 | ${({ projectId }) =>
44 | projectId !== -1
45 | ? css`
46 | .floating-button {
47 | display: none;
48 | }
49 | `
50 | : ''}
51 | `;
52 |
--------------------------------------------------------------------------------
/apps/ceos/src/components/Modals/timeModal.tsx:
--------------------------------------------------------------------------------
1 | import { Text, theme } from '@ceos-fe/ui';
2 | import { css } from '@emotion/react';
3 | import { backCss } from '../MenuBar';
4 | import { forwardRef, useEffect, useState } from 'react';
5 | import { useRouter } from 'next/router';
6 |
7 | export const TimeModal = forwardRef(
8 | ({ generation }, ref) => {
9 | const [opacity, setOpacity] = useState(100);
10 | const router = useRouter();
11 |
12 | const fadeOut = () => {
13 | if (opacity === 100) {
14 | setTimeout(() => {
15 | setOpacity(opacity - 1);
16 | }, 500);
17 | } else if (opacity > 0) {
18 | setTimeout(() => {
19 | setOpacity(opacity - 2);
20 | }, 100);
21 | } else {
22 | router.push('/');
23 | }
24 | };
25 |
26 | useEffect(() => {
27 | fadeOut();
28 | }, [fadeOut]);
29 |
30 | return (
31 |
32 |
33 |
34 | CEOS {generation}기가 되신 것을
35 |
환영합니다 :)
36 |
37 |
38 | 활동에 관련된 사항들은
39 | 개별적으로 연락드리겠습니다.
40 |
41 |
42 |
43 | );
44 | },
45 | );
46 |
47 | TimeModal.displayName = 'TimeModal';
48 |
49 | const TimeModalCss = (opacity: number) => css`
50 | width: 504px;
51 | z-index: 10;
52 | border-radius: 20px;
53 | background-color: #ffffff;
54 | padding: 40px;
55 | box-sizing: border-box;
56 | text-align: center;
57 | justify-content: center;
58 | align-items: center;
59 | display: flex;
60 | flex-direction: column;
61 | ${theme.typo.Web.Body2};
62 | gap: 12px;
63 | position: relative;
64 |
65 | shadow: ${theme.shadow.PopUp};
66 | opacity: ${opacity}%;
67 |
68 | .mobile {
69 | display: none;
70 | }
71 |
72 | @media (max-width: 1023px) {
73 | width: 346px;
74 | height: 184px;
75 | padding: 1.25rem 1.25rem 1.44rem 1.25rem;
76 |
77 | .mobile {
78 | display: block;
79 | }
80 | }
81 | `;
82 |
--------------------------------------------------------------------------------
/apps/ceos/src/components/Title/index.tsx:
--------------------------------------------------------------------------------
1 | import { Desktop, Flex, Mobile, Text } from '@ceos-fe/ui';
2 | import styled from '@emotion/styled';
3 |
4 | export const Title = ({
5 | title,
6 | explain,
7 | className,
8 | }: {
9 | title: string;
10 | explain: string[];
11 | className?: string;
12 | }) => {
13 | let webString = '';
14 | explain.forEach((ex, idx) => {
15 | if (idx >= 1) {
16 | webString += ` ${ex}`;
17 | } else {
18 | webString += ex;
19 | }
20 | });
21 |
22 | return (
23 |
24 |
29 | {title}
30 |
31 |
32 |
33 | {webString}
34 |
35 |
36 |
37 |
38 | {explain.map((ex, idx) => (
39 |
40 | {ex}
41 |
42 | ))}
43 |
44 |
45 |
46 | );
47 | };
48 |
49 | const Container = styled(Flex)`
50 | flex-direction: column;
51 | margin-top: 150px;
52 |
53 | @media (max-width: 1023px) {
54 | margin-top: 160px;
55 |
56 | &.mentor {
57 | margin-top: 36px;
58 | }
59 | }
60 | `;
61 |
--------------------------------------------------------------------------------
/apps/ceos/src/components/project/ProjectCardContainer/index.tsx:
--------------------------------------------------------------------------------
1 | import { ProjectCard, ProjectCardProps } from '@ceos-fe/ui';
2 | import { projectId } from '@ceos/state';
3 | import { useRecoilState } from 'recoil';
4 |
5 | export const ProjectCardContainer = (props: ProjectCardProps) => {
6 | const [id, setId] = useRecoilState(projectId);
7 | const openModal = () => {
8 | setId(props.id);
9 | };
10 | return (
11 | <>
12 |
15 | >
16 | );
17 | };
18 |
--------------------------------------------------------------------------------
/apps/ceos/src/components/recruit/Common.tsx:
--------------------------------------------------------------------------------
1 | import { Text } from '@ceos-fe/ui';
2 | import { RowLine, Section } from '../../pages/recruit/apply';
3 | import { CustomTextField, QuestionFlex } from './style';
4 | import { RecruitApplyFormInterface } from './interface';
5 |
6 | interface CommonProps {
7 | register: RecruitApplyFormInterface['register'];
8 | questionList?: RecruitApplyFormInterface['questionList'];
9 | }
10 |
11 | const Common = ({ register, questionList }: CommonProps) => {
12 | return (
13 | <>
14 |
15 |
16 | 공통 질문
17 |
18 | {questionList?.commonQuestions.map((ques, idx) => (
19 |
20 | {
26 | return {
27 | type: detail.color === 'gray' ? 'normal' : 'important',
28 | text: detail.explaination,
29 | };
30 | })}
31 | />
32 |
33 | ))}
34 |
35 |
36 | >
37 | );
38 | };
39 |
40 | export default Common;
41 |
--------------------------------------------------------------------------------
/apps/ceos/src/components/recruit/interface.tsx:
--------------------------------------------------------------------------------
1 | import { RecruitApplyValuesInterface } from '@ceos-fe/utils';
2 | import {
3 | FormState,
4 | UseFormGetValues,
5 | UseFormHandleSubmit,
6 | UseFormRegister,
7 | UseFormSetValue,
8 | UseFormWatch,
9 | } from 'react-hook-form';
10 |
11 | export interface QuestionProps {
12 | questionId: number;
13 | questionIndex: number;
14 | question: string;
15 | multiline: boolean;
16 | questionDetail: { explaination: string; color: string }[];
17 | }
18 | export interface AnswerInterface {
19 | questionId: number;
20 | answer: string;
21 | }
22 | export interface RecruitApplyResponse {
23 | commonQuestions: QuestionProps[];
24 | productQuestions: QuestionProps[];
25 | designQuestions: QuestionProps[];
26 | frontendQuestions: QuestionProps[];
27 | backendQuestions: QuestionProps[];
28 | times: { date: string; durations: string[] }[];
29 | }
30 |
31 | export interface RecruitApplyFormInterface {
32 | register: UseFormRegister;
33 | watch: UseFormWatch;
34 | setValue: UseFormSetValue;
35 | getValues: UseFormGetValues;
36 | handleSubmit: UseFormHandleSubmit;
37 | formState: FormState;
38 | questionList?: RecruitApplyResponse;
39 | }
40 |
41 | export type PartName =
42 | | 'productQuestions'
43 | | 'designQuestions'
44 | | 'frontendQuestions'
45 | | 'backendQuestions';
46 |
47 | export interface PassDataInterface {
48 | uuid: string;
49 | generation: number;
50 | email: string;
51 | pass: string;
52 | name: string;
53 | part?: string;
54 | attendanceStatus: boolean;
55 | date: string;
56 | otDate: string;
57 | openChatUrl: string;
58 | duration: string;
59 | }
60 |
61 | export interface RecruitStudyResponse {
62 | generation: number;
63 | prodStudyUrl: string;
64 | designStudyUrl: string;
65 | devStudyUrl: string;
66 | startDateDoc: string;
67 | endDateDoc: string;
68 | resultDateDoc: string;
69 | startDateInterview: string;
70 | endDateInterview: string;
71 | resultDateFinal: string;
72 | openChatUrl: string;
73 | otDate: string;
74 | ideathonDate: string;
75 | hackathonDate: string;
76 | demodayDate: string;
77 | }
78 |
79 | export interface DateProps {
80 | startDateDoc: Date;
81 | endDateDoc: Date;
82 | resultDateDoc: Date;
83 | resultDateFinal: Date;
84 | }
85 |
--------------------------------------------------------------------------------
/apps/ceos/src/components/recruit/recruitBox.tsx:
--------------------------------------------------------------------------------
1 | import { Text, media, theme } from '@ceos-fe/ui';
2 | import { css } from '@emotion/react';
3 |
4 | interface MiniBoxProps {
5 | header: string;
6 | content: string;
7 | }
8 |
9 | export const RecruitBoxCss = ({
10 | width,
11 | margin = '0',
12 | }: {
13 | width: number;
14 | margin?: string;
15 | }) => css`
16 | background-color: ${theme.palette.Gray1};
17 | width: ${width}px;
18 | margin: ${margin};
19 | display: flex;
20 | flex-direction: column;
21 | justify-content: center;
22 | align-items: center;
23 | padding: 18px;
24 | box-sizing: border-box;
25 | border-radius: 16px;
26 | word-break: keep-all;
27 | text-align: center;
28 | ${theme.typo.Web.Body1};
29 |
30 | ${media.mobile} {
31 | width: 100%;
32 | height: 219px;
33 | ${theme.typo.Mobile.Body1};
34 | margin-bottom: 48px;
35 | }
36 | `;
37 |
38 | export const RecruitMiniBox = (props: MiniBoxProps) => {
39 | return (
40 |
41 |
42 | {props.header}
43 |
44 |
45 | {props.content}
46 |
47 |
48 | );
49 | };
50 |
51 | export const MiniBoxCss = css`
52 | background-color: ${theme.palette.Gray1};
53 | width: 240px;
54 | height: 107px;
55 | display: flex;
56 | flex-direction: column;
57 | justify-content: center;
58 | align-items: center;
59 | padding: 18px;
60 | box-sizing: border-box;
61 | border-radius: 16px;
62 | word-break: keep-all;
63 | text-align: center;
64 |
65 | ${media.mobile} {
66 | width: 100%;
67 | height: 97px;
68 | }
69 | `;
70 |
--------------------------------------------------------------------------------
/apps/ceos/src/components/recruit/style/index.tsx:
--------------------------------------------------------------------------------
1 | import styled from '@emotion/styled';
2 | import { Flex, Text, TextField, theme } from '@ceos-fe/ui';
3 |
4 | export const CustomFlex = styled(Flex)`
5 | flex-direction: row;
6 | justify-content: space-between;
7 | align-items: start;
8 | width: 680px;
9 | gap: 24px;
10 |
11 | @media (max-width: 1023px) {
12 | width: 100%;
13 | flex-direction: column;
14 | justify-content: start;
15 | align-items: center;
16 | gap: 28px;
17 | }
18 | `;
19 |
20 | export const CustomTextField = styled(TextField)<{
21 | webWidth?: string;
22 | mobileWidth?: string;
23 | }>`
24 | width: ${({ webWidth }) => webWidth ?? '100%'};
25 |
26 | @media (max-width: 1023px) {
27 | width: ${({ mobileWidth }) => mobileWidth ?? '100%'};
28 | }
29 | `;
30 |
31 | export const QuestionFlex = styled(Flex)`
32 | flex-direction: column;
33 | align-items: start;
34 | gap: 8px;
35 | width: 100%;
36 | @media (max-width: 1023px) {
37 | gap: 14px;
38 | }
39 | `;
40 |
41 | export const Question = styled(Text)`
42 | ${theme.typo.Web.Label3};
43 | @media (max-width: 1023px) {
44 | ${theme.typo.Mobile.Heading4};
45 | }
46 | `;
47 |
48 | export const Explain = styled(Text)`
49 | ${theme.typo.Web.Body3};
50 | color: ${theme.palette.Gray5};
51 |
52 | @media (max-width: 1023px) {
53 | ${theme.typo.Mobile.Body2};
54 | }
55 | `;
56 |
--------------------------------------------------------------------------------
/apps/ceos/src/components/recruitModal/ErrorModal.tsx:
--------------------------------------------------------------------------------
1 | import { css } from '@emotion/react';
2 | import styled from '@emotion/styled';
3 | import { Flex, Text } from '@ceos-fe/ui';
4 | import { useRef } from 'react';
5 | import { backCss, containerCss } from './SubmitModal';
6 |
7 | export const ErrorModal = ({
8 | text,
9 | onClose,
10 | }: {
11 | text: string;
12 | onClose: () => void;
13 | }) => {
14 | const modalRef = useRef(null);
15 |
16 | return (
17 | <>
18 |
19 |
20 |
21 |
22 | {text}
23 |
24 |
25 |
26 | >
27 | );
28 | };
29 |
30 | const Container = styled.div`
31 | position: fixed;
32 | top: 409px;
33 | display: flex;
34 | width: 504px;
35 | padding: 40px 24px;
36 | flex-direction: column;
37 | align-items: center;
38 | gap: 14px;
39 |
40 | border-radius: 20px;
41 | background: #fff;
42 |
43 | /* 팝업창그림자 */
44 | box-shadow: 0px 12px 20px 0px rgba(0, 0, 0, 0.1);
45 |
46 | @media (max-width: 1023px) {
47 | top: 300px;
48 | width: 80%;
49 | }
50 | `;
51 |
--------------------------------------------------------------------------------
/apps/ceos/src/components/recruitModal/SubmitModal.tsx:
--------------------------------------------------------------------------------
1 | import { css } from '@emotion/react';
2 | import styled from '@emotion/styled';
3 | import { ModalBgImage } from '../../assets/apply/ModalBgImage';
4 | import { Button, CheckBox, Desktop, Flex, Mobile, Text } from '@ceos-fe/ui';
5 | import { useState, useRef } from 'react';
6 |
7 | export interface ModalProps {
8 | submitForm: () => void;
9 | onClose: () => void;
10 | }
11 |
12 | export const SubmitModal = ({ submitForm, onClose }: ModalProps) => {
13 | const [isChecked, setIsChecked] = useState(false);
14 | const modalRef = useRef(null);
15 |
16 | return (
17 | <>
18 |
19 |
20 |
21 |
22 |
23 |
24 | 서류를 제출하시겠습니까?
25 |
26 |
27 |
28 | 제출 후 수정은 불가능합니다.
29 |
30 |
31 | {`면접 날짜를 '불가능한 시간'에 체크했는지 확인해주세요.`}
32 |
33 |
34 |
35 | setIsChecked(!isChecked)}
38 | value={['최종 확인 및 ‘불가능한 시간’에 체크했습니다.']}
39 | type="row"
40 | />
41 |
42 |
49 |
50 |
51 | >
52 | );
53 | };
54 |
55 | export const backCss = () => css`
56 | position: absolute;
57 | top: 0;
58 | left: 0;
59 | bottom: 0;
60 | right: 0;
61 | background-color: rgba(0, 0, 0, 0.5);
62 | `;
63 |
64 | export const containerCss = () => css`
65 | display: flex;
66 | justify-content: center;
67 | align-items: center;
68 | `;
69 |
70 | const TextContainer = styled.div`
71 | position: fixed;
72 | top: 456px;
73 |
74 | display: flex;
75 | flex-direction: column;
76 | align-items: center;
77 | gap: 24px;
78 |
79 | @media (max-width: 1023px) {
80 | top: 300px;
81 | }
82 | `;
83 |
--------------------------------------------------------------------------------
/apps/ceos/src/components/recruitModal/SuccessModal.tsx:
--------------------------------------------------------------------------------
1 | import { css } from '@emotion/react';
2 | import styled from '@emotion/styled';
3 | import { Flex, Text } from '@ceos-fe/ui';
4 | import { backCss } from '../MenuBar';
5 | import { containerCss } from './SubmitModal';
6 |
7 | export const SuccessModal = () => {
8 | return (
9 | <>
10 |
11 |
12 |
13 |
19 | 제출이 완료되었습니다:)
20 |
21 |
22 |
23 | 지원서 내용을 작성하신 이메일로 전송드렸으니,
24 |
25 |
26 | 확인 부탁드립니다.
27 |
28 |
29 |
30 |
31 | >
32 | );
33 | };
34 |
35 | const Container = styled.div`
36 | position: fixed;
37 | top: 409px;
38 | display: flex;
39 | width: 504px;
40 | padding: 40px 24px;
41 | flex-direction: column;
42 | align-items: center;
43 | gap: 14px;
44 |
45 | border-radius: 20px;
46 | background: #fff;
47 |
48 | /* 팝업창그림자 */
49 | box-shadow: 0px 12px 20px 0px rgba(0, 0, 0, 0.1);
50 |
51 | @media (max-width: 1023px) {
52 | top: 300px;
53 | width: 80%;
54 | }
55 | `;
56 |
--------------------------------------------------------------------------------
/apps/ceos/src/hooks/useWindoSize.ts:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from 'react';
2 |
3 | function useWindowSize() {
4 | const isClient = typeof window === 'object';
5 |
6 | function getWindowSize() {
7 | return {
8 | width: isClient ? window.innerWidth : 0,
9 | height: isClient ? window.innerHeight : 0,
10 | };
11 | }
12 |
13 | const [windowSize, setWindowSize] = useState({ width: 0, height: 0 });
14 |
15 | useEffect(() => {
16 | if (!isClient) {
17 | return;
18 | }
19 |
20 | function handleResize() {
21 | setWindowSize(getWindowSize());
22 | }
23 |
24 | setWindowSize(getWindowSize());
25 | window.addEventListener('resize', handleResize);
26 | return () => {
27 | window.removeEventListener('resize', handleResize);
28 | };
29 | }, []);
30 |
31 | return windowSize;
32 | }
33 |
34 | export default useWindowSize;
35 |
--------------------------------------------------------------------------------
/apps/ceos/src/pages/404.tsx:
--------------------------------------------------------------------------------
1 | import styled from '@emotion/styled';
2 | import { Button, Flex, Space, Text, media, theme } from '@ceos-fe/ui';
3 | import { useRouter } from 'next/router';
4 |
5 | const NotFound = () => {
6 | const router = useRouter();
7 |
8 | return (
9 |
10 |
11 |
17 | 페이지를 찾을 수 없습니다.
18 |
19 |
20 |
21 |
22 |
28 | 원하시는 페이지의 주소가 잘못되었거나,
29 |
30 | 페이지가 존재하지 않습니다.
31 |
32 | 올바른 주소인지 확인해주시기 바랍니다.
33 |
34 |
35 |
36 |
37 |
46 |
47 |
48 | );
49 | };
50 |
51 | export default NotFound;
52 |
53 | const Wrapper = styled.div`
54 | width: 100vw;
55 | height: 100vh;
56 | overflow: hidden;
57 | background-color: ${theme.palette.Blue};
58 | `;
59 |
60 | const Container = styled(Flex)`
61 | margin-top: -40px;
62 |
63 | position: fixed;
64 | flex-direction: column;
65 |
66 | width: 100vw;
67 | height: 900px;
68 | background-image: url('/404-desktop.png');
69 | background-size: 1660px;
70 | background-position: center;
71 | background-repeat: no-repeat;
72 |
73 | text-align: center;
74 |
75 | ${media.mobile} {
76 | background-size: 646px;
77 | height: 800px;
78 | background-image: url('/404-mobile.png');
79 | }
80 | `;
81 |
--------------------------------------------------------------------------------
/apps/ceos/src/pages/_app.tsx:
--------------------------------------------------------------------------------
1 | import '@ceos/styles/globals.css';
2 | import { Desktop, globalStyle, theme } from '@ceos-fe/ui';
3 | import { Global, ThemeProvider } from '@emotion/react';
4 | import type { AppProps } from 'next/app';
5 | import { Layout } from '../components/Layout';
6 | import { FloatingCss } from '@ceos/styles/landing';
7 | import { FloatingButton } from '@ceos-fe/ui';
8 | import {
9 | Hydrate,
10 | QueryClient,
11 | QueryClientProvider,
12 | } from '@tanstack/react-query';
13 | import { useState } from 'react';
14 | import { RecoilRoot } from 'recoil';
15 |
16 | export default function App({ Component, pageProps }: AppProps) {
17 | const [queryClient] = useState(
18 | () =>
19 | new QueryClient({
20 | defaultOptions: {
21 | queries: {
22 | refetchOnWindowFocus: false,
23 | },
24 | },
25 | }),
26 | );
27 |
28 | return (
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | );
45 | }
46 |
--------------------------------------------------------------------------------
/apps/ceos/src/pages/_document.tsx:
--------------------------------------------------------------------------------
1 | import { Html, Head, Main, NextScript } from 'next/document';
2 |
3 | export default function Document() {
4 | return (
5 |
6 |
7 | CEOS | 세오스
8 |
9 |
13 |
19 |
23 | {/* meta tag for naver search console */}
24 |
28 |
29 |
33 |
37 |
47 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | );
59 | }
60 |
--------------------------------------------------------------------------------
/apps/ceos/src/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { css } from '@emotion/react';
3 | import { SubHeader } from '@ceos/components/Landing/subHeader';
4 | import { Rewards } from '@ceos/components/Landing/rewards';
5 | import { HomeFlex, SponsorFlex } from '@ceos/styles/landing';
6 | import { Buttons } from '@ceos/components/Landing/buttons';
7 | import { Text, media } from '@ceos-fe/ui';
8 | import { Sponsors } from '@ceos/components/Landing/sponsor';
9 | import { QueryClient, dehydrate } from '@tanstack/react-query';
10 | import { awardApi, sponsorApi } from '@ceos-fe/utils';
11 | import { FooterText, FooterTextCss } from '@ceos/components/FooterText';
12 | import { useForm } from 'react-hook-form';
13 |
14 | export default function Home() {
15 | return (
16 |
17 |
18 | {/* section1 => blue */}
19 |
20 |
21 |
22 | {/* section2 => white */}
23 |
24 | {/* section3 => blue */}
25 |
26 |
27 |
28 | {/* section4 => white */}
29 |
30 |
31 |
32 | {/*section 5 */}
33 |
34 | );
35 | }
36 |
37 | export const getStaticProps = async () => {
38 | try {
39 | const queryClient = new QueryClient();
40 |
41 | await queryClient.prefetchQuery(['ceos', 'award'], () => {
42 | awardApi.GET_AWARD({ pageNum: 0, limit: 20 });
43 | });
44 | await queryClient.prefetchQuery(['ceos', 'sponsor'], () => {
45 | sponsorApi.GET_SPONSORS({ pageNum: 0, limit: 10 });
46 | });
47 |
48 | return {
49 | props: {
50 | dehydratedProps: dehydrate(queryClient),
51 | },
52 | };
53 | } catch (err) {
54 | console.error(err);
55 | }
56 | };
57 |
--------------------------------------------------------------------------------
/apps/ceos/src/state/index.tsx:
--------------------------------------------------------------------------------
1 | import { KeyOfPalette } from '@ceos-fe/ui';
2 | import { atom } from 'recoil';
3 |
4 | export const HeaderState = atom({
5 | key: 'backColor',
6 | default: 'Blue',
7 | });
8 | export const generationState = atom({ key: 'generation', default: 0 });
9 |
10 | export const ScrollState = atom({
11 | key: 'isScroll',
12 | default: false,
13 | });
14 |
15 | export const projectId = atom({ key: 'projectId', default: -1 });
16 |
17 | export const projectModalOpen = atom({
18 | key: 'projectModalOpen',
19 | default: false,
20 | });
21 |
--------------------------------------------------------------------------------
/apps/ceos/src/styles/Home.module.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/apps/ceos/src/styles/Home.module.css
--------------------------------------------------------------------------------
/apps/ceos/src/styles/globals.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/apps/ceos/src/styles/globals.css
--------------------------------------------------------------------------------
/apps/ceos/src/styles/recruit/index.tsx:
--------------------------------------------------------------------------------
1 | import { media, theme } from '@ceos-fe/ui';
2 | import { css } from '@emotion/react';
3 |
4 | export const RecruitCss = css`
5 | background-image: url('/recruit/banner-desktop.png');
6 | background-position: center;
7 | background-size: 1660px;
8 | background-repeat: no-repeat;
9 | background-color: ${theme.palette.Blue};
10 | height: 600px;
11 | width: 100%;
12 |
13 | z-index: 1;
14 | margin-bottom: 80px;
15 |
16 | ${media.mobile} {
17 | background-image: url('/recruit/banner-mobile.png');
18 | background-size: 687px;
19 | height: 630px;
20 | margin-bottom: 48px;
21 | }
22 | `;
23 |
24 | export const RecruitBgText = css`
25 | display: flex;
26 | align-items: center;
27 | flex-direction: column;
28 | margin-top: 195px;
29 | white-space: nowrap;
30 | color: white;
31 |
32 | .mobile {
33 | display: none;
34 | }
35 |
36 | ${media.mobile} {
37 | .subText {
38 | ${theme.typo.Mobile.Body1};
39 | }
40 | .mobile {
41 | display: block;
42 | }
43 | margin-top: 250px;
44 | }
45 | `;
46 |
47 | export const RecruitTextCss = css`
48 | font-family: 'Gilroy-Bold', 'Apple SD Gothic Neo';
49 | font-weight: 800;
50 | font-size: 3.75rem;
51 | line-height: 120%;
52 | color: white;
53 | text-align: center;
54 | margin-bottom: 12px;
55 |
56 | @media (max-width: 1023px) {
57 | font-size: 2.5rem;
58 | line-height: 130%;
59 | margin-bottom: 8px;
60 | margin-bottom: 24px;
61 | }
62 | `;
63 | export const RecruitMainCss = css`
64 | display: flex;
65 | flex-direction: column;
66 | width: 1032px;
67 | justify-content: flex-start;
68 | margin-bottom: 100px;
69 |
70 | ${media.mobile} {
71 | width: 90%;
72 | margin-bottom: 48px;
73 | margin-top: 0px;
74 | }
75 | `;
76 |
--------------------------------------------------------------------------------
/apps/ceos/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "compilerOptions": {
4 | "target": "es5",
5 | "lib": ["dom", "dom.iterable", "esnext"],
6 | "allowJs": true,
7 | "skipLibCheck": true,
8 | "strict": true,
9 | "forceConsistentCasingInFileNames": false,
10 | "noEmit": true,
11 | "esModuleInterop": true,
12 | "module": "esnext",
13 | "moduleResolution": "node",
14 | "resolveJsonModule": true,
15 | "isolatedModules": true,
16 | "jsx": "preserve",
17 | "incremental": true,
18 | "paths": {
19 | "@ceos/*": ["./apps/ceos/src/*"]
20 | }
21 | },
22 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "../../**/*.d.ts"],
23 | "exclude": ["node_modules"]
24 | }
25 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ceos-fe",
3 | "version": "0.0.0",
4 | "private": true,
5 | "workspaces": [
6 | "apps/*",
7 | "packages/*"
8 | ],
9 | "scripts": {
10 | "admin": "yarn workspace @ceos-fe/admin dev",
11 | "ceos": "yarn workspace @ceos-fe/ceos dev",
12 | "build": "turbo run build",
13 | "dev": "turbo run dev",
14 | "lint": "turbo run lint",
15 | "format": "prettier --write \"**/*.{ts,tsx,md}\""
16 | },
17 | "devDependencies": {
18 | "@types/jest": "^29.5.1",
19 | "@types/node": "^20.1.0",
20 | "@types/react": "^18.2.6",
21 | "@types/react-dom": "latest",
22 | "@types/react-modal": "^3",
23 | "@typescript-eslint/eslint-plugin": "^5.59.2",
24 | "@typescript-eslint/parser": "^5.59.2",
25 | "babel-plugin-emotion": "^11.0.0",
26 | "eslint": "^8.40.0",
27 | "eslint-config-custom": "*",
28 | "eslint-config-prettier": "^8.8.0",
29 | "eslint-import-resolver-typescript": "^3.5.5",
30 | "eslint-plugin-import": "^2.27.5",
31 | "eslint-plugin-react": "^7.32.2",
32 | "eslint-plugin-react-hooks": "^4.6.0",
33 | "prettier": "^2.8.8",
34 | "turbo": "latest"
35 | },
36 | "engines": {
37 | "node": ">=14.0.0"
38 | },
39 | "packageManager": "yarn@4.6.0",
40 | "dependencies": {
41 | "@emotion/babel-plugin": "^11.11.0",
42 | "@emotion/react": "11.11.0",
43 | "@emotion/styled": "^11.11.0",
44 | "@next/font": "^13.4.1",
45 | "@svgr/webpack": "^8.0.1",
46 | "@tanstack/react-query": "4.29.15",
47 | "axios": "^1.4.0",
48 | "date-fns": "^2.30.0",
49 | "emotion-reset": "^3.0.1",
50 | "next": "13.4.4",
51 | "next-images": "^1.8.5",
52 | "react": "^18.2.0",
53 | "react-dom": "^18.2.0",
54 | "react-hook-form": "^7.45.2",
55 | "react-intersection-observer": "^9.5.2",
56 | "react-modal": "^3.16.1",
57 | "recoil": "^0.7.7",
58 | "typescript": "5.0.4",
59 | "webpack": "^5.97.1"
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/packages/eslint-config-custom/index.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ["next", "turbo", "prettier"],
3 | rules: {
4 | "@next/next/no-html-link-for-pages": "off",
5 | },
6 | parserOptions: {
7 | babelOptions: {
8 | presets: [require.resolve("next/babel")],
9 | },
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/packages/eslint-config-custom/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "eslint-config-custom",
3 | "version": "0.0.0",
4 | "main": "index.js",
5 | "license": "MIT",
6 | "dependencies": {
7 | "eslint": "^7.23.0",
8 | "eslint-config-next": "13.0.0",
9 | "eslint-config-prettier": "^8.3.0",
10 | "eslint-config-turbo": "latest",
11 | "eslint-plugin-react": "7.31.8",
12 | "next": "13.4.4"
13 | },
14 | "devDependencies": {
15 | "typescript": "^4.7.4"
16 | },
17 | "publishConfig": {
18 | "access": "public"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/packages/tsconfig/README.md:
--------------------------------------------------------------------------------
1 | # `tsconfig`
2 |
3 | These are base shared `tsconfig.json`s from which all other `tsconfig.json`'s inherit from.
4 |
--------------------------------------------------------------------------------
/packages/tsconfig/base.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "display": "Default",
4 | "compilerOptions": {
5 | "composite": false,
6 | "declaration": true,
7 | "declarationMap": true,
8 | "esModuleInterop": true,
9 | "forceConsistentCasingInFileNames": false,
10 | "inlineSources": false,
11 | "isolatedModules": true,
12 | "moduleResolution": "node",
13 | "noUnusedLocals": false,
14 | "noUnusedParameters": false,
15 | "preserveWatchOutput": true,
16 | "skipLibCheck": true,
17 | "strict": true
18 | },
19 | "exclude": ["node_modules"]
20 | }
21 |
--------------------------------------------------------------------------------
/packages/tsconfig/nextjs.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "display": "Next.js",
4 | "extends": "./base.json",
5 | "compilerOptions": {
6 | "target": "es5",
7 | "lib": ["dom", "dom.iterable", "esnext"],
8 | "allowJs": true,
9 | "skipLibCheck": true,
10 | "strict": true,
11 | "forceConsistentCasingInFileNames": false,
12 | "noEmit": true,
13 | "incremental": true,
14 | "esModuleInterop": true,
15 | "module": "esnext",
16 | "resolveJsonModule": true,
17 | "isolatedModules": true,
18 | "jsx": "preserve"
19 | },
20 | "include": ["src", "next-env.d.ts"],
21 | "exclude": ["node_modules"]
22 | }
23 |
--------------------------------------------------------------------------------
/packages/tsconfig/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tsconfig",
3 | "version": "0.0.0",
4 | "private": true,
5 | "files": [
6 | "base.json",
7 | "nextjs.json",
8 | "react-library.json"
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/packages/tsconfig/react-library.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "display": "React Library",
4 | "extends": "./base.json",
5 | "compilerOptions": {
6 | "jsx": "react-jsx",
7 | "lib": ["ES2015"],
8 | "module": "ESNext",
9 | "target": "es6"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/packages/ui/custom.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.jpg';
2 | declare module '*.png';
3 | declare module '*.jpeg';
4 | declare module '*.gif';
5 | declare module '*.svg' {
6 | import * as React from 'react';
7 |
8 | export const ReactComponent: React.FunctionComponent<
9 | React.SVGProps & { title?: string }
10 | >;
11 |
12 | const src: string;
13 | export default src;
14 | }
15 |
--------------------------------------------------------------------------------
/packages/ui/index.tsx:
--------------------------------------------------------------------------------
1 | export * from './src/components/Button';
2 | export * from './src/components/Checkbox';
3 | export * from './src/components/TextField';
4 | export * from './src/components/FloatingButton';
5 | export * from './src/components/Card';
6 | export * from './src/styles/';
7 | export * from './src/components/common';
8 | export * from './src/components/SelectButton';
9 | export * from './src/components/DatePicker';
10 |
--------------------------------------------------------------------------------
/packages/ui/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@ceos-fe/ui",
3 | "version": "0.0.0",
4 | "main": "./index.tsx",
5 | "types": "./index.tsx",
6 | "license": "MIT",
7 | "scripts": {
8 | "lint": "eslint \"**/*.ts*\""
9 | },
10 | "devDependencies": {
11 | "@emotion/react": "^11.11.0",
12 | "@emotion/styled": "^11.11.0",
13 | "@types/node": "^20.1.0",
14 | "@types/react": "^18.2.6",
15 | "@types/react-datepicker": "^4",
16 | "@types/react-dom": "^18.2.4",
17 | "eslint": "^7.32.0",
18 | "eslint-config-custom": "*",
19 | "react": "^18.2.0",
20 | "react-dom": "^18.2.0",
21 | "tsconfig": "*",
22 | "typescript": "^5.0.4"
23 | },
24 | "dependencies": {
25 | "@ceos-fe/utils": "workspace:^",
26 | "date-fns": "^2.30.0",
27 | "emotion-reset": "^3.0.1",
28 | "next": "^13.4.12",
29 | "react-datepicker": "^4.14.1"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/packages/ui/src/assets/Arrow/index.tsx:
--------------------------------------------------------------------------------
1 | import { css } from '@emotion/react';
2 |
3 | export const Up = ({
4 | width = 30,
5 | height = 18,
6 | margin = '20px 0 0 0',
7 | }: {
8 | width?: number;
9 | height?: number;
10 | margin?: string;
11 | }) => {
12 | return (
13 |
20 |
47 |
48 | );
49 | };
50 |
51 | export const Down = ({
52 | width = 30,
53 | height = 18,
54 | margin = '20px 0 0 0',
55 | }: {
56 | width?: number;
57 | height?: number;
58 | margin?: string;
59 | }) => {
60 | return (
61 |
68 |
95 |
96 | );
97 | };
98 |
--------------------------------------------------------------------------------
/packages/ui/src/assets/Calender/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export const Calendar = () => {
4 | return (
5 |
26 | );
27 | };
28 |
--------------------------------------------------------------------------------
/packages/ui/src/assets/CheckIcon/index.tsx:
--------------------------------------------------------------------------------
1 | import { css } from '@emotion/react';
2 |
3 | export const CheckIcon = ({
4 | width = 20,
5 | height = 20,
6 | checked = false,
7 | }: {
8 | width?: number;
9 | height?: number;
10 | checked?: boolean;
11 | }) => {
12 | return (
13 |
20 |
41 |
42 | );
43 | };
44 |
--------------------------------------------------------------------------------
/packages/ui/src/assets/CloseIcon/WhiteCloseIcon.tsx:
--------------------------------------------------------------------------------
1 | import { css } from '@emotion/react';
2 | import React from 'react';
3 | import styled from '@emotion/styled';
4 |
5 | export interface CloseProps {
6 | fillColor?: string;
7 | }
8 |
9 | export const WhiteCloseIcon = (props: CloseProps) => {
10 | const { fillColor } = props;
11 | return (
12 |
13 |
30 |
31 | );
32 | };
33 |
34 | const Container = styled.div`
35 | width: 26px;
36 | height: 26px;
37 |
38 | :hover {
39 | cursor: pointer;
40 | }
41 | `;
42 |
--------------------------------------------------------------------------------
/packages/ui/src/assets/CloseIcon/index.tsx:
--------------------------------------------------------------------------------
1 | import { css } from '@emotion/react';
2 | import { useModal } from '../../../../utils';
3 |
4 | export interface CloseProps {
5 | width?: number;
6 | height?: number;
7 | margin?: string;
8 | isOpen: boolean;
9 | toggleModal: () => void;
10 | }
11 |
12 | export const CloseIcon = (props: CloseProps) => {
13 | const { width, height, margin, isOpen, toggleModal } = props;
14 | return (
15 |
42 | );
43 | };
44 |
--------------------------------------------------------------------------------
/packages/ui/src/assets/FloatingButton/Email/index.tsx:
--------------------------------------------------------------------------------
1 | import { css } from '@emotion/react';
2 |
3 | export const Email = ({
4 | width = 26,
5 | height = 26,
6 | }: {
7 | width?: number;
8 | height?: number;
9 | }) => {
10 | return (
11 |
45 | );
46 | };
47 |
--------------------------------------------------------------------------------
/packages/ui/src/assets/FloatingButton/Instagram/index.tsx:
--------------------------------------------------------------------------------
1 | import { css } from '@emotion/react';
2 |
3 | export const Instagram = ({
4 | width = 26,
5 | height = 26,
6 | }: {
7 | width?: number;
8 | height?: number;
9 | }) => {
10 | return (
11 |
22 |
51 |
52 | );
53 | };
54 |
--------------------------------------------------------------------------------
/packages/ui/src/assets/RewardCheck/index.tsx:
--------------------------------------------------------------------------------
1 | import { css } from '@emotion/react';
2 |
3 | export const RewardCheck = ({
4 | width = 20,
5 | height = 20,
6 | margin = '0 10px 0 0',
7 | }: {
8 | width?: number;
9 | height?: number;
10 | margin?: string;
11 | }) => {
12 | return (
13 |
20 |
49 |
50 | );
51 | };
52 |
--------------------------------------------------------------------------------
/packages/ui/src/assets/SubTextFieldIcon/index.tsx:
--------------------------------------------------------------------------------
1 | import styled from '@emotion/styled';
2 | export const SubTextFieldIcon = () => {
3 | return (
4 |
5 |
14 |
15 | );
16 | };
17 |
18 | const Container = styled.div`
19 | margin: 0 8px;
20 | `;
21 |
--------------------------------------------------------------------------------
/packages/ui/src/components/Card/index.tsx:
--------------------------------------------------------------------------------
1 | export * from './ActivityCard';
2 | export * from './ManagementCard';
3 | export * from './ProjectCard';
4 | export * from './RewardCard';
5 | export * from './SponsorCard';
6 |
--------------------------------------------------------------------------------
/packages/ui/src/components/Checkbox/index.tsx:
--------------------------------------------------------------------------------
1 | import styled from '@emotion/styled';
2 | import { theme } from '../../styles';
3 | import { Flex, Text } from '../common';
4 | import { CheckIcon } from '../../assets/CheckIcon';
5 |
6 | interface CheckBoxProps {
7 | checked: boolean; //check 되어있는지 여부
8 | onClick: () => void; // useState 이용하여 setChecked(prev=>!prev)
9 | value: string[]; // text
10 | type: string; //'column' or 'row'
11 | }
12 |
13 | export const CheckBox = ({ checked, onClick, value, type }: CheckBoxProps) => {
14 | return (
15 |
16 |
17 |
18 |
19 |
20 | {value.map((text, idx) => (
21 |
28 | {text}
29 |
30 | ))}
31 |
32 |
33 | );
34 | };
35 |
36 | // checkbox
37 | const StyledCheckBoxContainer = styled.div<{ type?: string }>`
38 | display: flex;
39 | flex-direction: ${(props) => (props.type == 'row' ? 'row' : 'column')};
40 | align-items: center;
41 | justify-content: center;
42 | width: fit-content;
43 | height: fit-content;
44 | gap: 14px;
45 |
46 | // 이미지 및 텍스트 드래그 방지
47 | -webkit-user-select: none;
48 | -moz-user-select: none;
49 | -ms-use-select: none;
50 | user-select: none;
51 |
52 | @media (min-width: 1023px) {
53 | gap: 7px;
54 | }
55 | `;
56 | const StyledCheckBox = styled.div`
57 | width: 20px;
58 | height: 20px;
59 | cursor: pointer;
60 | border-radius: 4px;
61 | background-color: ${theme.palette.Gray2};
62 |
63 | @media (max-width: 1023px) {
64 | background-color: ${theme.palette.Gray2};
65 | border-radius: 2px;
66 | }
67 | `;
68 |
--------------------------------------------------------------------------------
/packages/ui/src/components/FloatingButton/index.tsx:
--------------------------------------------------------------------------------
1 | import styled from '@emotion/styled';
2 | import { theme } from '../../styles';
3 | import { Email } from '../../assets/FloatingButton/Email';
4 | import { Instagram } from '../../assets/FloatingButton/Instagram';
5 |
6 | export interface FloatingProps {
7 | className?: string;
8 | direction?: string;
9 | }
10 |
11 | export const FloatingButton = (props: FloatingProps) => {
12 | const { direction } = props;
13 | return (
14 |
15 | window.open('https://www.instagram.com/ceos.sinchon/')}
17 | >
18 |
19 |
20 |
21 |
22 |
23 |
24 | );
25 | };
26 |
27 | const FloatingBtnContainer = styled.div<{ direction?: string }>`
28 | display: flex;
29 | flex-direction: ${({ direction }) => (direction ? `${direction}` : 'column')};
30 | gap: 12px;
31 |
32 | // 이미지 및 텍스트 드래그 방지
33 | -webkit-user-select: none;
34 | -moz-user-select: none;
35 | -ms-use-select: none;
36 | user-select: none;
37 | `;
38 | const FloatingBtnCircle = styled.a`
39 | width: 50px;
40 | height: 50px;
41 | background-color: ${theme.palette.Yellow};
42 | border-radius: 50%;
43 | box-shadow: ${theme.shadow.Button.Yellow};
44 | cursor: pointer;
45 | display: flex;
46 | align-items: center;
47 | justify-content: center;
48 | `;
49 |
--------------------------------------------------------------------------------
/packages/ui/src/components/common/Text.tsx:
--------------------------------------------------------------------------------
1 | import styled from '@emotion/styled';
2 | import {
3 | KeyOfAdminPalette,
4 | KeyOfMobileTypo,
5 | KeyOfWebTypo,
6 | theme,
7 | } from '../../styles';
8 | import { KeyOfPalette } from '../../styles';
9 |
10 | export const Text = styled.div<{
11 | webTypo?: KeyOfWebTypo;
12 | mobileTypo?: KeyOfMobileTypo;
13 | paletteColor?: KeyOfPalette | KeyOfAdminPalette;
14 | colorCode?: string;
15 | margin?: string;
16 | }>`
17 | ${({ webTypo }) => (webTypo ? theme.typo.Web[webTypo] : '')};
18 | color: ${({ paletteColor, colorCode }) => {
19 | if (theme.palette[paletteColor as KeyOfPalette]) {
20 | return theme.palette[paletteColor as KeyOfPalette];
21 | } else if (theme.palette.Admin[paletteColor as KeyOfAdminPalette]) {
22 | return theme.palette.Admin[paletteColor as KeyOfAdminPalette];
23 | } else {
24 | return `${colorCode}`;
25 | }
26 | }};
27 | display: flex;
28 | align-items: center;
29 | margin: ${({ margin }) => (margin ? margin : '0')};
30 |
31 | /* 브라우저 크기에 따라 가로 크기 변경 */
32 | @media (max-width: 1023px) {
33 | ${({ mobileTypo }) => (mobileTypo ? theme.typo.Mobile[mobileTypo] : '')};
34 | }
35 | `;
36 |
--------------------------------------------------------------------------------
/packages/ui/src/components/common/Wrapper.tsx:
--------------------------------------------------------------------------------
1 | import styled from '@emotion/styled';
2 | import { KeyOfPalette, media, theme } from '../../styles';
3 |
4 | export const Flex = styled.div<{
5 | direction?: string;
6 | justify?: string;
7 | align?: string;
8 | margin?: string;
9 | padding?: string;
10 | webGap?: number;
11 | mobileGap?: number;
12 | widthPer?: number;
13 | heightPer?: number;
14 | width?: number | string;
15 | height?: number | string;
16 | borderRadius?: number;
17 | backgroundColor?: KeyOfPalette;
18 | wrap?: boolean;
19 | }>`
20 | display: flex;
21 | flex-direction: ${({ direction }) => (direction ? `${direction}` : 'row')};
22 | justify-content: ${({ justify }) => (justify ? `${justify}` : 'center')};
23 | align-items: ${({ align }) => (align ? `${align}` : 'center')};
24 | gap: ${({ webGap }) => (webGap ? `${webGap}px` : '0px')};
25 | width: ${({ width, widthPer }) =>
26 | width ? `${width}px` : widthPer ? `${widthPer}%` : '100%'};
27 | height: ${({ height, heightPer }) =>
28 | height ? `${height}px` : heightPer ? `${heightPer}%` : '100%'};
29 | margin: ${({ margin }) => (margin ? margin : '0')};
30 | padding: ${({ padding }) => (padding ? padding : '0')};
31 | box-sizing: border-box;
32 | border-radius: ${({ borderRadius }) =>
33 | borderRadius ? `${borderRadius}px` : '0px'};
34 |
35 | background-color: ${({ backgroundColor }) =>
36 | backgroundColor ? theme.palette[backgroundColor] : `transparent`};
37 |
38 | flex-wrap: ${({ wrap }) => (wrap ? 'wrap' : 'nowrap')};
39 |
40 | /* 브라우저 크기에 따라 가로 크기 변경 */
41 | @media (max-width: 1023px) {
42 | gap: ${({ mobileGap }) => (mobileGap ? `${mobileGap}px` : '0px')};
43 | }
44 | `;
45 |
46 | export const RelativeContainer = styled(Flex)`
47 | position: relative;
48 |
49 | .is-hover {
50 | display: none;
51 | }
52 | :hover {
53 | .is-hover {
54 | display: flex;
55 | }
56 | }
57 | `;
58 |
59 | export const AbsoluteFlex = styled(Flex)`
60 | position: absolute;
61 | top: 0;
62 | left: 0;
63 |
64 | &.is-hover {
65 | background-color: rgba(0, 0, 0, 0.5);
66 | }
67 | `;
68 |
69 | export const Space = styled.div<{
70 | height?: number;
71 | width?: number;
72 | mobileHeight?: number;
73 | mobileWidth?: number;
74 | }>`
75 | height: ${({ height }) => (height ? `${height}px` : '')};
76 | width: ${({ width }) => (width ? `${width}px` : '')};
77 |
78 | ${media.mobile} {
79 | height: ${({ mobileHeight }) => (mobileHeight ? `${mobileHeight}px` : '')};
80 | width: ${({ mobileWidth }) => (mobileWidth ? `${mobileWidth}px` : '')};
81 | }
82 | `;
83 |
--------------------------------------------------------------------------------
/packages/ui/src/components/common/index.tsx:
--------------------------------------------------------------------------------
1 | export * from './Text';
2 | export * from './Wrapper';
3 |
--------------------------------------------------------------------------------
/packages/ui/src/custom.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.jpg';
2 | declare module '*.png';
3 | declare module '*.jpeg';
4 | declare module '*.gif';
5 | declare module '*.svg' {
6 | const value: string;
7 | export default value;
8 | }
9 |
--------------------------------------------------------------------------------
/packages/ui/src/styles/GlobalStyles.ts:
--------------------------------------------------------------------------------
1 | import { css } from '@emotion/react';
2 | import emotionReset from 'emotion-reset';
3 |
4 | export const globalStyle = css`
5 | ${emotionReset}
6 | body {
7 | min-height: 100vh;
8 | @supports (-webkit-appearance: none) and (stroke-color: transparent) {
9 | min-height: -webkit-fill-available;
10 | scroll: smooth;
11 | }
12 | font-family: 'Pretendard';
13 | }
14 | button {
15 | background: inherit;
16 | border: none;
17 | box-shadow: none;
18 | border-radius: 0;
19 | padding: 0;
20 | overflow: visible;
21 | cursor: pointer;
22 | user-select: none;
23 | -webkit-user-select: none;
24 | -moz-user-select: none;
25 | -ms-user-select: none;
26 | }
27 | button:focus {
28 | outline: none;
29 | }
30 | button:disabled {
31 | pointer-events: none;
32 | }
33 | input:focus {
34 | outline: none;
35 | }
36 | textarea:focus {
37 | outline: none;
38 | }
39 | input,
40 | textarea {
41 | border: none;
42 | margin: 0;
43 | }
44 | `;
45 |
--------------------------------------------------------------------------------
/packages/ui/src/styles/emotion.d.ts:
--------------------------------------------------------------------------------
1 | //emotion.d.ts
2 | import '@emotion/react';
3 | import { TypeOfPalette, TypeOfTypo, TypeOfShadow, TypeOfGlass } from './theme';
4 |
5 | declare module '@emotion/react' {
6 | export interface Theme {
7 | palette: TypeOfPalette;
8 | typo: TypeOfTypo;
9 | shadow: TypeOfShadow;
10 | glass: TypeOfGlass;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/packages/ui/src/styles/index.tsx:
--------------------------------------------------------------------------------
1 | export * from './palette';
2 | export * from './shadow';
3 | export * from './theme';
4 | export * from './typo';
5 | export * from './glass';
6 |
7 | export * from './GlobalStyles';
8 | export * from './mediaQuery';
9 |
--------------------------------------------------------------------------------
/packages/ui/src/styles/mediaQuery.ts:
--------------------------------------------------------------------------------
1 | import styled from '@emotion/styled';
2 |
3 | export const Desktop = styled.div`
4 | display: flex;
5 | @media (max-width: 1023px) {
6 | display: none;
7 | }
8 | `;
9 |
10 | export const Mobile = styled.div`
11 | display: none;
12 | @media (max-width: 1023px) {
13 | width: 100%;
14 | display: block;
15 | }
16 | `;
17 |
--------------------------------------------------------------------------------
/packages/ui/src/styles/palette.tsx:
--------------------------------------------------------------------------------
1 | export const palette = {
2 | Blue: '#3E4CF7',
3 | Yellow: '#FFC466',
4 | Skyblue: '#5ED8FF',
5 | Green: '#01D1A8',
6 |
7 | White: '#FFFFFF',
8 | Gray1: '#F4F6F9',
9 | Gray2: '#E9EBEF',
10 | Gray3: '#D6DADF',
11 | Gray4: '#B0B5BD',
12 | Gray5: '#787E88',
13 | Gray6: '#B0B5BD', //헤더 버튼 색
14 | Gray7: '#E9EBEF', //헤더 버튼 색
15 | Gray8: '#787E88', //메뉴 버튼
16 | Gray9: '#F4F6F9;', //FAQ A색
17 | Black: '#232527',
18 |
19 | Admin: {
20 | Navy: '#31314E',
21 | DeepNavy: '#212135',
22 | Green1: '#01D1A8',
23 | Green2: '#D4FFF7',
24 | Red1: '#FF6262',
25 | Red2: '#FFE7E7',
26 | },
27 |
28 | Shadow: {
29 | Card: {
30 | Black: 'rgba(0, 0, 0, 0.10)',
31 | },
32 | Button: {
33 | Blue: 'rgba(56, 77, 248, 0.2)',
34 | Yellow: 'rgba(201, 145, 0, 0.15)',
35 | },
36 | Date: {
37 | Blue: 'rgba(0, 0, 0, 0.15)',
38 | },
39 | },
40 | Opacity: {
41 | Blue: 'rgba(62,76,247,0)',
42 | },
43 | };
44 |
--------------------------------------------------------------------------------
/packages/ui/src/styles/shadow.tsx:
--------------------------------------------------------------------------------
1 | import { palette } from './palette';
2 |
3 | /* offset-x | offset-y | blur-radius | spread-radius | color */
4 | export const shadow = {
5 | Card: {
6 | Black: `
7 | 0px 20px 20px 0px ${palette.Shadow.Card.Black};
8 | `,
9 | },
10 | Button: {
11 | Blue: `
12 | 0px 4px 10px 0px ${palette.Shadow.Button.Blue};
13 | `,
14 | Yellow: `
15 | 0px 4px 10px 0px ${palette.Shadow.Button.Yellow};
16 | `,
17 | },
18 | Date: {
19 | Blue: `
20 | 0px 10px 30px 0px ${palette.Shadow.Date.Blue};
21 | `,
22 | },
23 | PopUp: {
24 | Gray: `
25 | 0px 12px 20px 0px rgba(0, 0, 0, 0.10);
26 | `,
27 | },
28 | };
29 |
--------------------------------------------------------------------------------
/packages/ui/src/styles/theme.tsx:
--------------------------------------------------------------------------------
1 | import { palette } from './palette';
2 | import { shadow } from './shadow';
3 | import { typo } from './typo';
4 | import { glass } from './glass';
5 |
6 | export interface TypeOfTheme {
7 | typo: TypeOfTypo;
8 | palette: TypeOfPalette;
9 | shadow: TypeOfShadow;
10 | glass: TypeOfGlass;
11 | }
12 |
13 | export const theme: TypeOfTheme = {
14 | typo,
15 | palette,
16 | shadow,
17 | glass,
18 | };
19 |
20 | export type TypeOfPalette = typeof palette;
21 | export type KeyOfPalette = keyof typeof palette;
22 |
23 | export type TypeOfAdminPalette = typeof palette.Admin;
24 | export type KeyOfAdminPalette = keyof typeof palette.Admin;
25 |
26 | export type KeyofTheme = keyof typeof theme;
27 |
28 | export type TypeOfTypo = typeof typo;
29 | export type KeyOfTypo = keyof typeof typo;
30 | export type KeyOfWebTypo = keyof typeof typo.Web;
31 | export type KeyOfMobileTypo = keyof typeof typo.Mobile;
32 |
33 | export type TypeOfShadow = typeof shadow;
34 | export type KeyOfTShdow = keyof typeof shadow;
35 |
36 | export type TypeOfGlass = typeof glass;
37 | export type KeyOfGlass = keyof typeof glass;
38 |
39 | export const customMediaQuery = (minWidth: number): string =>
40 | `@media (min-width: ${minWidth}px)`;
41 | export const media = {
42 | custom: customMediaQuery,
43 | pc: customMediaQuery(1024),
44 | mobile: `@media (max-width : 1023px)`,
45 | };
46 |
--------------------------------------------------------------------------------
/packages/ui/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "compilerOptions": {
4 | "target": "es6",
5 | "lib": ["dom", "dom.iterable", "esnext"],
6 | "allowJs": true,
7 | "skipLibCheck": true,
8 | "esModuleInterop": true,
9 | "allowSyntheticDefaultImports": true,
10 | "strict": true,
11 | "forceConsistentCasingInFileNames": false,
12 | "noFallthroughCasesInSwitch": true,
13 | "module": "esnext",
14 | "moduleResolution": "node",
15 | "resolveJsonModule": true,
16 | "isolatedModules": true,
17 | "noEmit": true,
18 | "jsx": "react-jsx",
19 | "composite": true,
20 | "declaration": true,
21 | "jsxImportSource": "@emotion/react"
22 | },
23 | "include": ["src/**/*.ts", "custom.d.ts"]
24 | }
25 |
--------------------------------------------------------------------------------
/packages/utils/README.md:
--------------------------------------------------------------------------------
1 | # utils
2 |
--------------------------------------------------------------------------------
/packages/utils/index.tsx:
--------------------------------------------------------------------------------
1 | export * from './src/hooks/useModal';
2 | export * from './src/hooks/useWindowResize';
3 | export * from './src/apis';
4 | export * from './src/utils/portal';
5 |
--------------------------------------------------------------------------------
/packages/utils/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@ceos-fe/utils",
3 | "packageManager": "yarn@3.5.0",
4 | "main": "./index.tsx",
5 | "types": "./index.tsx",
6 | "devDependencies": {
7 | "@types/node": "^20.1.0",
8 | "@types/react": "^18.2.6",
9 | "@types/react-dom": "^18.2.4",
10 | "react": "^18.2.0",
11 | "react-dom": "^18.2.0"
12 | },
13 | "dependencies": {
14 | "@tanstack/react-query": "^4.29.19",
15 | "axios": "^1.4.0"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/packages/utils/src/apis/admin/adminActivityApi.ts:
--------------------------------------------------------------------------------
1 | import { adminInstance } from '../axiosConfig';
2 |
3 | export interface ActivityDTO {
4 | id: number;
5 | name: string;
6 | content: string;
7 | imageUrl: string;
8 | }
9 |
10 | export interface ActivityResponse {
11 | content: ActivityDTO[];
12 | pageInfo: {
13 | pageNum: number;
14 | limit: number;
15 | totalPages: number;
16 | totalElements: number;
17 | };
18 | }
19 |
20 | export const adminActivityApi = {
21 | GET_ACTIVITY: async ({ pageNum = 0, limit = 12 }) => {
22 | const response = await adminInstance.get(
23 | `/activities?pageNum=${pageNum}&limit=${limit}`,
24 | );
25 |
26 | return response.data.data;
27 | },
28 | GET_ONE_ACTIVITY: async (id: number) => {
29 | const response = await adminInstance.get(`/activities/${id}`);
30 |
31 | return response.data.data;
32 | },
33 | POST_ACTIVITY: async ({
34 | payload,
35 | }: {
36 | payload: ActivityDTO;
37 | }): Promise => {
38 | const response = await adminInstance.post(`/activities`, payload);
39 | return response.data.data;
40 | },
41 | PUT_ACTIVITY: async ({
42 | payload,
43 | id,
44 | }: {
45 | payload: ActivityDTO;
46 | id: number;
47 | }): Promise => {
48 | const response = await adminInstance.put(`/activities/${id}`, payload);
49 | return response.data.data;
50 | },
51 | DELETE_ACTIVITY: async (id: number): Promise => {
52 | const response = await adminInstance.delete(`/activities/${id}`);
53 | return response.data.data;
54 | },
55 | };
56 |
--------------------------------------------------------------------------------
/packages/utils/src/apis/admin/adminApplicationApi.ts:
--------------------------------------------------------------------------------
1 | import { adminInstance } from '../axiosConfig';
2 |
3 | export type AdminSelectedPartType = '기획' | '디자인' | '프론트엔드' | '백엔드';
4 | export type AdminSelectedQuestionsType =
5 | | 'productQuestions'
6 | | 'designQuestions'
7 | | 'frontendQuestions'
8 | | 'backendQuestions';
9 | export interface AdminApplicationListItemInterface {
10 | questionIndex: number;
11 | question: string;
12 | multiline: boolean;
13 | questionDetail: {
14 | explaination: string;
15 | color: string;
16 | }[];
17 | }
18 | export interface AdminPartQuestionsInterface {
19 | productQuestions: AdminApplicationListItemInterface[];
20 | designQuestions: AdminApplicationListItemInterface[];
21 | frontendQuestions: AdminApplicationListItemInterface[];
22 | backendQuestions: AdminApplicationListItemInterface[];
23 | }
24 | export interface AdminApplicationInterface extends AdminPartQuestionsInterface {
25 | commonQuestions: AdminApplicationListItemInterface[];
26 | times: {
27 | date: string;
28 | durations: string[];
29 | }[];
30 | }
31 |
32 | export const adminApplicationApi = {
33 | GET_APPLICATION: async () => {
34 | const response = await adminInstance.get(`/applications/question`);
35 |
36 | return response.data.data;
37 | },
38 | PUT_APPLICATION: async (question: AdminApplicationInterface) => {
39 | const response = await adminInstance.put(
40 | `/applications/question`,
41 | question,
42 | );
43 |
44 | return response.data.data;
45 | },
46 | };
47 |
--------------------------------------------------------------------------------
/packages/utils/src/apis/admin/adminAuthApi.tsx:
--------------------------------------------------------------------------------
1 | import { adminInstance } from '../axiosConfig';
2 |
3 | export interface CommonInterface {
4 | name: string;
5 | part: string;
6 | email: string;
7 | }
8 | export interface signUpInterface extends CommonInterface {
9 | username: string;
10 | password: string;
11 | }
12 | export interface signInInterface {
13 | username: string;
14 | password: string;
15 | }
16 | export interface findIdInterface extends CommonInterface {}
17 | export interface findPwInterface extends CommonInterface {
18 | username: string;
19 | }
20 | // export interface authDataFormInterface {
21 | // name: string;
22 | // email: string;
23 | // username: string;
24 | // password: string;
25 | // partDropdown: { label: string; value: string };
26 | // }
27 |
28 | export const adminAuthApi = {
29 | SIGN_UP: async (signUpData: signUpInterface) => {
30 | const response = await adminInstance.post(`/admin/signup`, signUpData);
31 | return response.data;
32 | },
33 | SIGN_IN: async (signInData: signInInterface) => {
34 | const response = await adminInstance.post(`/admin/signin`, signInData);
35 | return response.data.data;
36 | },
37 | SIGN_OUT: async () => {
38 | const response = await adminInstance.post(`/admin/logout`);
39 | return response.data;
40 | },
41 | CHECK_ID: async (userid: string) => {
42 | const response = await adminInstance.post(`/admin/username`, {
43 | username: userid,
44 | });
45 | return response.data;
46 | },
47 | FIND_ID: async (findIDdata: findIdInterface) => {
48 | const response = await adminInstance.post(`/admin/id`, findIDdata);
49 | return response.data;
50 | },
51 | FIND_PW: async (findPWdata: findPwInterface) => {
52 | const response = await adminInstance.post(`/admin/password`, findPWdata);
53 | return response.data;
54 | },
55 | POST_REFRESHTOKEN: async (refreshToken: string) => {
56 | const response = await adminInstance.post(`/admin/reissue`, {
57 | refreshToken: refreshToken,
58 | });
59 | return response.data;
60 | },
61 | };
62 |
--------------------------------------------------------------------------------
/packages/utils/src/apis/admin/adminFaqApi.ts:
--------------------------------------------------------------------------------
1 | import { adminInstance } from '../axiosConfig';
2 |
3 | export type CategoryType = 'RECRUIT' | 'ACTIVITY' | 'PART';
4 | export interface FaqListItemInterface {
5 | id: number;
6 | category: CategoryType;
7 | question: string;
8 | answer: string;
9 | }
10 |
11 | export const adminFaqApi = {
12 | GET_FAQ: async (category: CategoryType) => {
13 | const response = await adminInstance.get(`/faq?category=${category}`);
14 |
15 | return response.data.data;
16 | },
17 | POST_FAQ: async (question: FaqListItemInterface) => {
18 | const { id, ...body } = question;
19 | const response = await adminInstance.post(`/faq`, body);
20 |
21 | return response.data.data;
22 | },
23 | PATCH_FAQ: async (question: FaqListItemInterface) => {
24 | const { id, category, ...body } = question;
25 | const response = await adminInstance.patch(`/faq/${id}`, body);
26 |
27 | return response.data.data;
28 | },
29 | DELETE_FAQ: async (question: FaqListItemInterface) => {
30 | const response = await adminInstance.delete(`/faq/${question.id}`);
31 |
32 | return response.data.data;
33 | },
34 | };
35 |
--------------------------------------------------------------------------------
/packages/utils/src/apis/admin/adminInterviewAvailabilityApi.tsx:
--------------------------------------------------------------------------------
1 | import { adminInstance } from '../axiosConfig';
2 |
3 | export interface InterviewAvailabilityInterface {
4 | interviewAvailability: boolean;
5 | reason: string | undefined;
6 | }
7 |
8 | export const adminInterviewAvailabilityApi = {
9 | GET_INTERVIEW_AVAILABILITY: async (idx: number): Promise => {
10 | const response = await adminInstance.get(`/applications/${idx}/interview/availability`);
11 |
12 | return {
13 | interviewAvailability: response.data.data.interviewAvailability,
14 | reason: response.data.data.reason,
15 | };
16 | },
17 | };
--------------------------------------------------------------------------------
/packages/utils/src/apis/admin/adminManageUserApi.tsx:
--------------------------------------------------------------------------------
1 | import { adminInstance } from '../axiosConfig';
2 |
3 | export interface managementInterface {
4 | id: number;
5 | name: string;
6 | email: string;
7 | adminRole: string;
8 | part?: string | undefined;
9 | }
10 |
11 | export const adminManageUserApi = {
12 | GET_MANAGEMENT: async (pageNum: number, limit: number) => {
13 | const response = await adminInstance.get(
14 | `admin/super?pageNum=${pageNum}&limit=${limit}`,
15 | );
16 | return response.data;
17 | },
18 | DELETE_MANAGEMENT: async (idx: number) => {
19 | const response = await adminInstance.delete(`/admin/super?adminId=${idx}`);
20 | return response;
21 | },
22 | CHANGE_MANAGEMENTROLE: async (idx: number, role: string) => {
23 | const response = await adminInstance.post(`/admin/super`, {
24 | id: idx,
25 | adminRole: role,
26 | });
27 | return response;
28 | },
29 | };
30 |
--------------------------------------------------------------------------------
/packages/utils/src/apis/admin/adminManagementApi.ts:
--------------------------------------------------------------------------------
1 | import { adminInstance } from '../axiosConfig';
2 |
3 | type RoleType = '운영진' | '멘토';
4 |
5 | type UniversityType =
6 | | '서강대학교'
7 | | '연세대학교'
8 | | '이화여자대학교'
9 | | '홍익대학교';
10 |
11 | export interface ManagementDTO {
12 | id: number;
13 | name: string;
14 | role: RoleType;
15 | part: string;
16 | generation: number;
17 | managementGeneration: number;
18 | university: UniversityType;
19 | major: string;
20 | company: string;
21 | imageUrl: string;
22 | }
23 |
24 | export interface ManagementResponse {
25 | data: {
26 | content: ManagementDTO[];
27 | pageInfo: {
28 | pageNum: number;
29 | limit: number;
30 | totalPages: number;
31 | totalElements: number;
32 | };
33 | };
34 | }
35 |
36 | export const adminManagementApi = {
37 | GET_MANAGEMENT: async ({ pageNum = 0, limit = 12 }) => {
38 | const response = await adminInstance.get(
39 | `/managements?pageNum=${pageNum}&limit=${limit}`,
40 | );
41 |
42 | return response.data;
43 | },
44 | GET_ONE_MANAGEMENT: async (id: number) => {
45 | const response = await adminInstance.get(`/managements/${id}`);
46 |
47 | return response.data.data;
48 | },
49 | POST_MANAGEMENT: async ({
50 | payload,
51 | }: {
52 | payload: ManagementDTO;
53 | }): Promise => {
54 | const response = await adminInstance.post(`/managements`, payload);
55 | return response.data.data;
56 | },
57 |
58 | PATCH_MANAGEMENT: async ({
59 | payload,
60 | id,
61 | }: {
62 | payload: ManagementDTO;
63 | id: number;
64 | }): Promise => {
65 | const response = await adminInstance.patch(`/managements/${id}`, payload);
66 | return response.data.data;
67 | },
68 |
69 | DELETE_MANAGEMENT: async (id: number): Promise => {
70 | const response = await adminInstance.delete(`/managements/${id}`);
71 | return response.data.data;
72 | },
73 | };
74 |
--------------------------------------------------------------------------------
/packages/utils/src/apis/admin/adminProjectApi.ts:
--------------------------------------------------------------------------------
1 | import { adminInstance } from '../axiosConfig';
2 |
3 | export type ProjectImageType = '썸네일' | '상세';
4 | export type ProjectUrlType = '서비스' | '깃허브' | '비핸스' | '인스타';
5 | export interface ProjectItemInterface {
6 | name: string;
7 | description: string;
8 | generation: number;
9 | projectUrls: {
10 | category: ProjectUrlType;
11 | linkUrl: string;
12 | }[];
13 | projectImages: {
14 | category: ProjectImageType;
15 | imageUrl: string;
16 | }[];
17 | participants: {
18 | part: '기획' | '디자인' | '프론트엔드' | '백엔드';
19 | name: string;
20 | }[];
21 | }
22 | export interface ProjectListInterface {
23 | content: {
24 | id: number;
25 | name: string;
26 | description: string;
27 | generation: number;
28 | thumbnailImage: {
29 | id: number;
30 | category: ProjectImageType;
31 | imageUrl: string;
32 | project: ProjectItemInterface;
33 | };
34 | }[];
35 | pageInfo: {
36 | pageNum: number;
37 | limit: number;
38 | totalPages: number;
39 | totalElements: number;
40 | };
41 | }
42 |
43 | export const adminProjectApi = {
44 | GET_PROJECTS: async ({
45 | pageNum,
46 | limit,
47 | }: {
48 | pageNum: number;
49 | limit: number;
50 | }) => {
51 | const response = await adminInstance.get(`/projects`, {
52 | params: {
53 | pageNum,
54 | limit,
55 | },
56 | });
57 |
58 | return response.data.data;
59 | },
60 | POST_PROJECT: async ({ payload }: { payload: ProjectItemInterface }) => {
61 | const response = await adminInstance.post(`/projects`, payload);
62 |
63 | return response.data.data;
64 | },
65 | PATCH_PROJECT: async ({
66 | payload,
67 | id,
68 | }: {
69 | payload: ProjectItemInterface;
70 | id: number;
71 | }) => {
72 | const response = await adminInstance.patch(`/projects/${id}`, payload);
73 |
74 | return response.data.data;
75 | },
76 | GET_PROJECT: async (projectId: number) => {
77 | const response = await adminInstance.get(`/projects/${projectId}`);
78 |
79 | return response.data.data;
80 | },
81 | DELETE_PROJECT: async (projectId: number) => {
82 | const response = await adminInstance.delete(`/projects/${projectId}`);
83 |
84 | return response.data.data;
85 | },
86 | };
87 |
--------------------------------------------------------------------------------
/packages/utils/src/apis/admin/adminRecruitApi.ts:
--------------------------------------------------------------------------------
1 | import { adminInstance } from '../axiosConfig';
2 |
3 | export interface RecruitBaseInterface {
4 | generation: number;
5 | prodStudyUrl: string;
6 | designStudyUrl: string;
7 | devStudyUrl: string;
8 | openChatUrl: string;
9 | }
10 | export interface RecruitInterface extends RecruitBaseInterface {
11 | startDateDoc: Date;
12 | endDateDoc: Date;
13 | resultDateDoc: Date;
14 | startDateInterview: Date;
15 | endDateInterview: Date;
16 | resultDateFinal: Date;
17 | otDate: Date;
18 | ideathonDate: Date;
19 | hackathonDate: Date;
20 | demodayDate: Date;
21 | }
22 |
23 | export const adminRecruitApi = {
24 | GET_RECRUIT: async () => {
25 | const response = await adminInstance.get(`/recruitments/all`);
26 |
27 | return response.data.data;
28 | },
29 | POST_RECRUIT: async (recruit: RecruitInterface) => {
30 | const response = await adminInstance.put(`/recruitments`, recruit);
31 |
32 | return response.data.data;
33 | },
34 | };
35 |
--------------------------------------------------------------------------------
/packages/utils/src/apis/admin/adminRewardApi.ts:
--------------------------------------------------------------------------------
1 | import { adminInstance } from '../axiosConfig';
2 |
3 | export interface RewardInterface {
4 | id: number;
5 | content: string;
6 | }
7 |
8 | export interface ProjectInterface {
9 | name: string;
10 | description: string;
11 | generation: number;
12 | }
13 |
14 | export interface RewardDTO {
15 | generation: number;
16 | startDate: string;
17 | awards: RewardInterface[];
18 | projects: ProjectInterface[];
19 | }
20 |
21 | export interface RewardResponse {
22 | content: RewardDTO[];
23 | pageInfo: {
24 | pageNum: number;
25 | limit: number;
26 | totalPages: number;
27 | totalElements: number;
28 | };
29 | }
30 |
31 | export const adminRewardApi = {
32 | GET_REWARD: async ({ pageNum = 0, limit = 12 }) => {
33 | const response = await adminInstance.get(
34 | `/awards?pageNum=${pageNum}&limit=${limit}`,
35 | );
36 |
37 | return response.data.data;
38 | },
39 | GET_ONE_REWARD: async (id: number) => {
40 | const response = await adminInstance.get(`/awards/${id}`);
41 |
42 | return response.data.data;
43 | },
44 | POST_REWARD: async ({
45 | payload,
46 | }: {
47 | payload: RewardDTO;
48 | }): Promise => {
49 | const response = await adminInstance.post(`/awards`, payload);
50 | return response.data.data;
51 | },
52 |
53 | PUT_REWARD: async ({
54 | payload,
55 | id,
56 | }: {
57 | payload: RewardDTO;
58 | id: number;
59 | }): Promise => {
60 | const response = await adminInstance.put(`/awards/${id}`, payload);
61 | return response.data.data;
62 | },
63 |
64 | DELETE_REWARD: async (id: number): Promise => {
65 | const response = await adminInstance.delete(`/awards/${id}`);
66 | return response.data.data;
67 | },
68 | };
69 |
--------------------------------------------------------------------------------
/packages/utils/src/apis/admin/adminSponsoredByApi.tsx:
--------------------------------------------------------------------------------
1 | import { adminInstance } from '../axiosConfig';
2 |
3 | export interface SponsoredByInterface {
4 | id: number;
5 | generation: number;
6 | content: string;
7 | startDate: string;
8 | }
9 |
10 | export interface SponsoredByDTO {
11 | id: number;
12 | name: string;
13 | imageUrl: string;
14 | }
15 |
16 | export interface SponsoredByResponse {
17 | content: SponsoredByDTO[];
18 | pageInfo: {
19 | pageNum: number;
20 | limit: number;
21 | totalPages: number;
22 | totalElements: number;
23 | };
24 | }
25 |
26 | export const adminSponsoredByApi = {
27 | GET_SPONSOR: async ({ pageNum = 0, limit = 12 }) => {
28 | const response = await adminInstance.get(
29 | `/sponsors?pageNum=${pageNum}&limit=${limit}`,
30 | );
31 |
32 | return response.data.data;
33 | },
34 | GET_ONE_SPONSOR: async (id: number) => {
35 | const response = await adminInstance.get(`/sponsors/${id}`);
36 |
37 | return response.data.data;
38 | },
39 | POST_SPONSOR: async ({
40 | payload,
41 | }: {
42 | payload: SponsoredByDTO;
43 | }): Promise => {
44 | const response = await adminInstance.post(`/sponsors`, payload);
45 | return response.data.data;
46 | },
47 | PAPTCH_SPONSOR: async ({
48 | payload,
49 | id,
50 | }: {
51 | payload: SponsoredByDTO;
52 | id: number;
53 | }): Promise => {
54 | const response = await adminInstance.patch(`/sponsors/${id}`, payload);
55 | return response.data.data;
56 | },
57 | DELETE_SPONSOR: async (id: number): Promise => {
58 | const response = await adminInstance.delete(`/sponsors/${id}`);
59 | return response.data.data;
60 | },
61 | };
62 |
--------------------------------------------------------------------------------
/packages/utils/src/apis/admin/imageApi.ts:
--------------------------------------------------------------------------------
1 | import { adminInstance, publicInstance } from '../axiosConfig';
2 |
3 | export interface uploadImageProps {
4 | url: string;
5 | file: File;
6 | }
7 |
8 | export const imageApi = {
9 | GET_ACTIVITY_IMAGE: async (): Promise => {
10 | const response = await adminInstance.get(`/activities/image`);
11 |
12 | return response.data.data.url;
13 | },
14 | GET_SPONSOR_IMAGE: async (): Promise => {
15 | const response = await adminInstance.get(`/sponsors/image`);
16 |
17 | return response.data.data.url;
18 | },
19 | GET_MANAGEMENT_IMAGE: async (): Promise => {
20 | const response = await adminInstance.get(`/managements/image`);
21 |
22 | return response.data.data.url;
23 | },
24 | GET_PROJECTS_IMAGE: async (): Promise => {
25 | const response = await adminInstance.get(`/projects/image`);
26 |
27 | return response.data.data.url;
28 | },
29 | PUT_IMAGE: async ({ url, file }: uploadImageProps) => {
30 | const response = await publicInstance.put(url, file, {
31 | headers: {
32 | 'Content-Type': file.type,
33 | },
34 | baseURL: '',
35 | });
36 | return response.status;
37 | },
38 | };
39 |
--------------------------------------------------------------------------------
/packages/utils/src/apis/admin/index.ts:
--------------------------------------------------------------------------------
1 | export * from './adminFaqApi';
2 | export * from './adminAuthApi';
3 | export * from './imageApi';
4 | export * from './adminManageUserApi';
5 | export * from './adminRecruitApi';
6 | export * from './adminApplicationApi';
7 | export * from './adminRewardApi';
8 | export * from './adminManagementApi';
9 | export * from './adminProjectApi';
10 | export * from './adminSponsoredByApi';
11 | export * from './adminActivityApi';
12 |
--------------------------------------------------------------------------------
/packages/utils/src/apis/admin/sendEmailApi.ts:
--------------------------------------------------------------------------------
1 | import { adminInstance } from '../axiosConfig';
2 |
3 | export const sendEmailApi = {
4 | GET_SEND_EMAIL: async () => {
5 | try {
6 | const response = await adminInstance.get(`/subscribe/mail`);
7 | return response.data;
8 | } catch (error: any) {
9 | return error.response.data;
10 | }
11 | },
12 | };
13 |
--------------------------------------------------------------------------------
/packages/utils/src/apis/axiosConfig.ts:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | export const BASE_URL = process.env.NEXT_PUBLIC_API_URL;
4 |
5 | export const ceosInstance = axios.create({
6 | baseURL: BASE_URL,
7 | });
8 |
9 | export const adminInstance = axios.create({
10 | baseURL: BASE_URL,
11 | });
12 |
13 | export const publicInstance = axios.create({
14 | baseURL: BASE_URL,
15 | });
16 |
--------------------------------------------------------------------------------
/packages/utils/src/apis/ceos/activityApi.ts:
--------------------------------------------------------------------------------
1 | import { ceosInstance } from '../axiosConfig';
2 |
3 | export const activityApi = {
4 | GET_ACTIVITY: async ({
5 | pageNum,
6 | limit,
7 | }: {
8 | pageNum: number;
9 | limit: number;
10 | }) => {
11 | const response = await ceosInstance.get(`/activities`, {
12 | params: { pageNum, limit },
13 | });
14 |
15 | return response.data.data;
16 | },
17 | };
18 |
--------------------------------------------------------------------------------
/packages/utils/src/apis/ceos/awardApi.ts:
--------------------------------------------------------------------------------
1 | import { ceosInstance } from '../axiosConfig';
2 |
3 | export const awardApi = {
4 | GET_AWARD: async ({ pageNum = 0, limit = 12 }) => {
5 | const response = await ceosInstance.get(
6 | `/awards?pageNum=${pageNum}&limit=${limit}`,
7 | );
8 |
9 | return response.data.data;
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/packages/utils/src/apis/ceos/emailApi.ts:
--------------------------------------------------------------------------------
1 | import { ceosInstance } from '../axiosConfig';
2 |
3 | export interface InformationInterface {
4 | email: string;
5 | }
6 |
7 | export const emailApi = {
8 | POST_EMAIL: async ({ email }: { email: string }) => {
9 | try {
10 | const response = await ceosInstance.post(`/subscribe`, {
11 | email: email,
12 | });
13 | return response.data.message;
14 | } catch (e: any) {
15 | if (e.response && e.response.status >= 400 && e.response.status < 500) {
16 | return e.response.data.reason;
17 | }
18 | }
19 | },
20 | };
21 |
--------------------------------------------------------------------------------
/packages/utils/src/apis/ceos/faqApi.ts:
--------------------------------------------------------------------------------
1 | import { ceosInstance } from '../axiosConfig';
2 |
3 | export const faqApi = {
4 | GET_FAQ: async ({ category }: { category: string }) => {
5 | try {
6 | const response = await ceosInstance.get(`/faq?category=${category}`);
7 | return response.data.data;
8 | } catch (error) {
9 | console.error(error);
10 | }
11 | },
12 | };
13 |
--------------------------------------------------------------------------------
/packages/utils/src/apis/ceos/index.ts:
--------------------------------------------------------------------------------
1 | export * from './activityApi';
2 | export * from './faqApi';
3 | export * from './projectApi';
4 | export * from './recruitApi';
5 | export * from './awardApi';
6 | export * from './sponsorApi';
7 | export * from './managementApi';
8 |
--------------------------------------------------------------------------------
/packages/utils/src/apis/ceos/managementApi.ts:
--------------------------------------------------------------------------------
1 | import { ceosInstance } from '../axiosConfig';
2 |
3 | export const managementApi = {
4 | GET_MENTOR: async ({
5 | pageNum,
6 | limit,
7 | }: {
8 | pageNum: number;
9 | limit: number;
10 | }) => {
11 | const response = await ceosInstance
12 | .get(`/managements`, {
13 | params: { pageNum, limit },
14 | })
15 | .then((res) => {
16 | return res.data.data;
17 | });
18 | return response;
19 | },
20 |
21 | GET_MANAGER: async () => {
22 | const response = await ceosInstance.get(`/managements/part`).then((res) => {
23 | return res.data.data;
24 | });
25 | return response;
26 | },
27 | };
28 |
--------------------------------------------------------------------------------
/packages/utils/src/apis/ceos/projectApi.ts:
--------------------------------------------------------------------------------
1 | import { ceosInstance } from '../axiosConfig';
2 |
3 | export interface DetailProjectInterface {
4 | projectId: number;
5 | name: string;
6 | description: string;
7 | generation: number;
8 | projectUrls: {
9 | id: number;
10 | category: string;
11 | linkUrl: string;
12 | }[];
13 | projectImages: {
14 | created_at: string;
15 | updated_at: string;
16 | id: number;
17 | category: string;
18 | imageUrl: string;
19 | }[];
20 | participants: {
21 | created_at: string;
22 | updated_at: string;
23 | id: number;
24 | part: string;
25 | name: string;
26 | }[];
27 | }
28 |
29 | export const projectApi = {
30 | GET_ALL_PROJECTS: async ({
31 | pageNum,
32 | limit,
33 | }: {
34 | pageNum: number;
35 | limit: number;
36 | }) => {
37 | const response = await ceosInstance.get(`/projects`, {
38 | params: { pageNum, limit },
39 | });
40 |
41 | return response.data.data;
42 | },
43 | GET_A_PROJECT: async ({ id }: { id: number }) => {
44 | const response = await ceosInstance.get(`/projects/${id}`);
45 |
46 | return response.data.data;
47 | },
48 | };
49 |
--------------------------------------------------------------------------------
/packages/utils/src/apis/ceos/sponsorApi.ts:
--------------------------------------------------------------------------------
1 | import { ceosInstance } from '../axiosConfig';
2 |
3 | export const sponsorApi = {
4 | GET_SPONSORS: async ({
5 | pageNum,
6 | limit,
7 | }: {
8 | pageNum: number;
9 | limit: number;
10 | }) => {
11 | const response = await ceosInstance
12 | .get(`/sponsors`, {
13 | params: { pageNum, limit },
14 | })
15 | .then((res) => {
16 | return res.data.data;
17 | });
18 | return response;
19 | },
20 | };
21 |
--------------------------------------------------------------------------------
/packages/utils/src/apis/index.ts:
--------------------------------------------------------------------------------
1 | export * from './admin';
2 | export * from './ceos';
3 | export * from './axiosConfig';
4 |
--------------------------------------------------------------------------------
/packages/utils/src/hooks/useModal.ts:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef, useState } from 'react';
2 |
3 | export const useModal = () => {
4 | const [isOpen, setIsOpen] = useState(false);
5 | const modalRef = useRef(null);
6 |
7 | useEffect(() => {
8 | document.addEventListener('mousedown', handleOutsideClick);
9 |
10 | return () => {
11 | document.removeEventListener('mousedown', handleOutsideClick);
12 | };
13 | }, [isOpen]);
14 |
15 | const toggleModal = () => {
16 | setIsOpen((prevIsOpen) => {
17 | if (!prevIsOpen) document.body.style.overflowY = 'hidden';
18 | else document.body.style.overflowY = 'auto';
19 | return !prevIsOpen;
20 | });
21 | };
22 |
23 | const openModal = () => {
24 | document.body.style.overflowY = 'hidden';
25 | setIsOpen(true);
26 | };
27 |
28 | const closeModal = () => {
29 | document.body.style.overflowY = 'auto';
30 | setIsOpen(false);
31 | };
32 |
33 | const handleOutsideClick = (e: Event) => {
34 | const current = modalRef.current;
35 | if (isOpen && current && !current.contains(e.target as Node)) {
36 | document.body.style.overflowY = 'auto';
37 | setIsOpen(false);
38 | }
39 | };
40 |
41 | return { isOpen, modalRef, toggleModal, closeModal, openModal };
42 | };
43 |
--------------------------------------------------------------------------------
/packages/utils/src/hooks/useWindowResize.ts:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from 'react';
2 |
3 | export const useWindowResize = () => {
4 | const [isMobile, setIsMobile] = useState(false);
5 |
6 | useEffect(() => {
7 | const handleResize = () => {
8 | setIsMobile(window.matchMedia('(max-width: 390px)').matches);
9 | };
10 |
11 | handleResize(); // 초기 렌더링 시 크기 확인
12 |
13 | window.addEventListener('resize', handleResize); // resize 이벤트 감지
14 |
15 | return () => {
16 | window.removeEventListener('resize', handleResize); // 컴포넌트 언마운트 시 이벤트 제거
17 | };
18 | }, []);
19 |
20 | return isMobile;
21 | };
22 |
23 | export const useWindowTabletResize = () => {
24 | const [isMobile, setIsMobile] = useState(false);
25 |
26 | useEffect(() => {
27 | const handleResize = () => {
28 | setIsMobile(window.matchMedia('(max-width: 1023px)').matches);
29 | };
30 |
31 | handleResize(); // 초기 렌더링 시 크기 확인
32 |
33 | window.addEventListener('resize', handleResize); // resize 이벤트 감지
34 |
35 | return () => {
36 | window.removeEventListener('resize', handleResize); // 컴포넌트 언마운트 시 이벤트 제거
37 | };
38 | }, []);
39 |
40 | return isMobile;
41 | };
42 |
--------------------------------------------------------------------------------
/packages/utils/src/utils/index.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CEOS-Developers/CEOS-FE/6bc33c767ba5bdb7e574bcbf2b3975380d383b14/packages/utils/src/utils/index.ts
--------------------------------------------------------------------------------
/packages/utils/src/utils/portal.tsx:
--------------------------------------------------------------------------------
1 | import { ReactNode, useEffect, useState } from 'react';
2 | import ReactDOM from 'react-dom';
3 |
4 | export const ModalPortal = ({ children }: { children: ReactNode }) => {
5 | const [mounted, setMounted] = useState(false);
6 |
7 | useEffect(() => {
8 | setMounted(true);
9 | }, []);
10 |
11 | if (!mounted) {
12 | return null;
13 | }
14 | const el = document.getElementById('modal_root');
15 | if (el === null) {
16 | return null;
17 | }
18 | return ReactDOM.createPortal(children, el);
19 | };
20 |
--------------------------------------------------------------------------------
/packages/utils/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "compilerOptions": {
4 | "target": "es6",
5 | "lib": ["dom", "dom.iterable", "esnext"],
6 | "allowJs": true,
7 | "skipLibCheck": true,
8 | "esModuleInterop": true,
9 | "allowSyntheticDefaultImports": true,
10 | "strict": true,
11 | "forceConsistentCasingInFileNames": false,
12 | "noFallthroughCasesInSwitch": true,
13 | "module": "esnext",
14 | "moduleResolution": "node",
15 | "resolveJsonModule": true,
16 | "isolatedModules": true,
17 | "noEmit": true,
18 | "jsx": "react-jsx",
19 | "composite": true,
20 | "declaration": true,
21 | "jsxImportSource": "@emotion/react"
22 | },
23 | "include": ["src"]
24 | }
25 |
--------------------------------------------------------------------------------
/tsconfig.base.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES6",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "esModuleInterop": true,
8 | "allowSyntheticDefaultImports": true,
9 | "strict": true,
10 | "forceConsistentCasingInFileNames": false,
11 | "noFallthroughCasesInSwitch": true,
12 | "module": "esnext",
13 | "moduleResolution": "node",
14 | "resolveJsonModule": true,
15 | "isolatedModules": true,
16 | "noEmit": true,
17 | "jsx": "react-jsx",
18 | "jsxImportSource": "@emotion/react",
19 | "baseUrl": "./",
20 | "paths": {
21 | "@ceos-fe/ui": ["./packages/ui/src/*"],
22 | "@ceos-fe/utils/*": ["./packages/utils/src/*"]
23 | }
24 | },
25 | "references": [
26 | {
27 | "path": "apps/ceos"
28 | },
29 | {
30 | "path": "apps/admin"
31 | },
32 | {
33 | "path": "packages/ui"
34 | },
35 | {
36 | "path": "packages/utils"
37 | }
38 | ],
39 | "include": ["src", "custom.d.ts"],
40 | "exclude": ["apps/**/dist/**"]
41 | }
42 |
--------------------------------------------------------------------------------
/turbo.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://turbo.build/schema.json",
3 | "globalDependencies": ["**/.env.*local"],
4 | "pipeline": {
5 | "build": {
6 | "dependsOn": ["^build"],
7 | "outputs": ["dist/**", ".next/**", "!.next/cache/**"]
8 | },
9 | "lint": {
10 | "outputs": []
11 | },
12 | "dev": {
13 | "cache": false
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------