diff --git a/package.json b/package.json index 6255de34..1446967a 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@types/qs": "6.9.7", "axios": "^0.27.2", "classcat": "^5.0.4", + "googleapis": "126.0.0", "nanoid": "4.0.2", "next": "13.3.0", "qs": "6.11.1", @@ -26,7 +27,8 @@ "react-responsive": "9.0.0-beta.10", "react-test-renderer": "^18.2.0", "react-toastify": "^9.0.8", - "shortid": "^2.2.16" + "shortid": "^2.2.16", + "styled-components": "^6.0.7" }, "devDependencies": { "@babel/core": "^7.18.10", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e9b1654f..bbc3ea8e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,6 +38,7 @@ specifiers: eslint-plugin-react: ^7.30.0 eslint-plugin-react-hooks: ^4.5.0 git-cz: ^4.9.0 + googleapis: 126.0.0 husky: ^8.0.1 jest: ^28.1.0 jest-environment-jsdom: ^28.1.0 @@ -71,6 +72,7 @@ dependencies: '@types/qs': 6.9.7 axios: 0.27.2 classcat: 5.0.4 + googleapis: 126.0.0 nanoid: 4.0.2 next: 13.3.0_a6exmopoj4illbm7c6eh7topwe qs: 6.11.1 @@ -2884,6 +2886,15 @@ packages: - supports-color dev: true + /agent-base/7.1.0: + resolution: {integrity: sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==} + engines: {node: '>= 14'} + dependencies: + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: false + /aggregate-error/3.1.0: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} engines: {node: '>=8'} @@ -3244,6 +3255,10 @@ packages: /balanced-match/1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + /base64-js/1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: false + /big-integer/1.6.51: resolution: {integrity: sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==} engines: {node: '>=0.6'} @@ -3253,6 +3268,10 @@ packages: resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} dev: true + /bignumber.js/9.1.1: + resolution: {integrity: sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig==} + dev: false + /binary-extensions/2.2.0: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} engines: {node: '>=8'} @@ -3313,6 +3332,10 @@ packages: node-int64: 0.4.0 dev: true + /buffer-equal-constant-time/1.0.1: + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + dev: false + /buffer-from/1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} dev: true @@ -3809,6 +3832,12 @@ packages: domhandler: 5.0.3 dev: true + /ecdsa-sig-formatter/1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + dependencies: + safe-buffer: 5.2.1 + dev: false + /electron-to-chromium/1.4.210: resolution: {integrity: sha512-kSiX4tuyZijV7Cz0MWVmGT8K2siqaOA4Z66K5dCttPPRh0HicOcOAEj1KlC8O8J1aOS/1M8rGofOzksLKaHWcQ==} @@ -4436,6 +4465,10 @@ packages: jest-util: 28.1.3 dev: true + /extend/3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + dev: false + /fast-deep-equal/3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} dev: true @@ -4601,6 +4634,30 @@ packages: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} dev: true + /gaxios/6.1.0: + resolution: {integrity: sha512-EIHuesZxNyIkUGcTQKQPMICyOpDD/bi+LJIJx+NLsSGmnS7N+xCLRX5bi4e9yAu9AlSZdVq+qlyWWVuTh/483w==} + engines: {node: '>=14'} + dependencies: + extend: 3.0.2 + https-proxy-agent: 7.0.1 + is-stream: 2.0.1 + node-fetch: 2.6.13 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + + /gcp-metadata/6.0.0: + resolution: {integrity: sha512-Ozxyi23/1Ar51wjUT2RDklK+3HxqDr8TLBNK8rBBFQ7T85iIGnXnVusauj06QyqCXRFZig8LZC+TUddWbndlpQ==} + engines: {node: '>=14'} + dependencies: + gaxios: 6.1.0 + json-bigint: 1.0.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + /gensync/1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -4735,6 +4792,48 @@ packages: resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} dev: true + /google-auth-library/9.0.0: + resolution: {integrity: sha512-IQGjgQoVUAfOk6khqTVMLvWx26R+yPw9uLyb1MNyMQpdKiKt0Fd9sp4NWoINjyGHR8S3iw12hMTYK7O8J07c6Q==} + engines: {node: '>=14'} + dependencies: + base64-js: 1.5.1 + ecdsa-sig-formatter: 1.0.11 + gaxios: 6.1.0 + gcp-metadata: 6.0.0 + gtoken: 7.0.1 + jws: 4.0.0 + lru-cache: 6.0.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + + /googleapis-common/7.0.0: + resolution: {integrity: sha512-58iSybJPQZ8XZNMpjrklICefuOuyJ0lMxfKmBqmaC0/xGT4SiOs4BE60LAOOGtBURy1n8fHa2X2YUNFEWWbXyQ==} + engines: {node: '>=14.0.0'} + dependencies: + extend: 3.0.2 + gaxios: 6.1.0 + google-auth-library: 9.0.0 + qs: 6.11.1 + url-template: 2.0.8 + uuid: 9.0.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + + /googleapis/126.0.0: + resolution: {integrity: sha512-BeCwYJfthEWUgY0ka7msSxyMuRwrwJTqL9yMlnuCxyy1JlRZwaI5ZVVp4ofwiGiNP9UuuR3Yk9CJKWQLg4Tq1A==} + engines: {node: '>=14.0.0'} + dependencies: + google-auth-library: 9.0.0 + googleapis-common: 7.0.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + /gopd/1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: @@ -4749,6 +4848,17 @@ packages: resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} dev: true + /gtoken/7.0.1: + resolution: {integrity: sha512-KcFVtoP1CVFtQu0aSk3AyAt2og66PFhZAlkUOuWKwzMLoulHXG5W5wE5xAnHb+yl3/wEFoqGW7/cDGMU8igDZQ==} + engines: {node: '>=14.0.0'} + dependencies: + gaxios: 6.1.0 + jws: 4.0.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + /has-bigints/1.0.2: resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} dev: true @@ -4837,6 +4947,16 @@ packages: - supports-color dev: true + /https-proxy-agent/7.0.1: + resolution: {integrity: sha512-Eun8zV0kcYS1g19r78osiQLEFIRspRUDd9tIfBCTBPBeMieF/EsJNL8VI3xOIdYRDEkjQnqOYPsZ2DsWsVsFwQ==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.0 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: false + /human-signals/2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} @@ -5047,7 +5167,6 @@ packages: /is-stream/2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} - dev: true /is-string/1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} @@ -5653,6 +5772,12 @@ packages: engines: {node: '>=4'} hasBin: true + /json-bigint/1.0.0: + resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==} + dependencies: + bignumber.js: 9.1.1 + dev: false + /json-parse-even-better-errors/2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} @@ -5689,6 +5814,21 @@ packages: object.assign: 4.1.2 dev: true + /jwa/2.0.0: + resolution: {integrity: sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==} + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + dev: false + + /jws/4.0.0: + resolution: {integrity: sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==} + dependencies: + jwa: 2.0.0 + safe-buffer: 5.2.1 + dev: false + /kleur/3.0.3: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} @@ -5853,7 +5993,6 @@ packages: engines: {node: '>=10'} dependencies: yallist: 4.0.0 - dev: true /lz-string/1.4.4: resolution: {integrity: sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ==} @@ -6053,6 +6192,18 @@ packages: - babel-plugin-macros dev: false + /node-fetch/2.6.13: + resolution: {integrity: sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: false + /node-int64/0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} dev: true @@ -6799,7 +6950,6 @@ packages: /safe-buffer/5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - dev: true /safe-regex-test/1.0.0: resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} @@ -7285,6 +7435,10 @@ packages: universalify: 0.1.2 dev: true + /tr46/0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: false + /tr46/3.0.0: resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} engines: {node: '>=12'} @@ -7504,6 +7658,15 @@ packages: webpack: 5.74.0 dev: true + /url-template/2.0.8: + resolution: {integrity: sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==} + dev: false + + /uuid/9.0.0: + resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} + hasBin: true + dev: false + /v8-compile-cache/2.3.0: resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==} dev: true @@ -7544,6 +7707,10 @@ packages: graceful-fs: 4.2.10 dev: true + /webidl-conversions/3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: false + /webidl-conversions/7.0.0: resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} engines: {node: '>=12'} @@ -7622,6 +7789,13 @@ packages: webidl-conversions: 7.0.0 dev: true + /whatwg-url/5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: false + /which-boxed-primitive/1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} dependencies: @@ -7715,7 +7889,6 @@ packages: /yallist/4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - dev: true /yaml/1.10.2: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} diff --git a/src/assets/icons/ic_arrow_right_white.svg b/src/assets/icons/ic_arrow_right_white.svg new file mode 100644 index 00000000..d9d38c28 --- /dev/null +++ b/src/assets/icons/ic_arrow_right_white.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/ic_email.svg b/src/assets/icons/ic_email.svg new file mode 100644 index 00000000..154b5bee --- /dev/null +++ b/src/assets/icons/ic_email.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/icons/ic_facebook.svg b/src/assets/icons/ic_facebook.svg new file mode 100644 index 00000000..3a13f447 --- /dev/null +++ b/src/assets/icons/ic_facebook.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/icons/ic_kakao.svg b/src/assets/icons/ic_kakao.svg new file mode 100644 index 00000000..da3892e1 --- /dev/null +++ b/src/assets/icons/ic_kakao.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/icons/img_instagram.png b/src/assets/icons/img_instagram.png new file mode 100644 index 00000000..9629a728 Binary files /dev/null and b/src/assets/icons/img_instagram.png differ diff --git a/src/assets/images/img_mainvalue_logos.png b/src/assets/images/img_mainvalue_logos.png new file mode 100644 index 00000000..d6854df2 Binary files /dev/null and b/src/assets/images/img_mainvalue_logos.png differ diff --git a/src/assets/mainLogo/index.ts b/src/assets/mainLogo/index.ts index 49370ed5..05cd9a19 100644 --- a/src/assets/mainLogo/index.ts +++ b/src/assets/mainLogo/index.ts @@ -18,6 +18,7 @@ import logo28 from './logo_28.svg'; import logo29 from './logo_29.svg'; import logo30 from './logo_30.svg'; import logo31 from './logo_31.svg'; +import logoDoSopt from './logo_dosopt@3x.png'; export { logo11, @@ -40,4 +41,5 @@ export { logo29, logo30, logo31, + logoDoSopt, }; diff --git a/src/assets/mainLogo/logo_dosopt.png b/src/assets/mainLogo/logo_dosopt.png new file mode 100644 index 00000000..dcbe16cb Binary files /dev/null and b/src/assets/mainLogo/logo_dosopt.png differ diff --git a/src/assets/mainLogo/logo_dosopt@2x.png b/src/assets/mainLogo/logo_dosopt@2x.png new file mode 100644 index 00000000..a678b358 Binary files /dev/null and b/src/assets/mainLogo/logo_dosopt@2x.png differ diff --git a/src/assets/mainLogo/logo_dosopt@3x.png b/src/assets/mainLogo/logo_dosopt@3x.png new file mode 100644 index 00000000..09aceaad Binary files /dev/null and b/src/assets/mainLogo/logo_dosopt@3x.png differ diff --git a/src/components/Header/Desktop/DesktopHeader.tsx b/src/components/Header/Desktop/DesktopHeader.tsx index a3853010..36ab3f39 100644 --- a/src/components/Header/Desktop/DesktopHeader.tsx +++ b/src/components/Header/Desktop/DesktopHeader.tsx @@ -243,6 +243,11 @@ const menuTitleUnderline = css` width: 100%; border-bottom: 2px solid white; } + &:last-child { + &::after { + width: calc(100% + 40px); + } + } `; export const MenuTitle = styled.div` diff --git a/src/components/Header/menuTapList.ts b/src/components/Header/menuTapList.ts index 46d9a797..98ee20dd 100644 --- a/src/components/Header/menuTapList.ts +++ b/src/components/Header/menuTapList.ts @@ -33,8 +33,8 @@ export const menuTapList: MenuTapList = [ href: '/sponsor', }, { - type: MenuTapType.Anchor, - title: '지원하기', - href: 'https://sopt-recruiting.web.app/recruiting/apply/ob', + type: MenuTapType.Router, + title: '리크루팅', + href: '/recruit', }, ]; diff --git a/src/components/Layout/Layout.tsx b/src/components/Layout/Layout.tsx index ed7f533b..0243120d 100644 --- a/src/components/Layout/Layout.tsx +++ b/src/components/Layout/Layout.tsx @@ -1,11 +1,11 @@ import styled from '@emotion/styled'; -import { PropsWithChildren } from 'react'; +import { CSSProperties, PropsWithChildren } from 'react'; -export function Layout({ children }: PropsWithChildren) { - return
{children}
; +export function Layout({ children, moreStyle }: PropsWithChildren<{ moreStyle?: CSSProperties }>) { + return
{children}
; } -const Main = styled.div` +const Main = styled.div<{ moreStyle?: CSSProperties }>` width: 100%; @media (max-width: 1279px) { diff --git a/src/pages/api/register.ts b/src/pages/api/register.ts new file mode 100644 index 00000000..da424266 --- /dev/null +++ b/src/pages/api/register.ts @@ -0,0 +1,41 @@ +import { NextApiRequest, NextApiResponse } from 'next'; +import { googleSheetCredential } from '@src/utils/const/googlesheet-env'; +import { google } from 'googleapis'; + +export default async function handler(request: NextApiRequest, response: NextApiResponse) { + try { + if (request.method === 'POST') { + const resultStatus = await writeRow(request.body.email); + return response.status(200).json({ success: resultStatus === 200, resultStatus }); + } + } catch (error) { + return response.status(500).json({ error: 'Internal server error' }); + } + + return response.status(200).json({ success: true }); +} + +export const writeRow = async (email: string) => { + const now = new Date(); + const dateString = `${now.toDateString()} ${now.toTimeString()}`; + const auth = new google.auth.GoogleAuth({ + credentials: { + client_email: googleSheetCredential.client_email, + client_id: googleSheetCredential.client_id, + private_key: googleSheetCredential.private_key, + }, + scopes: ['https://www.googleapis.com/auth/spreadsheets'], + }); + // google spread sheet api 가져오기 + const googleSheet = google.sheets({ + version: 'v4', + auth, + }); + const result = await googleSheet.spreadsheets.values.append({ + spreadsheetId: '1u1gRgpx7PEKYkG8VPfqQZQ2BI5c2OHaj0UnYs5uaQ6E', + range: 'A:B', + valueInputOption: 'USER_ENTERED', + requestBody: { values: [[email, dateString]] }, + }); + return result.status; +}; diff --git a/src/pages/recruit.tsx b/src/pages/recruit.tsx index bdb2951a..33a6cb94 100644 --- a/src/pages/recruit.tsx +++ b/src/pages/recruit.tsx @@ -1,57 +1 @@ -import styled from '@emotion/styled'; -import Image from 'next/image'; -import { useRouter } from 'next/router'; -import Sopt404 from '@src/assets/images/sopt_404.png'; -import { Header } from '@src/components'; -import RoundButton from '@src/components/common/RoundButton'; -import theme from '@src/styles/theme'; - -function Recruit() { - const router = useRouter(); - const handleClick = () => { - router.push('/'); - }; - - return ( - <> -
- - SOPT - 아직 지원 기간이 아니에요! - - 홈으로 가기 - - - - ); -} - -export default Recruit; - -const Styled = { - Root: styled.section` - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - width: 100%; - height: 100vh; - - & span { - margin-top: 99px; - margin-bottom: 99px; - line-height: 56px; - color: ${theme.colors.soptWhite}; - font-size: 45px; - font-weight: 400; - font-style: normal; - } - `, -}; +export { default } from '@src/views/RecruitPage'; diff --git a/src/utils/const/googlesheet-env.ts b/src/utils/const/googlesheet-env.ts new file mode 100644 index 00000000..894140f9 --- /dev/null +++ b/src/utils/const/googlesheet-env.ts @@ -0,0 +1,13 @@ +export const googleSheetCredential = { + type: 'service_account', + project_id: process.env.NEXT_GOOGLE_SHEET_PROJECT_ID, + private_key_id: process.env.NEXT_GOOGLE_SHEET_PRIVATE_KEY_ID, + private_key: process.env.NEXT_GOOGLE_SHEET_PRIVATE_KEY, + client_email: process.env.NEXT_GOOGLE_SHEET_CLIENT_EMAIL, + client_id: process.env.NEXT_GOOGLE_SHEET_CLIENT_ID, + auth_uri: process.env.NEXT_GOOGLE_SHEET_AUTH_URI, + token_uri: process.env.NEXT_GOOGLE_SHEET_TOKEN_URI, + auth_provider_x509_cert_url: process.env.NEXT_GOOGLE_SHEET_AUTH_PROVIDER_X509_CERT_URL, + client_x509_cert_url: process.env.NEXT_GOOGLE_SHEET_CLIENT_X509_CERT_URL, + universe_domain: process.env.NEXT_GOOGLE_SHEET_UNIVERSE_DOMAIN, +}; diff --git a/src/views/FAQPage/components/faq/QuestionBox.tsx b/src/views/FAQPage/components/faq/QuestionBox.tsx index 7d7fbfbb..34ec1c1b 100644 --- a/src/views/FAQPage/components/faq/QuestionBox.tsx +++ b/src/views/FAQPage/components/faq/QuestionBox.tsx @@ -1,5 +1,5 @@ import styled from '@emotion/styled'; -import { ReactComponent as IToggle } from '@src/assets/images/toggle.svg'; +import { ReactComponent as IcArrow } from '@src/assets/icons/ic_arrow_right_white.svg'; import { FAQType } from '../../types'; interface QuestionBoxProps { @@ -13,40 +13,15 @@ function QuestionBox(props: QuestionBoxProps) { status, } = props; - const makeBoldText = (text: string) => { - const regex = 'Shout Our Passion Together!'; - if (text.includes(regex)) { - const index = text.indexOf(regex); - const rest = text.slice(0, index); - return ( - <> - {rest} {regex} - - ); - } - return text; - }; - return ( - + - - {question.split('\n').map((text) => ( -
{text}
- ))} -
+ {question} - +
- - {status && ( - - {answer.split('\n').map((text) => ( -
{makeBoldText(text)}
- ))} -
- )} + {status && {answer}}
); } @@ -54,44 +29,45 @@ function QuestionBox(props: QuestionBoxProps) { export default QuestionBox; const Styled = { - Root: styled.div` + Root: styled.div<{ isOpened: boolean }>` + transition: 0.2s; display: flex; flex-direction: column; - background: #262626; - border-radius: 10px; - padding: 56px; - padding-right: 54px; + background: ${({ isOpened }) => (isOpened ? '#21212C' : '#1a1a20')}; + border-radius: 30px; + padding: 40px 50px; cursor: pointer; /* 태블릿 뷰 */ @media (max-width: 1919.9px) and (min-width: 766px) { font-size: 25px; - padding: 48px; + padding: 32px 40px; + border-radius: 20px; } /* 모바일 뷰 */ @media (max-width: 765.9px) { - padding: 28px; + padding: 18px 30px; + border-radius: 20px; } `, QuestionWrapper: styled.div<{ isOpened: boolean }>` display: flex; + align-items: center; justify-content: space-between; - /* align-items: center; */ - margin-bottom: ${({ isOpened }) => (isOpened ? '37px' : '0')}; /* 태블릿 뷰 */ @media (max-width: 1919.9px) and (min-width: 766px) { margin-bottom: ${({ isOpened }) => (isOpened ? '16px' : '0')}; } `, Title: styled.h1` - font-weight: 700; - font-size: 30px; + font-weight: 600; + font-size: 24px; line-height: 100%; color: #ffffff; - - /* 태블릿 뷰 */ - @media (max-width: 1919.9px) and (min-width: 766px) { - font-size: 25px; + &::before { + content: 'Q. '; + color: #1deda2; } + /* 모바일 뷰 */ @media (max-width: 765.9px) { font-size: 16px; @@ -106,36 +82,27 @@ const Styled = { height: 40px; /* 태블릿 뷰 */ @media (max-width: 1919.9px) and (min-width: 766px) { - width: 32px; - height: 32px; + transform: ${({ isOpened }) => (isOpened ? 'rotate(180deg)' : 'rotate(0deg)')} scale(0.9); + transform-origin: center; } /* 모바일 뷰 */ @media (max-width: 765.9px) { - width: 24px; - height: 24px; - } - & > svg { - width: 25px; - height: 18.33px; - /* 태블릿 뷰 */ - @media (max-width: 1919.9px) and (min-width: 766px) { - width: 20px; - height: 14.67px; - } - /* 모바일 뷰 */ - @media (max-width: 765.9px) { - width: 15px; - height: 11px; - } + transform: ${({ isOpened }) => (isOpened ? 'rotate(180deg)' : 'rotate(0deg)')} scale(0.7); + transform-origin: center; } - transform: ${({ isOpened }) => (isOpened ? 'rotate(90deg)' : 'rotate(0deg')}; `, Content: styled.div` font-weight: 400; font-size: 25px; line-height: 40px; - + word-break: keep-all; color: rgba(253, 253, 253, 0.8); + margin-top: 12px; + + &::before { + content: 'A. '; + color: #1deda2; + } /* 태블릿 뷰 */ @media (max-width: 1919.9px) and (min-width: 766px) { font-size: 22px; diff --git a/src/views/FAQPage/lib/constants.ts b/src/views/FAQPage/lib/constants.ts index a14da766..51b64069 100644 --- a/src/views/FAQPage/lib/constants.ts +++ b/src/views/FAQPage/lib/constants.ts @@ -9,17 +9,17 @@ export const contactInfo: ContactInfoType[] = [ export const questionList: FAQType[] = [ { - question: 'Q. 직장인/휴학생/졸업유예생도 활동할 수 있나요?', + question: '직장인/휴학생/졸업유예생도 활동할 수 있나요?', answer: '재직, 휴학, 졸업유예 여부에 관계없이 대학생이면 지원 가능해요.\n다만, 대부분의 SOPT 회원들이 활동에 많은 시간을 투자하고 있으므로 직장 재직자는 활동에 충분히 참여할\n 여유가 있을 경우에 지원하시는 것을 권장해요.', }, { - question: 'Q. 파트별 커리큘럼이 어떻게 되나요?', + question: '파트별 커리큘럼이 어떻게 되나요?', answer: '상단의 ‘리크루팅’ 메뉴 또는 ‘SOPT 인스타그램’에 파트별로 자세하게 안내되어 있으니 참고해 주세요.', }, { - question: 'Q. 경험과 실력이 부족한데 지원해도 괜찮을까요?', + question: '경험과 실력이 부족한데 지원해도 괜찮을까요?', answer: 'SOPT는 기획, 디자인, 개발 각 분야에 열정이 있는 사람들이 모여 화합을 통해 변화하고 성장하는 가치를\n추구해요. 따라서 경험과 실력보다는 각 파트에 대한 열정과 SOPT 활동을 통해 이루고자 하는 명확한 목표를 더\n중요시해요. 열정을 갖춘 분들의 용기 있는 도전을 기다릴게요! Shout Our Passion Together!', }, @@ -27,17 +27,17 @@ export const questionList: FAQType[] = [ export const questionListTablet: FAQType[] = [ { - question: 'Q. 직장인/휴학생/졸업유예생도 활동할 수 있나요?', + question: '직장인/휴학생/졸업유예생도 활동할 수 있나요?', answer: '재직, 휴학, 졸업유예 여부에 관계없이 대학생이면 지원\n가능해요.다만, 대부분의 SOPT 회원들이 활동에 많은\n시간을 투자하고 있으므로 직장 재직자는 활동에 충분히\n참여할 여유가 있을 경우에 지원하시는 것을 권장해요.', }, { - question: 'Q. 파트별 커리큘럼이 어떻게 되나요?', + question: '파트별 커리큘럼이 어떻게 되나요?', answer: '상단의 ‘리크루팅’ 메뉴 또는 ‘SOPT 인스타그램’에 파트별로\n자세하게 안내되어 있으니 참고해 주세요.', }, { - question: 'Q. 경험과 실력이 부족한데 지원해도 괜찮을까요?', + question: '경험과 실력이 부족한데 지원해도 괜찮을까요?', answer: 'SOPT는 기획, 디자인, 개발 각 분야에 열정이 있는\n사람들이 모여 화합을 통해 변화하고 성장하는 가치를\n추구해요. 따라서 경험과 실력보다는 각 파트에 대한 열정과\nSOPT 활동을 통해 이루고자 하는 명확한 목표를 더 중요시\n해요. 열정을 갖춘 분들의 용기 있는 도전을 기다릴게요!\nShout Our Passion Together!', }, @@ -45,17 +45,17 @@ export const questionListTablet: FAQType[] = [ export const questionListMobile: FAQType[] = [ { - question: 'Q. 직장인/휴학생/졸업유예생도\n활동할 수 있나요?', + question: '직장인/휴학생/졸업유예생도\n활동할 수 있나요?', answer: '재직, 휴학, 졸업유예 여부에 관계없이\n대학생이면 지원 가능해요.다만, 대부분의\nSOPT 회원들이 활동에 많은 시간을\n투자하고 있으므로 직장 재직자는 활동에\n충분히 참여할 여유가 있을 경우에\n지원하시는 것을 권장해요.', }, { - question: 'Q. 파트별 커리큘럼이 어떻게 되나요?', + question: '파트별 커리큘럼이 어떻게 되나요?', answer: '상단의 ‘리크루팅’ 메뉴 또는 ‘SOPT\n인스타그램’에 파트별로 자세하게 안내되어\n있으니 참고해 주세요.', }, { - question: 'Q. 경험과 실력이 부족한데\n지원해도 괜찮을까요?', + question: '경험과 실력이 부족한데\n지원해도 괜찮을까요?', answer: 'SOPT는 기획, 디자인, 개발 각 분야에\n열정이 있는 사람들이 모여 화합을 통해\n변화하고 성장하는 가치를 추구해요.\n따라서 경험과 실력보다는 각 파트에 대한\n열정과 SOPT 활동을 통해 이루고자 하는\n명확한 목표를 더 중요시해요. 열정을 갖춘\n분들의 용기 있는 도전을 기다릴게요!\nShout Our Passion Together!', }, diff --git a/src/views/MainPage/assets/arrow_right_white.svg b/src/views/MainPage/assets/arrow_right_white.svg index db00caab..0c0b26f6 100644 --- a/src/views/MainPage/assets/arrow_right_white.svg +++ b/src/views/MainPage/assets/arrow_right_white.svg @@ -1,5 +1,5 @@ - + diff --git a/src/views/ProjectDetailPage/ProjectDetail.style.tsx b/src/views/ProjectDetailPage/ProjectDetail.style.tsx index 0004d57e..467e955f 100644 --- a/src/views/ProjectDetailPage/ProjectDetail.style.tsx +++ b/src/views/ProjectDetailPage/ProjectDetail.style.tsx @@ -363,6 +363,7 @@ export const ProjectDescription = styled(CommonWrapper)` border-radius: 10px; background-color: transparent; padding: 40px; + white-space: pre-wrap; /* 태블릿 뷰 */ @media (max-width: 1280px) { width: 346px; diff --git a/src/views/RecruitPage/RecruitPage.tsx b/src/views/RecruitPage/RecruitPage.tsx new file mode 100644 index 00000000..d74e46bc --- /dev/null +++ b/src/views/RecruitPage/RecruitPage.tsx @@ -0,0 +1,62 @@ +import styled from '@emotion/styled'; +import { Footer, Header, Layout, ScrollToTopButton } from '@src/components'; +import { ActivityReview } from './components/ActivityReview/ActivityReview'; +import ApplySection from './components/ApplySection'; +import BottomLogo from './components/BottomLogo'; +import ChapterInfo from './components/ChapterInfo'; +import Contact from './components/Contact'; +import FaqInfo from './components/FAQ'; +import RecruiteeInfo from './components/RecruteeInfo'; +import Schedule from './components/Schedule'; + +function Recruit() { + return ( + +
+ + + + + + + + + + + + + +