diff --git a/.eslintrc.js b/.eslintrc.js index 9fcb6ce4..6d618942 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -29,7 +29,13 @@ module.exports = { '@typescript-eslint/parser': ['.ts', '.tsx'], }, }, - extends: ['next', 'prettier', 'plugin:import/recommended', 'plugin:import/typescript'], + extends: [ + 'next', + 'prettier', + 'plugin:import/recommended', + 'plugin:import/typescript', + 'plugin:storybook/recommended', + ], plugins: ['prettier', 'import', '@typescript-eslint', 'simple-import-sort', 'unused-imports'], parser: '@typescript-eslint/parser', rules: { diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml new file mode 100644 index 00000000..fed7404a --- /dev/null +++ b/.github/workflows/chromatic.yml @@ -0,0 +1,36 @@ +# Workflow name +name: 'Chromatic' + +# Event for the workflow +on: + pull_request: + branches: [main, develop] + push: + branches: [main, develop] + +# List of jobs +jobs: + chromatic-deployment: + # Operating System + runs-on: ubuntu-latest + # Job steps + steps: + - uses: actions/checkout@v1 + - name: Install dependencies + # 👇 Install dependencies with the same package manager used in the project (replace it as needed), e.g. yarn, npm, pnpm + run: yarn + # 👇 Adds Chromatic as a step in the workflow + - name: Publish to Chromatic + uses: chromaui/action@v1 + id: chromatic + # Chromatic GitHub Action options + with: + # 👇 Chromatic projectToken, refer to the manage page to obtain it. + projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} + onlyChanged: true + - name: comment PR + uses: thollander/actions-comment-pull-request@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + message: '🚀storybook: ${{ steps.chromatic.outputs.storybookUrl }}' diff --git a/.gitignore b/.gitignore index 7e810107..4112bcbd 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,4 @@ next-env.d.ts .idea *.swp *.bak +.env diff --git a/.storybook/main.ts b/.storybook/main.ts new file mode 100644 index 00000000..6c316c09 --- /dev/null +++ b/.storybook/main.ts @@ -0,0 +1,27 @@ +const path = require('path'); +import type { StorybookConfig } from '@storybook/nextjs'; + +const config: StorybookConfig = { + stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'], + addons: [ + '@storybook/addon-links', + '@storybook/addon-essentials', + '@storybook/addon-onboarding', + 'storybook-addon-next', + '@storybook/addon-interactions', + '@storybook/addon-styling', + ], + framework: { + name: '@storybook/nextjs', + options: { nextConfigPath: path.resolve(__dirname, '../next.config.js') }, + }, + staticDirs: ['../public'], + docs: { + autodocs: 'tag', + }, + babel: async options => { + options.presets!.push('@emotion/babel-preset-css-prop'); + return options; + }, +}; +export default config; diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx new file mode 100644 index 00000000..ec1a6510 --- /dev/null +++ b/.storybook/preview.tsx @@ -0,0 +1,36 @@ +const path = require('path'); + +import type { Preview } from '@storybook/react'; +import React from 'react'; +import GlobalStyle from '../src/styles/globalStyle'; +import { ThemeProvider } from '@emotion/react'; +import { theme } from '../src/styles/theme'; + +const preview: Preview = { + decorators: [ + Story => ( + + + + + ), + ], + parameters: { + actions: { argTypesRegex: '^on[A-Z].*' }, + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/, + }, + }, + webpackFinal: async config => { + config.resolve.alias = { + ...config.resolve.alias, + '~': path.resolve(__dirname, '../src/'), + }; + return config; + }, + }, +}; + +export default preview; diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 00000000..97c1779a --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,18 @@ +{ + "configurations": [ + { + "name": "macos-clang-x64", + "includePath": [ + "${workspaceFolder}/**" + ], + "compilerPath": "/usr/bin/clang", + "cStandard": "${default}", + "cppStandard": "${default}", + "intelliSenseMode": "macos-clang-x64", + "compilerArgs": [ + "" + ] + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..a85b3bca --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,13 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "C/C++ Runner: Debug Session", + "type": "lldb", + "request": "launch", + "args": [], + "cwd": "/Users/kangjiyoung/Downloads/2018112024_강지영_lab03", + "program": "/Users/kangjiyoung/Downloads/2018112024_강지영_lab03/build/Debug/outDebug" + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 2a7a14ea..183231bc 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,5 +2,63 @@ "editor.codeActionsOnSave": { "source.fixAll.eslint": true }, - "editor.formatOnSave": true -} + "editor.formatOnSave": true, + "typescript.tsdk": "node_modules/typescript/lib", + "C_Cpp_Runner.msvcBatchPath": "", + "C_Cpp_Runner.cCompilerPath": "clang", + "C_Cpp_Runner.cppCompilerPath": "clang++", + "C_Cpp_Runner.debuggerPath": "lldb", + "C_Cpp_Runner.cStandard": "", + "C_Cpp_Runner.cppStandard": "", + "C_Cpp_Runner.useMsvc": false, + "C_Cpp_Runner.warnings": [ + "-Wall", + "-Wextra", + "-Wpedantic", + "-Wshadow", + "-Wformat=2", + "-Wcast-align", + "-Wconversion", + "-Wsign-conversion", + "-Wnull-dereference" + ], + "C_Cpp_Runner.msvcWarnings": [ + "/W4", + "/permissive-", + "/w14242", + "/w14287", + "/w14296", + "/w14311", + "/w14826", + "/w44062", + "/w44242", + "/w14905", + "/w14906", + "/w14263", + "/w44265", + "/w14928" + ], + "C_Cpp_Runner.enableWarnings": true, + "C_Cpp_Runner.warningsAsError": false, + "C_Cpp_Runner.compilerArgs": [], + "C_Cpp_Runner.linkerArgs": [], + "C_Cpp_Runner.includePaths": [], + "C_Cpp_Runner.includeSearch": [ + "*", + "**/*" + ], + "C_Cpp_Runner.excludeSearch": [ + "**/build", + "**/build/**", + "**/.*", + "**/.*/**", + "**/.vscode", + "**/.vscode/**" + ], + "C_Cpp_Runner.useAddressSanitizer": false, + "C_Cpp_Runner.useUndefinedSanitizer": false, + "C_Cpp_Runner.useLeakSanitizer": false, + "C_Cpp_Runner.showCompilationTime": false, + "C_Cpp_Runner.useLinkTimeOptimization": false, + "C_Cpp_Runner.msvcSecureNoWarnings": false +} \ No newline at end of file diff --git a/package.json b/package.json index becc039f..3d5aa121 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,9 @@ "lint": "next lint", "lint:fix": "eslint 'src/**/*.{js,jsx,ts,tsx}' --fix", "analyze": "ANALYZE=true next build", - "prepare": "husky install" + "prepare": "husky install", + "storybook": "storybook dev -p 6006", + "build-storybook": "storybook build" }, "dependencies": { "@emotion/react": "^11.10.6", @@ -26,19 +28,29 @@ "next": "13.2.1", "react": "18.2.0", "react-dom": "18.2.0", - "react-responsive-carousel": "^3.2.23", - "sharp": "^0.31.3" + "react-fast-marquee": "^1.6.1" }, "devDependencies": { "@commitlint/cli": "^17.4.4", "@commitlint/config-conventional": "^17.4.4", + "@emotion/babel-preset-css-prop": "^11.11.0", "@next/bundle-analyzer": "^13.2.1", + "@storybook/addon-essentials": "^7.4.0", + "@storybook/addon-interactions": "^7.4.0", + "@storybook/addon-links": "^7.4.0", + "@storybook/addon-onboarding": "^1.0.8", + "@storybook/addon-styling": "^1.3.7", + "@storybook/blocks": "^7.4.0", + "@storybook/nextjs": "^7.4.0", + "@storybook/react": "^7.4.0", + "@storybook/testing-library": "^0.2.0", "@swc-jotai/react-refresh": "^0.0.4", "@types/node": "18.14.2", "@types/react": "18.0.28", "@types/react-dom": "18.0.11", "@typescript-eslint/eslint-plugin": "^5.54.0", "@typescript-eslint/parser": "^5.54.0", + "chromatic": "^7.1.0", "compression-webpack-plugin": "^10.0.0", "eslint": "8.35.0", "eslint-config-next": "13.2.1", @@ -46,11 +58,14 @@ "eslint-plugin-import": "^2.27.5", "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-simple-import-sort": "^10.0.0", + "eslint-plugin-storybook": "^0.6.13", "eslint-plugin-unused-imports": "^2.0.0", "husky": "^8.0.3", "lint-staged": "^13.1.2", "next-sitemap": "^3.1.54", "prettier": "^2.8.4", + "storybook": "^7.4.0", + "storybook-addon-next": "^1.8.0", "typescript": "4.9.5" } } diff --git a/public/common/cursor.webp b/public/common/cursor.webp deleted file mode 100644 index e8402bf9..00000000 Binary files a/public/common/cursor.webp and /dev/null differ diff --git a/public/fonts/Decimal-Bold.woff b/public/fonts/Decimal-Bold.woff new file mode 100644 index 00000000..4227d74e Binary files /dev/null and b/public/fonts/Decimal-Bold.woff differ diff --git a/public/fonts/Decimal-Medium.woff b/public/fonts/Decimal-Medium.woff new file mode 100644 index 00000000..3e02bf9b Binary files /dev/null and b/public/fonts/Decimal-Medium.woff differ diff --git a/public/fonts/Decimal-Semibold.woff b/public/fonts/Decimal-Semibold.woff new file mode 100644 index 00000000..58110a9f Binary files /dev/null and b/public/fonts/Decimal-Semibold.woff differ diff --git a/public/fonts/Decimal-book.woff b/public/fonts/Decimal-book.woff new file mode 100644 index 00000000..66b14eb1 Binary files /dev/null and b/public/fonts/Decimal-book.woff differ diff --git a/public/fonts/Decimal-light.woff b/public/fonts/Decimal-light.woff new file mode 100644 index 00000000..092543ec Binary files /dev/null and b/public/fonts/Decimal-light.woff differ diff --git a/public/images/about/airplane.png b/public/images/about/airplane.png new file mode 100644 index 00000000..4569b53c Binary files /dev/null and b/public/images/about/airplane.png differ diff --git a/public/images/about/android.webp b/public/images/about/android.webp deleted file mode 100644 index b2c79c0b..00000000 Binary files a/public/images/about/android.webp and /dev/null differ diff --git a/public/images/about/coffeechat.webp b/public/images/about/coffeechat.webp deleted file mode 100644 index 1f664498..00000000 Binary files a/public/images/about/coffeechat.webp and /dev/null differ diff --git a/public/images/about/designer.webp b/public/images/about/designer.webp deleted file mode 100644 index 06c2161d..00000000 Binary files a/public/images/about/designer.webp and /dev/null differ diff --git a/public/images/about/group.webp b/public/images/about/group.webp deleted file mode 100644 index 88d19477..00000000 Binary files a/public/images/about/group.webp and /dev/null differ diff --git a/public/images/about/hackathon.webp b/public/images/about/hackathon.webp deleted file mode 100644 index da6eb902..00000000 Binary files a/public/images/about/hackathon.webp and /dev/null differ diff --git a/public/images/about/header-back.webp b/public/images/about/header-back.webp deleted file mode 100644 index 15abb232..00000000 Binary files a/public/images/about/header-back.webp and /dev/null differ diff --git a/public/images/about/header-front.webp b/public/images/about/header-front.webp deleted file mode 100644 index 7efa8659..00000000 Binary files a/public/images/about/header-front.webp and /dev/null differ diff --git a/public/images/about/ios.webp b/public/images/about/ios.webp deleted file mode 100644 index 2977bfdb..00000000 Binary files a/public/images/about/ios.webp and /dev/null differ diff --git a/public/images/about/meeting.webp b/public/images/about/meeting.webp deleted file mode 100644 index c158df45..00000000 Binary files a/public/images/about/meeting.webp and /dev/null differ diff --git a/public/images/about/mobile-header.webp b/public/images/about/mobile-header.webp deleted file mode 100644 index 6fe730d3..00000000 Binary files a/public/images/about/mobile-header.webp and /dev/null differ diff --git a/public/images/about/networking.webp b/public/images/about/networking.webp deleted file mode 100644 index 3d017f20..00000000 Binary files a/public/images/about/networking.webp and /dev/null differ diff --git a/public/images/about/passport.png b/public/images/about/passport.png new file mode 100644 index 00000000..6ad63948 Binary files /dev/null and b/public/images/about/passport.png differ diff --git a/public/images/about/server.webp b/public/images/about/server.webp deleted file mode 100644 index d632c307..00000000 Binary files a/public/images/about/server.webp and /dev/null differ diff --git a/public/images/about/study.webp b/public/images/about/study.webp deleted file mode 100644 index 69220eb0..00000000 Binary files a/public/images/about/study.webp and /dev/null differ diff --git a/public/images/about/web.webp b/public/images/about/web.webp deleted file mode 100644 index ee47a0c3..00000000 Binary files a/public/images/about/web.webp and /dev/null differ diff --git a/public/images/error/career.png b/public/images/error/career.png new file mode 100644 index 00000000..eb6f32e7 Binary files /dev/null and b/public/images/error/career.png differ diff --git a/public/images/home/header-back.webp b/public/images/home/header-back.webp deleted file mode 100644 index 31272964..00000000 Binary files a/public/images/home/header-back.webp and /dev/null differ diff --git a/public/images/home/header-front.png b/public/images/home/header-front.png deleted file mode 100644 index e3655bf4..00000000 Binary files a/public/images/home/header-front.png and /dev/null differ diff --git a/public/images/home/header.webp b/public/images/home/header.webp deleted file mode 100644 index 9e5f99b5..00000000 Binary files a/public/images/home/header.webp and /dev/null differ diff --git a/public/images/home/heart.webp b/public/images/home/heart.webp deleted file mode 100644 index 145ae6a6..00000000 Binary files a/public/images/home/heart.webp and /dev/null differ diff --git a/public/images/home/meet.webp b/public/images/home/meet.webp deleted file mode 100644 index 831d84a9..00000000 Binary files a/public/images/home/meet.webp and /dev/null differ diff --git a/public/images/home/mobile-header-back.webp b/public/images/home/mobile-header-back.webp deleted file mode 100644 index 7216ed9e..00000000 Binary files a/public/images/home/mobile-header-back.webp and /dev/null differ diff --git a/public/images/home/mobile-header-front.webp b/public/images/home/mobile-header-front.webp deleted file mode 100644 index d881a2a0..00000000 Binary files a/public/images/home/mobile-header-front.webp and /dev/null differ diff --git a/public/images/home/mobile-heart.webp b/public/images/home/mobile-heart.webp deleted file mode 100644 index 4777dba9..00000000 Binary files a/public/images/home/mobile-heart.webp and /dev/null differ diff --git a/public/images/home/mobile-meet.webp b/public/images/home/mobile-meet.webp deleted file mode 100644 index fbf8ec3d..00000000 Binary files a/public/images/home/mobile-meet.webp and /dev/null differ diff --git a/public/images/home/mobile-programmer.webp b/public/images/home/mobile-programmer.webp deleted file mode 100644 index 0f8028ea..00000000 Binary files a/public/images/home/mobile-programmer.webp and /dev/null differ diff --git a/public/images/home/programmer.webp b/public/images/home/programmer.webp deleted file mode 100644 index 21194ef1..00000000 Binary files a/public/images/home/programmer.webp and /dev/null differ diff --git a/public/images/logo.png b/public/images/logo.png new file mode 100644 index 00000000..8556cb3c Binary files /dev/null and b/public/images/logo.png differ diff --git a/public/images/main/coin-drop.png b/public/images/main/coin-drop.png new file mode 100644 index 00000000..77914736 Binary files /dev/null and b/public/images/main/coin-drop.png differ diff --git a/public/images/main/main-bg.png b/public/images/main/main-bg.png new file mode 100644 index 00000000..cf24aa56 Binary files /dev/null and b/public/images/main/main-bg.png differ diff --git a/public/images/main/passport-combination.png b/public/images/main/passport-combination.png new file mode 100644 index 00000000..c32b12e2 Binary files /dev/null and b/public/images/main/passport-combination.png differ diff --git "a/public/images/organizer/\352\271\200\353\217\231\352\267\234.webp" "b/public/images/organizer/\352\271\200\353\217\231\352\267\234.webp" deleted file mode 100644 index 6da1458e..00000000 Binary files "a/public/images/organizer/\352\271\200\353\217\231\352\267\234.webp" and /dev/null differ diff --git "a/public/images/organizer/\352\271\200\353\254\270\352\267\234.webp" "b/public/images/organizer/\352\271\200\353\254\270\352\267\234.webp" deleted file mode 100644 index 51d4fd42..00000000 Binary files "a/public/images/organizer/\352\271\200\353\254\270\352\267\234.webp" and /dev/null differ diff --git "a/public/images/organizer/\352\271\200\353\257\274\354\210\230.webp" "b/public/images/organizer/\352\271\200\353\257\274\354\210\230.webp" deleted file mode 100644 index 2ae85814..00000000 Binary files "a/public/images/organizer/\352\271\200\353\257\274\354\210\230.webp" and /dev/null differ diff --git "a/public/images/organizer/\353\260\225\354\206\214\355\230\204.webp" "b/public/images/organizer/\353\260\225\354\206\214\355\230\204.webp" deleted file mode 100644 index c08c96a3..00000000 Binary files "a/public/images/organizer/\353\260\225\354\206\214\355\230\204.webp" and /dev/null differ diff --git "a/public/images/organizer/\353\260\225\354\210\230\354\227\260.webp" "b/public/images/organizer/\353\260\225\354\210\230\354\227\260.webp" deleted file mode 100644 index 16f31dc2..00000000 Binary files "a/public/images/organizer/\353\260\225\354\210\230\354\227\260.webp" and /dev/null differ diff --git "a/public/images/organizer/\354\230\244\355\230\234\354\204\261.webp" "b/public/images/organizer/\354\230\244\355\230\234\354\204\261.webp" deleted file mode 100644 index f6f6e015..00000000 Binary files "a/public/images/organizer/\354\230\244\355\230\234\354\204\261.webp" and /dev/null differ diff --git "a/public/images/organizer/\354\235\264\354\204\261\355\203\234.webp" "b/public/images/organizer/\354\235\264\354\204\261\355\203\234.webp" deleted file mode 100644 index 12d95992..00000000 Binary files "a/public/images/organizer/\354\235\264\354\204\261\355\203\234.webp" and /dev/null differ diff --git "a/public/images/organizer/\354\235\264\354\212\271\355\235\254.webp" "b/public/images/organizer/\354\235\264\354\212\271\355\235\254.webp" deleted file mode 100644 index eca64461..00000000 Binary files "a/public/images/organizer/\354\235\264\354\212\271\355\235\254.webp" and /dev/null differ diff --git "a/public/images/organizer/\354\235\264\354\235\200\354\247\200.webp" "b/public/images/organizer/\354\235\264\354\235\200\354\247\200.webp" deleted file mode 100644 index 7f10ca7b..00000000 Binary files "a/public/images/organizer/\354\235\264\354\235\200\354\247\200.webp" and /dev/null differ diff --git "a/public/images/organizer/\354\235\264\354\242\205\354\233\220.webp" "b/public/images/organizer/\354\235\264\354\242\205\354\233\220.webp" deleted file mode 100644 index e8acfd8f..00000000 Binary files "a/public/images/organizer/\354\235\264\354\242\205\354\233\220.webp" and /dev/null differ diff --git "a/public/images/organizer/\354\235\264\354\260\254\354\247\204.webp" "b/public/images/organizer/\354\235\264\354\260\254\354\247\204.webp" deleted file mode 100644 index 55ab4cbc..00000000 Binary files "a/public/images/organizer/\354\235\264\354\260\254\354\247\204.webp" and /dev/null differ diff --git "a/public/images/organizer/\354\236\204\355\232\250\354\227\260.webp" "b/public/images/organizer/\354\236\204\355\232\250\354\227\260.webp" deleted file mode 100644 index 82ead86b..00000000 Binary files "a/public/images/organizer/\354\236\204\355\232\250\354\227\260.webp" and /dev/null differ diff --git "a/public/images/organizer/\354\240\225\353\214\200\354\234\244.webp" "b/public/images/organizer/\354\240\225\353\214\200\354\234\244.webp" deleted file mode 100644 index e0feba7b..00000000 Binary files "a/public/images/organizer/\354\240\225\353\214\200\354\234\244.webp" and /dev/null differ diff --git "a/public/images/organizer/\354\260\250\354\232\224\354\205\211.webp" "b/public/images/organizer/\354\260\250\354\232\224\354\205\211.webp" deleted file mode 100644 index 26b8f0ee..00000000 Binary files "a/public/images/organizer/\354\260\250\354\232\224\354\205\211.webp" and /dev/null differ diff --git a/public/images/position/aos.png b/public/images/position/aos.png new file mode 100644 index 00000000..064700ff Binary files /dev/null and b/public/images/position/aos.png differ diff --git a/public/images/position/design.png b/public/images/position/design.png new file mode 100644 index 00000000..537885ac Binary files /dev/null and b/public/images/position/design.png differ diff --git a/public/images/position/icon/back.webp b/public/images/position/icon/back.webp deleted file mode 100644 index a6c1f934..00000000 Binary files a/public/images/position/icon/back.webp and /dev/null differ diff --git a/public/images/position/icon/project-link--active.webp b/public/images/position/icon/project-link--active.webp deleted file mode 100644 index a73fe3ff..00000000 Binary files a/public/images/position/icon/project-link--active.webp and /dev/null differ diff --git a/public/images/position/icon/project-link--default.webp b/public/images/position/icon/project-link--default.webp deleted file mode 100644 index 6065a8b8..00000000 Binary files a/public/images/position/icon/project-link--default.webp and /dev/null differ diff --git a/public/images/position/icon/project-prize.webp b/public/images/position/icon/project-prize.webp deleted file mode 100644 index 2056907b..00000000 Binary files a/public/images/position/icon/project-prize.webp and /dev/null differ diff --git a/public/images/position/ios.png b/public/images/position/ios.png new file mode 100644 index 00000000..db694561 Binary files /dev/null and b/public/images/position/ios.png differ diff --git a/public/images/position/server.png b/public/images/position/server.png new file mode 100644 index 00000000..7e0ae993 Binary files /dev/null and b/public/images/position/server.png differ diff --git a/public/images/position/web.png b/public/images/position/web.png new file mode 100644 index 00000000..09a424e9 Binary files /dev/null and b/public/images/position/web.png differ diff --git a/public/projects/thumbnails/archive.png "b/public/images/project/10\352\270\260/Archive.png" similarity index 100% rename from public/projects/thumbnails/archive.png rename to "public/images/project/10\352\270\260/Archive.png" diff --git a/public/projects/thumbnails/bboxx.png "b/public/images/project/10\352\270\260/BBOXX.png" similarity index 100% rename from public/projects/thumbnails/bboxx.png rename to "public/images/project/10\352\270\260/BBOXX.png" diff --git a/public/projects/thumbnails/bodymood.png "b/public/images/project/10\352\270\260/Bodymood.png" similarity index 100% rename from public/projects/thumbnails/bodymood.png rename to "public/images/project/10\352\270\260/Bodymood.png" diff --git a/public/projects/thumbnails/imgoing.png "b/public/images/project/10\352\270\260/IMGOING.png" similarity index 100% rename from public/projects/thumbnails/imgoing.png rename to "public/images/project/10\352\270\260/IMGOING.png" diff --git a/public/projects/thumbnails/omo.png "b/public/images/project/10\352\270\260/OMO.png" similarity index 100% rename from public/projects/thumbnails/omo.png rename to "public/images/project/10\352\270\260/OMO.png" diff --git a/public/projects/thumbnails/noonbody.png "b/public/images/project/10\352\270\260/noonbody.png" similarity index 100% rename from public/projects/thumbnails/noonbody.png rename to "public/images/project/10\352\270\260/noonbody.png" diff --git "a/public/projects/thumbnails/\353\202\230\353\202\230\352\263\265.png" "b/public/images/project/10\352\270\260/\353\202\230\353\202\230\352\263\265.png" similarity index 100% rename from "public/projects/thumbnails/\353\202\230\353\202\230\352\263\265.png" rename to "public/images/project/10\352\270\260/\353\202\230\353\202\230\352\263\265.png" diff --git "a/public/projects/thumbnails/\353\214\200\353\217\231\353\271\265\354\247\200\353\217\204.png" "b/public/images/project/10\352\270\260/\353\214\200\353\217\231\353\271\265\354\247\200\353\217\204.png" similarity index 100% rename from "public/projects/thumbnails/\353\214\200\353\217\231\353\271\265\354\247\200\353\217\204.png" rename to "public/images/project/10\352\270\260/\353\214\200\353\217\231\353\271\265\354\247\200\353\217\204.png" diff --git "a/public/projects/thumbnails/\354\230\201\354\260\250.png" "b/public/images/project/10\352\270\260/\354\230\201\354\260\250.png" similarity index 100% rename from "public/projects/thumbnails/\354\230\201\354\260\250.png" rename to "public/images/project/10\352\270\260/\354\230\201\354\260\250.png" diff --git "a/public/projects/thumbnails/\354\230\244\353\247\265\353\225\241.png" "b/public/images/project/10\352\270\260/\354\230\244\353\247\265\353\225\241.png" similarity index 100% rename from "public/projects/thumbnails/\354\230\244\353\247\265\353\225\241.png" rename to "public/images/project/10\352\270\260/\354\230\244\353\247\265\353\225\241.png" diff --git "a/public/projects/thumbnails/\352\260\234\353\257\270\353\212\224\355\210\260\355\210\260.png" "b/public/images/project/11\352\270\260/\352\260\234\353\257\270\353\212\224 \355\210\260\355\210\260.png" similarity index 100% rename from "public/projects/thumbnails/\352\260\234\353\257\270\353\212\224\355\210\260\355\210\260.png" rename to "public/images/project/11\352\270\260/\352\260\234\353\257\270\353\212\224 \355\210\260\355\210\260.png" diff --git "a/public/projects/thumbnails/\353\252\275\354\213\244.png" "b/public/images/project/11\352\270\260/\353\252\275\354\213\244.png" similarity index 100% rename from "public/projects/thumbnails/\353\252\275\354\213\244.png" rename to "public/images/project/11\352\270\260/\353\252\275\354\213\244.png" diff --git "a/public/projects/thumbnails/\353\254\264\353\223\234\355\224\275.png" "b/public/images/project/11\352\270\260/\353\254\264\353\223\234\355\224\275.png" similarity index 100% rename from "public/projects/thumbnails/\353\254\264\353\223\234\355\224\275.png" rename to "public/images/project/11\352\270\260/\353\254\264\353\223\234\355\224\275.png" diff --git "a/public/projects/thumbnails/\353\260\224\355\206\265.png" "b/public/images/project/11\352\270\260/\353\260\224\355\206\265.png" similarity index 100% rename from "public/projects/thumbnails/\353\260\224\355\206\265.png" rename to "public/images/project/11\352\270\260/\353\260\224\355\206\265.png" diff --git "a/public/projects/thumbnails/\353\271\204\354\226\264\354\227\220\354\226\264.png" "b/public/images/project/11\352\270\260/\353\271\204\354\226\264\354\227\220\354\226\264.png" similarity index 100% rename from "public/projects/thumbnails/\353\271\204\354\226\264\354\227\220\354\226\264.png" rename to "public/images/project/11\352\270\260/\353\271\204\354\226\264\354\227\220\354\226\264.png" diff --git "a/public/projects/thumbnails/\354\230\201\352\260\220\355\203\261.png" "b/public/images/project/11\352\270\260/\354\230\201\352\260\220\355\203\261.png" similarity index 100% rename from "public/projects/thumbnails/\354\230\201\352\260\220\355\203\261.png" rename to "public/images/project/11\352\270\260/\354\230\201\352\260\220\355\203\261.png" diff --git "a/public/projects/thumbnails/\355\213\260\355\202\244\355\203\200\354\271\264.png" "b/public/images/project/11\352\270\260/\355\213\260\355\202\244\355\203\200\354\271\264.png" similarity index 100% rename from "public/projects/thumbnails/\355\213\260\355\202\244\355\203\200\354\271\264.png" rename to "public/images/project/11\352\270\260/\355\213\260\355\202\244\355\203\200\354\271\264.png" diff --git "a/public/projects/thumbnails/\355\216\230\354\226\264\353\237\254.png" "b/public/images/project/11\352\270\260/\355\216\230\354\226\264\353\237\254.png" similarity index 100% rename from "public/projects/thumbnails/\355\216\230\354\226\264\353\237\254.png" rename to "public/images/project/11\352\270\260/\355\216\230\354\226\264\353\237\254.png" diff --git a/public/projects/thumbnails/KNOCKNOCK.png "b/public/images/project/12\352\270\260/KNOCKNOCK.png" similarity index 100% rename from public/projects/thumbnails/KNOCKNOCK.png rename to "public/images/project/12\352\270\260/KNOCKNOCK.png" diff --git a/public/projects/thumbnails/PING-PONG.png "b/public/images/project/12\352\270\260/PING-PONG!.png" similarity index 100% rename from public/projects/thumbnails/PING-PONG.png rename to "public/images/project/12\352\270\260/PING-PONG!.png" diff --git a/public/projects/thumbnails/TICLEMOA.png "b/public/images/project/12\352\270\260/TICLEMOA.png" similarity index 100% rename from public/projects/thumbnails/TICLEMOA.png rename to "public/images/project/12\352\270\260/TICLEMOA.png" diff --git "a/public/projects/thumbnails/\352\274\254\352\271\203.png" "b/public/images/project/12\352\270\260/\352\274\254\352\271\203.png" similarity index 100% rename from "public/projects/thumbnails/\352\274\254\352\271\203.png" rename to "public/images/project/12\352\270\260/\352\274\254\352\271\203.png" diff --git "a/public/projects/thumbnails/\353\230\221\354\212\244.png" "b/public/images/project/12\352\270\260/\353\230\221\354\212\244.png" similarity index 100% rename from "public/projects/thumbnails/\353\230\221\354\212\244.png" rename to "public/images/project/12\352\270\260/\353\230\221\354\212\244.png" diff --git "a/public/projects/thumbnails/\354\225\204\353\247\236\353\213\244.png" "b/public/images/project/12\352\270\260/\354\225\204\353\247\236\353\213\244.png" similarity index 100% rename from "public/projects/thumbnails/\354\225\204\353\247\236\353\213\244.png" rename to "public/images/project/12\352\270\260/\354\225\204\353\247\236\353\213\244.png" diff --git "a/public/projects/thumbnails/\354\247\235\354\213\254\354\202\274\354\235\274.png" "b/public/images/project/12\352\270\260/\354\247\235\354\213\254\354\202\274\354\235\274.png" similarity index 100% rename from "public/projects/thumbnails/\354\247\235\354\213\254\354\202\274\354\235\274.png" rename to "public/images/project/12\352\270\260/\354\247\235\354\213\254\354\202\274\354\235\274.png" diff --git "a/public/projects/thumbnails/\354\275\224\355\200\204\353\246\254\355\213\260.png" "b/public/images/project/12\352\270\260/\354\275\224\355\200\204\353\246\254\355\213\260.png" similarity index 100% rename from "public/projects/thumbnails/\354\275\224\355\200\204\353\246\254\355\213\260.png" rename to "public/images/project/12\352\270\260/\354\275\224\355\200\204\353\246\254\355\213\260.png" diff --git "a/public/images/project/13\352\270\260/Ding-Dong (\353\224\251\353\217\231).png" "b/public/images/project/13\352\270\260/Ding-Dong (\353\224\251\353\217\231).png" new file mode 100644 index 00000000..e42d06e4 Binary files /dev/null and "b/public/images/project/13\352\270\260/Ding-Dong (\353\224\251\353\217\231).png" differ diff --git "a/public/images/project/13\352\270\260/Na Lab(\353\202\230\353\236\251).png" "b/public/images/project/13\352\270\260/Na Lab(\353\202\230\353\236\251).png" new file mode 100644 index 00000000..fbebccbe Binary files /dev/null and "b/public/images/project/13\352\270\260/Na Lab(\353\202\230\353\236\251).png" differ diff --git "a/public/images/project/13\352\270\260/Pumping (\355\216\214\355\225\221).png" "b/public/images/project/13\352\270\260/Pumping (\355\216\214\355\225\221).png" new file mode 100644 index 00000000..d44c36af Binary files /dev/null and "b/public/images/project/13\352\270\260/Pumping (\355\216\214\355\225\221).png" differ diff --git "a/public/images/project/13\352\270\260/Street Drop.png" "b/public/images/project/13\352\270\260/Street Drop.png" new file mode 100644 index 00000000..2f247cf5 Binary files /dev/null and "b/public/images/project/13\352\270\260/Street Drop.png" differ diff --git "a/public/images/project/13\352\270\260/Whatnow (\354\231\224\353\202\230).png" "b/public/images/project/13\352\270\260/Whatnow (\354\231\224\353\202\230).png" new file mode 100644 index 00000000..51bb5fff Binary files /dev/null and "b/public/images/project/13\352\270\260/Whatnow (\354\231\224\353\202\230).png" differ diff --git "a/public/images/project/13\352\270\260/\354\230\244\353\262\204\354\212\244\354\234\227.png" "b/public/images/project/13\352\270\260/\354\230\244\353\262\204\354\212\244\354\234\227.png" new file mode 100644 index 00000000..fb574d4c Binary files /dev/null and "b/public/images/project/13\352\270\260/\354\230\244\353\262\204\354\212\244\354\234\227.png" differ diff --git "a/public/images/project/13\352\270\260/\354\235\270\354\202\254\354\235\264\355\212\270\354\225\204\354\233\203.png" "b/public/images/project/13\352\270\260/\354\235\270\354\202\254\354\235\264\355\212\270\354\225\204\354\233\203.png" new file mode 100644 index 00000000..6ed99a10 Binary files /dev/null and "b/public/images/project/13\352\270\260/\354\235\270\354\202\254\354\235\264\355\212\270\354\225\204\354\233\203.png" differ diff --git "a/public/images/project/13\352\270\260/\354\236\220\353\246\260\352\263\240\353\271\204.png" "b/public/images/project/13\352\270\260/\354\236\220\353\246\260\352\263\240\353\271\204.png" new file mode 100644 index 00000000..f5a76ac0 Binary files /dev/null and "b/public/images/project/13\352\270\260/\354\236\220\353\246\260\352\263\240\353\271\204.png" differ diff --git "a/public/projects/thumbnails/\353\234\273\353\260\226\354\235\230\355\200\264\354\246\210.png" "b/public/images/project/5\352\270\260/\353\234\273\353\260\226\354\235\230 \355\200\264\354\246\210.png" similarity index 100% rename from "public/projects/thumbnails/\353\234\273\353\260\226\354\235\230\355\200\264\354\246\210.png" rename to "public/images/project/5\352\270\260/\353\234\273\353\260\226\354\235\230 \355\200\264\354\246\210.png" diff --git a/public/projects/thumbnails/therto.png "b/public/images/project/6\352\270\260/Therto.png" similarity index 100% rename from public/projects/thumbnails/therto.png rename to "public/images/project/6\352\270\260/Therto.png" diff --git "a/public/projects/thumbnails/\354\271\274\355\207\264\354\232\224\354\240\225.png" "b/public/images/project/6\352\270\260/\354\271\274\355\207\264\354\232\224\354\240\225.png" similarity index 100% rename from "public/projects/thumbnails/\354\271\274\355\207\264\354\232\224\354\240\225.png" rename to "public/images/project/6\352\270\260/\354\271\274\355\207\264\354\232\224\354\240\225.png" diff --git "a/public/projects/thumbnails/\354\277\250\355\224\274\354\212\244.png" "b/public/images/project/6\352\270\260/\354\277\250\355\224\274\354\212\244.png" similarity index 100% rename from "public/projects/thumbnails/\354\277\250\355\224\274\354\212\244.png" rename to "public/images/project/6\352\270\260/\354\277\250\355\224\274\354\212\244.png" diff --git "a/public/projects/thumbnails/\352\260\200\354\212\264\354\206\2153\354\262\234\354\233\220.png" "b/public/images/project/7\352\270\260/\352\260\200\354\212\264\354\206\215 3\354\262\234\354\233\220.png" similarity index 100% rename from "public/projects/thumbnails/\352\260\200\354\212\264\354\206\2153\354\262\234\354\233\220.png" rename to "public/images/project/7\352\270\260/\352\260\200\354\212\264\354\206\215 3\354\262\234\354\233\220.png" diff --git a/public/projects/thumbnails/avocado.png "b/public/images/project/8\352\270\260/Avocado.png" similarity index 100% rename from public/projects/thumbnails/avocado.png rename to "public/images/project/8\352\270\260/Avocado.png" diff --git "a/public/projects/thumbnails/\353\266\201\354\252\275\354\234\274\353\241\234.png" "b/public/images/project/8\352\270\260/\353\266\201\354\252\275\354\234\274\353\241\234.png" similarity index 100% rename from "public/projects/thumbnails/\353\266\201\354\252\275\354\234\274\353\241\234.png" rename to "public/images/project/8\352\270\260/\353\266\201\354\252\275\354\234\274\353\241\234.png" diff --git "a/public/projects/thumbnails/\354\225\204\353\254\264\352\261\260\353\202\230.png" "b/public/images/project/8\352\270\260/\354\225\204\353\254\264\352\261\260\353\202\230.png" similarity index 100% rename from "public/projects/thumbnails/\354\225\204\353\254\264\352\261\260\353\202\230.png" rename to "public/images/project/8\352\270\260/\354\225\204\353\254\264\352\261\260\353\202\230.png" diff --git "a/public/projects/thumbnails/3\353\214\200\354\226\274\353\247\210.png" "b/public/images/project/9\352\270\260/3\353\214\200 \354\226\274\353\247\210.png" similarity index 100% rename from "public/projects/thumbnails/3\353\214\200\354\226\274\353\247\210.png" rename to "public/images/project/9\352\270\260/3\353\214\200 \354\226\274\353\247\210.png" diff --git a/public/projects/thumbnails/hush.png "b/public/images/project/9\352\270\260/Hush.png" similarity index 100% rename from public/projects/thumbnails/hush.png rename to "public/images/project/9\352\270\260/Hush.png" diff --git a/public/projects/thumbnails/tooni.png "b/public/images/project/9\352\270\260/TOONI TOONI.png" similarity index 100% rename from public/projects/thumbnails/tooni.png rename to "public/images/project/9\352\270\260/TOONI TOONI.png" diff --git "a/public/projects/thumbnails/\353\247\201\355\201\254\354\244\215\354\244\215.png" "b/public/images/project/9\352\270\260/\353\247\201\355\201\254\354\244\215\354\244\215.png" similarity index 100% rename from "public/projects/thumbnails/\353\247\201\355\201\254\354\244\215\354\244\215.png" rename to "public/images/project/9\352\270\260/\353\247\201\355\201\254\354\244\215\354\244\215.png" diff --git "a/public/projects/thumbnails/\353\247\210\354\235\264\353\240\210\354\213\234\355\224\275.png" "b/public/images/project/9\352\270\260/\353\247\210\354\235\264\353\240\210\354\213\234\355\224\275.png" similarity index 100% rename from "public/projects/thumbnails/\353\247\210\354\235\264\353\240\210\354\213\234\355\224\275.png" rename to "public/images/project/9\352\270\260/\353\247\210\354\235\264\353\240\210\354\213\234\355\224\275.png" diff --git "a/public/projects/thumbnails/\354\230\244\353\212\230\354\235\230\355\205\214\354\212\244\355\212\270.png" "b/public/images/project/9\352\270\260/\354\230\244\353\212\230\354\235\230 \355\205\214\354\212\244\355\212\270.png" similarity index 100% rename from "public/projects/thumbnails/\354\230\244\353\212\230\354\235\230\355\205\214\354\212\244\355\212\270.png" rename to "public/images/project/9\352\270\260/\354\230\244\353\212\230\354\235\230 \355\205\214\354\212\244\355\212\270.png" diff --git "a/public/projects/thumbnails/\354\240\234\353\241\234\354\232\260\354\245\254.png" "b/public/images/project/9\352\270\260/\354\240\234\353\241\234\354\232\260\354\245\254.png" similarity index 100% rename from "public/projects/thumbnails/\354\240\234\353\241\234\354\232\260\354\245\254.png" rename to "public/images/project/9\352\270\260/\354\240\234\353\241\234\354\232\260\354\245\254.png" diff --git "a/public/projects/thumbnails/\355\201\254\353\236\230\354\273\244\353\266\201.png" "b/public/images/project/9\352\270\260/\355\201\254\353\236\230\354\273\244\353\266\201.png" similarity index 100% rename from "public/projects/thumbnails/\355\201\254\353\236\230\354\273\244\353\266\201.png" rename to "public/images/project/9\352\270\260/\355\201\254\353\236\230\354\273\244\353\266\201.png" diff --git a/public/images/recruit-detail/header-android.webp b/public/images/recruit-detail/header-android.webp deleted file mode 100644 index c846e321..00000000 Binary files a/public/images/recruit-detail/header-android.webp and /dev/null differ diff --git a/public/images/recruit-detail/header-design.webp b/public/images/recruit-detail/header-design.webp deleted file mode 100644 index a1bd028e..00000000 Binary files a/public/images/recruit-detail/header-design.webp and /dev/null differ diff --git a/public/images/recruit-detail/header-ios.webp b/public/images/recruit-detail/header-ios.webp deleted file mode 100644 index aedcdcc4..00000000 Binary files a/public/images/recruit-detail/header-ios.webp and /dev/null differ diff --git a/public/images/recruit-detail/header-server.webp b/public/images/recruit-detail/header-server.webp deleted file mode 100644 index 879e539b..00000000 Binary files a/public/images/recruit-detail/header-server.webp and /dev/null differ diff --git a/public/images/recruit-detail/header-web.webp b/public/images/recruit-detail/header-web.webp deleted file mode 100644 index 14d72df0..00000000 Binary files a/public/images/recruit-detail/header-web.webp and /dev/null differ diff --git "a/public/images/recruit-detail/\352\271\200\353\217\231\352\267\234.webp" "b/public/images/recruit-detail/\352\271\200\353\217\231\352\267\234.webp" deleted file mode 100644 index 095e3b1a..00000000 Binary files "a/public/images/recruit-detail/\352\271\200\353\217\231\352\267\234.webp" and /dev/null differ diff --git "a/public/images/recruit-detail/\352\271\200\353\257\274\354\210\230.webp" "b/public/images/recruit-detail/\352\271\200\353\257\274\354\210\230.webp" deleted file mode 100644 index 1f9524ad..00000000 Binary files "a/public/images/recruit-detail/\352\271\200\353\257\274\354\210\230.webp" and /dev/null differ diff --git "a/public/images/recruit-detail/\352\271\200\354\243\274\355\231\230.webp" "b/public/images/recruit-detail/\352\271\200\354\243\274\355\231\230.webp" deleted file mode 100644 index b5e16674..00000000 Binary files "a/public/images/recruit-detail/\352\271\200\354\243\274\355\231\230.webp" and /dev/null differ diff --git "a/public/images/recruit-detail/\352\271\200\355\230\234\354\235\270.webp" "b/public/images/recruit-detail/\352\271\200\355\230\234\354\235\270.webp" deleted file mode 100644 index 583ebacb..00000000 Binary files "a/public/images/recruit-detail/\352\271\200\355\230\234\354\235\270.webp" and /dev/null differ diff --git "a/public/images/recruit-detail/\353\260\225\354\210\230\354\227\260.webp" "b/public/images/recruit-detail/\353\260\225\354\210\230\354\227\260.webp" deleted file mode 100644 index b808ad46..00000000 Binary files "a/public/images/recruit-detail/\353\260\225\354\210\230\354\227\260.webp" and /dev/null differ diff --git "a/public/images/recruit-detail/\354\230\244\355\230\234\354\204\261.webp" "b/public/images/recruit-detail/\354\230\244\355\230\234\354\204\261.webp" deleted file mode 100644 index 751d9a37..00000000 Binary files "a/public/images/recruit-detail/\354\230\244\355\230\234\354\204\261.webp" and /dev/null differ diff --git "a/public/images/recruit-detail/\354\235\264\354\204\261\355\203\234.webp" "b/public/images/recruit-detail/\354\235\264\354\204\261\355\203\234.webp" deleted file mode 100644 index 662e0f71..00000000 Binary files "a/public/images/recruit-detail/\354\235\264\354\204\261\355\203\234.webp" and /dev/null differ diff --git "a/public/images/recruit-detail/\354\235\264\354\212\271\355\235\254.webp" "b/public/images/recruit-detail/\354\235\264\354\212\271\355\235\254.webp" deleted file mode 100644 index 940a6d2f..00000000 Binary files "a/public/images/recruit-detail/\354\235\264\354\212\271\355\235\254.webp" and /dev/null differ diff --git "a/public/images/recruit-detail/\354\235\264\354\242\205\354\233\220.webp" "b/public/images/recruit-detail/\354\235\264\354\242\205\354\233\220.webp" deleted file mode 100644 index bab6f226..00000000 Binary files "a/public/images/recruit-detail/\354\235\264\354\242\205\354\233\220.webp" and /dev/null differ diff --git "a/public/images/recruit-detail/\354\235\264\354\260\254\354\247\204.webp" "b/public/images/recruit-detail/\354\235\264\354\260\254\354\247\204.webp" deleted file mode 100644 index 379bb5cf..00000000 Binary files "a/public/images/recruit-detail/\354\235\264\354\260\254\354\247\204.webp" and /dev/null differ diff --git "a/public/images/recruit-detail/\354\236\204\355\232\250\354\227\260.webp" "b/public/images/recruit-detail/\354\236\204\355\232\250\354\227\260.webp" deleted file mode 100644 index 0722ad6c..00000000 Binary files "a/public/images/recruit-detail/\354\236\204\355\232\250\354\227\260.webp" and /dev/null differ diff --git "a/public/images/recruit-detail/\354\240\204\355\225\264\354\204\261.webp" "b/public/images/recruit-detail/\354\240\204\355\225\264\354\204\261.webp" deleted file mode 100644 index 183770fd..00000000 Binary files "a/public/images/recruit-detail/\354\240\204\355\225\264\354\204\261.webp" and /dev/null differ diff --git "a/public/images/recruit-detail/\354\240\225\353\214\200\354\234\244.webp" "b/public/images/recruit-detail/\354\240\225\353\214\200\354\234\244.webp" deleted file mode 100644 index 58aa42f6..00000000 Binary files "a/public/images/recruit-detail/\354\240\225\353\214\200\354\234\244.webp" and /dev/null differ diff --git "a/public/images/recruit-detail/\354\260\250\354\232\224\354\205\211.webp" "b/public/images/recruit-detail/\354\260\250\354\232\224\354\205\211.webp" deleted file mode 100644 index f8e371ec..00000000 Binary files "a/public/images/recruit-detail/\354\260\250\354\232\224\354\205\211.webp" and /dev/null differ diff --git "a/public/images/recruit-detail/\355\231\251\352\267\234\354\235\274.webp" "b/public/images/recruit-detail/\355\231\251\352\267\234\354\235\274.webp" deleted file mode 100644 index 65890e85..00000000 Binary files "a/public/images/recruit-detail/\355\231\251\352\267\234\354\235\274.webp" and /dev/null differ diff --git a/public/images/recruit/home.webp b/public/images/recruit/home.webp deleted file mode 100644 index 55017e5b..00000000 Binary files a/public/images/recruit/home.webp and /dev/null differ diff --git a/public/images/session/final.png b/public/images/session/final.png new file mode 100644 index 00000000..01d39bd1 Binary files /dev/null and b/public/images/session/final.png differ diff --git a/public/images/session/launching.png b/public/images/session/launching.png new file mode 100644 index 00000000..1c7e618c Binary files /dev/null and b/public/images/session/launching.png differ diff --git a/public/images/session/midterm.png b/public/images/session/midterm.png new file mode 100644 index 00000000..17e1eeac Binary files /dev/null and b/public/images/session/midterm.png differ diff --git a/public/images/session/networking.png b/public/images/session/networking.png new file mode 100644 index 00000000..2994d758 Binary files /dev/null and b/public/images/session/networking.png differ diff --git a/public/images/session/orientation.png b/public/images/session/orientation.png new file mode 100644 index 00000000..4311207e Binary files /dev/null and b/public/images/session/orientation.png differ diff --git a/public/images/session/usability.png b/public/images/session/usability.png new file mode 100644 index 00000000..a764a6df Binary files /dev/null and b/public/images/session/usability.png differ diff --git a/public/images/sign/about.png b/public/images/sign/about.png new file mode 100644 index 00000000..9b27a490 Binary files /dev/null and b/public/images/sign/about.png differ diff --git a/public/images/sign/main.png b/public/images/sign/main.png new file mode 100644 index 00000000..8f7677b7 Binary files /dev/null and b/public/images/sign/main.png differ diff --git a/public/images/sign/project.png b/public/images/sign/project.png new file mode 100644 index 00000000..1a84a5fe Binary files /dev/null and b/public/images/sign/project.png differ diff --git a/public/images/sign/recruit.png b/public/images/sign/recruit.png new file mode 100644 index 00000000..cc30e77d Binary files /dev/null and b/public/images/sign/recruit.png differ diff --git a/public/images/sponsor/aws.svg b/public/images/sponsor/aws.svg deleted file mode 100644 index 09328394..00000000 --- a/public/images/sponsor/aws.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/public/images/sponsor/dcamp.svg b/public/images/sponsor/dcamp.svg deleted file mode 100644 index 643c5ad0..00000000 --- a/public/images/sponsor/dcamp.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/public/images/sponsor/impact-campus.svg b/public/images/sponsor/impact-campus.svg deleted file mode 100644 index dcbe46de..00000000 --- a/public/images/sponsor/impact-campus.svg +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/public/images/sponsor/inflearn.svg b/public/images/sponsor/inflearn.svg deleted file mode 100644 index e61fb37c..00000000 --- a/public/images/sponsor/inflearn.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/public/images/sponsor/naver-cloud.svg b/public/images/sponsor/naver-cloud.svg deleted file mode 100644 index 6b218a00..00000000 --- a/public/images/sponsor/naver-cloud.svg +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/images/support/inflearn.png b/public/images/support/inflearn.png new file mode 100644 index 00000000..8493da1b Binary files /dev/null and b/public/images/support/inflearn.png differ diff --git a/public/images/support/naver-cloud.png b/public/images/support/naver-cloud.png new file mode 100644 index 00000000..54269f3d Binary files /dev/null and b/public/images/support/naver-cloud.png differ diff --git a/public/images/support/next.png b/public/images/support/next.png new file mode 100644 index 00000000..08a6a54d Binary files /dev/null and b/public/images/support/next.png differ diff --git "a/public/images/support/\353\252\250\353\221\220\354\235\230\354\227\260\352\265\254\354\206\214.png" "b/public/images/support/\353\252\250\353\221\220\354\235\230\354\227\260\352\265\254\354\206\214.png" new file mode 100644 index 00000000..403a68c5 Binary files /dev/null and "b/public/images/support/\353\252\250\353\221\220\354\235\230\354\227\260\352\265\254\354\206\214.png" differ diff --git a/public/og-main.png b/public/og-main.png new file mode 100644 index 00000000..ea120a0c Binary files /dev/null and b/public/og-main.png differ diff --git a/public/og-main.webp b/public/og-main.webp deleted file mode 100644 index 1ea92873..00000000 Binary files a/public/og-main.webp and /dev/null differ diff --git a/public/project/check.webp b/public/project/check.webp deleted file mode 100644 index 4409f4c1..00000000 Binary files a/public/project/check.webp and /dev/null differ diff --git a/public/project/detailBtn.webp b/public/project/detailBtn.webp deleted file mode 100644 index 344f74c1..00000000 Binary files a/public/project/detailBtn.webp and /dev/null differ diff --git a/public/project/dropdown.webp b/public/project/dropdown.webp deleted file mode 100644 index 4bc07176..00000000 Binary files a/public/project/dropdown.webp and /dev/null differ diff --git a/public/project/header-back.webp b/public/project/header-back.webp deleted file mode 100644 index 1e0c8f8d..00000000 Binary files a/public/project/header-back.webp and /dev/null differ diff --git a/public/project/header-front.webp b/public/project/header-front.webp deleted file mode 100644 index b74cd8e9..00000000 Binary files a/public/project/header-front.webp and /dev/null differ diff --git a/public/project/mobile-header-back.webp b/public/project/mobile-header-back.webp deleted file mode 100644 index 669abec0..00000000 Binary files a/public/project/mobile-header-back.webp and /dev/null differ diff --git a/public/project/mobile-header-front.webp b/public/project/mobile-header-front.webp deleted file mode 100644 index 64171b15..00000000 Binary files a/public/project/mobile-header-front.webp and /dev/null differ diff --git "a/public/projects/details/3\353\214\200\354\226\274\353\247\210.png" "b/public/projects/details/3\353\214\200\354\226\274\353\247\210.png" deleted file mode 100644 index d635f2f5..00000000 Binary files "a/public/projects/details/3\353\214\200\354\226\274\353\247\210.png" and /dev/null differ diff --git a/public/projects/details/KNOCKNOCK.png b/public/projects/details/KNOCKNOCK.png deleted file mode 100644 index 37fea8e0..00000000 Binary files a/public/projects/details/KNOCKNOCK.png and /dev/null differ diff --git a/public/projects/details/PING-PONG.png b/public/projects/details/PING-PONG.png deleted file mode 100644 index 42b6eade..00000000 Binary files a/public/projects/details/PING-PONG.png and /dev/null differ diff --git a/public/projects/details/TICLEMOA.png b/public/projects/details/TICLEMOA.png deleted file mode 100644 index a2b87f3f..00000000 Binary files a/public/projects/details/TICLEMOA.png and /dev/null differ diff --git a/public/projects/details/archive.png b/public/projects/details/archive.png deleted file mode 100644 index 705e7a6c..00000000 Binary files a/public/projects/details/archive.png and /dev/null differ diff --git a/public/projects/details/avocado.png b/public/projects/details/avocado.png deleted file mode 100644 index daee00d8..00000000 Binary files a/public/projects/details/avocado.png and /dev/null differ diff --git a/public/projects/details/bboxx.png b/public/projects/details/bboxx.png deleted file mode 100644 index 1284ee86..00000000 Binary files a/public/projects/details/bboxx.png and /dev/null differ diff --git a/public/projects/details/bodymood.png b/public/projects/details/bodymood.png deleted file mode 100644 index 95207497..00000000 Binary files a/public/projects/details/bodymood.png and /dev/null differ diff --git a/public/projects/details/hush.png b/public/projects/details/hush.png deleted file mode 100644 index fb7b0563..00000000 Binary files a/public/projects/details/hush.png and /dev/null differ diff --git a/public/projects/details/imgoing.png b/public/projects/details/imgoing.png deleted file mode 100644 index 8efd285f..00000000 Binary files a/public/projects/details/imgoing.png and /dev/null differ diff --git a/public/projects/details/noonbody.png b/public/projects/details/noonbody.png deleted file mode 100644 index 3e22735c..00000000 Binary files a/public/projects/details/noonbody.png and /dev/null differ diff --git a/public/projects/details/omo.png b/public/projects/details/omo.png deleted file mode 100644 index 76f637d0..00000000 Binary files a/public/projects/details/omo.png and /dev/null differ diff --git a/public/projects/details/therto.png b/public/projects/details/therto.png deleted file mode 100644 index c78fa6da..00000000 Binary files a/public/projects/details/therto.png and /dev/null differ diff --git a/public/projects/details/tooni.png b/public/projects/details/tooni.png deleted file mode 100644 index 3986e2ec..00000000 Binary files a/public/projects/details/tooni.png and /dev/null differ diff --git "a/public/projects/details/\352\260\200\354\212\264\354\206\2153\354\262\234\354\233\220.png" "b/public/projects/details/\352\260\200\354\212\264\354\206\2153\354\262\234\354\233\220.png" deleted file mode 100644 index 9ab1ff76..00000000 Binary files "a/public/projects/details/\352\260\200\354\212\264\354\206\2153\354\262\234\354\233\220.png" and /dev/null differ diff --git "a/public/projects/details/\352\260\234\353\257\270\353\212\224\355\210\260\355\210\260.png" "b/public/projects/details/\352\260\234\353\257\270\353\212\224\355\210\260\355\210\260.png" deleted file mode 100644 index a21ae59c..00000000 Binary files "a/public/projects/details/\352\260\234\353\257\270\353\212\224\355\210\260\355\210\260.png" and /dev/null differ diff --git "a/public/projects/details/\352\274\254\352\271\203.png" "b/public/projects/details/\352\274\254\352\271\203.png" deleted file mode 100644 index 4dfe436f..00000000 Binary files "a/public/projects/details/\352\274\254\352\271\203.png" and /dev/null differ diff --git "a/public/projects/details/\353\202\230\353\202\230\352\263\265.png" "b/public/projects/details/\353\202\230\353\202\230\352\263\265.png" deleted file mode 100644 index 6394c279..00000000 Binary files "a/public/projects/details/\353\202\230\353\202\230\352\263\265.png" and /dev/null differ diff --git "a/public/projects/details/\353\214\200\353\217\231\353\271\265\354\247\200\353\217\204.png" "b/public/projects/details/\353\214\200\353\217\231\353\271\265\354\247\200\353\217\204.png" deleted file mode 100644 index 84803c61..00000000 Binary files "a/public/projects/details/\353\214\200\353\217\231\353\271\265\354\247\200\353\217\204.png" and /dev/null differ diff --git "a/public/projects/details/\353\230\221\354\212\244.png" "b/public/projects/details/\353\230\221\354\212\244.png" deleted file mode 100644 index 25851a18..00000000 Binary files "a/public/projects/details/\353\230\221\354\212\244.png" and /dev/null differ diff --git "a/public/projects/details/\353\234\273\353\260\226\354\235\230\355\200\264\354\246\210.png" "b/public/projects/details/\353\234\273\353\260\226\354\235\230\355\200\264\354\246\210.png" deleted file mode 100644 index 05489aa5..00000000 Binary files "a/public/projects/details/\353\234\273\353\260\226\354\235\230\355\200\264\354\246\210.png" and /dev/null differ diff --git "a/public/projects/details/\353\247\201\355\201\254\354\244\215\354\244\215.png" "b/public/projects/details/\353\247\201\355\201\254\354\244\215\354\244\215.png" deleted file mode 100644 index 6cc84100..00000000 Binary files "a/public/projects/details/\353\247\201\355\201\254\354\244\215\354\244\215.png" and /dev/null differ diff --git "a/public/projects/details/\353\247\210\354\235\264\353\240\210\354\213\234\355\224\275.png" "b/public/projects/details/\353\247\210\354\235\264\353\240\210\354\213\234\355\224\275.png" deleted file mode 100644 index ecfac565..00000000 Binary files "a/public/projects/details/\353\247\210\354\235\264\353\240\210\354\213\234\355\224\275.png" and /dev/null differ diff --git "a/public/projects/details/\353\252\275\354\213\244.png" "b/public/projects/details/\353\252\275\354\213\244.png" deleted file mode 100644 index 67d620b1..00000000 Binary files "a/public/projects/details/\353\252\275\354\213\244.png" and /dev/null differ diff --git "a/public/projects/details/\353\254\264\353\223\234\355\224\275.png" "b/public/projects/details/\353\254\264\353\223\234\355\224\275.png" deleted file mode 100644 index cb391b37..00000000 Binary files "a/public/projects/details/\353\254\264\353\223\234\355\224\275.png" and /dev/null differ diff --git "a/public/projects/details/\353\260\224\355\206\265.png" "b/public/projects/details/\353\260\224\355\206\265.png" deleted file mode 100644 index 63ae5f1b..00000000 Binary files "a/public/projects/details/\353\260\224\355\206\265.png" and /dev/null differ diff --git "a/public/projects/details/\353\266\201\354\252\275\354\234\274\353\241\234.png" "b/public/projects/details/\353\266\201\354\252\275\354\234\274\353\241\234.png" deleted file mode 100644 index a26e17b8..00000000 Binary files "a/public/projects/details/\353\266\201\354\252\275\354\234\274\353\241\234.png" and /dev/null differ diff --git "a/public/projects/details/\353\271\204\354\226\264\354\227\220\354\226\264.png" "b/public/projects/details/\353\271\204\354\226\264\354\227\220\354\226\264.png" deleted file mode 100644 index a8669786..00000000 Binary files "a/public/projects/details/\353\271\204\354\226\264\354\227\220\354\226\264.png" and /dev/null differ diff --git "a/public/projects/details/\354\225\204\353\247\236\353\213\244.png" "b/public/projects/details/\354\225\204\353\247\236\353\213\244.png" deleted file mode 100644 index 4bbfb52d..00000000 Binary files "a/public/projects/details/\354\225\204\353\247\236\353\213\244.png" and /dev/null differ diff --git "a/public/projects/details/\354\225\204\353\254\264\352\261\260\353\202\230.png" "b/public/projects/details/\354\225\204\353\254\264\352\261\260\353\202\230.png" deleted file mode 100644 index 013ff974..00000000 Binary files "a/public/projects/details/\354\225\204\353\254\264\352\261\260\353\202\230.png" and /dev/null differ diff --git "a/public/projects/details/\354\230\201\352\260\220\355\203\261.png" "b/public/projects/details/\354\230\201\352\260\220\355\203\261.png" deleted file mode 100644 index 68196d83..00000000 Binary files "a/public/projects/details/\354\230\201\352\260\220\355\203\261.png" and /dev/null differ diff --git "a/public/projects/details/\354\230\201\354\260\250.png" "b/public/projects/details/\354\230\201\354\260\250.png" deleted file mode 100644 index 36e57243..00000000 Binary files "a/public/projects/details/\354\230\201\354\260\250.png" and /dev/null differ diff --git "a/public/projects/details/\354\230\244\353\212\230\354\235\230\355\205\214\354\212\244\355\212\270.png" "b/public/projects/details/\354\230\244\353\212\230\354\235\230\355\205\214\354\212\244\355\212\270.png" deleted file mode 100644 index 731e9a5f..00000000 Binary files "a/public/projects/details/\354\230\244\353\212\230\354\235\230\355\205\214\354\212\244\355\212\270.png" and /dev/null differ diff --git "a/public/projects/details/\354\230\244\353\247\265\353\225\241.png" "b/public/projects/details/\354\230\244\353\247\265\353\225\241.png" deleted file mode 100644 index 8c7290fd..00000000 Binary files "a/public/projects/details/\354\230\244\353\247\265\353\225\241.png" and /dev/null differ diff --git "a/public/projects/details/\354\240\234\353\241\234\354\232\260\354\245\254.png" "b/public/projects/details/\354\240\234\353\241\234\354\232\260\354\245\254.png" deleted file mode 100644 index fb76108b..00000000 Binary files "a/public/projects/details/\354\240\234\353\241\234\354\232\260\354\245\254.png" and /dev/null differ diff --git "a/public/projects/details/\354\247\235\354\213\254\354\202\274\354\235\274.png" "b/public/projects/details/\354\247\235\354\213\254\354\202\274\354\235\274.png" deleted file mode 100644 index 74c396a2..00000000 Binary files "a/public/projects/details/\354\247\235\354\213\254\354\202\274\354\235\274.png" and /dev/null differ diff --git "a/public/projects/details/\354\271\274\355\207\264\354\232\224\354\240\225.png" "b/public/projects/details/\354\271\274\355\207\264\354\232\224\354\240\225.png" deleted file mode 100644 index 586e6368..00000000 Binary files "a/public/projects/details/\354\271\274\355\207\264\354\232\224\354\240\225.png" and /dev/null differ diff --git "a/public/projects/details/\354\275\224\355\200\204\353\246\254\355\213\260.png" "b/public/projects/details/\354\275\224\355\200\204\353\246\254\355\213\260.png" deleted file mode 100644 index 10a83b8d..00000000 Binary files "a/public/projects/details/\354\275\224\355\200\204\353\246\254\355\213\260.png" and /dev/null differ diff --git "a/public/projects/details/\354\277\250\355\224\274\354\212\244.png" "b/public/projects/details/\354\277\250\355\224\274\354\212\244.png" deleted file mode 100644 index e7bcaaec..00000000 Binary files "a/public/projects/details/\354\277\250\355\224\274\354\212\244.png" and /dev/null differ diff --git "a/public/projects/details/\355\201\254\353\236\230\354\273\244\353\266\201.png" "b/public/projects/details/\355\201\254\353\236\230\354\273\244\353\266\201.png" deleted file mode 100644 index 51cdabcc..00000000 Binary files "a/public/projects/details/\355\201\254\353\236\230\354\273\244\353\266\201.png" and /dev/null differ diff --git "a/public/projects/details/\355\213\260\355\202\244\355\203\200\354\271\264.png" "b/public/projects/details/\355\213\260\355\202\244\355\203\200\354\271\264.png" deleted file mode 100644 index e1f5dacd..00000000 Binary files "a/public/projects/details/\355\213\260\355\202\244\355\203\200\354\271\264.png" and /dev/null differ diff --git "a/public/projects/details/\355\216\230\354\226\264\353\237\254.png" "b/public/projects/details/\355\216\230\354\226\264\353\237\254.png" deleted file mode 100644 index b85ed187..00000000 Binary files "a/public/projects/details/\355\216\230\354\226\264\353\237\254.png" and /dev/null differ diff --git "a/public/projects/icons/3\353\214\200\354\226\274\353\247\210.png" "b/public/projects/icons/3\353\214\200\354\226\274\353\247\210.png" deleted file mode 100644 index 9e123dcf..00000000 Binary files "a/public/projects/icons/3\353\214\200\354\226\274\353\247\210.png" and /dev/null differ diff --git a/public/projects/icons/archive.png b/public/projects/icons/archive.png deleted file mode 100644 index 34e53a4d..00000000 Binary files a/public/projects/icons/archive.png and /dev/null differ diff --git a/public/projects/icons/avocado.png b/public/projects/icons/avocado.png deleted file mode 100644 index f20345f1..00000000 Binary files a/public/projects/icons/avocado.png and /dev/null differ diff --git a/public/projects/icons/bboxx.png b/public/projects/icons/bboxx.png deleted file mode 100644 index 379c54a3..00000000 Binary files a/public/projects/icons/bboxx.png and /dev/null differ diff --git a/public/projects/icons/bodymood.png b/public/projects/icons/bodymood.png deleted file mode 100644 index dd18545c..00000000 Binary files a/public/projects/icons/bodymood.png and /dev/null differ diff --git a/public/projects/icons/hush.png b/public/projects/icons/hush.png deleted file mode 100644 index e159e838..00000000 Binary files a/public/projects/icons/hush.png and /dev/null differ diff --git a/public/projects/icons/imgoing.png b/public/projects/icons/imgoing.png deleted file mode 100644 index b8c8dd98..00000000 Binary files a/public/projects/icons/imgoing.png and /dev/null differ diff --git a/public/projects/icons/noonbody.png b/public/projects/icons/noonbody.png deleted file mode 100644 index e12e3912..00000000 Binary files a/public/projects/icons/noonbody.png and /dev/null differ diff --git a/public/projects/icons/omo.png b/public/projects/icons/omo.png deleted file mode 100644 index c5dab9d4..00000000 Binary files a/public/projects/icons/omo.png and /dev/null differ diff --git a/public/projects/icons/therto.png b/public/projects/icons/therto.png deleted file mode 100644 index 6453092d..00000000 Binary files a/public/projects/icons/therto.png and /dev/null differ diff --git a/public/projects/icons/tooni.png b/public/projects/icons/tooni.png deleted file mode 100644 index adef6c93..00000000 Binary files a/public/projects/icons/tooni.png and /dev/null differ diff --git "a/public/projects/icons/\352\260\200\354\212\264\354\206\2153\354\262\234\354\233\220.png" "b/public/projects/icons/\352\260\200\354\212\264\354\206\2153\354\262\234\354\233\220.png" deleted file mode 100644 index 6bc10f3a..00000000 Binary files "a/public/projects/icons/\352\260\200\354\212\264\354\206\2153\354\262\234\354\233\220.png" and /dev/null differ diff --git "a/public/projects/icons/\352\260\234\353\257\270\353\212\224\355\210\260\355\210\260.png" "b/public/projects/icons/\352\260\234\353\257\270\353\212\224\355\210\260\355\210\260.png" deleted file mode 100644 index bae75a7f..00000000 Binary files "a/public/projects/icons/\352\260\234\353\257\270\353\212\224\355\210\260\355\210\260.png" and /dev/null differ diff --git "a/public/projects/icons/\353\202\230\353\202\230\352\263\265.png" "b/public/projects/icons/\353\202\230\353\202\230\352\263\265.png" deleted file mode 100644 index bcf68ea2..00000000 Binary files "a/public/projects/icons/\353\202\230\353\202\230\352\263\265.png" and /dev/null differ diff --git "a/public/projects/icons/\353\214\200\353\217\231\353\271\265\354\247\200\353\217\204.png" "b/public/projects/icons/\353\214\200\353\217\231\353\271\265\354\247\200\353\217\204.png" deleted file mode 100644 index b77e614c..00000000 Binary files "a/public/projects/icons/\353\214\200\353\217\231\353\271\265\354\247\200\353\217\204.png" and /dev/null differ diff --git "a/public/projects/icons/\353\234\273\353\260\226\354\235\230\355\200\264\354\246\210.png" "b/public/projects/icons/\353\234\273\353\260\226\354\235\230\355\200\264\354\246\210.png" deleted file mode 100644 index 05724adc..00000000 Binary files "a/public/projects/icons/\353\234\273\353\260\226\354\235\230\355\200\264\354\246\210.png" and /dev/null differ diff --git "a/public/projects/icons/\353\247\201\355\201\254\354\244\215\354\244\215.png" "b/public/projects/icons/\353\247\201\355\201\254\354\244\215\354\244\215.png" deleted file mode 100644 index 3e84df0a..00000000 Binary files "a/public/projects/icons/\353\247\201\355\201\254\354\244\215\354\244\215.png" and /dev/null differ diff --git "a/public/projects/icons/\353\247\210\354\235\264\353\240\210\354\213\234\355\224\275.png" "b/public/projects/icons/\353\247\210\354\235\264\353\240\210\354\213\234\355\224\275.png" deleted file mode 100644 index 2044dcb9..00000000 Binary files "a/public/projects/icons/\353\247\210\354\235\264\353\240\210\354\213\234\355\224\275.png" and /dev/null differ diff --git "a/public/projects/icons/\353\252\275\354\213\244.png" "b/public/projects/icons/\353\252\275\354\213\244.png" deleted file mode 100644 index 47f998c2..00000000 Binary files "a/public/projects/icons/\353\252\275\354\213\244.png" and /dev/null differ diff --git "a/public/projects/icons/\353\254\264\353\223\234\355\224\275.png" "b/public/projects/icons/\353\254\264\353\223\234\355\224\275.png" deleted file mode 100644 index 3a4b8943..00000000 Binary files "a/public/projects/icons/\353\254\264\353\223\234\355\224\275.png" and /dev/null differ diff --git "a/public/projects/icons/\353\260\224\355\206\265.png" "b/public/projects/icons/\353\260\224\355\206\265.png" deleted file mode 100644 index f3dc1e2f..00000000 Binary files "a/public/projects/icons/\353\260\224\355\206\265.png" and /dev/null differ diff --git "a/public/projects/icons/\353\266\201\354\252\275\354\234\274\353\241\234.png" "b/public/projects/icons/\353\266\201\354\252\275\354\234\274\353\241\234.png" deleted file mode 100644 index 8d3a5564..00000000 Binary files "a/public/projects/icons/\353\266\201\354\252\275\354\234\274\353\241\234.png" and /dev/null differ diff --git "a/public/projects/icons/\353\271\204\354\226\264\354\227\220\354\226\264.png" "b/public/projects/icons/\353\271\204\354\226\264\354\227\220\354\226\264.png" deleted file mode 100644 index 11754e88..00000000 Binary files "a/public/projects/icons/\353\271\204\354\226\264\354\227\220\354\226\264.png" and /dev/null differ diff --git "a/public/projects/icons/\354\225\204\353\254\264\352\261\260\353\202\230.png" "b/public/projects/icons/\354\225\204\353\254\264\352\261\260\353\202\230.png" deleted file mode 100644 index c777cf3d..00000000 Binary files "a/public/projects/icons/\354\225\204\353\254\264\352\261\260\353\202\230.png" and /dev/null differ diff --git "a/public/projects/icons/\354\230\201\352\260\220\355\203\261.png" "b/public/projects/icons/\354\230\201\352\260\220\355\203\261.png" deleted file mode 100644 index 6e7abacd..00000000 Binary files "a/public/projects/icons/\354\230\201\352\260\220\355\203\261.png" and /dev/null differ diff --git "a/public/projects/icons/\354\230\201\354\260\250.png" "b/public/projects/icons/\354\230\201\354\260\250.png" deleted file mode 100644 index 3f8eced0..00000000 Binary files "a/public/projects/icons/\354\230\201\354\260\250.png" and /dev/null differ diff --git "a/public/projects/icons/\354\230\244\353\212\230\354\235\230\355\205\214\354\212\244\355\212\270.png" "b/public/projects/icons/\354\230\244\353\212\230\354\235\230\355\205\214\354\212\244\355\212\270.png" deleted file mode 100644 index b10abde4..00000000 Binary files "a/public/projects/icons/\354\230\244\353\212\230\354\235\230\355\205\214\354\212\244\355\212\270.png" and /dev/null differ diff --git "a/public/projects/icons/\354\230\244\353\247\265\353\225\241.png" "b/public/projects/icons/\354\230\244\353\247\265\353\225\241.png" deleted file mode 100644 index b08dbf6b..00000000 Binary files "a/public/projects/icons/\354\230\244\353\247\265\353\225\241.png" and /dev/null differ diff --git "a/public/projects/icons/\354\240\234\353\241\234\354\232\260\354\245\254.png" "b/public/projects/icons/\354\240\234\353\241\234\354\232\260\354\245\254.png" deleted file mode 100644 index 4db0b1fd..00000000 Binary files "a/public/projects/icons/\354\240\234\353\241\234\354\232\260\354\245\254.png" and /dev/null differ diff --git "a/public/projects/icons/\354\271\274\355\207\264\354\232\224\354\240\225.png" "b/public/projects/icons/\354\271\274\355\207\264\354\232\224\354\240\225.png" deleted file mode 100644 index 91830bc7..00000000 Binary files "a/public/projects/icons/\354\271\274\355\207\264\354\232\224\354\240\225.png" and /dev/null differ diff --git "a/public/projects/icons/\354\277\250\355\224\274\354\212\244.png" "b/public/projects/icons/\354\277\250\355\224\274\354\212\244.png" deleted file mode 100644 index 91ef23fb..00000000 Binary files "a/public/projects/icons/\354\277\250\355\224\274\354\212\244.png" and /dev/null differ diff --git "a/public/projects/icons/\355\201\254\353\236\230\354\273\244\353\266\201.png" "b/public/projects/icons/\355\201\254\353\236\230\354\273\244\353\266\201.png" deleted file mode 100644 index d6e69f5c..00000000 Binary files "a/public/projects/icons/\355\201\254\353\236\230\354\273\244\353\266\201.png" and /dev/null differ diff --git "a/public/projects/icons/\355\213\260\355\202\244\355\203\200\354\271\264.png" "b/public/projects/icons/\355\213\260\355\202\244\355\203\200\354\271\264.png" deleted file mode 100644 index 50aebc22..00000000 Binary files "a/public/projects/icons/\355\213\260\355\202\244\355\203\200\354\271\264.png" and /dev/null differ diff --git "a/public/projects/icons/\355\216\230\354\226\264\353\237\254.png" "b/public/projects/icons/\355\216\230\354\226\264\353\237\254.png" deleted file mode 100644 index 975a77b1..00000000 Binary files "a/public/projects/icons/\355\216\230\354\226\264\353\237\254.png" and /dev/null differ diff --git a/public/sitemap-0.xml b/public/sitemap-0.xml index a2ff25f7..7c8b112d 100644 --- a/public/sitemap-0.xml +++ b/public/sitemap-0.xml @@ -5,51 +5,4 @@ https://www.depromeet.com/contact2023-03-05T16:02:03.395Zdaily0.7 https://www.depromeet.com/project2023-03-05T16:02:03.395Zdaily0.7 https://www.depromeet.com/recruit2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/recruit/ios2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/recruit/android2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/recruit/web2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/recruit/backend2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/recruit/design2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/짝심삼일2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/KNOCKNOCK2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/TICLEMOA2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/똑스2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/코퀄리티2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/아맞다2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/PING-PONG!2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/꼬깃2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/비어에어2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/영감탱2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/바통2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/무드픽2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/티키타카2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/몽실2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/페어러2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/개미는 툰툰2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/noonbody2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/IMGOING2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/BBOXX2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/나나공2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/Archive2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/대동빵지도2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/오맵땡2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/Bodymood2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/OMO2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/영차2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/TOONI TOONI2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/마이레시픽2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/오늘의 테스트2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/Hush2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/링크줍줍2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/제로우쥬2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/크래커북2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/3대 얼마2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/가슴속 3천원2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/북쪽으로2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/Avocado2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/Therto2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/쿨피스2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/칼퇴요정2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/아무거나2023-03-05T16:02:03.395Zdaily0.7 -https://www.depromeet.com/project/뜻밖의 퀴즈2023-03-05T16:02:03.395Zdaily0.7 \ No newline at end of file diff --git a/public/svg/icon-android.svg b/public/svg/icon-android.svg deleted file mode 100644 index 630a8ef1..00000000 --- a/public/svg/icon-android.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/public/svg/icon-backend.svg b/public/svg/icon-backend.svg deleted file mode 100644 index b49a9fda..00000000 --- a/public/svg/icon-backend.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/public/svg/icon-design.svg b/public/svg/icon-design.svg deleted file mode 100644 index 0b5a22e5..00000000 --- a/public/svg/icon-design.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/public/svg/icon-designer.svg b/public/svg/icon-designer.svg deleted file mode 100644 index 1e074e8b..00000000 --- a/public/svg/icon-designer.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/public/svg/icon-developer.svg b/public/svg/icon-developer.svg deleted file mode 100644 index 84360ace..00000000 --- a/public/svg/icon-developer.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/public/svg/icon-hand-shake.svg b/public/svg/icon-hand-shake.svg deleted file mode 100644 index 0e198aad..00000000 --- a/public/svg/icon-hand-shake.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/public/svg/icon-ios.svg b/public/svg/icon-ios.svg deleted file mode 100644 index 483f3d3a..00000000 --- a/public/svg/icon-ios.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/public/svg/icon-web.svg b/public/svg/icon-web.svg deleted file mode 100644 index 7bf245e6..00000000 --- a/public/svg/icon-web.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/@types/emotion.d.ts b/src/@types/emotion.d.ts new file mode 100644 index 00000000..d2b2d9df --- /dev/null +++ b/src/@types/emotion.d.ts @@ -0,0 +1,9 @@ +import '@emotion/react'; + +import { theme } from '~/styles/theme'; + +declare module '@emotion/react' { + type CustomTheme = typeof theme; + + export interface Theme extends CustomTheme {} +} diff --git a/src/components/AboutInfo/AboutInfo.tsx b/src/components/AboutInfo/AboutInfo.tsx new file mode 100644 index 00000000..6d779258 --- /dev/null +++ b/src/components/AboutInfo/AboutInfo.tsx @@ -0,0 +1,152 @@ +import Image from 'next/image'; +import { css, Theme } from '@emotion/react'; + +import { ABOUT_INFO } from '~/constant/aboutInfo'; +import { commonLayoutCss } from '~/styles/layout'; +import { mediaQuery } from '~/styles/media'; +import { pxToRem } from '~/styles/style.utils'; + +export function AboutInfo() { + return ( +
+
+

{'IT 사이드 프로젝트의 시작\n디프만의 열정적인 여정에 합류하세요'}

+
+ +
+ ); +} + +const layoutCss = css` + margin-top: 200px; + white-space: pre-line; + display: flex; + flex-direction: column; + align-items: center; + ${mediaQuery('pc')} { + margin-top: 200px; + } + + ${mediaQuery('mobile')} { + margin-top: 20px; + } +`; + +const headerCss = (theme: Theme) => css` + font-size: ${pxToRem(40)}; + color: ${theme.colors.white}; + text-align: center; + line-height: 56px; /* 140% */ + letter-spacing: -0.4px; + ${mediaQuery('mobile')} { + font-size: ${pxToRem(20)}; + line-height: 150%; /* 30px */ + letter-spacing: -0.2px; + } +`; + +const aboutBodyCss = css` + display: flex; + flex-direction: column; + margin-top: 200px; + gap: 24px; + ${mediaQuery('tablet')} { + margin-top: 100px; + gap: 57px; + } + ${mediaQuery('mobile')} { + margin-top: 100px; + gap: 50px; + } +`; + +const aboutItemCss = (reverse: boolean) => css` + display: flex; + gap: 24px; + align-items: center; + justify-content: center; + ${reverse && + css` + padding-left: 80px; + + ${mediaQuery('tablet')} { + padding-left: 34px; + } + ${mediaQuery('mobile')} { + padding-left: 0; + } + `} + ${mediaQuery('mobile')} { + flex-direction: column; + gap: 20px; + text-align: center; + ${reverse && 'flex-direction: column-reverse;'} + } +`; + +const aboutInfoCss = css` + display: flex; + flex-direction: column; + gap: 24px; +`; + +const imageCss = css` + position: relative; + width: 400px; + height: 400px; + object-fit: cover; + object-position: center; + + ${mediaQuery('tablet')} { + width: 270px; + height: 270px; + + img { + object-fit: inherit; + } + } + + ${mediaQuery('mobile')} { + width: 220px; + height: 220px; + } +`; + +const aboutTitleCss = (theme: Theme) => css` + ${theme.typos.pretendard.subTitle1}; + color: ${theme.colors.white}; +`; + +const aboutDescriptionCss = (theme: Theme) => css` + ${theme.typos.pretendard.subTitle2}; + color: ${theme.colors.gray100}; + ${mediaQuery('mobile')} { + letter-spacing: ${pxToRem(-0.14)}; + } +`; diff --git a/src/components/AboutInfo/index.tsx b/src/components/AboutInfo/index.tsx new file mode 100644 index 00000000..ba7d7047 --- /dev/null +++ b/src/components/AboutInfo/index.tsx @@ -0,0 +1 @@ +export { AboutInfo } from './AboutInfo'; diff --git a/src/components/Button/Button.stories.tsx b/src/components/Button/Button.stories.tsx new file mode 100644 index 00000000..2475fede --- /dev/null +++ b/src/components/Button/Button.stories.tsx @@ -0,0 +1,36 @@ +import { css } from '@emotion/react'; +import type { Meta, StoryObj } from '@storybook/react'; + +import { Button } from './index'; + +const meta: Meta = { + title: 'components/Button', + component: Button, + args: {}, +}; + +export default meta; + +type Story = StoryObj; + +export const Primary: Story = { + render: () => ( +
+ + + + +
+ ), +}; + +const containerCss = css` + background-color: black; + padding: 20px; + + & > * { + margin-bottom: 20px; + } +`; diff --git a/src/components/Button/Button.tsx b/src/components/Button/Button.tsx new file mode 100644 index 00000000..9ec6e216 --- /dev/null +++ b/src/components/Button/Button.tsx @@ -0,0 +1,63 @@ +import { ButtonHTMLAttributes } from 'react'; +import { css, Interpolation, Theme } from '@emotion/react'; + +import { mediaQuery } from '~/styles/media'; + +type ButtonSize = 'md' | 'lg'; +export interface ButtonProps extends ButtonHTMLAttributes { + size?: ButtonSize; + overrideCss?: Interpolation; +} + +export function Button({ children, size = 'md', overrideCss, ...props }: ButtonProps) { + return ( + + ); +} + +const buttonCss = (theme: Theme, size: ButtonSize) => css` + ${theme.typos.pretendard.body1}; + background-color: ${theme.colors.yellow500}; + color: ${theme.colors.black800}; + display: block; + + ${size === 'md' && + css` + padding: 0 24px; + height: 42px; + + ${mediaQuery('mobile')} { + font-size: 14px; + height: 34px; + } + `} + + ${size === 'lg' && + css` + width: 100%; + padding: 0 24px; + height: 54px; + + ${mediaQuery('mobile')} { + ${theme.typos.pretendard.body2}; + height: 42px; + } + `} + + + &:hover { + background-color: ${theme.colors.yellow400}; + } + + &:active { + background-color: ${theme.colors.yellow300}; + } + + &:disabled { + background-color: ${theme.colors.gray300}; + color: ${theme.colors.gray100}; + cursor: not-allowed; + } +`; diff --git a/src/components/Button/index.ts b/src/components/Button/index.ts new file mode 100644 index 00000000..fe9c53c5 --- /dev/null +++ b/src/components/Button/index.ts @@ -0,0 +1 @@ +export { Button } from './Button'; diff --git a/src/components/Contact/Contact.tsx b/src/components/Contact/Contact.tsx new file mode 100644 index 00000000..c2dc9385 --- /dev/null +++ b/src/components/Contact/Contact.tsx @@ -0,0 +1,76 @@ +import Link from 'next/link'; +import { css, Theme } from '@emotion/react'; + +import { SectionTitle } from '~/components/SectionTitle'; +import { CONTACT_INFO } from '~/constant/contactInfo'; +import { commonLayoutCss } from '~/styles/layout'; +import { mediaQuery } from '~/styles/media'; + +export function Contact() { + return ( +
+ +
    + {CONTACT_INFO.map(footer => ( +
  • + + {footer.name} + {footer.detail} + +
  • + ))} +
+
+ ); +} + +const layoutCss = css` + margin-top: 150px; + margin-bottom: 150px; + ${mediaQuery('tablet')} { + margin-top: 150px; + margin-bottom: 150px; + } + ${mediaQuery('mobile')} { + margin-top: 100px; + margin-bottom: 100px; + } +`; + +const infoListCss = css` + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 20px; + ${mediaQuery('mobile')} { + gap: 10px; + } +`; + +const InfoCss = (theme: Theme) => css` + ${theme.typos.pretendard.body1}; + background-color: ${theme.colors.black400}; + color: ${theme.colors.gray20}; + width: 470px; + height: 172px; + padding: 48px 36px; + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: flex-start; + gap: 20px; + ${mediaQuery('tablet')} { + width: 100%; + } + + ${mediaQuery('mobile')} { + font-size: 0.8rem; + width: 100%; + height: 96px; + padding: 16px 8px; + } +`; + +const infoNameCss = (theme: Theme) => css` + ${theme.typos.decimal.subTitle1}; + color: ${theme.colors.blue300}; +`; diff --git a/src/components/Contact/index.tsx b/src/components/Contact/index.tsx new file mode 100644 index 00000000..5817bd12 --- /dev/null +++ b/src/components/Contact/index.tsx @@ -0,0 +1 @@ +export { Contact } from './Contact'; diff --git a/src/components/FAQ/FAQ.stories.tsx b/src/components/FAQ/FAQ.stories.tsx new file mode 100644 index 00000000..bae1e90f --- /dev/null +++ b/src/components/FAQ/FAQ.stories.tsx @@ -0,0 +1,68 @@ +/* eslint-disable react-hooks/rules-of-hooks */ +import { useState } from 'react'; +import { Meta } from '@storybook/react'; + +import { FAQItem } from '~/components/FAQ/FAQItem'; +import { FAQList } from '~/components/FAQ/FAQList'; +import { FAQS } from '~/constant/faq'; + +import { FAQ } from './index'; + +const meta: Meta = { + title: 'components/FAQ', +}; + +export default meta; + +export const Primary = { + render: () => ( +
+ +
+ ), +}; + +export const List = { + render: () => , +}; + +export const Interaction = { + render: () => { + const [isOpen, setIsOpen] = useState(false); + + const onClickOpenButton = () => { + setIsOpen(prev => !prev); + }; + + return ( + + ); + }, +}; + +export const Close = { + render: () => ( + {}} + question={FAQS[0].question} + answer={FAQS[0].answer} + /> + ), +}; + +export const Open = { + render: () => ( + {}} + question={FAQS[0].question} + answer={FAQS[0].answer} + /> + ), +}; diff --git a/src/components/FAQ/FAQ.tsx b/src/components/FAQ/FAQ.tsx new file mode 100644 index 00000000..b9f88de0 --- /dev/null +++ b/src/components/FAQ/FAQ.tsx @@ -0,0 +1,73 @@ +import { useState } from 'react'; +import { css, Theme } from '@emotion/react'; + +import { FAQList } from '~/components/FAQ/FAQList'; +import { SectionTitle } from '~/components/SectionTitle'; +import { FAQ_GROUP, FAQGroupType, FAQS } from '~/constant/faq'; +import { commonLayoutCss } from '~/styles/layout'; +import { mediaQuery } from '~/styles/media'; + +export function FAQ() { + const [activeTab, setActiveTab] = useState('지원자격'); + + const onClickTab = (target: FAQGroupType) => { + setActiveTab(target); + }; + + const isActive = (target: FAQGroupType) => activeTab === target; + + return ( +
+ +
    + {FAQ_GROUP.map(label => ( +
  • onClickTab(label)} + css={theme => tabCss(theme, isActive(label))} + > + {label} +
  • + ))} +
+ {activeTab === '지원자격' && } + {activeTab === '면접' && } + {activeTab === '활동' && } +
+ ); +} + +const 지원자격질문들 = FAQS.filter(x => x.group === '지원자격'); + +const 면접질문들 = FAQS.filter(x => x.group === '면접'); + +const 활동질문들 = FAQS.filter(x => x.group === '활동'); + +const layoutCss = css` + ${commonLayoutCss} + display: flex; + flex-direction: column; + gap: 16px; +`; + +const tabLayoutCss = css` + display: flex; + > li:first-child { + padding-left: 0px; + } + ${mediaQuery('tablet')} { + justify-content: center; + } +`; + +const tabCss = (theme: Theme, isActive: boolean) => css` + ${theme.typos.pretendard.subTitle2} + color: ${isActive ? theme.colors.yellow500 : theme.colors.white}; + cursor: pointer; + padding: 16px 24px; + + ${mediaQuery('mobile')} { + font-size: 14px; + padding: 8px 12px; + } +`; diff --git a/src/components/FAQ/FAQItem.tsx b/src/components/FAQ/FAQItem.tsx new file mode 100644 index 00000000..79abeb39 --- /dev/null +++ b/src/components/FAQ/FAQItem.tsx @@ -0,0 +1,108 @@ +import { css, Theme } from '@emotion/react'; +import { motion, Variants } from 'framer-motion'; + +import { ArrowIcon } from '~/components/Icons'; +import { mediaQuery } from '~/styles/media'; +import { theme } from '~/styles/theme'; + +interface FAQItemProps { + isOpen: boolean; + onClickOpenButton: () => void; + question: string; + answer: string; +} + +export function FAQItem({ isOpen, onClickOpenButton, question, answer }: FAQItemProps) { + return ( +
  • + headerCss(theme, isOpen)} + animate={isOpen ? 'open' : 'closed'} + variants={headerVariants} + transition={{ duration: 0.3, ease: 'easeOut' }} + onClick={onClickOpenButton} + > +

    {question}

    + + arrowIconCss(theme, isOpen)} + /> + +
    + +

    {answer}

    +
    +
  • + ); +} + +const headerVariants: Variants = { + open: { backgroundColor: theme.colors.blue400 }, + closed: { backgroundColor: theme.colors.black400 }, +}; + +const bodyVariants: Variants = { + initial: { opacity: 0, height: 0, display: 'none' }, + open: { opacity: 1, height: 'fit-content', display: 'block' }, + closed: { opacity: 0, height: 0, display: 'none' }, +}; + +const arrowIconVariants: Variants = { + open: { stroke: theme.colors.black800 }, + closed: { stroke: theme.colors.blue400 }, +}; + +const headerCss = (theme: Theme, isOpen: boolean) => css` + background-color: ${isOpen ? theme.colors.blue400 : theme.colors.black400}; + display: flex; + justify-content: space-between; + align-items: center; + padding: 25px 30px; + cursor: pointer; + > h3 { + color: ${isOpen ? theme.colors.black800 : theme.colors.white}; + text-align: center; + ${theme.typos.pretendard.subTitle2} + } + + ${mediaQuery('mobile')} { + padding: 8px; + + > h3 { + font-weight: 500; + font-size: 14px; + } + } +`; + +const arrowIconCss = (theme: Theme, isOpen: boolean) => css` + > path { + stroke: ${isOpen ? theme.colors.black800 : theme.colors.blue400}; + } + + ${mediaQuery('mobile')} { + width: 24px; + height: 24px; + } +`; + +const bodyCss = (theme: Theme) => css` + background-color: ${theme.colors.black800}; + > p { + padding: 40px; + color: ${theme.colors.white}; + ${theme.typos.pretendard.body1}; + } + ${mediaQuery('mobile')} { + > p { + padding: 16px; + font-weight: 400; + } + } +`; diff --git a/src/components/FAQ/FAQList.tsx b/src/components/FAQ/FAQList.tsx new file mode 100644 index 00000000..48ab892e --- /dev/null +++ b/src/components/FAQ/FAQList.tsx @@ -0,0 +1,51 @@ +import { useEffect, useState } from 'react'; +import { css } from '@emotion/react'; + +import { FAQItem } from '~/components/FAQ/FAQItem'; +import { FAQType } from '~/constant/faq'; +import { mediaQuery } from '~/styles/media'; + +interface FAQListProps { + FAQList: FAQType[]; +} + +const DEFAULT_OPEN = 0; +const CLOSE = -1; + +export function FAQList({ FAQList }: FAQListProps) { + const [activeIndex, setActiveIndex] = useState(DEFAULT_OPEN); + + const onClickActiveFaq = (idx: number) => { + /** + * 열려 있는 아이템 다시 클릭하면 닫히게 하기 + */ + setActiveIndex(prev => (prev === idx ? CLOSE : idx)); + }; + + useEffect(() => { + setActiveIndex(DEFAULT_OPEN); + }, []); + + return ( +
      + {FAQList.map((item, index) => ( + onClickActiveFaq(index)} + {...item} + /> + ))} +
    + ); +} + +const containerCss = css` + display: flex; + flex-direction: column; + gap: 16px; + + ${mediaQuery('mobile')} { + gap: 8px; + } +`; diff --git a/src/components/FAQ/index.tsx b/src/components/FAQ/index.tsx new file mode 100644 index 00000000..f687bc95 --- /dev/null +++ b/src/components/FAQ/index.tsx @@ -0,0 +1 @@ +export { FAQ } from './FAQ'; diff --git a/src/components/Footer/Footer.tsx b/src/components/Footer/Footer.tsx new file mode 100644 index 00000000..5555d074 --- /dev/null +++ b/src/components/Footer/Footer.tsx @@ -0,0 +1,111 @@ +import Link from 'next/link'; +import { css, Theme } from '@emotion/react'; + +import { FIRST_ROW_FOOTER_INFOS, SECOND_ROW_FOOTER_INFOS } from '~/constant/contactInfo'; +import { colors } from '~/styles/colors'; +import { mediaQuery } from '~/styles/media'; + +export function Footer() { + return ( +
    +
    +
      + {FIRST_ROW_FOOTER_INFOS.map(footer => ( +
    • + + {footer.name} + +
    • + ))} +
    +
      + {SECOND_ROW_FOOTER_INFOS.map(footer => ( +
    • + + {footer.name} + {footer.detail} + +
    • + ))} +
    +

    © 2023 DEPROMEET. ALL RIGHTS RESERVED.

    +
    +
    + ); +} + +const footerCss = css` + background-color: ${colors.black800}; + padding: 0 20px; + width: 100vw; +`; + +const footerInfoWrapper = css` + max-width: 1240px; + margin: 0 auto; + display: flex; + flex-direction: column; + height: 218px; + justify-content: center; + align-items: center; + + ${mediaQuery('mobile')} { + height: 167px; + width: 100%; + } +`; + +const rowCss = css` + display: flex; + gap: 40px; + + ${mediaQuery('mobile')} { + width: 100%; + gap: 0; + justify-content: space-between; + } +`; + +const secondRowCss = css` + display: flex; + gap: 40px; + margin-top: 16px; + + span + span { + margin-left: 12px; + } + ${mediaQuery('mobile')} { + width: 100%; + gap: 40px; + justify-content: center; + margin-top: 8px; + + span + span { + margin-left: 16px; + } + } +`; + +const linkCss = (theme: Theme) => css` + ${theme.typos.pretendard.body1}; + color: ${theme.colors.gray100}; + + ${mediaQuery('mobile')} { + font-size: 11px; + } +`; + +const strongLinkCss = (theme: Theme) => css` + ${theme.typos.pretendard.subTitle2}; +`; + +const copyrightCss = (theme: Theme) => css` + ${theme.typos.pretendard.body1}; + color: ${theme.colors.gray200}; + margin-top: 40px; + + ${mediaQuery('mobile')} { + font-size: 11px; + margin-top: 24px; + } +`; diff --git a/src/components/Footer/index.ts b/src/components/Footer/index.ts new file mode 100644 index 00000000..65e2506f --- /dev/null +++ b/src/components/Footer/index.ts @@ -0,0 +1 @@ +export { Footer } from './Footer'; diff --git a/src/components/GNB/GNB.tsx b/src/components/GNB/GNB.tsx new file mode 100644 index 00000000..8bf7d940 --- /dev/null +++ b/src/components/GNB/GNB.tsx @@ -0,0 +1,162 @@ +import Image from 'next/image'; +import Link from 'next/link'; +import { useRouter } from 'next/router'; +import { css, Theme } from '@emotion/react'; +import { AnimatePresence } from 'framer-motion'; + +import { Button } from '~/components/Button'; +import { MobileMenu } from '~/components/GNB/MobileMenu'; +import { MobileMenuIcon } from '~/components/GNB/MobileMenuIcon'; +import { GNB_MENU_NAME, GNBMenu } from '~/constant/gnb'; +import { useDropDown } from '~/hooks/useDropdown'; +import useIsInProgress from '~/hooks/useIsInProgress'; +import { mediaQuery } from '~/styles/media'; + +const LOGO_IMAGE = `/images/logo.png`; + +function ApplyButton({ menu }: { menu: GNBMenu }) { + const { isInProgress } = useIsInProgress(); + const router = useRouter(); + + const onClick = () => { + router.push(menu.href); + }; + + return ( + + ); +} + +const linkButtonCss = (theme: Theme) => css` + ${theme.typos.pretendard.body1}; +`; + +export function GNB() { + const { pathname } = useRouter(); + const { containerRef, isDropdownOpen, openDropdown, closeDropdown } = useDropDown(); + + const getActiveLinkcss = (menu: GNBMenu) => { + if (pathname.startsWith(menu.href)) { + return activeLinkCss; + } + return inActiveLinkCss; + }; + + return ( + <> + + +
    + + ); +} + +const navCommonCss = (theme: Theme) => css` + background-color: ${theme.colors.black800}; + position: fixed; + top: 0; + left: 0; + z-index: 9998; + width: 100vw; +`; + +const navCss = (theme: Theme) => css` + ${navCommonCss(theme)}; + padding: 20px 32px; + + ${mediaQuery('mobile')} { + display: none; + } +`; + +const blankCss = css` + width: 100vw; + height: 82px; + + ${mediaQuery('mobile')} { + height: 72px; + } +`; + +const navWrapperCss = css` + max-width: 1240px; + display: flex; + justify-content: space-between; + align-items: center; + margin: 0 auto; +`; + +const menuContainerCss = css` + display: flex; + gap: 32px; +`; + +const mobileNavCss = css` + display: none; + + ${mediaQuery('mobile')} { + display: block; + } +`; + +const menuCss = css` + margin: auto 0; +`; + +const activeLinkCss = (theme: Theme) => css` + color: ${theme.colors.yellow500}; +`; + +const inActiveLinkCss = (theme: Theme) => css` + color: ${theme.colors.white}; +`; + +const linkCss = (theme: Theme) => css` + ${theme.typos.pretendard.body1}; +`; + +const mobileMenuGNBCss = (theme: Theme) => css` + ${navCommonCss(theme)}; + padding: 20px 32px; + display: flex; + align-items: center; + justify-content: space-between; + + & > a { + margin-top: 6px; + } +`; diff --git a/src/components/GNB/MobileMenu.tsx b/src/components/GNB/MobileMenu.tsx new file mode 100644 index 00000000..71c2f422 --- /dev/null +++ b/src/components/GNB/MobileMenu.tsx @@ -0,0 +1,101 @@ +import Link from 'next/link'; +import { useRouter } from 'next/router'; +import { css, Theme } from '@emotion/react'; +import { m } from 'framer-motion'; + +import { GNB_MENU_NAME, GNBMenu } from '~/constant/gnb'; +import useIsInProgress from '~/hooks/useIsInProgress'; +import { mediaQuery } from '~/styles/media'; + +interface MobileMenuProps { + onClickMenu: () => void; +} + +export function MobileMenu({ onClickMenu }: MobileMenuProps) { + const { pathname, push } = useRouter(); + const { isInProgress } = useIsInProgress(); + + const getActiveLinkcss = (menu: GNBMenu) => { + if (pathname.startsWith(menu.href)) { + return activeLinkCss; + } + return inActiveLinkCss; + }; + + return ( + +
      + {GNB_MENU_NAME.map(menu => ( + + {menu.type === 'button' ? ( + + ) : ( + + {menu.name} + + )} + + ))} +
    +
    + ); +} + +const mobileMenuCss = (theme: Theme) => css` + z-index: 9997; + + width: 100vw; + height: fit-content; + position: fixed; + top: 0; + left: 0; + margin: auto; + background-color: ${theme.colors.black800}; + padding-top: 72px; + border-bottom: 1px solid ${theme.colors.gray300}; + + overflow: hidden; + li { + padding: 12px 32px; + } +`; + +const linkCss = (theme: Theme) => css` + ${theme.typos.pretendard.body1}; + color: ${theme.colors.white}; + + ${mediaQuery('mobile')} { + font-size: 1rem; + } + + &:hover, + &:active { + color: ${theme.colors.yellow500}; + } + + &:disabled { + color: ${theme.colors.gray200}; + cursor: not-allowed; + } +`; + +const activeLinkCss = (theme: Theme) => css` + color: ${theme.colors.yellow500}; +`; + +const inActiveLinkCss = (theme: Theme) => css` + color: ${theme.colors.white}; +`; diff --git a/src/components/GNB/MobileMenuIcon.tsx b/src/components/GNB/MobileMenuIcon.tsx new file mode 100644 index 00000000..2ffb8e66 --- /dev/null +++ b/src/components/GNB/MobileMenuIcon.tsx @@ -0,0 +1,102 @@ +import { css } from '@emotion/react'; + +interface Props { + onClick?: () => void; + isChecked?: boolean; +} +export function MobileMenuIcon({ onClick, isChecked }: Props) { + return ( +
    + + +
    + ); +} + +const containerCss = css` + position: relative; + width: 24px; + height: 24px; + + .menu { + position: absolute; + top: 0; + right: 0; + height: 100%; + max-width: 0; + min-width: 100px; + transition: 0.5s ease; + z-index: 1; + background-color: #eee; + } + + .burger-icon { + cursor: pointer; + display: inline-block; + position: absolute; + z-index: 2; + padding: 8px 0; + top: 8px; + right: 4px; + user-select: none; + width: auto; + + .burger-sticks { + background: #d9d9d9; + display: block; + height: 3px; + position: relative; + transition: background 0.2s ease-out; + width: 24px; + + &:before, + &:after { + background: #d9d9d9; + content: ''; + display: block; + height: 100%; + position: absolute; + transition: all 0.2s ease-out; + width: 100%; + } + + &:before { + top: 8px; + } + + &:after { + top: -8px; + } + } + } + + .burger-check { + display: none; + } + + .burger-check:checked ~ .burger-icon .burger-sticks { + background: transparent; + &:before { + transform: rotate(-45deg); + } + &:after { + transform: rotate(45deg); + } + } + + .burger-check:checked ~ .burger-icon:not(.steps) .burger-sticks { + &:before, + &:after { + top: 0; + } + } +`; diff --git a/src/components/GNB/index.ts b/src/components/GNB/index.ts new file mode 100644 index 00000000..f0886146 --- /dev/null +++ b/src/components/GNB/index.ts @@ -0,0 +1 @@ +export { GNB } from './GNB'; diff --git a/src/components/Icons/ArrowIcon.tsx b/src/components/Icons/ArrowIcon.tsx new file mode 100644 index 00000000..35da1b96 --- /dev/null +++ b/src/components/Icons/ArrowIcon.tsx @@ -0,0 +1,50 @@ +import { css } from '@emotion/react'; + +import { Props, Svg } from './Svg'; + +export interface ChevronIconProps extends Props { + direction?: 'up' | 'right' | 'down' | 'left'; +} + +export function ArrowIcon({ + direction = 'down', + color = '#070814', + css, + ...props +}: ChevronIconProps) { + return ( + + + + + ); +} + +const DIRECTION_DEGREE = { + up: 180, + right: 270, + down: 0, + left: 90, +} as const; + +const ArrowIconCss = (degree: number) => css` + transform: rotate(${degree}deg); +`; diff --git a/src/components/Icons/Icon.stories.tsx b/src/components/Icons/Icon.stories.tsx new file mode 100644 index 00000000..9451042f --- /dev/null +++ b/src/components/Icons/Icon.stories.tsx @@ -0,0 +1,27 @@ +import { Meta } from '@storybook/react'; + +import { ArrowIcon } from './index'; + +const meta: Meta = { + title: 'components/Icon', +}; + +// Icon 폴더의 파일명을 알파벳순서로 정렬해주세요~ + +export default meta; + +export const ArrowDown = { + render: () => , +}; + +export const ArrowUp = { + render: () => , +}; + +export const ArrowLeft = { + render: () => , +}; + +export const ArrowRight = { + render: () => , +}; diff --git a/src/components/Icons/MenuIcon.tsx b/src/components/Icons/MenuIcon.tsx new file mode 100644 index 00000000..287ac367 --- /dev/null +++ b/src/components/Icons/MenuIcon.tsx @@ -0,0 +1,17 @@ +import { Props, Svg } from '~/components/Icons/Svg'; + +export function MenuIcon({ color = '#fff', ...props }: Props) { + return ( + + + + + + + + + ); +} diff --git a/src/components/common/icons/Svg.tsx b/src/components/Icons/Svg.tsx similarity index 81% rename from src/components/common/icons/Svg.tsx rename to src/components/Icons/Svg.tsx index 582cb3fd..9c3e0ef7 100644 --- a/src/components/common/icons/Svg.tsx +++ b/src/components/Icons/Svg.tsx @@ -2,13 +2,7 @@ import { PropsWithChildren, SVGProps } from 'react'; export interface Props extends SVGProps {} -export default function Svg({ - children, - width, - height, - viewBox, - ...rest -}: PropsWithChildren) { +export function Svg({ children, width, height, viewBox, ...rest }: PropsWithChildren) { return ( +

    + 디자이너와 개발자를 만나 +
    + 공동의 성장을 위한 여정에 합류해보세요 +

    +

    + 디자이너와 개발자를 만나 공동의
    + 성장을 위한 여정에 합류해보세요 +

    +
    + passport combination +
    +
    +
    +

    누적 멤버 수

    +

    850+

    +
    +
    +

    탄생한지

    +

    7 YEARS

    +
    +
    +

    10-13기 런칭 성공률

    +

    100%

    +
    +
    +

    5-13기 런칭 서비스

    +

    50+

    +
    +
    + + ); +} + +const layoutCss = (theme: Theme) => css` + display: flex; + flex-direction: column; + align-items: center; + gap: 80px; + padding: 0 30px; + + color: ${theme.colors.white}; + + h1, + h2 { + ${theme.typos.decimal.title2}; + text-align: center; + } + + h2 { + font-size: 20px; + display: none; + } + + ${mediaQuery('mobile')} { + gap: 24px; + font-size: ${pxToRem(20)}; + + h1 { + display: none; + } + h2 { + display: block; + } + + img { + width: 240px; + height: 155px; + } + } +`; + +const infoContainerCss = (theme: Theme) => css` + display: grid; + gap: 20px; + width: 100%; + + grid-template-columns: repeat(4, 1fr); + & > div { + display: flex; + flex-direction: column; + align-items: center; + gap: 20px; + + background-color: ${theme.colors.black400}; + padding: 52px 0; + } + + h3 { + ${theme.typos.pretendard.body1}; + color: ${theme.colors.gray100}; + } + + p { + ${theme.typos.decimal.subTitle1}; + } + + ${mediaQuery('mobile')} { + grid-template-columns: repeat(2, 1fr); + gap: 4px; + + h3, + p { + line-height: 30px; + } + & > div { + padding: 8px 4px; + gap: 8px; + } + } +`; + +const imageContainerCss = css` + width: 530.326px; + height: 340px; + + img { + width: 100%; + height: 100%; + object-position: center; + object-fit: cover; + position: relative; + bottom: 24px; + } + ${mediaQuery('mobile')} { + width: 240px; + height: 155px; + } +`; diff --git a/src/components/Main/RecruitEntrance.tsx b/src/components/Main/RecruitEntrance.tsx new file mode 100644 index 00000000..079a715d --- /dev/null +++ b/src/components/Main/RecruitEntrance.tsx @@ -0,0 +1,103 @@ +import Image from 'next/image'; +import Link from 'next/link'; +import { css, Theme } from '@emotion/react'; + +import { Button } from '~/components/Button'; +import { commonLayoutCss } from '~/styles/layout'; +import { mediaQuery } from '~/styles/media'; + +export function RecruitEntrance() { + return ( +
    +
    + passport combination +
    +
    +

    14기 모집 안내

    +
    +

    지원 자격부터 모집 직무까지

    +

    상세 내용을 한 번에 확인해보세요

    +
    + + + +
    +
    + ); +} + +const imageContainerCss = css` + padding: 24px; + ${mediaQuery('tablet')} { + width: 346px; + padding: 0; + margin-left: 53px; + img { + position: relative; + left: -53px; + } + } + + ${mediaQuery('mobile')} { + width: 124px; + margin-left: 0; + img { + width: auto; + height: 170px; + left: -16px; + } + } +`; + +const infoContainerCss = (theme: Theme) => css` + display: flex; + flex-direction: column; + justify-content: center; + align-items: flex-start; + gap: 24px; + text-align: left; + padding-right: 80px; + + h1 { + ${theme.typos.pretendard.subTitle1}; + color: ${theme.colors.white}; + } + p { + ${theme.typos.pretendard.subTitle2}; + color: ${theme.colors.gray100}; + } + + ${mediaQuery('tablet')} { + padding-right: 0; + } + + ${mediaQuery('mobile')} { + gap: 8px; + + p { + font-size: 14px; + } + button { + margin-top: 16px; + } + } +`; + +const layoutCss = css` + display: flex; + gap: 80px; + + ${mediaQuery('tablet')} { + gap: 7px; + } + + ${mediaQuery('mobile')} { + gap: 16px; + justify-content: center; + } +`; diff --git a/src/components/Main/RecruitTextSection.tsx b/src/components/Main/RecruitTextSection.tsx new file mode 100644 index 00000000..4ad6ec88 --- /dev/null +++ b/src/components/Main/RecruitTextSection.tsx @@ -0,0 +1,47 @@ +import { useRouter } from 'next/router'; +import { css, Theme } from '@emotion/react'; + +import { Button } from '~/components/Button'; +import useIsInProgress from '~/hooks/useIsInProgress'; +import { commonLayoutCss } from '~/styles/layout'; +import { mediaQuery } from '~/styles/media'; + +export function RecruitTextSection() { + const { isInProgress } = useIsInProgress(); + const router = useRouter(); + + const onButtonClick = () => { + router.push('/apply'); + }; + + return ( +
    +

    + 서비스 런칭부터 운영까지
    + 열정적인 여정에 지금 합류하세요 +

    + +
    + ); +} + +const layoutCss = (theme: Theme) => css` + display: flex; + flex-direction: column; + align-items: center; + gap: 40px; + + h1 { + text-align: center; + color: ${theme.colors.white}; + ${theme.typos.decimal.title2}; + } + + ${mediaQuery('mobile')} { + h1 { + font-size: 20px; + } + } +`; diff --git a/src/components/Main/SignImageSection.tsx b/src/components/Main/SignImageSection.tsx new file mode 100644 index 00000000..852f30b2 --- /dev/null +++ b/src/components/Main/SignImageSection.tsx @@ -0,0 +1,24 @@ +import Image from 'next/image'; +import { css } from '@emotion/react'; + +import { commonLayoutCss } from '~/styles/layout'; +import { autoImageRatio } from '~/styles/style.utils'; + +export function SignImageSection() { + return ( +
    +
    + DPM 14th +
    +
    + ); +} + +const layoutCss = css` + width: 100%; + height: 100%; +`; + +const imageCss = css` + ${autoImageRatio(959, 356)}; +`; diff --git a/src/components/Main/index.tsx b/src/components/Main/index.tsx new file mode 100644 index 00000000..87c9e233 --- /dev/null +++ b/src/components/Main/index.tsx @@ -0,0 +1,2 @@ +export { RecruitTextSection } from './RecruitTextSection'; +export { SignImageSection } from './SignImageSection'; diff --git a/src/components/OfflineSession/OfflineSession.tsx b/src/components/OfflineSession/OfflineSession.tsx new file mode 100644 index 00000000..d545f99a --- /dev/null +++ b/src/components/OfflineSession/OfflineSession.tsx @@ -0,0 +1,39 @@ +import { css } from '@emotion/react'; + +import { OfflineThumbnail } from '~/components/OfflineSession/OfflineThumbnail'; +import { SectionTitle } from '~/components/SectionTitle'; +import { OFFLINE_SESSIONS } from '~/constant/offline'; +import { commonLayoutCss } from '~/styles/layout'; +import { mediaQuery } from '~/styles/media'; + +export function OfflineSession() { + return ( +
    + +
      + {OFFLINE_SESSIONS.map(session => ( + + ))} +
    +
    + ); +} + +const layoutCss = css` + margin-top: 150px; + ${mediaQuery('tablet')} { + margin-top: 150px; + } + ${mediaQuery('mobile')} { + margin-top: 100px; + } +`; + +const sessionContainerCss = css` + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 12px; + ${mediaQuery('tablet')} { + grid-template-columns: repeat(2, 1fr); + } +`; diff --git a/src/components/OfflineSession/OfflineThumbnail.tsx b/src/components/OfflineSession/OfflineThumbnail.tsx new file mode 100644 index 00000000..3d065468 --- /dev/null +++ b/src/components/OfflineSession/OfflineThumbnail.tsx @@ -0,0 +1,230 @@ +import Image from 'next/image'; +import { css } from '@emotion/react'; +import { m, Variants } from 'framer-motion'; + +import { ArrowIcon } from '~/components/Icons'; +import { useCheckWindowSize } from '~/hooks/useCheckWindowSize'; +import useToggle from '~/hooks/useToggle'; +import { colors } from '~/styles/colors'; +import { mediaQuery } from '~/styles/media'; + +export type Link = { + type: 'Behance' | 'Github' | 'Web' | 'App'; + href: string; +}; + +type ThumbnailProps = { + title: string; + subTitle: string; + img: string; + description: string; + links?: Link[]; + showInfoDefault?: boolean; + backgroundShow?: boolean; +}; + +const defaultEasing = [0.6, -0.05, 0.01, 0.99]; + +export function OfflineThumbnail({ + title, + subTitle, + img, + description, + links, + showInfoDefault = false, + backgroundShow = false, +}: ThumbnailProps) { + const { isTargetSize: isMobileSize } = useCheckWindowSize('mobile'); + const [isOpen, toggleIsOpen] = useToggle(false); + + const onMobileClick = () => { + if (!isMobileSize) return; + toggleIsOpen(); + }; + + return ( + + + {title} + + + + + {title} + + + {subTitle} + + + + {links && ( + + {links.map(link => ( + + + {link.type} + + + + + + ))} + + )} + + + ); +} + +const articleCss = css` + position: relative; + height: 208px; + padding: 24px; + overflow: hidden; + ${mediaQuery('mobile')} { + padding: 14px; + height: 158px; + } + &:hover { + cursor: pointer; + } +`; + +const imageCss = css` + position: absolute; + top: 0; + left: 0; + object-fit: cover; + object-position: center; + z-index: -1; + width: 100%; + height: 100%; +`; + +const contentsCss = css` + display: flex; + flex-direction: column; + height: 100%; + justify-content: space-between; +`; + +const linkContainerCss = css` + display: flex; + gap: 12px; + align-items: center; +`; + +const linkWrapperCss = css` + display: flex; + align-items: center; +`; + +const linkCss = css` + color: ${colors.blue400}; + font-weight: 500; + font-size: 1rem; + line-height: 22px; + letter-spacing: -0.16px; + margin-right: 2px; +`; + +const titleCss = css` + position: relative; + font-weight: 700; + font-size: 1.25rem; + line-height: 30px; + color: ${colors.white}; + z-index: 10; + ${mediaQuery('mobile')} { + font-size: 1rem; + } +`; + +const subTitleCss = css` + position: relative; + font-weight: 500; + font-size: 1rem; + line-height: 22px; + color: ${colors.gray100}; + z-index: 10; + ${mediaQuery('mobile')} { + font-size: 0.8rem; + margin-top: -5px; + } +`; + +const descriptionCss = css` + position: relative; + font-weight: 500; + font-size: 1rem; + line-height: 22px; + color: ${colors.white}; + z-index: 10; + letter-spacing: -0.16px; + white-space: pre-wrap; + ${mediaQuery('mobile')} { + line-height: 20px; + font-size: 0.75rem; + } +`; + +const textVariants: Variants = { + default: { opacity: 0 }, + hover: { + opacity: 1, + transition: { + duration: 0.3, + ease: defaultEasing, + }, + }, +}; + +const articleVariants: Variants = { + default: { background: 'transparent' }, + hover: { + transition: { + duration: 0.3, + ease: defaultEasing, + }, + }, +}; + +const imageVariants: Variants = { + default: { + filter: 'blur(0px)', + }, + hover: { + filter: 'blur(5px) brightness(0.4)', + transition: { + duration: 0.3, + ease: defaultEasing, + }, + }, +}; diff --git a/src/components/OfflineSession/index.tsx b/src/components/OfflineSession/index.tsx new file mode 100644 index 00000000..8cef384f --- /dev/null +++ b/src/components/OfflineSession/index.tsx @@ -0,0 +1 @@ +export { OfflineSession } from './OfflineSession'; diff --git a/src/components/Pagination/Pagination.tsx b/src/components/Pagination/Pagination.tsx new file mode 100644 index 00000000..e4605cd4 --- /dev/null +++ b/src/components/Pagination/Pagination.tsx @@ -0,0 +1,76 @@ +import { useId } from 'react'; +import { css } from '@emotion/react'; + +import { mediaQuery } from '~/styles/media'; +import { theme } from '~/styles/theme'; + +type PaginationProps = { + handlePageClick: (clickedPage: number) => void; + numberOfPages: number; + currentPage: number; +}; + +export function Pagination({ handlePageClick, numberOfPages, currentPage }: PaginationProps) { + const id = useId(); + + return ( + <> +
      + {[...new Array(numberOfPages)].map((_, i) => { + return ( +
    • handlePageClick(i + 1)} + css={listItemCss(currentPage === i + 1)} + key={`page-${id}-${i + 1}`} + > + {i + 1} +
    • + ); + })} +
    +
    + {numberOfPages !== currentPage && ( + + )} +
    + + ); +} + +const listCss = css` + margin-top: 70px; + display: flex; + gap: 28px; + justify-content: center; + ${theme.typos.pretendard.subTitle2}; + &:hover { + cursor: pointer; + } + ${mediaQuery('mobile')} { + display: none; + } +`; + +const buttonWrapperCss = css` + display: flex; + justify-content: center; +`; + +const moreCss = css` + display: none; + font-size: 0.9rem; + color: ${theme.colors.yellow500}; + padding: 8px 24px; + margin-top: 30px; + font-weight: 700; + ${mediaQuery('mobile')} { + display: block; + } +`; + +const listItemCss = (selected: boolean) => css` + padding: 10px; + color: ${selected ? theme.colors.yellow500 : theme.colors.white}; +`; diff --git a/src/components/Pagination/index.ts b/src/components/Pagination/index.ts new file mode 100644 index 00000000..0a1fd4da --- /dev/null +++ b/src/components/Pagination/index.ts @@ -0,0 +1 @@ +export { Pagination } from './Pagination'; diff --git a/src/components/Positions/Positions.stories.tsx b/src/components/Positions/Positions.stories.tsx new file mode 100644 index 00000000..8f1225f9 --- /dev/null +++ b/src/components/Positions/Positions.stories.tsx @@ -0,0 +1,26 @@ +import { css } from '@emotion/react'; +import type { Meta, StoryObj } from '@storybook/react'; + +import { Positions } from './index'; + +const meta: Meta = { + title: 'components/Positions', + component: Positions, + args: {}, +}; + +export default meta; + +type Story = StoryObj; + +export const Primary: Story = { + render: () => ( +
    + , +
    + ), +}; diff --git a/src/components/Positions/Positions.tsx b/src/components/Positions/Positions.tsx new file mode 100644 index 00000000..ab74376d --- /dev/null +++ b/src/components/Positions/Positions.tsx @@ -0,0 +1,55 @@ +import { css } from '@emotion/react'; + +import { PositionsItem } from '~/components/Positions/PositionsItem'; +import { SectionTitle } from '~/components/SectionTitle'; +import { POSITIONS } from '~/constant/position'; +import { commonLayoutCss } from '~/styles/layout'; +import { mediaQuery } from '~/styles/media'; + +export function Positions() { + return ( +
    + +
    + {POSITIONS.map(({ ...info }) => ( + + ))} +
    +
    + ); +} + +const layoutCss = css` + ${commonLayoutCss} + display: flex; + flex-direction: column; + align-items: center; +`; + +const listCss = css` + display: flex; + flex-wrap: wrap; + gap: 20px; + align-items: flex-start; + justify-content: center; + position: relative; + width: 960px; // TODO 전체 너비 상수화 + + ${mediaQuery('tablet')} { + display: grid; + grid-template-columns: repeat(2, 1fr); + width: 100%; + } + + ${mediaQuery('mobile')} { + display: flex; + flex-direction: column; + align-items: center; + + gap: 8px; + } +`; diff --git a/src/components/Positions/PositionsBody.tsx b/src/components/Positions/PositionsBody.tsx new file mode 100644 index 00000000..7e51c7b5 --- /dev/null +++ b/src/components/Positions/PositionsBody.tsx @@ -0,0 +1,18 @@ +import { PropsWithChildren } from 'react'; +import { css } from '@emotion/react'; + +interface PositionsBodyProps {} + +export function PositionsBody({ children }: PropsWithChildren) { + return
    {children}
    ; +} + +const layoutCss = css` + display: flex; + flex-wrap: wrap; + gap: 20px; + align-items: flex-start; + justify-content: center; + position: relative; + width: 960px; // TODO 전체 너비 상수화 +`; diff --git a/src/components/Positions/PositionsItem.tsx b/src/components/Positions/PositionsItem.tsx new file mode 100644 index 00000000..55a56c51 --- /dev/null +++ b/src/components/Positions/PositionsItem.tsx @@ -0,0 +1,126 @@ +import Image from 'next/image'; +import { useRouter } from 'next/router'; +import { css, Theme } from '@emotion/react'; + +import { ArrowIcon } from '~/components/Icons'; +import { POSITION_BASE } from '~/constant/image'; +import useIsInProgress from '~/hooks/useIsInProgress'; +import { mediaQuery } from '~/styles/media'; + +type Position = 'aos' | 'design' | 'ios' | 'server' | 'web'; + +interface PositionsItemProps { + type: Position; + title: string; + link: string; +} + +export function PositionsItem({ type, title, link }: PositionsItemProps) { + const { isInProgress } = useIsInProgress(); + + const router = useRouter(); + + const onClick = () => { + if (isInProgress) { + router.push(link); + } + }; + + return ( +
    + {title} +
    +

    {title}

    + +
    +
    + ); +} + +const layoutCss = (theme: Theme) => css` + display: flex; + flex-direction: column; + align-items: flex-start; + padding: 36px 32px; + background-color: ${theme.colors.black400}; + width: 306px; + height: 272px; + + img { + position: relative; + left: -14px; + } + + ${mediaQuery('tablet')} { + width: 100%; + height: 248px; + padding: 24px 32px; + } + + ${mediaQuery('mobile')} { + padding: 8px 16px; + height: 92px; + flex-direction: row; + gap: 16px; + align-items: center; + + img { + position: static; + width: 76px; + height: 76px; + } + } +`; + +const titleCss = (theme: Theme) => css` + ${theme.typos.decimal.body1}; + color: ${theme.colors.white}; + margin-top: 28px; + + ${mediaQuery('mobile')} { + margin-top: 0; + font-size: 16px; + } +`; + +const linkCss = (theme: Theme) => css` + ${theme.typos.pretendard.body1}; + color: ${theme.colors.blue400}; + display: flex; + align-items: center; + margin-top: 8px; + > svg { + margin-left: 4px; + } + + &:disabled { + cursor: not-allowed; + color: ${theme.colors.gray200}; + } + + ${mediaQuery('mobile')} { + font-size: 14px; + } +`; + +const arrowIconCss = (theme: Theme, disabled: boolean) => css` + width: 24px; + height: 24px; + + > path { + stroke: ${theme.colors.blue400}; + stroke-width: 4; + } + + ${disabled && + css` + > path { + stroke: ${theme.colors.gray200}; + } + `} +`; diff --git a/src/components/Positions/index.ts b/src/components/Positions/index.ts new file mode 100644 index 00000000..f694e4de --- /dev/null +++ b/src/components/Positions/index.ts @@ -0,0 +1 @@ +export { Positions } from './Positions'; diff --git a/src/components/ProjectCarousel/ProjectCarousel.stories.tsx b/src/components/ProjectCarousel/ProjectCarousel.stories.tsx new file mode 100644 index 00000000..ea98d485 --- /dev/null +++ b/src/components/ProjectCarousel/ProjectCarousel.stories.tsx @@ -0,0 +1,17 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import { ProjectCarousel } from './index'; + +const meta: Meta = { + title: 'components/ProjectCarousel', + component: ProjectCarousel, + args: {}, +}; + +export default meta; + +type Story = StoryObj; + +export const Primary: Story = { + render: () => , +}; diff --git a/src/components/ProjectCarousel/ProjectCarousel.tsx b/src/components/ProjectCarousel/ProjectCarousel.tsx new file mode 100644 index 00000000..007b5f36 --- /dev/null +++ b/src/components/ProjectCarousel/ProjectCarousel.tsx @@ -0,0 +1,38 @@ +import Link from 'next/link'; +import { css, Theme } from '@emotion/react'; +import Marquee from 'react-fast-marquee'; + +import { Button } from '~/components/Button'; +import { ProjectCarouselItem } from '~/components/ProjectCarousel/ProjectCarouselItem'; +import { SectionTitle } from '~/components/SectionTitle'; +import { PROJECT_LIST } from '~/constant/project'; + +const PROJECT_13 = PROJECT_LIST.filter(project => project.subTitle === '13기'); + +export function ProjectCarousel() { + return ( +
    + + + {PROJECT_13.map(project => ( + + ))} + + +
    + ); +} + +const layoutCss = css` + display: flex; + flex-direction: column; + align-items: center; + overflow: hidden; +`; + +const projectButtonCss = (theme: Theme) => css` + ${theme.typos.pretendard.body1}; + margin-top: 88px; +`; diff --git a/src/components/ProjectCarousel/ProjectCarouselItem.tsx b/src/components/ProjectCarousel/ProjectCarouselItem.tsx new file mode 100644 index 00000000..c61699a8 --- /dev/null +++ b/src/components/ProjectCarousel/ProjectCarouselItem.tsx @@ -0,0 +1,30 @@ +import Image from 'next/image'; +import { css } from '@emotion/react'; + +import { Project } from '~/constant/project'; +import { mediaQuery } from '~/styles/media'; + +interface ProjectCarouselItemProps extends Project {} + +export function ProjectCarouselItem({ title, subTitle }: ProjectCarouselItemProps) { + return ( +
    + {title} +
    + ); +} + +const imageCss = css` + position: relative; + width: 312px; + height: 208px; + object-fit: cover; + object-position: center; + margin-left: 20px; + + ${mediaQuery('mobile')} { + width: 200px; + height: 130px; + margin-left: 8px; + } +`; diff --git a/src/components/ProjectCarousel/index.tsx b/src/components/ProjectCarousel/index.tsx new file mode 100644 index 00000000..db864e2a --- /dev/null +++ b/src/components/ProjectCarousel/index.tsx @@ -0,0 +1 @@ +export { ProjectCarousel } from './ProjectCarousel'; diff --git a/src/components/ProjectTab/ProjectTab.tsx b/src/components/ProjectTab/ProjectTab.tsx new file mode 100644 index 00000000..8e07b6df --- /dev/null +++ b/src/components/ProjectTab/ProjectTab.tsx @@ -0,0 +1,60 @@ +import { Dispatch, SetStateAction } from 'react'; +import { css } from '@emotion/react'; + +import { TAB_LIST } from '~/constant/project'; +import { mediaQuery } from '~/styles/media'; +import { theme } from '~/styles/theme'; + +type ProjectTabProps = { + currentTab: string; + setCurrentTab: Dispatch>; +}; + +export function ProjectTab({ currentTab, setCurrentTab }: ProjectTabProps) { + return ( +
      +
    • + {TAB_LIST.map(tab => ( + + ))} +
    • +
    + ); +} + +const tabWrapperCss = css` + display: flex; +`; + +const tabContainerCss = css` + display: flex; + + ${mediaQuery('mobile')} { + gap: 8px; + } +`; + +const tabCss = css` + ${theme.typos.pretendard.subTitle2}; + padding: 16px 24px; + ${mediaQuery('mobile')} { + ${theme.typos.pretendard.body2}; + padding: 16px 8px; + } +`; + +const activeTabCss = css` + ${tabCss}; + color: ${theme.colors.yellow500}; +`; + +const inActiveTabCss = css` + ${tabCss}; + color: ${theme.colors.white}; +`; diff --git a/src/components/ProjectTab/index.ts b/src/components/ProjectTab/index.ts new file mode 100644 index 00000000..0575eae4 --- /dev/null +++ b/src/components/ProjectTab/index.ts @@ -0,0 +1 @@ +export { ProjectTab } from './ProjectTab'; diff --git a/src/components/Qualification/Qualification.stories.tsx b/src/components/Qualification/Qualification.stories.tsx new file mode 100644 index 00000000..ce424e43 --- /dev/null +++ b/src/components/Qualification/Qualification.stories.tsx @@ -0,0 +1,25 @@ +import { css } from '@emotion/react'; +import type { Meta, StoryObj } from '@storybook/react'; + +import { Qualification } from './index'; + +const meta: Meta = { + title: 'components/Qualification', + args: {}, +}; + +export default meta; + +type Story = StoryObj; + +export const Primary: Story = { + render: () => ( +
    + +
    + ), +}; diff --git a/src/components/Qualification/Qualification.tsx b/src/components/Qualification/Qualification.tsx new file mode 100644 index 00000000..0544ac67 --- /dev/null +++ b/src/components/Qualification/Qualification.tsx @@ -0,0 +1,38 @@ +import { css } from '@emotion/react'; + +import { QualificationItem } from '~/components/Qualification/QualificationItem'; +import { SectionTitle } from '~/components/SectionTitle'; +import { QUALIFICATIONS } from '~/constant/qualification'; +import { commonLayoutCss } from '~/styles/layout'; +import { mediaQuery } from '~/styles/media'; + +export function Qualification() { + return ( +
    + +
    + {QUALIFICATIONS.map(({ index, description }) => ( + + ))} +
    +
    + ); +} + +const layoutCss = css` + ${commonLayoutCss} + display: flex; + flex-direction: column; + align-items: center; +`; + +const listCss = css` + display: grid; + grid-template-columns: repeat(3, 1fr); + grid-gap: 10px; + max-width: 960px; // TODO: 변수화해서 theme.ts에서 관리하기 + + ${mediaQuery('mobile')} { + grid-template-columns: repeat(2, 1fr); + } +`; diff --git a/src/components/Qualification/QualificationItem.tsx b/src/components/Qualification/QualificationItem.tsx new file mode 100644 index 00000000..4ac280b9 --- /dev/null +++ b/src/components/Qualification/QualificationItem.tsx @@ -0,0 +1,47 @@ +import { css, Theme } from '@emotion/react'; + +import { mediaQuery } from '~/styles/media'; +import { formatSingleDigit } from '~/utils/format'; + +interface QualificationItemProps { + index: number; + description: string; +} + +export function QualificationItem({ index, description }: QualificationItemProps) { + return ( +
    +

    {formatSingleDigit(index)}

    +

    {description}

    +
    + ); +} + +const layoutCss = (theme: Theme) => css` + background-color: ${theme.colors.black400}; + padding: 48px 30px; + display: flex; + flex-direction: column; + gap: 20px; + + ${mediaQuery('tablet')} { + padding: 48px 38px; + } + ${mediaQuery('mobile')} { + padding: 16px; + } +`; + +const indexCss = (theme: Theme) => css` + ${theme.typos.decimal.subTitle1}; + color: ${theme.colors.blue300}; +`; + +const descriptionCss = (theme: Theme) => css` + ${theme.typos.pretendard.body1}; + color: ${theme.colors.gray20}; + + ${mediaQuery('mobile')} { + ${theme.typos.pretendard.body3}; + } +`; diff --git a/src/components/Qualification/index.tsx b/src/components/Qualification/index.tsx new file mode 100644 index 00000000..584a850b --- /dev/null +++ b/src/components/Qualification/index.tsx @@ -0,0 +1 @@ +export { Qualification } from './Qualification'; diff --git a/src/components/Review/Review.stories.tsx b/src/components/Review/Review.stories.tsx new file mode 100644 index 00000000..3e6f64f5 --- /dev/null +++ b/src/components/Review/Review.stories.tsx @@ -0,0 +1,31 @@ +import { css } from '@emotion/react'; +import type { Meta } from '@storybook/react'; + +import { REVIEWS } from '~/constant/review'; + +import { Review } from './index'; +import { ReviewItem as ReviewItemComponent } from './ReviewItem'; + +const meta: Meta = { + title: 'components/Review', +}; + +export default meta; + +export const Primary = { + render: () => ( +
    + +
    + ), +}; + +export const ReviewItem = { + render: () => { + return ; + }, +}; diff --git a/src/components/Review/Review.tsx b/src/components/Review/Review.tsx new file mode 100644 index 00000000..e1645d36 --- /dev/null +++ b/src/components/Review/Review.tsx @@ -0,0 +1,26 @@ +import { css } from '@emotion/react'; +import Marquee from 'react-fast-marquee'; + +import { ReviewItem } from '~/components/Review/ReviewItem'; +import { SectionTitle } from '~/components/SectionTitle'; +import { REVIEWS } from '~/constant/review'; + +export function Review() { + return ( +
    + + + {REVIEWS.map(({ ...info }) => ( + + ))} + +
    + ); +} + +const layoutCss = css` + display: flex; + flex-direction: column; + align-items: center; + overflow: hidden; +`; diff --git a/src/components/Review/ReviewItem.tsx b/src/components/Review/ReviewItem.tsx new file mode 100644 index 00000000..0a1bb838 --- /dev/null +++ b/src/components/Review/ReviewItem.tsx @@ -0,0 +1,129 @@ +import Link from 'next/link'; +import { css, Theme } from '@emotion/react'; + +import { ArrowIcon } from '~/components/Icons'; +import { ReviewItemType } from '~/constant/review'; +import { mediaQuery } from '~/styles/media'; + +interface ReviewItemProps extends ReviewItemType {} +export function ReviewItem({ name, group, part, summary, links }: ReviewItemProps) { + return ( +
    +
    +
    +

    {name}

    +
    + {group} + {part} +
    +
    +
    +

    {summary}

    +
    +
    +
    + {links.map(({ label, url }) => ( + + {label} 보기 + + + ))} +
    +
    + ); +} + +const layoutCss = (theme: Theme) => css` + padding: 44px 52px; + background-color: ${theme.colors.black400}; + display: flex; + flex-direction: column; + justify-content: space-between; + max-width: 476px; + height: 289px; + margin-left: 20px; + + ${mediaQuery('tablet')} { + padding: 30px 50px; + max-width: 510px; + height: 336px; + } + + ${mediaQuery('mobile')} { + margin-left: 8px; + max-width: 277px; + height: 212px; + padding: 20px; + } +`; + +const titleLayoutCss = css` + display: flex; + gap: 12px; + align-items: center; +`; + +const titleH3Css = (theme: Theme) => css` + ${theme.typos.pretendard.subTitle2}; + color: ${theme.colors.white}; + + ${mediaQuery('tablet')} { + ${theme.typos.pretendard.subTitle1}; + } + + ${mediaQuery('mobile')} { + ${theme.typos.pretendard.subTitle1}; + } +`; + +const titleSpanCss = (theme: Theme) => css` + ${theme.typos.pretendard.body1}; + color: ${theme.colors.white}; + display: flex; + gap: 8px; +`; + +const summaryCss = (theme: Theme) => css` + ${theme.typos.pretendard.body1}; + color: ${theme.colors.gray100}; + margin-top: 16px; + > p { + word-break: break-all; + } + + ${mediaQuery('tablet')} { + margin-top: 32px; + } + ${mediaQuery('mobile')} { + margin-top: 8px; + } +`; + +const linkLayoutCss = css` + display: flex; + gap: 12px; +`; + +const arrowIconCss = (theme: Theme) => css` + width: 24px; + height: 24px; + + > path { + stroke: ${theme.colors.blue400}; + } +`; + +const linkCss = (theme: Theme) => css` + ${theme.typos.pretendard.body1}; + color: ${theme.colors.blue400}; + margin-top: 20px; + display: flex; + align-items: center; + + ${mediaQuery('tablet')} { + margin-top: 20px; + } + ${mediaQuery('mobile')} { + margin-top: 24px; + } +`; diff --git a/src/components/Review/index.tsx b/src/components/Review/index.tsx new file mode 100644 index 00000000..66313d56 --- /dev/null +++ b/src/components/Review/index.tsx @@ -0,0 +1 @@ +export { Review } from './Review'; diff --git a/src/components/common/SEO/SEO.tsx b/src/components/SEO/SEO.tsx similarity index 93% rename from src/components/common/SEO/SEO.tsx rename to src/components/SEO/SEO.tsx index a601d888..c170be25 100644 --- a/src/components/common/SEO/SEO.tsx +++ b/src/components/SEO/SEO.tsx @@ -23,13 +23,13 @@ interface Props { const DEFAULT_TITLE = '디프만 - Depromeet'; const DEFAULT_DESCRIPTION = '오직 디자이너와 프로그래머의 동반성장을 위해서'; -const DEFAULT_IMAGE = '/og-main.webp'; +const DEFAULT_IMAGE = '/og-main.png'; -export default function SEO({ +export const SEO = ({ title = DEFAULT_TITLE, description = DEFAULT_DESCRIPTION, image = DEFAULT_IMAGE, -}: Props) { +}: Props) => { return ( {title} @@ -44,4 +44,4 @@ export default function SEO({ ); -} +}; diff --git a/src/components/SEO/index.tsx b/src/components/SEO/index.tsx new file mode 100644 index 00000000..4599dec6 --- /dev/null +++ b/src/components/SEO/index.tsx @@ -0,0 +1 @@ +export { SEO } from './SEO'; diff --git a/src/components/ScheduleSection/ScheduleSection.stories.tsx b/src/components/ScheduleSection/ScheduleSection.stories.tsx new file mode 100644 index 00000000..addfb03c --- /dev/null +++ b/src/components/ScheduleSection/ScheduleSection.stories.tsx @@ -0,0 +1,94 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import { SectionTitle } from '~/components/SectionTitle'; +import { MEMBER_SCHEDULE, SESSION_SCHEDULES } from '~/constant/schedule'; + +import { ScheduleSection } from './index'; + +const meta: Meta = { + title: 'CATEGORY/ScheduleSection', + component: ScheduleSection, + args: {}, +}; + +export default meta; + +type Story = StoryObj; + +export const All: Story = { + render: () => ( +
    + + + +
    + ), +}; + +export const Members: Story = { + render: () => ( +
    + +
    + ), +}; + +export const Sessions: Story = { + render: () => ( +
    + +
    + ), +}; diff --git a/src/components/ScheduleSection/ScheduleSection.tsx b/src/components/ScheduleSection/ScheduleSection.tsx new file mode 100644 index 00000000..ef55b9af --- /dev/null +++ b/src/components/ScheduleSection/ScheduleSection.tsx @@ -0,0 +1,133 @@ +import { css, Theme } from '@emotion/react'; + +import { commonLayoutCss } from '~/styles/layout'; +import { mediaQuery } from '~/styles/media'; +import { theme } from '~/styles/theme'; + +interface ScheduleSectionProps { + label: string; + title: string; + schedule: Array<{ + date: string; + content: string; + }>; + + titleBgColor: keyof typeof theme.colors; +} + +export function ScheduleSection({ label, title, schedule, titleBgColor }: ScheduleSectionProps) { + return ( +
    +
    + {label.split('').map((char, index) => ( + {char} + ))} +
    +
    titleContainerCss(theme, titleBgColor)}> +

    {title}

    +
    +
    scheduleContainerCss(theme, schedule.length)}> + {schedule.map(item => ( +
    +

    {item.date}

    + {item.content} +
    + ))} +
    +
    + ); +} + +const layoutCss = (theme: Theme) => css` + color: ${theme.colors.white}; + margin: 0 auto; + + background-color: ${theme.colors.black800}; + + & + & { + margin-top: 32px; + } +`; + +const topLabelContainerCss = (theme: Theme) => css` + display: flex; + justify-content: space-between; + width: 100%; + text-align: center; + + gap: 2px; + & > span { + ${theme.typos.decimal.body1}; + background-color: ${theme.colors.black400}; + flex: 1; + padding: 6px 0; + color: ${theme.colors.gray200}; + text-transform: uppercase; + } + + ${mediaQuery('mobile')} { + & > span { + font-size: 12px; + padding: 2px 0px; + } + } +`; + +const titleContainerCss = (theme: Theme, titleBgColor: keyof typeof theme.colors) => css` + ${theme.typos.pretendard.subTitle1}; + background-color: ${theme.colors[titleBgColor]}; + color: ${theme.colors.black800}; + text-align: center; + padding: 40px 0; + + ${mediaQuery('mobile')} { + padding: 16px 0; + font-size: 16px; + } +`; + +const scheduleItemCss = (theme: Theme) => css` + display: flex; + flex-direction: column; + gap: 20px; + text-align: center; + + p { + ${theme.typos.decimal.body1}; + font-weight: 700; + } + span { + ${theme.typos.pretendard.body1}; + color: ${theme.colors.gray20}; + } + flex: 1; + + ${mediaQuery('mobile')} { + gap: 8px; + + span { + font-weight: 400; + } + } +`; + +const scheduleContainerCss = (theme: Theme, scheduleCount: number) => css` + display: flex; + padding: 50px 90px; + background-color: ${theme.colors.black400}; + flex-wrap: wrap; + + ${mediaQuery('tablet')} { + padding: 50px 48px; + } + + ${mediaQuery('mobile')} { + display: grid; + grid-template-rows: repeat(2, 1fr); + grid-template-columns: repeat(${scheduleCount / 2}, 1fr); + padding: 16px 8px; + row-gap: 32px; + column-gap: 0; + text-align: center; + } +`; diff --git a/src/components/ScheduleSection/index.tsx b/src/components/ScheduleSection/index.tsx new file mode 100644 index 00000000..37f94e1f --- /dev/null +++ b/src/components/ScheduleSection/index.tsx @@ -0,0 +1 @@ +export { ScheduleSection } from './ScheduleSection'; diff --git a/src/components/SectionTitle/SectionTitle.stories.tsx b/src/components/SectionTitle/SectionTitle.stories.tsx new file mode 100644 index 00000000..4043ada4 --- /dev/null +++ b/src/components/SectionTitle/SectionTitle.stories.tsx @@ -0,0 +1,34 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import { SectionTitle } from './index'; + +const meta: Meta = { + title: 'components/SectionTitle', + component: SectionTitle, + args: {}, +}; + +export default meta; + +type Story = StoryObj; + +export const Primary: Story = { + render: () => ( +
    + +
    + ), +}; + +export const Short: Story = { + render: () => ( +
    + +
    + ), +}; diff --git a/src/components/SectionTitle/SectionTitle.tsx b/src/components/SectionTitle/SectionTitle.tsx new file mode 100644 index 00000000..634d493d --- /dev/null +++ b/src/components/SectionTitle/SectionTitle.tsx @@ -0,0 +1,59 @@ +import { css, Theme } from '@emotion/react'; + +import { mediaQuery } from '~/styles/media'; + +interface SectionTitleProps { + /** + * 최상단 label + */ + label?: string; + /** + * 메인 타이틀 + */ + title?: string; + description?: string; +} + +export function SectionTitle({ label, title, description, ...layoutProps }: SectionTitleProps) { + return ( +
    + {label &&

    {label}

    } + {title &&

    {title}

    } + {description &&

    {description}

    } +
    + ); +} + +const layoutCss = css` + display: flex; + flex-direction: column; + align-items: center; + background-color: inherit; + padding: 88px 0; + + ${mediaQuery('mobile')} { + padding: 24px 0; + } +`; + +const labelCss = (theme: Theme) => css` + ${theme.typos.decimal.body1}; + color: ${theme.colors.yellow500}; + text-align: center; +`; + +const titleCss = (theme: Theme) => css` + ${theme.typos.pretendard.subTitle1}; + color: ${theme.colors.white}; + margin-top: 16px; + text-align: center; + text-align: center; + white-space: pre-line; +`; + +const descriptionCss = (theme: Theme) => css` + ${theme.typos.pretendard.body1}; + color: ${theme.colors.gray100}; + margin-top: 32px; + text-align: center; +`; diff --git a/src/components/SectionTitle/index.tsx b/src/components/SectionTitle/index.tsx new file mode 100644 index 00000000..d9f73ef0 --- /dev/null +++ b/src/components/SectionTitle/index.tsx @@ -0,0 +1 @@ +export { SectionTitle } from './SectionTitle'; diff --git a/src/components/Sign/Sign.tsx b/src/components/Sign/Sign.tsx new file mode 100644 index 00000000..50b415a9 --- /dev/null +++ b/src/components/Sign/Sign.tsx @@ -0,0 +1,49 @@ +import Image from 'next/image'; +import { useRouter } from 'next/router'; +import { css } from '@emotion/react'; + +import { mediaQuery } from '~/styles/media'; + +const signPathGroup = ['/about', '/recruit', '/project']; + +export function Sign() { + const router = useRouter(); + const path = router.pathname; + + if (!signPathGroup.includes(path)) return <>; + + return ( +
    +
    + sign +
    +
    + ); +} + +const imageContainerCss = css` + display: flex; + justify-content: center; + padding: 0 30px; + margin-bottom: 200px; + + ${mediaQuery('tablet')} { + margin-bottom: 150px; + } + + ${mediaQuery('mobile')} { + padding: 0 20px; + margin-bottom: 60px; + } +`; + +const imageWrapperCss = css` + width: 100vw; + max-width: 1024px; +`; diff --git a/src/components/Sign/index.ts b/src/components/Sign/index.ts new file mode 100644 index 00000000..7a9a9fdf --- /dev/null +++ b/src/components/Sign/index.ts @@ -0,0 +1 @@ +export { Sign } from './Sign'; diff --git a/src/components/Supports/SupportThumbnail.tsx b/src/components/Supports/SupportThumbnail.tsx new file mode 100644 index 00000000..63fb6c78 --- /dev/null +++ b/src/components/Supports/SupportThumbnail.tsx @@ -0,0 +1,162 @@ +import Image from 'next/image'; +import { css } from '@emotion/react'; +import { m } from 'framer-motion'; + +import { ArrowIcon } from '~/components/Icons'; +import { defaultFadeInVariants } from '~/constant/motion'; +import { colors } from '~/styles/colors'; + +export type Link = { + type: 'Behance' | 'Github' | 'Web' | 'App'; + href: string; +}; + +type ThumbnailProps = { + title: string; + subTitle: string; + img: string; + description: string; + links?: Link[]; +}; + +export function SupportThumbnail({ title, subTitle, img, description, links }: ThumbnailProps) { + return ( + + {title} +
    +
    +
    +

    {title}

    +

    {subTitle}

    +
    +

    + {links && ( +

    + {links.map(link => ( + + + {link.type} + + + + + + ))} +
    + )} +
    + + ); +} + +SupportThumbnail.OnlyImage = function OnlyImage({ + title, + img, +}: Pick) { + return ( +
    + {title} +
    + ); +}; + +const articleCss = css` + position: relative; + height: 208px; + padding: 24px; + width: 312px; + overflow: hidden; + &:hover { + cursor: pointer; + } + &:hover img { + filter: blur(5px) brightness(0.4); + } +`; + +const imageArticleCss = css` + position: relative; + height: 208px; + width: 312px; +`; + +const imageCss = css` + object-fit: cover; + object-position: center; +`; + +const contentsCss = css` + display: flex; + flex-direction: column; + height: 100%; + justify-content: space-between; + transition: opacity 0.3s ease; + opacity: 0; + + &:hover { + opacity: 1; + } +`; + +const linkContainerCss = css` + display: flex; + gap: 12px; + align-items: center; +`; + +const linkWrapperCss = css` + display: flex; + align-items: center; +`; + +const linkCss = css` + color: ${colors.blue400}; + font-weight: 500; + font-size: 1rem; + line-height: 22px; + letter-spacing: -0.16px; + margin-right: 2px; + z-index: 10; +`; + +const titleCss = css` + position: relative; + font-weight: 700; + font-size: 1.25rem; + line-height: 30px; + color: ${colors.white}; + z-index: 10; +`; + +const subTitleCss = css` + position: relative; + font-weight: 500; + font-size: 1rem; + line-height: 22px; + color: ${colors.gray100}; + z-index: 10; +`; + +const gradientCss = css` + position: absolute; + bottom: 0; + width: 100%; + height: 172px; +`; + +const descriptionCss = css` + position: relative; + font-weight: 500; + font-size: 1rem; + line-height: 22px; + color: ${colors.white}; + z-index: 10; + letter-spacing: -0.16px; + white-space: pre-wrap; +`; diff --git a/src/components/Supports/Supports.tsx b/src/components/Supports/Supports.tsx new file mode 100644 index 00000000..cb5caff0 --- /dev/null +++ b/src/components/Supports/Supports.tsx @@ -0,0 +1,39 @@ +import { css } from '@emotion/react'; + +import { SectionTitle } from '~/components/SectionTitle'; +import { SupportThumbnail } from '~/components/Supports/SupportThumbnail'; +import { SUPPORTS } from '~/constant/supports'; +import { commonLayoutCss } from '~/styles/layout'; +import { mediaQuery } from '~/styles/media'; + +export function Supports() { + return ( +
    + +
      + {SUPPORTS.map(support => ( + + ))} + +
    +
    + ); +} + +const layoutCss = css` + margin-top: 150px; + ${mediaQuery('tablet')} { + margin-top: 150px; + } + ${mediaQuery('mobile')} { + margin-top: 100px; + } +`; + +const supportContainerCss = css` + display: flex; + flex-wrap: wrap; + gap: 20px; + align-items: flex-start; + justify-content: center; +`; diff --git a/src/components/Supports/index.tsx b/src/components/Supports/index.tsx new file mode 100644 index 00000000..35d44379 --- /dev/null +++ b/src/components/Supports/index.tsx @@ -0,0 +1 @@ +export { Supports } from './Supports'; diff --git a/src/components/Thumbnail/Thumbnail.stories.tsx b/src/components/Thumbnail/Thumbnail.stories.tsx new file mode 100644 index 00000000..0c5127d9 --- /dev/null +++ b/src/components/Thumbnail/Thumbnail.stories.tsx @@ -0,0 +1,39 @@ +/* eslint-disable react-hooks/rules-of-hooks */ +import { Meta } from '@storybook/react'; + +import { Thumbnail } from './index'; + +const meta: Meta = { + title: 'components/Thumbnail', +}; + +export default meta; +const PROJECT_DUMMY_IMG = '/images/project/13-1.png'; +const SESSION_DUMMY_IMG = '/images/session/orientation.png'; + +export const Project = { + render: () => ( + + ), +}; + +export const Session = { + render: () => ( + + ), +}; diff --git a/src/components/Thumbnail/Thumbnail.tsx b/src/components/Thumbnail/Thumbnail.tsx new file mode 100644 index 00000000..e720b409 --- /dev/null +++ b/src/components/Thumbnail/Thumbnail.tsx @@ -0,0 +1,152 @@ +import Image from 'next/image'; +import { css } from '@emotion/react'; +import { m } from 'framer-motion'; + +import { ArrowIcon } from '~/components/Icons'; +import { defaultFadeInVariants } from '~/constant/motion'; +import { colors } from '~/styles/colors'; +import { mediaQuery } from '~/styles/media'; + +export type Link = { + type: 'Behance' | 'Github' | 'Web' | 'Android' | 'IOS'; + href: string; +}; + +type ThumbnailProps = { + title: string; + subTitle: string; + img: string; + description: string; + links?: Link[]; +}; + +export function Thumbnail({ title, subTitle, img, description, links }: ThumbnailProps) { + return ( + + {title} +
    +
    +
    +

    {title}

    +

    {subTitle}

    +
    +

    + {links && ( +

    + {links.map(link => ( + + + {link.type} + + + + + + ))} +
    + )} +
    + + ); +} + +const articleCss = css` + position: relative; + height: 208px; + max-width: 312px; + overflow: hidden; + ${mediaQuery('tablet')} { + max-width: 100%; + } + ${mediaQuery('mobile')} { + max-width: 100%; + } + &:hover { + cursor: pointer; + } + &:hover img { + filter: blur(5px) brightness(0.4); + } +`; + +const imageCss = css` + object-fit: cover; + object-position: center; +`; + +const contentsCss = css` + display: flex; + padding: 24px; + flex-direction: column; + height: 100%; + justify-content: space-between; + transition: opacity 0.3s ease; + opacity: 0; + + &:hover { + opacity: 1; + } +`; + +const linkContainerCss = css` + display: flex; + gap: 12px; + align-items: center; +`; + +const linkWrapperCss = css` + display: flex; + align-items: center; +`; + +const linkCss = css` + color: ${colors.blue400}; + font-weight: 500; + font-size: 1rem; + line-height: 22px; + letter-spacing: -0.16px; + margin-right: 2px; + z-index: 10; +`; + +const titleCss = css` + position: relative; + font-weight: 700; + font-size: 1.25rem; + line-height: 30px; + color: ${colors.white}; + z-index: 10; +`; + +const subTitleCss = css` + position: relative; + font-weight: 500; + font-size: 1rem; + line-height: 22px; + color: ${colors.gray100}; + z-index: 10; +`; + +const gradientCss = css` + position: absolute; + bottom: 0; + width: 100%; + height: 172px; +`; + +const descriptionCss = css` + position: relative; + font-weight: 500; + font-size: 1rem; + line-height: 22px; + color: ${colors.white}; + z-index: 10; + letter-spacing: -0.16px; + white-space: pre-wrap; +`; diff --git a/src/components/Thumbnail/index.ts b/src/components/Thumbnail/index.ts new file mode 100644 index 00000000..9a19e45c --- /dev/null +++ b/src/components/Thumbnail/index.ts @@ -0,0 +1 @@ +export { Thumbnail } from './Thumbnail'; diff --git a/src/components/TimerContainer/Timer.tsx b/src/components/TimerContainer/Timer.tsx new file mode 100644 index 00000000..100eb33b --- /dev/null +++ b/src/components/TimerContainer/Timer.tsx @@ -0,0 +1,107 @@ +import { css, Theme } from '@emotion/react'; + +import useMounted from '~/hooks/useMounted'; +import { mediaQuery } from '~/styles/media'; + +type KeyType = 'day' | 'hour' | 'min' | 'sec'; + +const keys: KeyType[] = ['day', 'hour', 'min', 'sec']; + +const labels = ['DAYS', 'HRS', 'MINS', 'SEC']; + +interface TimerProps { + time: Record; +} + +export function Timer({ time }: TimerProps) { + const mounted = useMounted(); + + if (!mounted) return <>; + + return ( +
    + {keys.map((key, index) => ( + <> + {index !== 0 && :} +
    +
    + {time[key].split('').map((text, jdx) => ( + {text} + ))} +
    + +

    {labels[index]}

    +
    + + ))} +
    + ); +} + +const layoutCss = (theme: Theme) => css` + width: 100%; + margin: auto; + display: flex; + background-color: ${theme.colors.black800}; + color: ${theme.colors.yellow500}; + + padding: 26px 24px; + + & > * { + flex: 1; + } + + ${mediaQuery('mobile')} { + padding: 10px; + } +`; + +const timeSplitCss = (theme: Theme) => css` + ${theme.typos.decimal.title1} + color: ${theme.colors.yellow500}; + line-height: 101px; + text-align: center; + + ${mediaQuery('mobile')} { + font-size: 24px; + line-height: 44px; + } +`; + +const timeTextCss = (theme: Theme) => css` + & > div { + ${theme.typos.decimal.title1} + color: ${theme.colors.yellow500}; + display: flex; + gap: 11px; + + span { + background-color: ${theme.colors.black400}; + width: 61px; + padding: 14px 10px 6px; // NOTE : 숫자 위아래 맞춤 + text-align: center; + } + } + + & > p { + ${theme.typos.decimal.body1} + color: ${theme.colors.white}; + text-align: center; + margin-top: 16px; + } + + ${mediaQuery('mobile')} { + & > div { + font-size: 24px; + gap: 2px; + span { + width: 29px; + padding: 6px; + } + } + + & > p { + font-size: 16px; + } + } +`; diff --git a/src/components/TimerContainer/TimerContainer.stories.tsx b/src/components/TimerContainer/TimerContainer.stories.tsx new file mode 100644 index 00000000..d6d84c98 --- /dev/null +++ b/src/components/TimerContainer/TimerContainer.stories.tsx @@ -0,0 +1,17 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import { TimerContainer } from './index'; + +const meta: Meta = { + title: 'components/TimerContainer', + component: TimerContainer, + args: {}, +}; + +export default meta; + +type Story = StoryObj; + +export const Primary: Story = { + render: () => , +}; diff --git a/src/components/TimerContainer/TimerContainer.tsx b/src/components/TimerContainer/TimerContainer.tsx new file mode 100644 index 00000000..e3b3082f --- /dev/null +++ b/src/components/TimerContainer/TimerContainer.tsx @@ -0,0 +1,181 @@ +import Image from 'next/image'; +import { useRouter } from 'next/router'; +import { css, Theme } from '@emotion/react'; + +import { Button } from '~/components/Button'; +import { END_DATE } from '~/constant/common'; +import useIsInProgress from '~/hooks/useIsInProgress'; +import { commonLayoutCss } from '~/styles/layout'; +import { mediaQuery } from '~/styles/media'; + +import { Timer } from './Timer'; +import useDiffDay from './useDiffDay'; + +export function TimerContainer() { + const { isInProgress, progressState } = useIsInProgress(); + const time = useDiffDay(END_DATE); + + const router = useRouter(); + + const onButtonClick = () => { + router.push('/apply'); + }; + + return ( +
    +
    + main-bg +
    +
    +
    +
    +
    +

    DEPROMEET

    +

    디프만은 디자이너와 개발자가 만나 서비스 기획부터 런칭까지

    +

    하나의 프로덕트를 완성하며 성장하는 IT 커뮤니티입니다

    + +
    +

    디프만은 디자이너와 개발자가 만나

    +

    서비스 기획부터 런칭까지 하나의 프로덕트를

    +

    완성하며 성장하는 IT 커뮤니티입니다

    +
    +
    + + +
    +
    +
    + ); +} + +const FINISH_TIME_OBJ = { + day: '00', + hour: '00', + min: '00', + sec: '00', +}; + +const containerCss = css` + position: relative; + padding: 30px 0; + background: linear-gradient(180deg, #0973ee 0%, rgba(9, 115, 238, 0) 100%); + overflow: hidden; + + height: 828px; + + ${mediaQuery('pc')} { + padding: 0; + } + + ${mediaQuery('mobile')} { + height: 428px; + } +`; + +const bgImageCss = css` + position: absolute; + top: 20px; + left: 0; + right: 0; + z-index: 0; + text-align: center; + + img { + width: 1300px; + height: 768.857px; + + @media screen and (max-width: 1300px) { + width: 100%; + height: auto; + } + } + + ${mediaQuery('pc')} { + top: 0; + } +`; + +const layoutCss = css` + margin: auto; + + max-width: 726px; + + & > div { + width: 100%; + position: relative; + z-index: 2; // NOTE : gradient 뒤로 가려지지 않게 + margin: 0 auto; + + & > * { + margin-bottom: 20px; + } + } + ${mediaQuery('pc')} { + margin: 0 auto; + } + + ${mediaQuery('mobile')} { + max-width: 400px; + + & > div { + & > * { + margin-bottom: 8px; + } + } + } +`; + +const gradientCss = css` + background: linear-gradient(0deg, #070814 0%, rgba(7, 8, 20, 0) 100%); + width: 100vw; + height: 445px; + position: absolute; + bottom: 0; + left: 0; + z-index: 1; +`; + +const headingCss = (theme: Theme) => css` + text-align: center; + padding-top: 147px; + padding-bottom: 20px; + + & > h1 { + ${theme.typos.decimal.title1} + color: ${theme.colors.white}; + margin-bottom: 20px; + } + + p { + ${theme.typos.pretendard.subTitle2}; + color: ${theme.colors.gray20}; + } + + ${mediaQuery('mobile')} { + padding-top: 65px; + padding-bottom: 16px; + & > h1 { + ${theme.typos.decimal.title2}; + margin-bottom: 8px; + } + + & > p { + display: none; + } + + div > p { + ${theme.typos.pretendard.body2}; + font-size: 14px; + } + } +`; + +const mobileOnlyCss = css` + display: none; + + ${mediaQuery('mobile')} { + display: block; + } +`; diff --git a/src/components/TimerContainer/index.tsx b/src/components/TimerContainer/index.tsx new file mode 100644 index 00000000..1799e55a --- /dev/null +++ b/src/components/TimerContainer/index.tsx @@ -0,0 +1 @@ +export { TimerContainer } from './TimerContainer'; diff --git a/src/components/TimerContainer/useDiffDay.ts b/src/components/TimerContainer/useDiffDay.ts new file mode 100644 index 00000000..e9824a9d --- /dev/null +++ b/src/components/TimerContainer/useDiffDay.ts @@ -0,0 +1,27 @@ +import { useEffect, useState } from 'react'; + +export default function useDiffDay(deadlineDay: string) { + const [date, setDate] = useState(diffDay(deadlineDay)); + + useEffect(() => { + const timer = setInterval(() => { + setDate(diffDay(deadlineDay)); + }, 1000); + return () => clearInterval(timer); + }, [deadlineDay]); + + return date; +} + +function diffDay(deadLine: string) { + const masTime = new Date(deadLine); + const todayTime = new Date(); + + const diff = new Date(masTime.getTime() - todayTime.getTime()).getTime(); + + const day = String(Math.floor(diff / (1000 * 3600 * 24))).padStart(2, '0'); + const hour = String(Math.floor((diff / (1000 * 3600)) % 24)).padStart(2, '0'); + const minute = String(Math.floor((diff / (1000 * 60)) % 60)).padStart(2, '0'); + const second = String(Math.floor((diff / 1000) % 60)).padStart(2, '0'); + return { day, hour, min: minute, sec: second }; +} diff --git a/src/components/about/DesktopSessions.tsx b/src/components/about/DesktopSessions.tsx deleted file mode 100644 index 3a6b1486..00000000 --- a/src/components/about/DesktopSessions.tsx +++ /dev/null @@ -1,130 +0,0 @@ -import { css } from '@emotion/react'; - -import { colors } from '~/styles/constants'; - -import { weekCircleSpanCss, weekHeadingCss } from './sessionCss'; - -export default function DesktopSessions() { - return ( - <> -
    -
    - -

    - 1 - 3 - WEEK -

    -

    - OT 이후 서비스 기획을 위한 -
    - 아이디에이션을 진행하고 -
    - 이를 바탕으로 MVP를 설정해요 -

    -
    - -
    - -

    - 4 - 8 - WEEK -

    -

    - 네트워킹 데이를 통해 같은 직군의 멤버들과 -
    - 친해지는 동시에 UT와 중간 발표로 -
    - 팀간 유의미한 피드백을 주고받아요 -

    -
    -
    - -
    -
    - -

    - 9 - 14 - WEEK -

    -

    - 열심히 팀 활동을 수행하여 -
    - 서비스를 론칭해요 -

    -
    - -
    - -

    - 15 - 16 - WEEK -

    -

    - 론칭된 서비스를 선보일 시간! -
    - DEMO DAY 에서 우리만의 서비스를 공유해요 -

    -
    -
    - - ); -} - -const weekParagraphCss = css` - font-weight: 600; - font-size: 1.25rem; - line-height: 140%; -`; - -const upperLineBoxCss = css` - margin-left: 10vw; - width: calc(100% - 10vw); - border-top: solid 1px ${colors.black}; - padding-top: 55px; - padding-right: 20px; - - display: flex; - gap: 15vw; - - margin-bottom: 50px; -`; - -const downlineBoxCss = css` - width: calc(100% - 10vw); - border-top: solid 1px ${colors.black}; - padding-top: 55px; - padding-left: 20px; - - display: flex; - justify-content: flex-end; - gap: 15vw; -`; - -const timelineArticleCss = css` - position: relative; -`; - -const timelineDotCss = css` - position: absolute; - /* NOTE: -paddint-top - (size/2)*/ - top: calc(-55px - 4px); - - width: 7px; - height: 7px; - border-radius: 50%; - background-color: ${colors.black}; - z-index: 10; -`; - -const downLastWeekCss = css` - &::after { - content: ''; - position: absolute; - top: calc(-55px - 4px); - left: 0; - width: 100%; - height: 20px; - background-color: ${colors.background}; - z-index: 9; - } -`; diff --git a/src/components/about/HeaderSection.tsx b/src/components/about/HeaderSection.tsx deleted file mode 100644 index 68ac5cda..00000000 --- a/src/components/about/HeaderSection.tsx +++ /dev/null @@ -1,151 +0,0 @@ -import Image from 'next/image'; -import { css } from '@emotion/react'; -import { m, useScroll, useSpring, useTransform } from 'framer-motion'; - -import { ABOUT_IMAGE_BASE } from '~/constants/images'; -import useMediaQuery from '~/hooks/use-media-query'; -import { mediaQuery } from '~/styles/constants'; - -const MOBILE_HEADER = `${ABOUT_IMAGE_BASE}/mobile-header.webp`; -const HEADER_FRONT = `${ABOUT_IMAGE_BASE}/header-front.webp`; -const HEADER_BACK = `${ABOUT_IMAGE_BASE}/header-back.webp`; - -export default function HeaderSection() { - const isMobile = useMediaQuery('xs'); - - const { scrollY } = useScroll(); - const allAboutX = useTransform(scrollY, [0, isMobile ? 200 : 320], [0, isMobile ? 350 : 560]); - const depromeetX = useTransform(scrollY, [0, isMobile ? 200 : 320], [0, isMobile ? 380 : 400]); - const springAllAboutX = useSpring(allAboutX, { stiffness: 200, damping: 40 }); - const springDepromeetX = useSpring(depromeetX, { stiffness: 200, damping: 40 }); - - return ( -
    - {!isMobile && ( - 디프만 - )} - - - ALL ABOUT - - - DEPROMEET - - - 디프만 - -

    디프만의 모든것

    -
    - ); -} - -const sectionCss = css` - position: relative; - width: 100%; - height: 538px; - padding-bottom: 25px; - display: flex; - flex-direction: column; - justify-content: flex-end; - align-items: center; - - margin-bottom: 130px; - - ${mediaQuery('xs')} { - height: 430px; - - margin-bottom: 80px; - } -`; - -const imageCss = css` - position: absolute; - top: 0; - left: 0; - object-fit: cover; - z-index: -1; -`; - -const graphicTextCss = css` - position: absolute; - font-weight: 600; - z-index: -2; - font-size: 145px; - - ${mediaQuery('sm')} { - font-size: 100px; - } - - ${mediaQuery('xs')} { - font-size: 45px; - } -`; - -const allAboutSpanCss = css` - ${graphicTextCss}; - top: 50px; - left: 55px; - - ${mediaQuery('sm')} { - left: 20px; - } - - ${mediaQuery('xs')} { - top: 24px; - left: 20px; - } -`; - -const depromeetSpanCss = css` - ${graphicTextCss}; - top: 200px; - left: 300px; - - ${mediaQuery('md')} { - left: 120px; - } - - ${mediaQuery('sm')} { - top: 150px; - left: 80px; - } - - ${mediaQuery('xs')} { - top: 72px; - left: 20px; - } -`; - -const headingCss = css` - font-weight: 500; - font-size: 1.5rem; - line-height: 1.8125rem; - - ${mediaQuery('xs')} { - font-size: 16px; - line-height: 140%; - } -`; diff --git a/src/components/about/JobGroupSection.tsx b/src/components/about/JobGroupSection.tsx deleted file mode 100644 index 4ca5757e..00000000 --- a/src/components/about/JobGroupSection.tsx +++ /dev/null @@ -1,344 +0,0 @@ -import { useEffect, useState } from 'react'; -import Image from 'next/image'; -import { css } from '@emotion/react'; -import { AnimatePresence, m, Variants } from 'framer-motion'; - -import { ABOUT_IMAGE_BASE } from '~/constants/images'; -import { defaultEasing } from '~/constants/motions'; -import useMediaQuery from '~/hooks/use-media-query'; -import { colors, mediaQuery } from '~/styles/constants'; -import { section36HeadingCss, sectionSmallCss } from '~/styles/css'; - -import { ClickableButton } from '../common/Clickable'; -import { SharpInCircleIcon } from '../common/icons/SharpInCircleIcon'; - -export default function JobGroupSection() { - const isMobile = useMediaQuery('xs'); - const { currentJob, onJobClick, currentJobInform } = useJobInform(); - - return ( -
    - JOB GROUP -

    - 디프만을 구성하는 -
    - 디자이너와 개발자 -

    - -
    - {JOBS.map(job => ( - - - {currentJob === job && ( - - - - )} - - {job} - - ))} -
    - - - -
    - {currentJobInform.name} -
    -
    - -

    - {currentJobInform.name} - OF DEPROMEET -

    -

    {currentJobInform.description}

    -
    -
    -
    -
    - ); -} - -const sectionCss = css` - width: 100%; - display: flex; - flex-direction: column; - align-items: center; - - margin-bottom: 180px; - - ${mediaQuery('xs')} { - margin-bottom: 100px; - } -`; - -const smallCss = css` - ${sectionSmallCss}; - - margin-bottom: 10px; -`; - -const headingCss = css` - ${section36HeadingCss}; - - margin-bottom: 60px; - - ${mediaQuery('xs')} { - margin-bottom: 40px; - } -`; - -const buttonWrapperCss = css` - display: flex; - - margin-bottom: 56px; - - ${mediaQuery('xs')} { - flex-wrap: wrap; - justify-content: center; - - margin-bottom: 20px; - } -`; - -const buttonCss = css` - position: relative; - padding: 15px 25px; - font-weight: 500; - font-size: 1.125rem; - line-height: 1.375rem; - - ${mediaQuery('xs')} { - font-size: 16px; - line-height: 19px; - } -`; - -const currentJobButtonCss = css` - text-decoration: underline; -`; - -const currentJobIconCss = css` - position: absolute; - left: 3px; - top: 17px; -`; - -const currentJobIconVariants: Variants = { - initial: { - opacity: 0, - y: 10, - transition: { - duration: 0.3, - ease: defaultEasing, - }, - }, - animate: { - opacity: 1, - y: 0, - transition: { - duration: 0.3, - ease: defaultEasing, - }, - }, - exit: { - opacity: 0, - scale: 0.2, - transition: { - duration: 0.3, - ease: defaultEasing, - }, - }, -}; - -const articleCss = css` - width: 100%; - height: 450px; - border-top: solid 1px ${colors.black}; - border-bottom: solid 1px ${colors.black}; - - display: flex; - - ${mediaQuery('xs')} { - flex-direction: column; - } -`; - -const articleVariants: Variants = { - initial: { - opacity: 0, - transition: { - duration: 0.5, - ease: defaultEasing, - }, - }, - animate: { - opacity: 1, - transition: { - duration: 0.5, - ease: defaultEasing, - }, - }, - exit: { - opacity: 0, - transition: { - duration: 0.5, - ease: defaultEasing, - }, - }, -}; - -const imageWrapperCss = css` - position: relative; - width: 50%; - height: 100%; - flex-shrink: 0; - - & > img { - object-fit: cover; - } - - ${mediaQuery('xs')} { - width: 100%; - height: 200px; - } -`; - -const descriptionWrapperCss = css` - max-width: 400px; - margin: 50px 100px; - display: flex; - flex-direction: column; - - ${mediaQuery('xs')} { - height: 100%; - margin: 20px auto; - padding: 0 16px; - } -`; - -const descriptionSharpIconCss = css` - margin-bottom: 8px; -`; - -const jobHeadingCss = css` - display: flex; - justify-content: space-between; - align-items: center; - - font-weight: 600; - font-size: 1.25rem; - line-height: 1.75rem; - - & > i { - font-family: 'Helvetica'; - font-style: italic; - font-weight: 400; - margin: 0 10px; - } -`; - -const jobParagraphCss = css` - flex-grow: 1; - display: flex; - align-items: flex-end; - - font-weight: 600; - font-size: 1.25rem; - line-height: 140%; - - ${mediaQuery('xs')} { - font-weight: 500; - font-size: 16px; - line-height: 22.4px; - } -`; - -const JOBS = ['UIUX DESIGN', 'iOS', 'ANDROID', 'WEB', 'SERVER'] as const; -type Job = (typeof JOBS)[number]; - -interface JobInform { - name: string; - description: string; - src: string; -} - -type JobInforms = { - [key in Job]: JobInform; -}; - -const JOB_INFORMS: JobInforms = { - 'UIUX DESIGN': { - name: 'UIUX DESIGNER', - description: - '디프만의 UIUX 디자이너는 UX/UI/GUI 등 서비스 런칭에 필요한 다양한 디자인 업무를 담당하고, 개발자와 커뮤니케이션하여 멋진 서비스를 만들어요!', - src: `${ABOUT_IMAGE_BASE}/designer.webp`, - }, - iOS: { - name: 'iOS DEVELOPER', - description: - '디프만의 iOS 개발자는 완성도 있는 UI와 플랫폼에 최적화된 기술로 백엔드 개발자에 의해 구축된 서버와 통신하며 실제 서비스를 만들어 볼 수 있는 특별한 기회를 경험할 수 있어요.', - src: `${ABOUT_IMAGE_BASE}/ios.webp`, - }, - ANDROID: { - name: 'ANDROID DEVELOPER', - description: - '디프만의 ANDROID 개발자는 완성도 있는 UI와 플랫폼에 최적화된 기술로 백엔드 개발자에 의해 구축된 서버와 통신하며 실제 서비스를 만들어 볼 수 있는 특별한 기회를 경험할 수 있어요.', - src: `${ABOUT_IMAGE_BASE}/android.webp`, - }, - WEB: { - name: 'WEB DEVELOPER', - description: - '디프만의 WEB 개발자는 서비스 아이디어에 따라 웹사이트 뿐만 아니라 웹앱, PWA에서 웹뷰 앱까지! 다양한 플랫폼에서 동작하는 웹 서비스를 구현해볼 수 있어요.', - src: `${ABOUT_IMAGE_BASE}/web.webp`, - }, - SERVER: { - name: 'SERVER DEVELOPER', - description: - '디프만의 SERVER 개발자는 서비스의 핵심 비즈니스 로직 구현을 담당하며, 서비스 내 데이터 흐름을 설계합니다. INFRASTRUCTURE 구축부터 배포, 운영까지 경험해보세요.', - src: `${ABOUT_IMAGE_BASE}/server.webp`, - }, -}; - -function useJobInform() { - const [currentJob, setCurrentJob] = useState('UIUX DESIGN'); - const [currentJobInform, setCurrentJobInform] = useState(JOB_INFORMS[currentJob]); - - useEffect(() => { - setCurrentJobInform(JOB_INFORMS[currentJob]); - }, [currentJob]); - - const onJobClick = (job: Job) => () => { - setCurrentJob(job); - }; - - return { currentJob, onJobClick, currentJobInform }; -} diff --git a/src/components/about/MobileSessions.tsx b/src/components/about/MobileSessions.tsx deleted file mode 100644 index e4ca5174..00000000 --- a/src/components/about/MobileSessions.tsx +++ /dev/null @@ -1,129 +0,0 @@ -import { css } from '@emotion/react'; - -import { colors } from '~/styles/constants'; - -import { weekCircleSpanCss, weekHeadingCss } from './sessionCss'; - -export default function MobileSessions() { - return ( -
    -
    - -

    - 1 - 3 - WEEK -

    -

    - OT 이후 서비스 기획을 위한 -
    - 아이디에이션을 진행하고 -
    - 이를 바탕으로 MVP를 설정해요 -

    -
    - -
    - -

    - 4 - 8 - WEEK -

    -

    - 네트워킹 데이를 통해 같은 직군의 멤버들과 -
    - 친해지는 동시에 UT와 중간 발표로 -
    - 팀간 유의미한 피드백을 주고받아요 -

    -
    - -
    - -

    - 9 - 14 - WEEK -

    -

    - 열심히 팀 활동을 수행하여 -
    - 서비스를 론칭해요 -

    -
    - -
    - -

    - 9 - 14 - WEEK -

    -

    - 론칭된 서비스를 선보일 시간! -
    - DEMO DAY 에서 우리만의 서비스를 공유해요 -

    -
    -
    - ); -} - -const wrapperCss = css` - padding: 0 16px; - - display: flex; - flex-direction: column; - gap: 60px; -`; - -const articleCss = css` - position: relative; - padding-left: 16px; - - &::before { - position: absolute; - /* NOTE : heading height / 2 */ - top: 10px; - left: 0; - - content: ''; - width: 1px; - /* NOTE : + gap */ - height: calc(100% + 60px); - background-color: ${colors.black}; - } -`; - -const timelineDotCss = css` - position: absolute; - /* NOTE : heading height / 2 */ - top: 10px; - /* NOTE : - width / 2 */ - left: -3px; - - width: 7px; - height: 7px; - border-radius: 50%; - background-color: ${colors.black}; - z-index: 10; -`; - -const lastWeekCss = css` - &::after { - content: ''; - position: absolute; - /* NOTE : heading height / 2 */ - top: 12px; - left: 0; - width: 4px; - - /* NOTE : + gap */ - height: calc(100% + 60px); - background-color: ${colors.background}; - z-index: 9; - } -`; - -const paragraphCss = css` - font-weight: 500; - font-size: 18px; - line-height: 140%; -`; diff --git a/src/components/about/MoreExperienceSection.tsx b/src/components/about/MoreExperienceSection.tsx deleted file mode 100644 index 928968bc..00000000 --- a/src/components/about/MoreExperienceSection.tsx +++ /dev/null @@ -1,316 +0,0 @@ -import Image from 'next/image'; -import { css } from '@emotion/react'; -import { m, Variants } from 'framer-motion'; - -import { ABOUT_IMAGE_BASE } from '~/constants/images'; -import { defaultEasing } from '~/constants/motions'; -import useMediaQuery from '~/hooks/use-media-query'; -import useToggle from '~/hooks/use-toggle'; -import { colors, mediaQuery } from '~/styles/constants'; -import { layoutCss, section36HeadingCss, sectionSmallCss } from '~/styles/css'; - -export default function MoreExperienceSection() { - return ( -
    - MORE EXPERIENCE -

    - 일할 땐 일하고 -
    - 놀땐 노는 디프만 -

    - -
    - {EXPERIENCES.map(experience => ( - - ))} -
    -
    - ); -} - -const sectionCss = css` - ${layoutCss}; - - display: flex; - flex-direction: column; - align-items: center; - - margin-bottom: 180px; - - ${mediaQuery('xs')} { - margin-bottom: 100px; - } -`; - -const smallCss = css` - ${sectionSmallCss}; - - margin-bottom: 10px; -`; - -const headingCss = css` - ${section36HeadingCss}; - text-align: center; - - margin-bottom: 80px; - - ${mediaQuery('xs')} { - margin-bottom: 60px; - } -`; - -const cardWrapperCss = css` - display: flex; - justify-content: center; - flex-wrap: wrap; - gap: 24px; - - ${mediaQuery('xs')} { - gap: 11px; - } -`; - -interface Experience { - icon: string; - name: string; - description: string; - src: string; -} - -const EXPERIENCES: Experience[] = [ - { - icon: 'H', - name: '해커톤', - description: '13기 처음 선보이는 디프만의 해커톤, 1박2일간 함께 프로젝트에 도전해봐요.', - src: `${ABOUT_IMAGE_BASE}/hackathon.webp`, - }, - { - icon: 'N', - name: '네트워킹 데이', - description: '같은 직군, 같은 개발 언어를 가진 디프만 멤버들과 네트워킹할 수 있어요.', - src: `${ABOUT_IMAGE_BASE}/networking.webp`, - }, - { - icon: 'S', - name: '스터디', - description: '독서, 공부부터 포폴까지 자유롭게 스터디를 만들고 참여할 수 있어요.', - src: `${ABOUT_IMAGE_BASE}/study.webp`, - }, - { - icon: 'C', - name: '커피챗', - description: '현업에서 일하는 멋진 디프만 선배들과 고민을 나누고 이야기를 들을 수 있어요.', - src: `${ABOUT_IMAGE_BASE}/coffeechat.webp`, - }, - { - icon: 'G', - name: '모임', - description: '같은 관심사를 가진 디프만 멤버들끼리 모임을 통해 취향을 공유할 수 있어요.', - src: `${ABOUT_IMAGE_BASE}/group.webp`, - }, - { - icon: 'M', - name: '번개', - description: '프로젝트와 별개로 디프만 멤버들과 가볍게 만나 친목을 즐길 수 있어요.', - src: `${ABOUT_IMAGE_BASE}/meeting.webp`, - }, -]; - -function Card({ icon, name, description, src }: Experience) { - const isMobile = useMediaQuery('xs'); - - const [isOpen, toggleIsOpen] = useToggle(false); - - const onMobileClick = () => { - if (!isMobile) return; - toggleIsOpen(); - }; - - return ( - - {name} - - - {icon} - - {name} - - - - - {description} - - - - ); -} - -const articleCss = css` - position: relative; - width: 384px; - height: 300px; - padding: 32px 40px; - - ${mediaQuery('sm')} { - width: calc(50% - 24px); - height: 224px; - padding: 20px; - } - - ${mediaQuery('xs')} { - width: calc(50% - 6px); - } -`; - -const imageCss = css` - position: absolute; - top: 0; - left: 0; - object-fit: cover; - z-index: -1; -`; - -const spanCss = css` - position: relative; - display: flex; - align-items: center; - gap: 6px; - - font-weight: 600; - font-size: 20px; - line-height: 28px; - color: ${colors.white}; - z-index: 10; - - ${mediaQuery('xs')} { - font-size: 16px; - } -`; - -const spanVriants: Variants = { - default: { - color: colors.white, - transition: { - duration: 0.3, - ease: defaultEasing, - }, - }, - hover: { - color: colors.point, - transition: { - duration: 0.3, - ease: defaultEasing, - }, - }, -}; - -const iconSpanCss = css` - display: flex; - justify-content: center; - align-items: center; - width: 22px; - height: 22px; - border-radius: 50%; - border: solid 2px ${colors.white}; - - font-weight: 500; - font-size: 17px; - letter-spacing: -1px; - color: ${colors.white}; -`; - -const iconSpanVariants: Variants = { - default: { - borderColor: colors.white, - transition: { - duration: 0.3, - ease: defaultEasing, - }, - }, - hover: { - borderColor: colors.point, - backgroundColor: colors.point, - transition: { - duration: 0.3, - ease: defaultEasing, - }, - }, -}; - -const hoverWrapperCss = css` - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - padding: 32px 40px; - - background: rgba(255, 255, 255, 0.5); - backdrop-filter: blur(12.5px); - z-index: 9; - - display: flex; - flex-direction: column; - justify-content: end; - opacity: 0; - - border-top: solid 1px ${colors.black}; - - ${mediaQuery('sm')} { - padding: 20px; - } -`; - -const hoverWrapperVariants: Variants = { - default: { - opacity: 0, - transition: { - duration: 0.3, - ease: defaultEasing, - }, - }, - hover: { - opacity: 1, - transition: { - duration: 0.3, - ease: defaultEasing, - }, - }, -}; - -const paragraphCss = css` - font-weight: 600; - font-size: 1.25rem; - line-height: 140%; - - ${mediaQuery('xs')} { - font-weight: 500; - font-size: 14px; - } -`; - -const paragraphVariants: Variants = { - default: { - opacity: 0, - y: 10, - transition: { - duration: 0.5, - ease: defaultEasing, - }, - }, - hover: { - opacity: 1, - y: 0, - transition: { - delay: 0.2, - duration: 0.5, - ease: defaultEasing, - }, - }, -}; diff --git a/src/components/about/SessionSection.tsx b/src/components/about/SessionSection.tsx deleted file mode 100644 index 970673da..00000000 --- a/src/components/about/SessionSection.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import { css } from '@emotion/react'; - -import useMediaQuery from '~/hooks/use-media-query'; -import { colors, mediaQuery } from '~/styles/constants'; -import { layoutCss, section36HeadingCss, sectionSmallCss } from '~/styles/css'; - -import DesktopSessions from './DesktopSessions'; -import MobileSessions from './MobileSessions'; - -export default function SessionSection() { - const isMobile = useMediaQuery('xs'); - - return ( -
    -
    - SESSION -

    - 체계적이고 효율적으로 굴러가는 -
    - 디프만 정규세션 -

    - - * -

    - 디프만 13기는 매주 토요일, 총 17주간 진행되며, -
    - 정규세션 이외에도 팀 활동은 자율적으로 진행합니다 -

    -
    - - {isMobile ? : } -
    - ); -} - -const sectionCss = css` - width: 100%; - - margin-bottom: 240px; - - ${mediaQuery('xs')} { - margin-bottom: 100px; - } -`; - -const headingArticleCss = css` - ${layoutCss}; - display: flex; - flex-direction: column; - align-items: center; - text-align: center; - - margin-bottom: 83px; - - ${mediaQuery('xs')} { - margin-bottom: 60px; - } -`; - -const smallCss = css` - ${sectionSmallCss}; - - margin-bottom: 10px; -`; - -const headingCss = css` - ${section36HeadingCss}; - - margin-bottom: 40px; - - ${mediaQuery('xs')} { - margin-bottom: 20px; - } -`; - -const asteriskCss = css` - font-weight: 500; - font-size: 26px; - line-height: 31px; - color: ${colors.point}; -`; - -const paragraphCss = css` - font-weight: 500; - font-size: 1rem; - line-height: 140%; - color: ${colors.gray600}; -`; diff --git a/src/components/about/SponsorSection.tsx b/src/components/about/SponsorSection.tsx deleted file mode 100644 index 3ceff447..00000000 --- a/src/components/about/SponsorSection.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import Image from 'next/image'; -import { css } from '@emotion/react'; - -import { SPONSOR_IMAGE_BASE } from '~/constants/images'; -import { mediaQuery } from '~/styles/constants'; -import { layoutCss, section36HeadingCss, sectionSmallCss } from '~/styles/css'; - -export default function SponsorSection() { - return ( -
    - SPONSOR -

    - 디프만과 함께하는 -
    - 후원사를 소개합니다 -

    -
    - {SPONSORS.map(sponsor => ( - - ))} -
    -
    - ); -} - -const sectionCss = css` - ${layoutCss}; - display: flex; - flex-direction: column; - align-items: center; - - margin-bottom: 180px; - - ${mediaQuery('xs')} { - margin-bottom: 100px; - } -`; - -const smallCss = css` - ${sectionSmallCss}; - margin-bottom: 10px; -`; - -const headingCss = css` - ${section36HeadingCss}; - text-align: center; - - margin-bottom: 80px; - - ${mediaQuery('xs')} { - margin-bottom: 40px; - } -`; - -const articleCss = css` - width: 80%; - display: flex; - flex-wrap: wrap; - justify-content: center; - align-items: center; - row-gap: 30px; - column-gap: 7rem; -`; - -interface SponsorImage { - name: string; - src: string; - width: number; - height: number; -} - -const SPONSORS: SponsorImage[] = [ - { name: '임팩트 캠퍼스', src: `${SPONSOR_IMAGE_BASE}/impact-campus.svg`, width: 211, height: 46 }, - { name: '네이버 클라우드', src: `${SPONSOR_IMAGE_BASE}/naver-cloud.svg`, width: 213, height: 23 }, - { name: '인프런', src: `${SPONSOR_IMAGE_BASE}/inflearn.svg`, width: 176, height: 33 }, - { name: 'AWS', src: `${SPONSOR_IMAGE_BASE}/aws.svg`, width: 88, height: 54 }, - { name: 'dcamp', src: `${SPONSOR_IMAGE_BASE}/dcamp.svg`, width: 162, height: 38 }, -]; - -function Sponsor({ name, src, width, height }: SponsorImage) { - return {name}; -} diff --git a/src/components/about/sessionCss.ts b/src/components/about/sessionCss.ts deleted file mode 100644 index 899228c4..00000000 --- a/src/components/about/sessionCss.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { css } from '@emotion/react'; - -import { colors } from '~/styles/constants'; - -export const weekHeadingCss = css` - display: flex; - align-items: center; - gap: 4px; - - margin-bottom: 26px; - - & > i { - font-family: 'Helvetica'; - font-style: italic; - font-weight: 400; - font-size: 20px; - line-height: 23px; - margin-left: 2px; - padding-top: 3px; - } -`; - -export const weekCircleSpanCss = css` - min-width: 29px; - padding-top: 1px; - padding-left: 7px; - padding-right: 7px; - height: 29px; - - display: flex; - justify-content: center; - align-items: center; - - border-radius: 50%; - background-color: ${colors.black}; - color: ${colors.gray100}; - - font-family: 'Helvetica'; - font-style: italic; - font-weight: 400; - font-size: 1.25rem; - letter-spacing: 3px; -`; diff --git a/src/components/common/ApplySection/ApplySection.tsx b/src/components/common/ApplySection/ApplySection.tsx deleted file mode 100644 index 32bce848..00000000 --- a/src/components/common/ApplySection/ApplySection.tsx +++ /dev/null @@ -1,109 +0,0 @@ -import { css, Interpolation, Theme } from '@emotion/react'; - -import { NOTION_RECRUIT_PATH } from '~/constants/common'; -import useIsInProgress from '~/hooks/use-is-in-progress'; -import { RecruitState } from '~/hooks/use-is-in-progress/use-is-in-progress'; -import { colors, mediaQuery } from '~/styles/constants'; -import { section36HeadingCss, sectionSmallCss } from '~/styles/css'; - -import { ClickableLink } from '../Clickable'; - -interface Props { - wrapperCss?: Interpolation; -} - -const applyMessageObj: Record = { - PREVIOUS: { - h1: '14기는 아직 준비중', - button: '모집 예정', - }, - IN_PROGRESS: { - h1: '이제 여러분 차례예요! \n디프만 13기 멤버가 되고 싶다면', - button: '바로 지원하기', - }, - FINISH: { - h1: '이제 여러분 차례예요! \n디프만 13기 멤버가 되고 싶다면', - button: '모집 마감', - }, -}; - -export default function ApplySection({ wrapperCss }: Props) { - const { isInProgress, progressState } = useIsInProgress(); - const applyMessage = applyMessageObj[progressState]; - - return ( -
    - APPLY -

    {applyMessage.h1}

    - - {isInProgress ? ( - - {applyMessage.button} - - ) : ( - - )} -
    - ); -} - -const sectionCss = css` - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - text-align: center; -`; - -const smallCss = css` - ${sectionSmallCss}; - margin-bottom: 10px; -`; - -const headingCss = css` - ${section36HeadingCss}; - margin-bottom: 60px; - - ${mediaQuery('xs')} { - margin-bottom: 36px; - } -`; - -const linkCss = css` - border-radius: 2px; - padding: 16px 98px; - background-color: ${colors.black}; - - font-weight: 600; - font-size: 20px; - line-height: 24px; - color: ${colors.gray100}; - - ${mediaQuery('xs')} { - padding: 18px 60px; - font-size: 16px; - line-height: 19px; - } -`; - -const disabledButtonCss = css` - border-radius: 2px; - padding: 16px 98px; - background-color: ${colors.gray500}; - - font-weight: 600; - font-size: 20px; - line-height: 24px; - color: ${colors.white}; - - ${mediaQuery('xs')} { - padding: 18px 60px; - font-size: 16px; - line-height: 19px; - } -`; diff --git a/src/components/common/ApplySection/index.tsx b/src/components/common/ApplySection/index.tsx deleted file mode 100644 index e3c073d0..00000000 --- a/src/components/common/ApplySection/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from './ApplySection'; diff --git a/src/components/common/BottomSheet/BottomSheet.tsx b/src/components/common/BottomSheet/BottomSheet.tsx deleted file mode 100644 index de91cce0..00000000 --- a/src/components/common/BottomSheet/BottomSheet.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import React, { ReactNode } from 'react'; -import { css } from '@emotion/react'; -import { motion, Variants } from 'framer-motion'; - -import { defaultEasing, defaultFadeInVariants, staggerOne } from '~/constants/motions'; - -import PortalWrapper from '../PortalWrapper'; - -export interface BottomSheetModalProps { - isShowing: boolean; - children: ReactNode; - onClose: VoidFunction; -} - -export default function BottomSheet({ isShowing, children, onClose }: BottomSheetModalProps) { - const onDeleteHandler = (e: React.MouseEvent) => { - if (e.target !== e.currentTarget) return; - onClose(); - }; - - return ( - - - - - {children} - - - - - ); -} - -const dimBackdropCss = () => css` - position: fixed; - z-index: 9000; - top: 0; - left: 0; - - width: 100vw; - height: 100%; - - background-color: rgba(0, 0, 0, 0.6); - - overflow: hidden; -`; - -const HIGHT = 190; -const contentWrapperCss = () => css` - position: absolute; - top: 100%; - transform: translateY(-100%); - z-index: 1000; - - width: 100%; - height: ${HIGHT}px; - - overflow-y: scroll; - border-radius: 20px 20px 0 0; -`; - -export const bottomSheetVariants: Variants = { - initial: { - y: 0, - transition: { duration: 0.4, ease: defaultEasing }, - willChange: 'transform', - }, - animate: { - y: '-100%', - transition: { duration: 0.4, ease: defaultEasing }, - willChange: 'transform', - }, - exit: { - y: 0, - transition: { duration: 0.4, ease: defaultEasing }, - willChange: 'transform', - }, -}; diff --git a/src/components/common/BottomSheet/index.tsx b/src/components/common/BottomSheet/index.tsx deleted file mode 100644 index a60bf829..00000000 --- a/src/components/common/BottomSheet/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from './BottomSheet'; diff --git a/src/components/common/Clickable/ClickableButton.tsx b/src/components/common/Clickable/ClickableButton.tsx deleted file mode 100644 index ae451fd3..00000000 --- a/src/components/common/Clickable/ClickableButton.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { HTMLAttributes } from 'react'; - -import useCursorState from '~/store/cursor/useCursorState'; - -export function ClickableButton({ children, ...props }: HTMLAttributes) { - const { onMouseEnter, onMouseLeave } = useCursorState(); - - return ( - - ); -} diff --git a/src/components/common/Clickable/ClickableLink.tsx b/src/components/common/Clickable/ClickableLink.tsx deleted file mode 100644 index 4209ffe3..00000000 --- a/src/components/common/Clickable/ClickableLink.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { ComponentProps } from 'react'; -import Link from 'next/link'; - -import useCursorState from '~/store/cursor/useCursorState'; - -export function ClickableLink({ children, ...props }: ComponentProps) { - const { onMouseEnter, onMouseLeave } = useCursorState(); - - return ( - - {children} - - ); -} diff --git a/src/components/common/Clickable/index.tsx b/src/components/common/Clickable/index.tsx deleted file mode 100644 index 0dd4d1a9..00000000 --- a/src/components/common/Clickable/index.tsx +++ /dev/null @@ -1,2 +0,0 @@ -export { ClickableButton } from './ClickableButton'; -export { ClickableLink } from './ClickableLink'; diff --git a/src/components/common/CustomCursor/CustomCursor.tsx b/src/components/common/CustomCursor/CustomCursor.tsx deleted file mode 100644 index baaf75de..00000000 --- a/src/components/common/CustomCursor/CustomCursor.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import { useEffect, useRef } from 'react'; -import { css } from '@emotion/react'; - -import { useUserAgent } from '~/hooks/use-user-agent'; -import useCursorState from '~/store/cursor/useCursorState'; - -const CURSOR_URL = '/common/cursor.webp'; - -export default function CustomCursorWrapper() { - const { isMobileAgent } = useUserAgent(); - - if (isMobileAgent) return <>; - return ; -} - -function CustomCursor() { - const cursorRef = useRef(null); - const { cursorState } = useCursorState(); - - useEffect(() => { - if (cursorRef == null || cursorRef.current == null) return; - - function handleMouseMove(e: MouseEvent) { - cursorRef.current?.setAttribute( - 'style', - `top: ${e.clientY}px;` + `left: ${e.clientX}px; display: inline` - ); - } - document.addEventListener('mousemove', handleMouseMove); - - function handleMouseLeave() { - cursorRef.current?.setAttribute('style', `display: none`); - } - document.addEventListener('mouseleave', handleMouseLeave); - // NOTE: firefox 대응 - document.documentElement.addEventListener('mouseleave', handleMouseLeave); - - return () => { - document.removeEventListener('mousemove', handleMouseMove); - document.removeEventListener('mouseleave', handleMouseLeave); - document.documentElement.removeEventListener('mouseleave', handleMouseLeave); - }; - }, []); - - return ; -} - -const cursorCss = css` - /* NOTE: 초기 값 */ - top: 1000px; - - background-image: url(${CURSOR_URL}); - background-size: contain; - width: 32px; - height: 32px; - position: fixed; - pointer-events: none; - z-index: 9999; - - transition: transform 0.3s cubic-bezier(0.6, -0.05, 0.01, 0.99); - transform-origin: left top; -`; - -const hoverCss = css` - /* NOTE: 44px */ - transform: scale(1.375); -`; diff --git a/src/components/common/CustomCursor/index.tsx b/src/components/common/CustomCursor/index.tsx deleted file mode 100644 index dd2fd94c..00000000 --- a/src/components/common/CustomCursor/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from './CustomCursor'; diff --git a/src/components/common/Footer/Footer.tsx b/src/components/common/Footer/Footer.tsx deleted file mode 100644 index 16317d00..00000000 --- a/src/components/common/Footer/Footer.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import { css } from '@emotion/react'; - -import { - DEPROMEET_BEHANCE, - DEPROMEET_EMAIL, - DEPROMEET_FACEBOOK, - DEPROMEET_GITHUB, - DEPROMEET_INSTAGRAM, - DEPROMEET_MEDIUM, -} from '~/constants/common'; -import { colors, mediaQuery } from '~/styles/constants'; -import { layoutCss } from '~/styles/css'; - -import { ClickableLink } from '../Clickable'; - -export default function Footer() { - const date = new Date(); - - return ( -
    -
    - - - - - - -
    - © {date.getFullYear()} DEPROMEET. ALL RIGHTS RESERVED. -
    - ); -} - -const footerCss = css` - ${layoutCss} - height: 136px; - - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - gap: 32px; - - ${mediaQuery('xs')} { - padding-top: 6px; - gap: 24px; - justify-content: start; - } -`; - -const anchorSectionCss = css` - display: flex; - gap: 3.25rem; - - ${mediaQuery('xs')} { - max-width: 348px; - - flex-wrap: wrap; - justify-content: center; - align-items: center; - - row-gap: 14px; - column-gap: 32px; - } -`; - -const copyRightCss = css` - font-size: 0.875rem; - font-weight: 500; - line-height: 140%; - color: ${colors.gray500}; -`; - -interface AnchorProps { - text: string; - href: string; -} - -function Anchor({ text, href }: AnchorProps) { - return ( - - {text} - - ); -} - -const anchorCss = css` - font-weight: 600; - font-size: 14px; - line-height: 140%; - - letter-spacing: -0.3px; -`; diff --git a/src/components/common/Footer/index.tsx b/src/components/common/Footer/index.tsx deleted file mode 100644 index be92134c..00000000 --- a/src/components/common/Footer/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from './Footer'; diff --git a/src/components/common/GNB/DesktopAnchorSection.tsx b/src/components/common/GNB/DesktopAnchorSection.tsx deleted file mode 100644 index 54ec7cf9..00000000 --- a/src/components/common/GNB/DesktopAnchorSection.tsx +++ /dev/null @@ -1,101 +0,0 @@ -import { PropsWithChildren } from 'react'; -import { useRouter } from 'next/router'; -import { css } from '@emotion/react'; -import { AnimatePresence, m } from 'framer-motion'; - -import { colors } from '~/styles/constants'; -import { layoutCss } from '~/styles/css'; - -import { ANCHORS_HEIGHT, aseteriskVariants, NAVIGATION_ROUTES } from './constants'; -import { ClickableLink } from '../Clickable'; -import { AsteriskIcon } from '../icons/AsteriskIcon'; -import { DepromeetIcon } from '../icons/DepromeetIcon'; - -export default function DesktopAnchorSection() { - const { pathname } = useRouter(); - - return ( -
    -
    - - - - - {NAVIGATION_ROUTES.map(route => ( - - - - {pathname.startsWith(route.path) && ( - - - - )} - - {route.name} - - - ))} -
    -
    - ); -} - -const anchorSectionCss = css` - height: ${ANCHORS_HEIGHT}px; - background: rgba(240, 240, 241, 0.6); - backdrop-filter: blur(25px); - - display: flex; - justify-content: center; - align-items: center; - - border-bottom: 1px solid ${colors.black}; -`; - -const anchorWrapperCss = css` - ${layoutCss}; - - display: flex; - justify-content: space-between; - align-items: center; -`; - -const anchorContentCss = css` - position: relative; - display: flex; - align-items: center; -`; - -const currentRouteIconCss = css` - position: absolute; - /* width - gap */ - left: calc(-14px - 4px); -`; - -interface AnchorProps { - href: string; -} - -function Anchor({ href, children }: PropsWithChildren) { - return ( - - {children} - - ); -} - -const anchorCss = css` - width: 20%; - display: flex; - justify-content: center; - align-items: center; - - font-weight: 600; - font-size: 1.125rem; -`; diff --git a/src/components/common/GNB/GNB.tsx b/src/components/common/GNB/GNB.tsx deleted file mode 100644 index d785f7bc..00000000 --- a/src/components/common/GNB/GNB.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { css } from '@emotion/react'; - -import useIsInProgress from '~/hooks/use-is-in-progress'; -import useMediaQuery from '~/hooks/use-media-query'; - -import { ANCHORS_HEIGHT, NAV_HEIGHT } from './constants'; -import DesktopAnchorSection from './DesktopAnchorSection'; -import MobileAnchorSection from './MobileAnchorSection'; -import RecrutingBanner from './RecrutingBanner'; - -export default function GNB() { - const isMobile = useMediaQuery('xs'); - const { isInProgress } = useIsInProgress(); - - return ( - <> - - -
    - - ); -} - -const navCss = css` - position: fixed; - top: 0; - left: 0; - z-index: 9998; - width: 100vw; -`; - -const scrollRemainerCss = (height: number) => css` - height: ${height}px; -`; diff --git a/src/components/common/GNB/HamburgerButton.tsx b/src/components/common/GNB/HamburgerButton.tsx deleted file mode 100644 index 2f4b3463..00000000 --- a/src/components/common/GNB/HamburgerButton.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { motion, SVGMotionProps } from 'framer-motion'; - -import { colors } from '~/styles/constants'; - -import Svg from '../icons/Svg'; - -interface Props { - toggleIsOpen: VoidFunction; -} - -export default function HamburgerButton({ toggleIsOpen }: Props) { - return ( - - ); -} - -function Path(props: SVGMotionProps) { - return ; -} diff --git a/src/components/common/GNB/HamburgerContent.tsx b/src/components/common/GNB/HamburgerContent.tsx deleted file mode 100644 index e8faff01..00000000 --- a/src/components/common/GNB/HamburgerContent.tsx +++ /dev/null @@ -1,110 +0,0 @@ -import Link from 'next/link'; -import { useRouter } from 'next/router'; -import { css } from '@emotion/react'; -import { AnimatePresence, m, Variants } from 'framer-motion'; - -import { defaultEasing } from '~/constants/motions'; -import { colors } from '~/styles/constants'; - -import { ANCHORS_HEIGHT, aseteriskVariants, NAVIGATION_ROUTES } from './constants'; -import { AsteriskIcon } from '../icons/AsteriskIcon'; - -export default function HamburgerContent() { - const { pathname } = useRouter(); - - return ( - - {NAVIGATION_ROUTES.map(eachRoute => ( - - - {pathname.startsWith(eachRoute.path) && ( - - - - )} - - - {eachRoute.name} - - - ))} - - ); -} - -const wrapperCss = css` - position: relative; - display: flex; - flex-direction: column; - flex-shrink: 0; - overflow: hidden; - z-index: 9998; -`; - -const contentVariants: Variants = { - closed: { - height: 0, - transition: { duration: 0.3, ease: defaultEasing }, - }, - open: { - height: 'auto', - transition: { duration: 0.3, ease: defaultEasing }, - }, -}; - -const anchorCss = css` - flex-shrink: 0; - font-weight: 600; - font-size: 1.125rem; - height: ${ANCHORS_HEIGHT}px; - background-color: ${colors.gray100}; - padding-left: 20px; - - display: flex; - align-items: center; - border-bottom: 1px solid ${colors.black}; - - transition: background-color 0.3s; - - &:active { - background-color: ${colors.gray200}; - } -`; - -const textCss = css` - position: absolute; -`; - -const textVariants: Variants = { - default: { - x: 0, - transition: { - duration: 0.3, - ease: defaultEasing, - delay: 0.3, - }, - }, - selected: { - x: 18, - transition: { - duration: 0.25, - ease: defaultEasing, - }, - }, -}; diff --git a/src/components/common/GNB/MobileAnchorSection.tsx b/src/components/common/GNB/MobileAnchorSection.tsx deleted file mode 100644 index 04eff27c..00000000 --- a/src/components/common/GNB/MobileAnchorSection.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import Link from 'next/link'; -import { css } from '@emotion/react'; -import { AnimatePresence, m } from 'framer-motion'; - -import useToggle from '~/hooks/use-toggle'; -import { colors } from '~/styles/constants'; -import { layoutCss } from '~/styles/css'; - -import { ANCHORS_HEIGHT } from './constants'; -import HamburgerButton from './HamburgerButton'; -import HamburgerContent from './HamburgerContent'; -import Overlay from './Overlay'; -import { DepromeetIcon } from '../icons/DepromeetIcon'; - -export default function MobileAnchorSection() { - const [isOpen, toggleIsOpen] = useToggle(); - - return ( - <> - -
    - - - - - -
    -
    - - {isOpen && } - - {isOpen && } - - ); -} - -const sectionCss = css` - position: relative; - height: ${ANCHORS_HEIGHT}px; - background-color: rgba(240, 240, 241, 0.6); - backdrop-filter: blur(25px); - transition: background-color 0.3s; - - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - - border-bottom: 1px solid ${colors.black}; - z-index: 9998; -`; - -const sectionOpenCss = css` - background-color: ${colors.gray100}; -`; - -const wrapperCss = css` - ${layoutCss}; - height: 100%; - display: flex; - justify-content: space-between; - align-items: center; - - flex-shrink: 0; -`; - -const titleCss = css` - font-weight: 700; - font-size: 1.125rem; -`; diff --git a/src/components/common/GNB/Overlay.tsx b/src/components/common/GNB/Overlay.tsx deleted file mode 100644 index 1720dbce..00000000 --- a/src/components/common/GNB/Overlay.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { css } from '@emotion/react'; - -interface Props { - close: VoidFunction; -} - -export default function Overlay({ close }: Props) { - return
    ; -} - -const overlayCss = css` - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100vh; - z-index: 9000; -`; diff --git a/src/components/common/GNB/RecrutingBanner.tsx b/src/components/common/GNB/RecrutingBanner.tsx deleted file mode 100644 index 673c1ff0..00000000 --- a/src/components/common/GNB/RecrutingBanner.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { css } from '@emotion/react'; - -import { NOTION_RECRUIT_PATH } from '~/constants/common'; -import { colors } from '~/styles/constants'; - -import { RECRUTING_BANNER_HEIGHT } from './constants'; -import { ClickableLink } from '../Clickable'; -import { ArrowIcon } from '../icons'; - -export default function RecrutingBanner() { - return ( -
    - - 디프만 13기 바로 지원하러 가기 - -
    - ); -} - -const wrapperCss = css` - position: relative; - height: ${RECRUTING_BANNER_HEIGHT}px; - background-color: ${colors.black}; - color: ${colors.white}; - - z-index: 9998; -`; - -const linkCss = css` - width: 100%; - height: 100%; - display: flex; - justify-content: center; - align-items: center; - gap: 9px; -`; diff --git a/src/components/common/GNB/constants.ts b/src/components/common/GNB/constants.ts deleted file mode 100644 index 3f266760..00000000 --- a/src/components/common/GNB/constants.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Variants } from 'framer-motion'; - -import { defaultEasing } from '~/constants/motions'; - -import { Route } from './type'; - -export const RECRUTING_BANNER_HEIGHT = 52; -export const ANCHORS_HEIGHT = 60; -export const NAV_HEIGHT = RECRUTING_BANNER_HEIGHT + ANCHORS_HEIGHT; - -export const NAVIGATION_ROUTES: readonly Route[] = [ - { name: '디프만 A TO Z', path: '/about' }, - { name: '지난 프로젝트', path: '/project' }, - { name: '문의하기', path: '/contact' }, - { name: '13기 모집 안내', path: '/recruit' }, -]; - -export const aseteriskVariants: Variants = { - initial: { - opacity: 0, - scale: 0, - transition: { - duration: 0.3, - ease: defaultEasing, - }, - }, - animate: { - opacity: 1, - scale: 1, - transition: { - duration: 0.5, - ease: defaultEasing, - }, - }, - exit: { - opacity: 0, - transition: { - duration: 0.25, - ease: defaultEasing, - }, - }, -}; diff --git a/src/components/common/GNB/index.tsx b/src/components/common/GNB/index.tsx deleted file mode 100644 index 06a5cc08..00000000 --- a/src/components/common/GNB/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from './GNB'; diff --git a/src/components/common/GNB/type.ts b/src/components/common/GNB/type.ts deleted file mode 100644 index 15acf97d..00000000 --- a/src/components/common/GNB/type.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface Route { - name: string; - path: string; -} diff --git a/src/components/common/PortalWrapper/PortalWrapper.tsx b/src/components/common/PortalWrapper/PortalWrapper.tsx deleted file mode 100644 index 74eaf2d5..00000000 --- a/src/components/common/PortalWrapper/PortalWrapper.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { PropsWithChildren } from 'react'; -import { AnimatePresence } from 'framer-motion'; -import { createPortal } from 'react-dom'; - -interface ModalWrapperProps { - isShowing: boolean; -} - -export default function PortalWrapper({ - children, - isShowing, -}: PropsWithChildren) { - const container = typeof window !== 'undefined' && document.body; - - return container ? ( - createPortal({isShowing && children}, container) - ) : ( - <> - ); -} diff --git a/src/components/common/PortalWrapper/index.tsx b/src/components/common/PortalWrapper/index.tsx deleted file mode 100644 index c022d39d..00000000 --- a/src/components/common/PortalWrapper/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from './PortalWrapper'; diff --git a/src/components/common/SEO/index.tsx b/src/components/common/SEO/index.tsx deleted file mode 100644 index 38d9fc1c..00000000 --- a/src/components/common/SEO/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from './SEO'; diff --git a/src/components/common/icons/AndPersentCircleIcon.tsx b/src/components/common/icons/AndPersentCircleIcon.tsx deleted file mode 100644 index 9e67e5d3..00000000 --- a/src/components/common/icons/AndPersentCircleIcon.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import Svg, { Props } from './Svg'; - -export function AndPersentCircleIcon({ color = '#121212', ...props }: Props) { - return ( - - - - - - - - - - - - ); -} diff --git a/src/components/common/icons/AnswerIcon.tsx b/src/components/common/icons/AnswerIcon.tsx deleted file mode 100644 index f435cb03..00000000 --- a/src/components/common/icons/AnswerIcon.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import Svg, { Props } from './Svg'; - -export function AnswerIcon(props: Props) { - return ( - - - - - ); -} diff --git a/src/components/common/icons/ArrowIcon.tsx b/src/components/common/icons/ArrowIcon.tsx deleted file mode 100644 index 889c6ae5..00000000 --- a/src/components/common/icons/ArrowIcon.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { css } from '@emotion/react'; - -import Svg, { Props } from './Svg'; - -export interface ChevronIconProps extends Props { - direction?: 'up' | 'right' | 'down' | 'left'; -} - -export function ArrowIcon({ - direction = 'right', - color = 'white', - css, - ...props -}: ChevronIconProps) { - return ( - - - - - - ); -} - -const DIRECTION_DEGREE = { - up: 270, - right: 0, - down: 90, - left: 180, -} as const; - -const ArrowIconCss = (degree: number) => css` - transform: rotate(${degree}deg); -`; diff --git a/src/components/common/icons/AsteriskIcon.tsx b/src/components/common/icons/AsteriskIcon.tsx deleted file mode 100644 index 1f9d6a5f..00000000 --- a/src/components/common/icons/AsteriskIcon.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import Svg, { Props } from './Svg'; - -export function AsteriskIcon({ color = '#0066FF', ...props }: Props) { - return ( - - - - - - - ); -} diff --git a/src/components/common/icons/BehanceIcon.tsx b/src/components/common/icons/BehanceIcon.tsx deleted file mode 100644 index 339985d4..00000000 --- a/src/components/common/icons/BehanceIcon.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { colors } from '~/styles/constants'; - -import Svg, { Props } from './Svg'; - -export function BehanceIcon(props: Props) { - return ( - - - - ); -} diff --git a/src/components/common/icons/BraceCircleIcon.tsx b/src/components/common/icons/BraceCircleIcon.tsx deleted file mode 100644 index bb8e3785..00000000 --- a/src/components/common/icons/BraceCircleIcon.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import Svg, { Props } from './Svg'; - -export function BraceCircleIcon({ color = '#121212', ...props }: Props) { - return ( - - - - - - - - ); -} diff --git a/src/components/common/icons/CheckIcon.tsx b/src/components/common/icons/CheckIcon.tsx deleted file mode 100644 index 177a7eb9..00000000 --- a/src/components/common/icons/CheckIcon.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import Svg, { Props } from './Svg'; - -export function CheckIcon(props: Props) { - return ( - - - - ); -} diff --git a/src/components/common/icons/DepromeetIcon.tsx b/src/components/common/icons/DepromeetIcon.tsx deleted file mode 100644 index f959523c..00000000 --- a/src/components/common/icons/DepromeetIcon.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import Svg, { Props } from './Svg'; - -export function DepromeetIcon({ ...props }: Props) { - return ( - - - - - ); -} diff --git a/src/components/common/icons/DropdownIcon.tsx b/src/components/common/icons/DropdownIcon.tsx deleted file mode 100644 index 3af4189b..00000000 --- a/src/components/common/icons/DropdownIcon.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import Svg, { Props } from './Svg'; - -export function DropdownIcon(props: Props) { - return ( - - - - ); -} diff --git a/src/components/common/icons/FacebookIcon.tsx b/src/components/common/icons/FacebookIcon.tsx deleted file mode 100644 index 29afd363..00000000 --- a/src/components/common/icons/FacebookIcon.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import Svg, { Props } from './Svg'; - -export function FacebookIcon(props: Props) { - return ( - - - - ); -} diff --git a/src/components/common/icons/GithubIcon.tsx b/src/components/common/icons/GithubIcon.tsx deleted file mode 100644 index 757d1acc..00000000 --- a/src/components/common/icons/GithubIcon.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { colors } from '~/styles/constants'; - -import Svg, { Props } from './Svg'; - -export function GithubIcon(props: Props) { - return ( - - - - ); -} diff --git a/src/components/common/icons/InstagramIcon.tsx b/src/components/common/icons/InstagramIcon.tsx deleted file mode 100644 index 436e4b92..00000000 --- a/src/components/common/icons/InstagramIcon.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import Svg, { Props } from './Svg'; - -export function InstagramIcon(props: Props) { - return ( - - - - ); -} diff --git a/src/components/common/icons/LinkedinIcon.tsx b/src/components/common/icons/LinkedinIcon.tsx deleted file mode 100644 index 770e5922..00000000 --- a/src/components/common/icons/LinkedinIcon.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { colors } from '~/styles/constants'; - -import Svg, { Props } from './Svg'; - -export function LinkedinIcon(props: Props) { - return ( - - - - ); -} diff --git a/src/components/common/icons/MailIcon.tsx b/src/components/common/icons/MailIcon.tsx deleted file mode 100644 index ef71dea0..00000000 --- a/src/components/common/icons/MailIcon.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import Svg, { Props } from './Svg'; - -export function MailIcon(props: Props) { - return ( - - - - ); -} diff --git a/src/components/common/icons/MediumIcon.tsx b/src/components/common/icons/MediumIcon.tsx deleted file mode 100644 index 254499c6..00000000 --- a/src/components/common/icons/MediumIcon.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import Svg, { Props } from './Svg'; - -export function MediumIcon(props: Props) { - return ( - - - - ); -} diff --git a/src/components/common/icons/QuestionIcon.tsx b/src/components/common/icons/QuestionIcon.tsx deleted file mode 100644 index 456d800e..00000000 --- a/src/components/common/icons/QuestionIcon.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import Svg, { Props } from './Svg'; - -export function QuestionIcon(props: Props) { - return ( - - - - - ); -} diff --git a/src/components/common/icons/SharpInCircleIcon.tsx b/src/components/common/icons/SharpInCircleIcon.tsx deleted file mode 100644 index 21225752..00000000 --- a/src/components/common/icons/SharpInCircleIcon.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import Svg, { Props } from './Svg'; - -export function SharpInCircleIcon({ color = '#0066FF', ...props }: Props) { - return ( - - - - - ); -} diff --git a/src/components/common/icons/WebIcon.tsx b/src/components/common/icons/WebIcon.tsx deleted file mode 100644 index 11de9201..00000000 --- a/src/components/common/icons/WebIcon.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import Svg, { Props } from './Svg'; - -export function WebIcon(props: Props) { - return ( - - - - - - ); -} diff --git a/src/components/common/icons/index.tsx b/src/components/common/icons/index.tsx deleted file mode 100644 index 83079a87..00000000 --- a/src/components/common/icons/index.tsx +++ /dev/null @@ -1,12 +0,0 @@ -export { AnswerIcon } from './AnswerIcon'; -export { ArrowIcon } from './ArrowIcon'; -export { BehanceIcon } from './BehanceIcon'; -export { DropdownIcon } from './DropdownIcon'; -export { FacebookIcon } from './FacebookIcon'; -export { GithubIcon } from './GithubIcon'; -export { InstagramIcon } from './InstagramIcon'; -export { LinkedinIcon } from './LinkedinIcon'; -export { MailIcon } from './MailIcon'; -export { MediumIcon } from './MediumIcon'; -export { QuestionIcon } from './QuestionIcon'; -export { WebIcon } from './WebIcon'; diff --git a/src/components/contact/ChannelSection.tsx b/src/components/contact/ChannelSection.tsx deleted file mode 100644 index ae233242..00000000 --- a/src/components/contact/ChannelSection.tsx +++ /dev/null @@ -1,188 +0,0 @@ -import { css } from '@emotion/react'; - -import { DEPROMEET_EMAIL, KAKAO_PLUS_FRIEND } from '~/constants/common'; -import { colors, mediaQuery } from '~/styles/constants'; -import { layoutCss } from '~/styles/css'; - -import { ClickableLink } from '../common/Clickable'; -import { ArrowIcon } from '../common/icons'; - -export default function ChannelSection() { - return ( -
    -
    -

    - 디프만에 대해 -
    - 궁금한 게 있으신가요? -

    -
    - -
    -

    카카오톡 채널 @depromeet로 물어보세요!

    -

    - 비즈니스 문의는{' '} - - 여기로 - -

    - -
    - KAKAO PLUS FRIEND - - @depromeet - - -
    - -
    - GMAIL - - depromeet@gmail.com - - -
    -
    -
    - ); -} - -const sectionCss = css` - ${layoutCss}; - width: 100%; - padding-top: 154px; - - display: flex; - - margin-bottom: 248px; - - ${mediaQuery('xs')} { - padding-top: 80px; - - flex-direction: column; - - margin-bottom: 133px; - } -`; - -const headingArticleCss = css` - /* NOTE : 486 / 1200 */ - width: 40%; - flex-shrink: 0; - - ${mediaQuery('xs')} { - width: 100%; - - margin-bottom: 20px; - } -`; - -const headingCss = css` - font-weight: 600; - font-size: 2.25rem; - line-height: 2.6875rem; - - ${mediaQuery('xs')} { - font-size: 24px; - line-height: 29px; - } -`; - -const channelArticleCss = css` - width: 100%; -`; - -const channelParagraphCss = css` - font-weight: 500; - font-size: 1.5rem; - line-height: 1.8125rem; - margin-bottom: 13px; - - ${mediaQuery('xs')} { - font-size: 16px; - line-height: 19px; - } -`; - -const lastChannelParagraphCss = css` - margin-bottom: 80px; -`; - -const businessAnchorCss = css` - color: ${colors.point}; - text-decoration: underline; -`; - -const channelWrapperCss = css` - position: relative; - height: 55px; - padding-left: 24px; - padding-right: 40px; - - display: flex; - justify-content: space-between; - align-items: center; - - font-weight: 500; - font-size: 1.5rem; - line-height: 1.8125rem; - - &::before { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 100vw; - height: 100%; - background-color: ${colors.background}; - z-index: -1; - border-top: solid 1px ${colors.black}; - border-bottom: solid 1px ${colors.black}; - } - - &:hover { - color: ${colors.white}; - - &::before { - background-color: ${colors.black}; - } - - & .icon * { - stroke: ${colors.white}; - } - } - - ${mediaQuery('xs')} { - padding: 0; - - font-size: 16px; - line-height: 140%; - - &::before { - left: -20px; - } - } -`; - -const channelAnchorCss = css` - display: flex; - align-items: center; - gap: 0.625rem; -`; diff --git a/src/components/contact/OrganizerCard.tsx b/src/components/contact/OrganizerCard.tsx deleted file mode 100644 index 591517c4..00000000 --- a/src/components/contact/OrganizerCard.tsx +++ /dev/null @@ -1,269 +0,0 @@ -import { ComponentProps } from 'react'; -import Image from 'next/image'; -import { css } from '@emotion/react'; -import { m, Variants } from 'framer-motion'; - -import { defaultEasing } from '~/constants/motions'; -import useMediaQuery from '~/hooks/use-media-query'; -import useToggle from '~/hooks/use-toggle'; -import { colors, mediaQuery } from '~/styles/constants'; - -import { Organizer } from './constants'; -import { ClickableLink } from '../common/Clickable'; -import { BehanceIcon, GithubIcon, LinkedinIcon, WebIcon } from '../common/icons'; - -export default function OrganizerCard({ - name, - position, - src, - behance, - linkedin, - github, - web, -}: Organizer) { - const isMobile = useMediaQuery('xs'); - const [isOpen, toggleIsOpen] = useToggle(false); - - const onMobileClick = () => { - if (!isMobile) return; - toggleIsOpen(); - }; - - return ( - - {name} -

    {name}

    -

    {position}

    - - - - * - - IF YOU - - - WISH TO KNOW - - - MORE - - - - - {behance && ( - - - - )} - - {linkedin && ( - - - - )} - - {github && ( - - - - )} - - {web && ( - - - - )} - - -
    - ); -} - -const articleCss = css` - position: relative; - /* NOTE gap size * gap count / card */ - width: calc(25% - (24px * 3 / 4)); - - height: 348px; - border-top: solid 1px ${colors.black}; - padding: 24px; - - display: flex; - flex-direction: column; - justify-content: flex-end; - color: ${colors.white}; - - ${mediaQuery('sm')} { - width: calc(50% - (24px / 2)); - } - - ${mediaQuery('xs')} { - width: calc(50% - (12px / 2)); - height: 200px; - padding: 12px; - } -`; - -const imageCss = css` - object-fit: cover; - z-index: -1; -`; - -const nameCss = css` - font-weight: 600; - font-size: 1.25rem; - line-height: 1.75rem; - margin-bottom: 4px; - - ${mediaQuery('xs')} { - font-size: 14px; - line-height: 140%; - } -`; - -const positionCss = css` - font-weight: 500; - font-size: 1rem; - line-height: 140%; - - ${mediaQuery('xs')} { - font-weight: 600; - font-size: 14px; - line-height: 140%; - } -`; - -const overlayCss = css` - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - padding-top: 24px; - padding-left: 24px; - padding-bottom: 20px; - padding-right: 24px; - - display: flex; - flex-direction: column; - justify-content: space-between; - background-color: ${colors.black}; - - ${mediaQuery('xs')} { - padding: 12px; - } -`; - -const overlayVariants: Variants = { - default: { - opacity: 0, - transition: { duration: 0.6, ease: defaultEasing }, - }, - hover: { - opacity: 1, - transition: { duration: 0.6, ease: defaultEasing, staggerChildren: 0.75 }, - }, -}; - -const hoverStaggerVariants: Variants = { - hover: { - transition: { staggerChildren: 0.5 }, - }, -}; - -const linkStaggerVariants: Variants = { - hover: { - transition: { delay: 3, staggerChildren: 0.5 }, - }, -}; - -const asteriskSpanCss = css` - font-weight: 500; - font-size: 26px; - line-height: 31px; - color: ${colors.point}; - - margin-bottom: 24px; - - ${mediaQuery('xs')} { - font-size: 15px; - line-height: 18px; - margin-bottom: 12px; - } -`; - -const paragraphCss = css` - font-weight: 500; - font-size: 1.25rem; - line-height: 1.5rem; - - ${mediaQuery('xs')} { - font-weight: 600; - font-size: 14px; - line-height: 140%; - } -`; - -const paragraphVariants: Variants = { - default: { - opacity: 0, - transition: { duration: 0.6, ease: defaultEasing }, - }, - hover: { - opacity: 1, - transition: { duration: 0.6, ease: defaultEasing }, - }, -}; - -const linkWrapperCss = css` - display: flex; - gap: 18px; - - ${mediaQuery('xs')} { - gap: 10px; - } -`; - -function MotionClickableLink({ href, children, ...props }: ComponentProps) { - return ( - - - {children} - - - ); -} - -const linkCss = css` - width: 45px; - height: 45px; - border-radius: 50%; - background-color: ${colors.white}; - display: flex; - justify-content: center; - align-items: center; - - ${mediaQuery('xs')} { - width: 28px; - height: 28px; - } -`; - -const linkVariants: Variants = { - default: { - opacity: 0, - y: 10, - transition: { duration: 0.6, ease: defaultEasing }, - }, - hover: { - opacity: 1, - y: 0, - transition: { duration: 0.6, ease: defaultEasing }, - }, -}; diff --git a/src/components/contact/OrganizerSection.tsx b/src/components/contact/OrganizerSection.tsx deleted file mode 100644 index 0c04d3de..00000000 --- a/src/components/contact/OrganizerSection.tsx +++ /dev/null @@ -1,120 +0,0 @@ -import { css } from '@emotion/react'; - -import { colors, mediaQuery } from '~/styles/constants'; -import { layoutCss, section36HeadingCss, sectionSmallCss } from '~/styles/css'; - -import { ORGANIZERS } from './constants'; -import OrganizerCard from './OrganizerCard'; - -export default function OrganizerSection() { - return ( -
    -
    - INTRODUCING -

    디프만 13기 운영진을 소개합니다

    - * -

    - 괜찮겠어? -
    - 우리는 멈추는 법을 모르는 디프만 운영진인데 -

    -
    - -
    -
    - 13기 운영진 - 2023. 02 ~ -
    - -
    - {ORGANIZERS.map(organizer => ( - - ))} -
    -
    -
    - ); -} - -const sectionCss = css` - ${layoutCss}; - - margin-bottom: 180px; - - ${mediaQuery('xs')} { - margin-bottom: 150px; - } -`; - -const headingArticleCss = css` - width: 100%; - display: flex; - flex-direction: column; - align-items: center; - - margin-bottom: 80px; - - ${mediaQuery('xs')} { - margin-bottom: 20px; - } -`; - -const smallCss = css` - ${sectionSmallCss}; - - margin-bottom: 10px; -`; - -const headingCss = css` - ${section36HeadingCss}; - - margin-bottom: 40px; - - ${mediaQuery('xs')} { - margin-bottom: 20px; - } -`; - -const asteriskSpanCss = css` - font-weight: 500; - font-size: 26px; - line-height: 31px; - color: ${colors.point}; -`; - -const paragraphCss = css` - color: ${colors.black}; - opacity: 0.6; - font-weight: 500; - font-size: 16px; - line-height: 140%; - text-align: center; -`; - -const organizerWrapperCss = css` - width: 100%; - border-top: solid 1px ${colors.black}; -`; - -const informBoxCss = css` - padding-top: 10px; - padding-bottom: 20px; - width: 100%; - display: flex; - justify-content: space-between; - align-items: center; - - font-weight: 500; - font-size: 1rem; - line-height: 140%; -`; - -const organizerCardWrapperCss = css` - display: flex; - flex-wrap: wrap; - gap: 24px; - - ${mediaQuery('xs')} { - gap: 12px; - } -`; diff --git a/src/components/contact/constants.ts b/src/components/contact/constants.ts deleted file mode 100644 index b11eeb21..00000000 --- a/src/components/contact/constants.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { ORGANIZER_IMAGE_BASE } from '~/constants/images'; - -export interface Organizer { - name: string; - position: string; - src: string; - behance?: string; - linkedin?: string; - github?: string; - web?: string; -} - -export const ORGANIZERS: readonly Organizer[] = [ - { - name: '박소현 (회장)', - position: 'UXUI DESIGNER', - src: `${ORGANIZER_IMAGE_BASE}/박소현.webp`, - web: 'https://brunch.co.kr/@tudandilion', - }, - { - name: '김동규 (부회장)', - position: 'WEB DEVELOPER', - src: `${ORGANIZER_IMAGE_BASE}/김동규.webp`, - linkedin: 'https://www.linkedin.com/in/dongkyu-kim-575969211/', - github: 'https://github.com/dongkyuuuu', - }, - { - name: '박수연', - position: 'UXUI DESIGNER', - src: `${ORGANIZER_IMAGE_BASE}/박수연.webp`, - behance: 'https://www.behance.net/sypak120c57e', - linkedin: 'https://www.linkedin.com/in/sooyeon-park-623857200/', - }, - { - name: '이승희', - position: 'UXUI DESIGNER', - src: `${ORGANIZER_IMAGE_BASE}/이승희.webp`, - behance: 'https://www.behance.net/seunghee555b99', - }, - { - name: '이종원', - position: 'UXUI DESIGNER', - src: `${ORGANIZER_IMAGE_BASE}/이종원.webp`, - behance: 'https://www.behance.net/093fec2d', - }, - { - name: '임효연', - position: 'UXUI DESIGNER', - src: `${ORGANIZER_IMAGE_BASE}/임효연.webp`, - behance: 'https://www.behance.net/gd054', - linkedin: 'https://www.linkedin.com/in/효연-임-2a2046231/', - }, - { - name: '차요셉', - position: 'iOS DEVELOPER', - src: `${ORGANIZER_IMAGE_BASE}/차요셉.webp`, - linkedin: 'https://www.linkedin.com/in/요셉-차-18478a207/', - github: 'https://github.com/joseph704', - web: 'https://josephcha.tistory.com', - }, - { - name: '김민수', - position: 'WEB DEVELOPER', - src: `${ORGANIZER_IMAGE_BASE}/김민수.webp`, - linkedin: 'https://www.linkedin.com/in/ding-co/', - github: 'https://github.com/ding-co', - web: 'https://ding-co.tistory.com/', - }, - { - name: '오혜성', - position: 'WEB DEVELOPER', - src: `${ORGANIZER_IMAGE_BASE}/오혜성.webp`, - linkedin: 'https://www.linkedin.com/in/hyesungoh414/', - github: 'https://github.com/hyesungoh', - web: 'https://www.hyesungoh.xyz/', - }, - { - name: '이은지', - position: 'WEB DEVELOPER', - src: `${ORGANIZER_IMAGE_BASE}/이은지.webp`, - github: 'https://github.com/eunddodi', - web: 'https://velog.io/@eunddodi', - }, - { - name: '정대윤', - position: 'WEB DEVELOPER', - src: `${ORGANIZER_IMAGE_BASE}/정대윤.webp`, - github: 'https://github.com/sensecodevalue', - }, - { - name: '김문규', - position: 'SERVER DEVELOPER', - src: `${ORGANIZER_IMAGE_BASE}/김문규.webp`, - github: 'https://github.com/kneeee188', - web: 'https://medium.com/@make.abundant', - }, - { - name: '이성태', - position: 'SERVER DEVELOPER', - src: `${ORGANIZER_IMAGE_BASE}/이성태.webp`, - linkedin: 'https://www.linkedin.com/in/성태-이-3b2348211/', - github: 'https://github.com/stae1102', - web: 'https://dev-scratch.tistory.com/', - }, - { - name: '이찬진', - position: 'SERVER DEVELOPER', - src: `${ORGANIZER_IMAGE_BASE}/이찬진.webp`, - github: 'https://github.com/ImNM', - web: 'https://devnm.tistory.com/', - }, -]; diff --git a/src/components/home/BigArrowIcon.tsx b/src/components/home/BigArrowIcon.tsx deleted file mode 100644 index 841f3f99..00000000 --- a/src/components/home/BigArrowIcon.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import Svg, { Props } from '../common/icons/Svg'; - -export function BigArrowIcon(props: Props) { - return ( - - - - - - ); -} diff --git a/src/components/home/ContentsSection.tsx b/src/components/home/ContentsSection.tsx deleted file mode 100644 index e4f182ba..00000000 --- a/src/components/home/ContentsSection.tsx +++ /dev/null @@ -1,213 +0,0 @@ -import Image from 'next/image'; -import { css } from '@emotion/react'; - -import { HOME_IMAGE_BASE } from '~/constants/images'; -import useMediaQuery from '~/hooks/use-media-query'; -import { colors, mediaQuery } from '~/styles/constants'; -import { layoutCss, section40HeadingCss, sectionSmallCss } from '~/styles/css'; - -import { ClickableLink } from '../common/Clickable'; - -const MEET_IMAGE = `${HOME_IMAGE_BASE}/meet.webp`; -const HEART_IMAGE = `${HOME_IMAGE_BASE}/heart.webp`; -const PROGRAMMER_IMAGE = `${HOME_IMAGE_BASE}/programmer.webp`; -const MOBILE_MEET_IMAGE = `${HOME_IMAGE_BASE}/mobile-meet.webp`; -const MOBILE_HEART_IMAGE = `${HOME_IMAGE_BASE}/mobile-heart.webp`; -const MOBILE_PROGRAMMER_IMAGE = `${HOME_IMAGE_BASE}/mobile-programmer.webp`; - -export default function ContentsSection() { - const isMobile = useMediaQuery('xs'); - - return ( -
    -
    - CONTENTS -

    디프만에 한발짝 더{isMobile &&
    } 가까워질 수 있게

    -
    - -
    - - 디프만 a to z -
    -

    디프만에 대한 모든 정보는 여기 쏙!

    - 디프만 A to Z -
    -
    - - -
    - 디프만 프로젝트 -
    -
    -

    디프만의 자랑거리인

    - 지난 프로젝트 보러가기 -
    -
    - - -
    - 디프만 모집 안내 -
    -
    -

    지원방법부터 모집일정까지

    - 13기 모집 안내 -
    -
    -
    -
    - ); -} - -const sectionCss = css` - ${layoutCss}; - display: flex; - flex-direction: column; - align-items: center; - - margin-bottom: 180px; - - ${mediaQuery('xs')} { - margin-bottom: 100px; - } -`; - -const paragraphArticleCss = css` - text-align: center; - - margin-bottom: 90px; - - ${mediaQuery('xs')} { - margin-bottom: 60px; - } -`; - -const smallCss = css` - ${sectionSmallCss} - display: block; - margin-bottom: 10px; -`; - -const linkArticleCss = css` - width: 100%; - display: flex; - justify-content: center; - gap: 24px; - - ${mediaQuery('xs')} { - flex-direction: column; - gap: 30px; - } -`; - -const linkCss = css` - position: relative; - width: 384px; - height: 366px; - border-top: 1px solid ${colors.black}; - background: linear-gradient(180deg, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 25%); - - ${mediaQuery('xs')} { - width: 100%; - height: 200px; - } -`; - -const linkContentWrapperCss = css` - position: relative; - padding-top: 30px; - padding-left: 30px; - z-index: 10; -`; - -const linkParagraphCss = css` - font-weight: 600; - font-size: 1.125rem; - line-height: 140%; - - margin-bottom: 6px; - - ${mediaQuery('xs')} { - font-size: 14px; - } -`; - -const linkSpanCss = css` - font-weight: 700; - font-size: 1.75rem; - line-height: 2.0625rem; - - ${mediaQuery('xs')} { - font-size: 20px; - } -`; - -const heartImageWrapperCss = css` - position: absolute; - top: 0; - left: 0; - width: 100%; - height: calc(100% + 40px); - - ${mediaQuery('xs')} { - height: 100%; - } -`; - -const programmerImageWrapperCss = css` - position: absolute; - top: 0; - left: 0; - width: calc(100% + 34px); - height: 100%; - - ${mediaQuery('xs')} { - width: 100%; - } -`; - -const linkImageCss = css` - object-fit: cover; - z-index: 1; -`; diff --git a/src/components/home/HeaderSection.tsx b/src/components/home/HeaderSection.tsx deleted file mode 100644 index 7f1d0864..00000000 --- a/src/components/home/HeaderSection.tsx +++ /dev/null @@ -1,141 +0,0 @@ -import Image from 'next/image'; -import { css } from '@emotion/react'; -import { m, useScroll, useSpring, useTransform } from 'framer-motion'; - -import { HOME_IMAGE_BASE } from '~/constants/images'; -import useMediaQuery from '~/hooks/use-media-query'; -import { mediaQuery } from '~/styles/constants'; - -import { BigArrowIcon } from './BigArrowIcon'; - -const HEADER_BACK_IMAGE = `${HOME_IMAGE_BASE}/header-back.webp`; -const MOBILE_HEADER_BACK_IMAGE = `${HOME_IMAGE_BASE}/mobile-header-back.webp`; -const HEADER_FRONT_IMAGE = `${HOME_IMAGE_BASE}/header-front.png`; -const MOBILE_HEADER_FRONT_IMAGE = `${HOME_IMAGE_BASE}/mobile-header-front.webp`; - -export default function HeaderSection() { - const isMobile = useMediaQuery('xs'); - - const { scrollY } = useScroll(); - const designerTextX = useTransform( - scrollY, - [0, 800], - [isMobile ? 100 : 400, isMobile ? -400 : -1000] - ); - const programmerTextX = useTransform( - scrollY, - [0, 800], - [isMobile ? -50 : 0, isMobile ? 300 : -1000] - ); - const springDesignerX = useSpring(designerTextX, { stiffness: 200, damping: 40 }); - const springProgrammerX = useSpring(programmerTextX, { stiffness: 200, damping: 40 }); - - return ( -
    -

    디자이너와 프로그래머가 만났을 때

    - - - 디프만 - - DESIGNER - - - &PROGRAMMER - - depromeet -
    - ); -} - -const sectionCss = css` - position: relative; - width: 100%; - height: 780px; - overflow: hidden; - - display: flex; - flex-direction: column; - justify-content: flex-end; - align-items: center; - - ${mediaQuery('xs')} { - height: 650px; - } -`; - -const headingCss = css` - font-weight: 600; - font-size: 20px; - line-height: 28px; - - margin-bottom: 24px; - - ${mediaQuery('xs')} { - font-weight: 500; - font-size: 16px; - margin-bottom: 20px; - } -`; - -const iconCss = css` - margin-bottom: 56px; - - ${mediaQuery('xs')} { - margin-bottom: 107px; - } -`; - -const imageCss = css` - position: absolute; - top: 0; - left: 0; - object-fit: cover; - z-index: -1; -`; - -const graphicTextCss = css` - position: absolute; - font-weight: 600; - font-size: 150px; - z-index: -1; - - ${mediaQuery('xs')} { - font-size: 50px; - } -`; - -const designerTextCss = css` - ${graphicTextCss}; - top: 165px; - - ${mediaQuery('xs')} { - top: 113px; - } -`; - -const programmerTextCss = css` - ${graphicTextCss}; - top: 327px; - - ${mediaQuery('xs')} { - top: 182px; - } -`; diff --git a/src/components/home/IntroductionSection.tsx b/src/components/home/IntroductionSection.tsx deleted file mode 100644 index c205bcaa..00000000 --- a/src/components/home/IntroductionSection.tsx +++ /dev/null @@ -1,268 +0,0 @@ -import { css } from '@emotion/react'; - -import useMediaQuery from '~/hooks/use-media-query'; -import { colors, mediaQuery } from '~/styles/constants'; -import { layoutCss, section40HeadingCss, sectionSmallCss } from '~/styles/css'; - -export default function IntroductionSection() { - const isMobile = useMediaQuery('xs'); - - return ( -
    -
    - INTRODUCTION -

    - 디프만은 디자이너와 개발자가 -
    - 서비스 기획부터 론칭까지 -
    - 함께 경험하는 성장추구형 커뮤니티입니다 -

    -
    - -
    -
    - 1 - -
    -

    800명+

    -

    누적 멤버 수

    -
    -
    -
    - 2 - -
    -

    7YEARS

    -

    탄생한지

    -
    -
    -
    - 3 - -
    -

    100%

    -
    -

    론칭 성공률

    - 10기~12기 기준 -
    -
    -
    -
    - 4 - -
    -

    42개+

    -
    -

    론칭 서비스

    - 5~12기 기준 -
    -
    -
    -
    -
    - ); -} - -const sectionCss = css` - ${layoutCss}; - padding-top: 130px; - - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - - margin-bottom: 180px; - - ${mediaQuery('xs')} { - padding-top: 100px; - - margin-bottom: 100px; - } -`; - -const paragraphArticleCss = css` - width: 100%; - - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - text-align: center; - - margin-bottom: 90px; - - ${mediaQuery('xs')} { - margin-bottom: 60px; - } -`; - -const marginSectionSmallCss = css` - ${sectionSmallCss}; - margin-bottom: 10px; -`; - -const infoArticleCss = css` - width: 100%; - display: flex; - - ${mediaQuery('xs')} { - flex-wrap: wrap; - } -`; - -const infoBoxCss = css` - width: 25%; - height: 265px; - - ${mediaQuery('xs')} { - width: calc(50% - 3px); - height: 150px; - - &:nth-of-type(even) { - margin-left: 6px; - } - } -`; - -const countSpanCss = css` - width: 40px; - height: 29px; - display: flex; - justify-content: center; - align-items: center; - border-radius: 50%; - border: 1px solid ${colors.gray700}; - - font-family: 'Helvetica'; - font-style: italic; - font-weight: 400; - font-size: 20px; - letter-spacing: 3px; - color: ${colors.gray700}; - - margin-bottom: 18px; - - ${mediaQuery('xs')} { - width: 24px; - height: 17px; - font-size: 14px; - letter-spacing: 1.5px; - - margin-bottom: 8px; - } -`; - -const descriptionBoxCss = css` - position: relative; - width: 100%; - height: calc(100% - 47px); - padding-top: 30px; - padding-left: 30px; - - &::before { - content: ''; - position: absolute; - top: 0; - left: 20px; - - width: calc(100% - 40px); - height: 1px; - background-color: ${colors.black}; - } - - &::after { - content: ''; - position: absolute; - bottom: 0; - right: 0; - - width: 1px; - height: calc(100% - 20px); - background-color: ${colors.black}; - } - - ${mediaQuery('xs')} { - height: 100%; - padding-top: 16px; - padding-left: 16px; - - &::before { - left: 0; - width: calc(100% - 6px); - } - - &::after { - top: 6px; - height: calc(100% - 12px); - } - } -`; - -const desktopFirstTopDividerCss = css` - &::before { - top: 0; - left: 0; - - width: calc(100% - 20px); - } -`; - -const disableRightDividerCss = css` - &::after { - all: unset; - } -`; - -const heading3Css = css` - font-weight: 600; - font-size: 3rem; - line-height: 2.6875rem; - - margin-bottom: 10px; - - ${mediaQuery('xs')} { - font-size: 24px; - line-height: 25px; - - margin-bottom: 4px; - } -`; - -const heading4WrapperCss = css` - display: flex; - - ${mediaQuery('xs')} { - flex-direction: column; - } -`; - -const heading4Css = css` - font-weight: 600; - font-size: 1.125rem; - line-height: 140%; - font-style: normal; - - color: ${colors.gray900}; - - ${mediaQuery('xs')} { - font-size: 14px; - } -`; - -const smallCss = css` - margin-left: 10px; - - font-size: 1.125rem; - line-height: 140%; - font-weight: 500; - - color: ${colors.gray700}; - - ${mediaQuery('xs')} { - margin-left: 0; - margin-top: 4px; - font-size: 14px; - } -`; diff --git a/src/components/project-detail/HeaderSection.tsx b/src/components/project-detail/HeaderSection.tsx deleted file mode 100644 index 19aef5f5..00000000 --- a/src/components/project-detail/HeaderSection.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import Image from 'next/image'; -import { css } from '@emotion/react'; - -import { PROJECTS_IMAGE_BASE } from '~/constants/images'; -import { mediaQuery } from '~/styles/constants'; - -import { Project } from '../project/constants'; - -export default function HeaderSection({ image, title }: Project) { - return ( -
    - {title} -
    - ); -} - -const sectionCss = css` - position: relative; - width: 100%; - height: 667px; - overflow: hidden; - - ${mediaQuery('md')} { - height: 500px; - } - - ${mediaQuery('sm')} { - height: 400px; - } - - ${mediaQuery('xs')} { - height: 174px; - } -`; diff --git a/src/components/project-detail/MobileProjectDetailSection.tsx b/src/components/project-detail/MobileProjectDetailSection.tsx deleted file mode 100644 index 852acf51..00000000 --- a/src/components/project-detail/MobileProjectDetailSection.tsx +++ /dev/null @@ -1,218 +0,0 @@ -import { css } from '@emotion/react'; - -import { POSITION_ICON_BASE } from '~/constants/images'; -import { colors } from '~/styles/constants'; - -import ProjectDetailLink from './ProjectDetailLink'; -import { Project } from '../project/constants'; - -export default function MobileProjectDetailSection({ - generation, - title, - catchphrase, - prize, - team, - designers, - frontends, - backends, - description, - ios, - android, - web, - behance, - github, -}: Project) { - return ( -
    -
    -

    - {generation}기 - {title} -

    -

    {catchphrase}

    - - {prize !== 'Default' &&
    {prize}
    } -
    - -
    -

    - {generation}기 {team} -

    - - - {designers && ( - - - {designers.map(designer => ( - - ))} - - )} - {frontends && ( - - - {frontends.map(frontend => ( - - ))} - - )} - {backends && ( - - - {backends.map(backend => ( - - ))} - - )} -
    DESIGN - {designer} -
    FRONTEND - {frontend} -
    BACKEND - {backend} -
    -
    - -
    -

    {description}

    -
    - {ios && } - {android && } - {web && } - {behance && } - {github && } -
    -
    -
    - ); -} - -const sectionCss = css` - width: 100%; - margin-bottom: 60px; -`; - -const headerCss = css` - position: relative; - display: flex; - flex-direction: column; - padding-top: 30px; - padding-bottom: 10px; - - border-bottom: solid 1px ${colors.black}; -`; - -const headingCss = css` - display: flex; - align-items: center; - - font-weight: 600; - font-size: 20px; - line-height: 28px; - - margin-bottom: 20px; - - & span { - width: 54px; - height: 34px; - color: ${colors.white}; - background-color: ${colors.black}; - margin-right: 12px; - border-radius: 50%; - - display: flex; - justify-content: center; - align-items: center; - - font-weight: 600; - font-size: 12px; - line-height: 140%; - } -`; - -const catchphraseCss = css` - font-weight: 600; - font-size: 14px; - line-height: 19px; -`; - -const prizeWrapperCss = css` - position: absolute; - top: 20px; - right: 0; - - width: 54px; - height: 54px; - - background-image: url(${POSITION_ICON_BASE}/project-prize.webp); - background-position: center center; - background-size: cover; - background-repeat: no-repeat; - - display: flex; - justify-content: center; - align-items: center; - font-size: 12px; -`; - -const teamArticleCss = css` - padding-top: 30px; - padding-bottom: 40px; - border-bottom: solid 1px ${colors.black}; -`; - -const teamHeadingCss = css` - font-weight: 600; - font-size: 18px; - line-height: 140%; - - margin-bottom: 16px; -`; - -const tableCss = css` - width: 100%; - display: flex; - flex-direction: column; - gap: 16px; -`; - -const trCss = css` - width: 100%; - display: flex; - flex-wrap: wrap; - gap: 20px; -`; - -const partTdCss = css` - font-weight: 500; - font-size: 16px; - line-height: 140%; - width: 84px; -`; - -const memberTdCss = css` - font-weight: 500; - font-size: 16px; - line-height: 140%; - color: ${colors.gray600}; -`; - -const descriptionArticleCss = css` - padding: 30px 0; - border-bottom: solid 1px black; -`; - -const descriptionCss = css` - font-weight: 500; - font-size: 16px; - line-height: 140%; - - margin-bottom: 20px; -`; - -const linkWrapperCss = css` - display: flex; - flex-wrap: wrap; - column-gap: 20px; - row-gap: 15px; -`; diff --git a/src/components/project-detail/OtherProjectSection.tsx b/src/components/project-detail/OtherProjectSection.tsx deleted file mode 100644 index bd8219d9..00000000 --- a/src/components/project-detail/OtherProjectSection.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import dynamic from 'next/dynamic'; -import { css } from '@emotion/react'; - -import { mediaQuery } from '~/styles/constants'; - -import { projects } from '../project/constants'; - -const ProjectItem = dynamic(() => import('../project/ProjectItem/ProjectItem'), { ssr: false }); - -export default function OtherProjectSection() { - const randomProjects = projects.sort(() => Math.random() - 0.5).slice(0, 3); - - return ( -
    -

    다른 프로젝트도 궁금하다면?

    -
    - {randomProjects.map(project => ( - - ))} -
    -
    - ); -} - -const projectDetailAnotherProjectCss = css` - width: 100%; - padding-top: 184px; - - margin-bottom: 209px; - - ${mediaQuery('xs')} { - padding-top: 0px; - margin-bottom: 150px; - } -`; - -const headingCss = css` - text-align: center; - font-weight: 600; - font-size: 2.25rem; - line-height: 43px; - - margin-bottom: 80px; - - ${mediaQuery('xs')} { - margin-bottom: 30px; - } -`; - -const wrapperCss = css` - width: 100%; - display: grid; - grid-template-columns: 1fr 1fr 1fr; - grid-template-rows: 300px; - gap: 24px; - - ${mediaQuery('sm')} { - grid-template-columns: 1fr 1fr; - } - - ${mediaQuery('xs')} { - grid-template-columns: 1fr; - } -`; diff --git a/src/components/project-detail/ProjectDetailLink.tsx b/src/components/project-detail/ProjectDetailLink.tsx deleted file mode 100644 index 949dd639..00000000 --- a/src/components/project-detail/ProjectDetailLink.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { useState } from 'react'; -import Image from 'next/image'; -import { css } from '@emotion/react'; - -import { POSITION_ICON_BASE } from '~/constants/images'; -import { colors } from '~/styles/constants'; - -import { ClickableLink } from '../common/Clickable'; - -export default function ProjectDetailLink({ - type, - link, -}: { - type: '앱스토어' | '플레이스토어' | 'WEB' | '비핸스' | '깃허브'; - link: string; -}) { - const [isHover, setIsHover] = useState(false); - const iconImage = isHover ? 'project-link--active.webp' : 'project-link--default.webp'; - - return ( - setIsHover(true)} - onMouseOut={() => setIsHover(false)} - > - 바로가기 - {type} - - ); -} - -const linkCss = css` - display: flex; - gap: 6px; - align-items: center; - - & > span { - font-weight: 500; - font-size: 16px; - line-height: 140%; - letter-spacing: -0.3px; - color: ${colors.point}; - } -`; diff --git a/src/components/project-detail/ProjectDetailSection.tsx b/src/components/project-detail/ProjectDetailSection.tsx deleted file mode 100644 index 876459d3..00000000 --- a/src/components/project-detail/ProjectDetailSection.tsx +++ /dev/null @@ -1,278 +0,0 @@ -import Image from 'next/image'; -import { css } from '@emotion/react'; - -import { ClickableLink } from '~/components/common/Clickable'; -import { Project } from '~/components/project/constants'; -import { POSITION_ICON_BASE } from '~/constants/images/images'; -import useMediaQuery from '~/hooks/use-media-query'; -import { colors } from '~/styles/constants'; - -import ProjectDetailLink from './ProjectDetailLink'; - -interface Props { - currentProject: Project; -} - -function ProjectDetailTeamMembers({ - part, - members, -}: { - part: 'DESIGN' | 'WEB' | 'SERVER'; - members: string[]; -}) { - return ( -
    - {part} - {members?.map((member, idx) => ( - {member} - ))} -
    - ); -} - -export default function ProjectDetailSection({ currentProject }: Props) { - const { generation, title, team, catchphrase, description, prize } = currentProject; - - const isMobile = useMediaQuery('xs'); - - return ( - <> - {!isMobile && ( - - 뒤로가기 - 이전 - - )} - -
    -
    -
    - {generation}기 -
    - {title} -
    -

    {catchphrase}

    -
    -
    - - {prize !== 'Default' && ( -
    -
    - {prize} -
    -
    - )} -
    - -
    -
    -
    - - {generation}기 {team}팀 - - {currentProject.designers && ( - - )} - {currentProject.frontends && ( - - )} - {currentProject.backends && ( - - )} -
    -
    -
    -

    {description}

    -
    - {currentProject.ios && ( - - )} - {currentProject.android && ( - - )} - {currentProject.web && } - {currentProject.behance && ( - - )} - {currentProject.github && ( - - )} -
    -
    -
    -
    -
    - - ); -} - -const goBackCss = css` - margin: 30px 0 26px 0; - width: 100%; - display: flex; - align-items: center; - gap: 10px; -`; - -const projectDetailSectionCss = css` - width: 100%; - display: flex; - flex-wrap: wrap; - .project-meta-header { - margin-bottom: 23px; - width: 100%; - display: flex; - align-items: center; - justify-content: space-between; - .project-meta-header__left { - display: flex; - align-items: center; - gap: 20px; - .project-meta__generation { - display: flex; - width: 98px; - height: 48px; - justify-content: center; - align-items: center; - border-radius: 50%; - background-color: ${colors.black}; - - font-weight: 600; - font-size: 1.25rem; - line-height: 140%; - text-align: center; - letter-spacing: -0.3px; - color: ${colors.gray100}; - } - .project-meta__info { - display: flex; - align-items: center; - span, - p { - font-weight: 600; - font-size: 1.25rem; - line-height: 140%; - letter-spacing: -0.3px; - color: ${colors.black}; - } - div { - margin: 0 12px; - width: 4px; - height: 4px; - border-radius: 50%; - background-color: ${colors.black}; - } - } - .project-meta__prize { - } - } - .project-meta-header__right { - width: 76px; - height: 76px; - - div { - display: flex; - justify-content: center; - align-items: center; - } - } - } - .project-detail { - width: 100%; - height: 389px; - display: flex; - justify-content: space-between; - .project-detail__team { - width: 50%; - padding: 40px; - display: flex; - flex-direction: column; - gap: 20px; - .project-detail__team--info { - font-weight: 500; - font-size: 1rem; - line-height: 140%; - letter-spacing: -0.3px; - color: ${colors.black}; - } - .project-detail__team--member { - display: flex; - align-items: center; - gap: 20px; - b { - width: 57px; - font-weight: 500; - font-size: 1rem; - line-height: 140%; - letter-spacing: -0.3px; - text-transform: uppercase; - color: ${colors.black}; - } - span { - font-weight: 500; - font-size: 16px; - line-height: 140%; - letter-spacing: -0.3px; - text-transform: uppercase; - color: ${colors.gray600}; - } - } - } - .project-detail__separator { - margin: 19px 0; - width: 1px; - background-color: ${colors.black}; - } - .project-detail__description { - width: 50%; - padding: 40px; - display: flex; - flex-direction: column; - justify-content: space-between; - p { - font-weight: 600; - font-size: 1.25rem; - line-height: 140%; - letter-spacing: -0.3px; - color: ${colors.black}; - } - .project-detail__links { - width: 100%; - display: flex; - gap: 32px; - align-items: center; - } - } - } - - .separator { - width: 100%; - height: 1px; - background-color: ${colors.black}; - } -`; - -const prizeSpanCss = (is최우수상: boolean) => css` - font-weight: 600; - font-size: ${is최우수상 ? '0.875rem' : '1.125rem'}; - line-height: 122%; - letter-spacing: -0.003em; - color: ${colors.black}; -`; diff --git a/src/components/project/HeaderSection/HeaderSection.tsx b/src/components/project/HeaderSection/HeaderSection.tsx deleted file mode 100644 index dc283ece..00000000 --- a/src/components/project/HeaderSection/HeaderSection.tsx +++ /dev/null @@ -1,185 +0,0 @@ -import Image from 'next/image'; -import { css } from '@emotion/react'; -import { m, useScroll, useSpring, useTransform } from 'framer-motion'; - -import useMediaQuery from '~/hooks/use-media-query'; -import { mediaQuery } from '~/styles/constants'; -import { body1Css, layoutCss } from '~/styles/css'; - -const HEADER_BACK = '/project/header-back.webp'; -const HEADER_FRONT = '/project/header-front.webp'; -const MOBILE_HEADER_BACK = '/project/mobile-header-back.webp'; -const MOBILE_HEADER_FRONT = '/project/mobile-header-front.webp'; - -export default function HeaderSection() { - const isMobile = useMediaQuery('xs'); - - const { scrollY } = useScroll(); - const designerX = useTransform(scrollY, [0, 250], [0, 200]); - const programmerX = useTransform(scrollY, [0, 250], [0, 300]); - const meetX = useTransform(scrollY, [0, 250], [0, 400]); - - const springDesignerX = useSpring(designerX, { stiffness: 200, damping: 40 }); - const springProgrammerX = useSpring(programmerX, { stiffness: 200, damping: 40 }); - const springMeetX = useSpring(meetX, { stiffness: 200, damping: 40 }); - - return ( -
    -
    - 디프만 프로젝트 - - - DESIGNERS - - - &PROGRAMMER - - - MEET - - - depromeet project -
    - -

    - 독창적이면서도 날카롭고 -
    - 실패를 두려워하지 않는 -
    - 오직 디프만에서만 가능한 -
    - 프로젝트들을 소개합니다. -

    -
    - ); -} - -const sectionCss = css` - position: relative; - width: 100vw; - height: 598px; - overflow: hidden; - - margin-bottom: 130px; - - ${mediaQuery('xs')} { - margin-bottom: 70px; - height: auto; - } -`; - -const imageWrapperCss = css` - position: relative; - width: 100%; - height: 100%; - - ${mediaQuery('xs')} { - margin-top: 60px; - height: 180px; - overflow-y: visible; - } -`; - -const headingCss = css` - position: absolute; - font-weight: 600; - font-size: 7.8125rem; - left: 110px; - z-index: 1; - - ${mediaQuery('md')} { - font-size: 90px; - left: 70px; - } - - ${mediaQuery('sm')} { - left: 20px; - } - - ${mediaQuery('xs')} { - font-size: 34px; - } -`; - -const designerCss = css` - ${headingCss}; - top: 30px; -`; - -const programmerCss = css` - ${headingCss}; - top: 155px; - - ${mediaQuery('md')} { - top: 120px; - } - - ${mediaQuery('xs')} { - top: 70px; - } -`; - -const meetCss = css` - ${headingCss}; - top: 280px; - - ${mediaQuery('md')} { - top: 210px; - } - - ${mediaQuery('xs')} { - top: 110px; - } -`; - -const descriptionCss = css` - ${body1Css} - - position: absolute; - right: 200px; - top: 346px; - z-index: 1; - - ${mediaQuery('md')} { - right: 100px; - } - - ${mediaQuery('xs')} { - ${layoutCss}; - position: static; - margin-top: 100px; - } -`; - -const imageCss = css` - position: absolute; - top: 0; - left: 0; - object-fit: cover; -`; - -const backImageCss = css` - z-index: -3; -`; - -const frontImageCss = css` - z-index: 2; -`; diff --git a/src/components/project/HeaderSection/index.tsx b/src/components/project/HeaderSection/index.tsx deleted file mode 100644 index 02dba600..00000000 --- a/src/components/project/HeaderSection/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from './HeaderSection'; diff --git a/src/components/project/HorizontalDivider/HorizontalDivider.tsx b/src/components/project/HorizontalDivider/HorizontalDivider.tsx deleted file mode 100644 index b824d29c..00000000 --- a/src/components/project/HorizontalDivider/HorizontalDivider.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { css } from '@emotion/react'; - -import { ArrowIcon } from '~/components/common/icons'; -import useMediaQuery from '~/hooks/use-media-query'; -import { colors } from '~/styles/constants'; - -export function HorizontalDivider() { - const isMobile = useMediaQuery('xs'); - - return ( -
    - -
    - ); -} - -const wrapperCss = css` - width: 100%; - margin: 0 auto; - - display: flex; - justify-content: center; -`; diff --git a/src/components/project/MobileProjectList/MobileProjectList.tsx b/src/components/project/MobileProjectList/MobileProjectList.tsx deleted file mode 100644 index c705f39d..00000000 --- a/src/components/project/MobileProjectList/MobileProjectList.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import { useEffect, useMemo, useState } from 'react'; -import Image from 'next/image'; -import { css } from '@emotion/react'; - -import { Project } from '../constants'; -import ProjectContainer from '../ProjectContainer'; -import { Order } from '../ProjectListSection/ProjectListSection'; - -interface Props { - projects: Project[]; - sortBy: Order; - sortByLatest: () => void; - sortByOldest: () => void; -} - -export default function MobileProjectList({ projects }: Props) { - const [showedProjectCount, setShowedProjectCount] = useState(4); - - const showMoreProjects = () => { - setShowedProjectCount(prev => Math.min(prev + 4, projects.length)); - }; - - const showedProjects = useMemo( - () => projects.slice(0, showedProjectCount), - [projects, showedProjectCount] - ); - - useEffect(() => { - setShowedProjectCount(4); - }, [projects]); - - return ( - <> - - - {showedProjectCount < projects.length && ( - - )} - - ); -} - -const buttonCss = css` - display: flex; - align-items: center; - padding: 16px; - margin: auto; - margin-top: 30px; - font-weight: 500; - font-size: 16px; - line-height: 19px; - span { - margin-right: 6px; - } -`; diff --git a/src/components/project/MobileProjectList/index.tsx b/src/components/project/MobileProjectList/index.tsx deleted file mode 100644 index e49034aa..00000000 --- a/src/components/project/MobileProjectList/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from './MobileProjectList'; diff --git a/src/components/project/Pagination/Pagination.tsx b/src/components/project/Pagination/Pagination.tsx deleted file mode 100644 index 289b51a0..00000000 --- a/src/components/project/Pagination/Pagination.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { useId } from 'react'; -import { css } from '@emotion/react'; - -import { colors } from '~/styles/constants'; - -export interface PaginationProps { - onClick: (clickedPage: number) => void; - numberOfPages: number; - currentPage: number; -} - -export default function Pagination({ onClick, numberOfPages, currentPage }: PaginationProps) { - const id = useId(); - return ( -
      - {[...new Array(numberOfPages)].map((_, i) => { - return ( -
    • { - onClick(i + 1); - }} - css={listItemCss(currentPage === i + 1)} - key={`page-${id}-${i + 1}`} - > - {i + 1} -
    • - ); - })} -
    - ); -} - -const listCss = css` - margin-top: 80px; - display: flex; - gap: 40px; - font-family: 'Helvetica'; - font-style: italic; - font-weight: 400; - font-size: 20px; - line-height: 23px; - justify-content: center; -`; - -const listItemCss = (selected: boolean) => css` - color: ${selected ? colors.black : colors.gray500}; -`; diff --git a/src/components/project/ProjectContainer/ProjectContainer.tsx b/src/components/project/ProjectContainer/ProjectContainer.tsx deleted file mode 100644 index 41dcb217..00000000 --- a/src/components/project/ProjectContainer/ProjectContainer.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { css } from '@emotion/react'; -import { AnimatePresence, m } from 'framer-motion'; - -import { staggerHalf } from '~/constants/motions'; -import { mediaQuery } from '~/styles/constants'; - -import { Project } from '../constants'; -import ProjectItem from '../ProjectItem/ProjectItem'; - -interface Props { - projects: Project[]; -} -export default function ProjectContainer({ projects }: Props) { - // NOTE: 모바일의 더보기를 눌렀을 때 같은 리스트인지 파악하기 위해 초기 3개만 사용 - const key = projects.slice(0, 3).reduce((a, p) => a + p.title, ''); - - return ( - - {projects.length && ( - - {projects.map(project => { - return ; - })} - - )} - - ); -} - -const wrapperCss = css` - width: 100%; - display: grid; - grid-template-columns: 1fr 1fr 1fr; - grid-template-rows: repeat(3, 300px); - gap: 24px; - - ${mediaQuery('sm')} { - grid-template-columns: 1fr 1fr; - } - - ${mediaQuery('xs')} { - display: flex; - flex-direction: column; - grid-template-columns: 1fr; - grid-template-rows: 1fr; - gap: 20px; - } -`; diff --git a/src/components/project/ProjectContainer/index.tsx b/src/components/project/ProjectContainer/index.tsx deleted file mode 100644 index b43bbf22..00000000 --- a/src/components/project/ProjectContainer/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from './ProjectContainer'; diff --git a/src/components/project/ProjectItem/ProjectItem.tsx b/src/components/project/ProjectItem/ProjectItem.tsx deleted file mode 100644 index ff14eeea..00000000 --- a/src/components/project/ProjectItem/ProjectItem.tsx +++ /dev/null @@ -1,147 +0,0 @@ -import Image from 'next/image'; -import { css } from '@emotion/react'; -import { m } from 'framer-motion'; - -import { ClickableLink } from '~/components/common/Clickable'; -import { ArrowIcon } from '~/components/common/icons'; -import { defaultFadeInUpVariants } from '~/constants/motions'; -import useMediaQuery from '~/hooks/use-media-query'; -import { colors, mediaQuery } from '~/styles/constants'; -import { body2Css, subtitle1Css } from '~/styles/css'; - -import { Project } from '../constants'; - -interface Props { - project: Project; -} -export default function ProjectItem({ project }: Props) { - const isMobile = useMediaQuery('xs'); - - return ( - - - {project.title} -
    -
    - {project.generation}기 -

    {project.title}

    -

    {project.catchphrase}

    - -
    - - - ); -} - -const wrapperCss = css` - background: black; - position: relative; - overflow: hidden; - - ${mediaQuery('xs')} { - height: 268px; - } -`; - -const gradientCss = css` - position: absolute; - bottom: 0; - width: 100%; - height: 172px; - - ${mediaQuery('xs')} { - background: linear-gradient(0deg, #121212 0%, rgba(18, 18, 18, 0) 100%); - } -`; - -const thumbnailCss = css` - object-fit: cover; - object-position: center; -`; - -const contentsWrapperCss = css` - opacity: 0; - &:hover { - background: linear-gradient(0deg, #121212 0%, rgba(18, 18, 18, 0) 100%); - opacity: 1; - } - width: 100%; - height: 100%; - position: relative; - text-align: left; - color: ${colors.white}; - span { - font-weight: 600; - font-size: 14px; - line-height: 140%; - text-decoration: underline; - position: absolute; - top: 158px; - left: 30px; - } - h3 { - ${subtitle1Css} - position: absolute; - top: 188px; - left: 30px; - } - p { - ${body2Css} - position: absolute; - top: 226px; - left: 30px; - width: 230px; - } -`; - -const mobileContentsWrapperCss = css` - height: 100%; - color: ${colors.white}; - position: relative; - text-align: left; - span { - font-weight: 600; - font-size: 14px; - line-height: 140%; - position: absolute; - left: 20px; - top: 146px; - } - h3 { - font-weight: 600; - font-size: 18px; - line-height: 22px; - position: absolute; - left: 20px; - top: 176px; - } - p { - font-weight: 500; - font-size: 14px; - line-height: 140%; - position: absolute; - left: 20px; - top: 208px; - width: 267px; - } -`; - -const detailLinkCss = css` - position: absolute; - bottom: 40px; - right: 40px; - - ${mediaQuery('xs')} { - bottom: 20px; - right: 20px; - } -`; diff --git a/src/components/project/ProjectList/ProjectList.tsx b/src/components/project/ProjectList/ProjectList.tsx deleted file mode 100644 index 184eb2bf..00000000 --- a/src/components/project/ProjectList/ProjectList.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { useEffect, useMemo, useState } from 'react'; - -import { Project } from '../constants'; -import Pagination from '../Pagination/Pagination'; -import ProjectContainer from '../ProjectContainer'; - -const sliceByPage = (projects: Project[], page: number) => { - return projects.slice(9 * (page - 1), 9 * page); -}; - -interface Props { - projects: Project[]; -} - -export default function ProjectList({ projects }: Props) { - const [currentPage, setCurrentPage] = useState(1); - - useEffect(() => { - setCurrentPage(1); - }, [projects]); - - const displayedProjects = useMemo( - () => sliceByPage(projects, currentPage), - [projects, currentPage] - ); - - const onClickPage = (page: number) => { - setCurrentPage(page); - }; - - return ( - <> - - - - ); -} diff --git a/src/components/project/ProjectList/index.tsx b/src/components/project/ProjectList/index.tsx deleted file mode 100644 index 292b102e..00000000 --- a/src/components/project/ProjectList/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from './ProjectList'; diff --git a/src/components/project/ProjectListSection/ProjectListSection.tsx b/src/components/project/ProjectListSection/ProjectListSection.tsx deleted file mode 100644 index de45a601..00000000 --- a/src/components/project/ProjectListSection/ProjectListSection.tsx +++ /dev/null @@ -1,195 +0,0 @@ -import { useMemo, useState } from 'react'; -import Image from 'next/image'; -import { css } from '@emotion/react'; - -import { ClickableButton } from '~/components/common/Clickable'; -import useMediaQuery from '~/hooks/use-media-query'; -import { colors, mediaQuery } from '~/styles/constants'; -import { section36HeadingCss, sectionSmallCss } from '~/styles/css'; - -import { Project, projects } from '../constants'; -import MobileProjectList from '../MobileProjectList'; -import ProjectList from '../ProjectList/ProjectList'; -import SelectGeneration from '../SelectGeneration'; -import SortBottomSheet from '../SortBottomSheet'; - -export type Order = 'latest' | 'oldest'; -export type Generation = 10 | 11 | 12; - -// 10기 이상은 이전기수로 통칭한다. -const oldGeneration = 10; -const organizedProjects = projects.reduce>((result, project) => { - const generation = project.generation > oldGeneration ? project.generation : oldGeneration; - result[generation] = [...(result[generation] ? result[generation] : []), project]; - return result; -}, {}); - -const sortedByLatestProjects = [...projects].sort((a, b) => { - return b.generation - a.generation; -}); - -const sortedByOldestProjects = [...projects].sort((a, b) => { - return a.generation - b.generation; -}); - -export default function ProjectListSection() { - const [generation, setGeneration] = useState(null); - const [sortBy, setSortBy] = useState('latest'); - const [showBottomSheet, setShowBottomSheet] = useState(false); - - const isMobile = useMediaQuery('xs'); - - const projectData = useMemo(() => { - if (generation) { - return organizedProjects[generation]; - } else if (sortBy === 'latest') { - return sortedByLatestProjects; - } else { - return sortedByOldestProjects; - } - }, [generation, sortBy]); - - const selectGeneration = (generation: null | Generation) => { - setGeneration(generation); - if (!generation) { - setSortBy('latest'); - } - }; - const closeBottomSheet = () => { - setShowBottomSheet(false); - }; - - const sortByLatest = () => { - setSortBy('latest'); - }; - - const sortByOldest = () => { - setSortBy('oldest'); - }; - - return ( -
    - PREVIOUS PROJECTS -

    지난 프로젝트

    - - -
    - {!generation && - (isMobile ? ( -
    -
    { - setShowBottomSheet(true); - }} - > - {sortBy === 'latest' ? '최신순' : '오래된순'} - -
    -
    - ) : ( -
    - - 최신순 - -
    - - 오래된순 - -
    - ))} -
    - - {isMobile ? ( - - ) : ( - - )} - - {isMobile && ( - - )} -
    - ); -} - -const sectionCss = css` - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - text-align: center; - width: 100%; - margin: auto; - margin-top: 130px; - margin-bottom: 180px; - - ${mediaQuery('xs')} { - margin-top: 106px; - margin-bottom: 150px; - } -`; - -const smallCss = css` - ${sectionSmallCss} - margin-bottom: 10px; -`; - -const headingCss = css` - ${section36HeadingCss} - margin-bottom: 60px; - ${mediaQuery('xs')} { - margin-bottom: 20px; - } -`; - -const mobileSortBtnsWrapperCss = css` - padding: 0 16px; - position: relative; -`; - -const mobileSortBtnCss = css` - display: flex; - align-items: center; - margin-right: 4px; - position: absolute; - right: 0; -`; - -const sortBtnsAreaCss = css` - height: 20px; - margin-bottom: 50px; - ${mediaQuery('xs')} { - margin-bottom: 40px; - width: 343px; - } -`; - -const sortBtnsWrapperCss = css``; - -const sortBtnCss = (selected: boolean) => css` - color: ${selected ? colors.black : colors.gray500}; - font-weight: 600; - font-size: 14px; - line-height: 140%; -`; - -const dividerCss = css` - display: inline-block; - margin-left: 22px; - margin-right: 16px; - width: 1px; - height: 12px; - background-color: ${colors.black}; -`; diff --git a/src/components/project/ProjectListSection/index.tsx b/src/components/project/ProjectListSection/index.tsx deleted file mode 100644 index 7855bdcc..00000000 --- a/src/components/project/ProjectListSection/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from './ProjectListSection'; diff --git a/src/components/project/SelectGeneration/SelectGeneration.tsx b/src/components/project/SelectGeneration/SelectGeneration.tsx deleted file mode 100644 index 23bd0e12..00000000 --- a/src/components/project/SelectGeneration/SelectGeneration.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import { css } from '@emotion/react'; - -import { ClickableButton } from '~/components/common/Clickable'; -import { colors, mediaQuery } from '~/styles/constants'; -import { caption2Css } from '~/styles/css'; - -import { Generation } from '../ProjectListSection/ProjectListSection'; - -interface Props { - selectGeneration: (clickedGeneration: null | Generation) => void; - selectedGeneration: null | Generation; -} - -export default function SelectGeneration({ selectGeneration, selectedGeneration }: Props) { - return ( -
    - { - selectGeneration(null); - }} - > - 전체 - - { - selectGeneration(12); - }} - > - 12기 - - { - selectGeneration(11); - }} - > - 11기 - - { - selectGeneration(10); - }} - > - -10기 - -
    - ); -} - -const wrapperCss = css` - margin-bottom: 28px; - display: flex; - gap: 40px; - ${mediaQuery('xs')} { - gap: 20px; - margin-bottom: 20px; - } -`; - -const buttonCss = (selected: boolean) => css` - ${caption2Css} - width: 64px; - height: 41px; - border: 1px solid ${colors.black}; - border-radius: 50%; - - background-color: ${selected && colors.black}; - border: ${!selected && `1px solid ${colors.black}`}; - color: ${selected ? colors.white : colors.black}; - - &:hover, - &:active { - background: ${selected ? colors.black : colors.gray200}; - } -`; diff --git a/src/components/project/SelectGeneration/index.tsx b/src/components/project/SelectGeneration/index.tsx deleted file mode 100644 index 0c704442..00000000 --- a/src/components/project/SelectGeneration/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from './SelectGeneration'; diff --git a/src/components/project/SortBottomSheet/SortBottomSheet.tsx b/src/components/project/SortBottomSheet/SortBottomSheet.tsx deleted file mode 100644 index 21a83a74..00000000 --- a/src/components/project/SortBottomSheet/SortBottomSheet.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import Image from 'next/image'; -import { css } from '@emotion/react'; - -import BottomSheet from '~/components/common/BottomSheet'; -import { BottomSheetModalProps } from '~/components/common/BottomSheet/BottomSheet'; -import { colors } from '~/styles/constants'; - -import { Order } from '../ProjectListSection/ProjectListSection'; - -type Props = Omit & { - sortBy: Order; - sortByLatest: () => void; - sortByOldest: () => void; -}; - -export default function SortBottomSheet({ - isShowing, - onClose, - sortBy, - sortByLatest, - sortByOldest, -}: Props) { - return ( - -
    - -
    - -
    -
    - ); -} - -const bottomSheetContentsCss = css` - background: ${colors.white}; - height: 198px; - padding: 30px; -`; - -const bottomSheetBtnCss = (selected: boolean) => css` - font-size: 18px; - line-height: 21px; - font-weignt: ${selected ? 700 : 500}; - display: flex; - justify-content: space-between; - align-items: center; - height: 24px; - width: 100%; -`; - -const bottomSheetDividerCss = css` - border: 0.3px solid ${colors.black}; - margin: 25px 0; -`; diff --git a/src/components/project/SortBottomSheet/index.tsx b/src/components/project/SortBottomSheet/index.tsx deleted file mode 100644 index bb391825..00000000 --- a/src/components/project/SortBottomSheet/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from './SortBottomSheet'; diff --git a/src/components/project/constants.ts b/src/components/project/constants.ts deleted file mode 100644 index 261b002f..00000000 --- a/src/components/project/constants.ts +++ /dev/null @@ -1,771 +0,0 @@ -type Prize = '대상' | '최우수상' | '우수상' | 'Default'; - -export interface Project { - order: number; - generation: number; - title: string; - team: string; - catchphrase: string; - description: string; - image: string; - icon?: string; - thumbnail: string; - prize: Prize; - ios?: string; - android?: string; - web?: string; - behance?: string; - github?: string; - frontends?: string[]; - backends?: string[]; - designers?: string[]; -} - -export const projects: Array> = [ - { - order: 42, - generation: 12, - title: '짝심삼일', - team: '막내온탑', - prize: '최우수상', - catchphrase: '나를 바꾸는 작은 습관의 힘, 습관 관리 서비스', - description: `새해 목표나 다짐 등 결심으로만 끝났던 경험이 있나요? 3일 연속을 습관을 - 집중적으로 실천하고 짝심삼일의 박수를 받아보세요! 짝심삼일은 쉽고 재 - 밌게 습관을 형성할 수 있도록 돕는 서비스입니다. `, - android: 'https://c11.kr/19ln2', - behance: 'https://url.kr/pyhgze', - github: 'https://github.com/depromeet12th/three-days-android', - image: 'details/짝심삼일.png', - thumbnail: 'thumbnails/짝심삼일.png', - designers: ['맹지영', '이승희', '장지현'], - frontends: ['김주환(Android)', '김혜인(Android)', '전해성(Android)'], - backends: ['김주현', '정구아', '채상엽'], - }, - { - order: 41, - generation: 12, - title: 'KNOCKNOCK', - team: '칠면조', - prize: 'Default', - catchphrase: '내 친구가 보내는 생생한 푸시알림 서비스', - description: `🏃‍♀️ “목표 달성까지 얼마 안남았어요, 화이팅!" 이런 푸시 알림, 무시해본 적 - 있나요? Knocknock에서 관심사 알림을 구독하고, 사람 냄새나는 푸 - 시 알림을 받아보세요. 의미있는 소통으로 동기부여 해드릴게요!`, - android: 'https://play.google.com/store/apps/details?id=com.depromeet.knockknock', - behance: 'https://www.behance.net/gallery/161848521/KNOCKNOCK-PUSH-NOTIFICATION-CUSTOM-SERVICE', - github: 'https://github.com/depromeet/12th-KnockKnock-Android', - image: 'details/KNOCKNOCK.png', - thumbnail: 'thumbnails/KNOCKNOCK.png', - designers: ['김나영', '박수연', '진승희'], - frontends: ['황규일(Android)', '이영준(Android)', '조준장(Android)', '최현정(Android)'], - backends: ['이찬진', '배정은', '이서준'], - }, - - { - order: 40, - generation: 12, - title: 'TICLEMOA', - team: '뇽뇽', - prize: 'Default', - catchphrase: '아티클을 모아 지식을 태산처럼, 아티클 스크랩 서비스', - description: `쏟아지는 아티클 플랫폼과 읽을거리의 홍수에 살고 있는 우리, 아티클만을 - 위한 편리한 저장고는 없을까요? 티클모아는 아티클을 저장하고 관리하여 - 지식을 쌓을 수 있도록 도와주는 앱 서비스입니다.`, - ios: 'https://apps.apple.com/kr/app/ticlemoa/id1659267166', - github: 'https://github.com/depromeet/ticlemoa-backend', - behance: 'https://www.behance.net/gallery/161983453/TICLEMOA-Article-clipping-service-', - image: 'details/TICLEMOA.png', - thumbnail: 'thumbnails/TICLEMOA.png', - designers: ['임효연', '허창민', '형성현'], - frontends: ['김용우(iOS)', '김우성(iOS)', '신재웅(iOS)', '차요셉(iOS)'], - backends: ['이성태', '송은우', '강시온'], - }, - { - order: 39, - generation: 12, - title: '똑스', - team: '오개안말', - prize: '우수상', - catchphrase: '내가 만든 퀴즈로 스터디를 재미있게, 똑스', - description: `덜컥 시작한 스터디, 점차 지쳐 마무리를 못한 적이 있으신가요? 똑스에서 - 는 스터디원과 다같이 모여 퀴즈를 만들고 풀 수 있어요. 더 많은 퀴즈를 풀 - 어가며 똑톡이의 방이 채워지는 모습도 확인할 수 있답니다. 마지막까지 즐 - 겁게 공부할 수 있는 똑스, 지금 바로 시작해보세요.`, - web: 'https://tokstudy.com/', - behance: 'https://www.behance.net/gallery/161231589/Toks-Quiz-Study-Service-', - github: 'https://github.com/depromeet/toks-web', - image: 'details/똑스.png', - thumbnail: 'thumbnails/똑스.png', - designers: ['김성념', '유정현', '이원희'], - frontends: ['강현구', '김채림', '윤두현', '최민석'], - backends: ['김동건', '김시은', '호선우'], - }, - { - order: 38, - generation: 12, - title: '코퀄리티', - team: '시원스쿨', - prize: 'Default', - catchphrase: '지식을 공유하고, 후원하며 함께 성장하는 블로깅 플랫폼', - description: `코컬리티는 IT 종사자가 글을 올리고 후원받을 수 있는 블로깅 플랫폼으로, - 성장이 필수적인 IT 현직자들을 위해 새로운 블로깅 플랫폼을 제안합니다.`, - web: 'coquality.vercel.app', - behance: 'https://www.behance.net/gallery/161841129/-Coquality-High-Quality-Blogging-Platform', - image: 'details/코퀄리티.png', - thumbnail: 'thumbnails/코퀄리티.png', - designers: ['김유리', '엄희수', '전수미'], - frontends: ['정시원', '김해나', '이상민'], - backends: ['지우영', '이제준'], - }, - { - order: 37, - generation: 12, - title: '아맞다', - team: '삼겹살', - prize: '대상', - catchphrase: '대신 외쳐주는 소지품 리스트', - description: `오늘도 외출할 때 ‘아맞다!’를 외치진 않으셨나요? - 아맞다는 오직 소지품에 집중한 체크리스트, 리마인드 알림, - 소지품 추천으로 일상의 작은 고민을 덜어주는 서비스입니다. - 매일 소지품을 깜빡해 스트레스 받는 당신을 위해, - 아맞다가 완벽하게 챙길 수 있도록 도와드릴게요.`, - ios: 'https://apps.apple.com/kr/app/%EC%95%84%EB%A7%9E%EB%8B%A4/id1660192508', - android: 'https://play.google.com/store/apps/details?id=com.ahmatda&hl=ko', - web: 'https://ahmatda.notion.site/ahmatda/3202c2a4e2dd440eb95ae3345a130fc4', - behance: 'https://www.behance.net/gallery/161161601/-Ahmatda-Checklist-for-Your-Belongings', - image: 'details/아맞다.png', - thumbnail: 'thumbnails/아맞다.png', - designers: ['이영희', '이종원', '윤가빈'], - frontends: ['구민규', '오혜성', '이은지', '박한솔'], - backends: ['김민걸', '조성민', '명수찬'], - }, - { - order: 36, - generation: 12, - title: 'PING-PONG!', - team: '말하는 감자들', - prize: 'Default', - catchphrase: '재능을 교환하고 나누며 성장하는 플랫폼, 핑퐁', - description: `'핑퐁'은 재능 공유 플랫폼으로, 자신의 재능과 스킬을 공유하고 다른 - 사용자들과 재능 교환을 할 수 있도록 도와줍니다. 온라인 환경에서도 - 여러분이 서로 동반성장을 이룰 수 있도록 '핑퐁'이 도와드릴게요.`, - ios: 'https://apps.apple.com/kr/app/%ED%95%91%ED%90%81-pingpong/id1662351621', - behance: 'https://www.behance.net/gallery/161783411/Ping-Pong', - image: 'details/PING-PONG.png', - thumbnail: 'thumbnails/PING-PONG.png', - designers: ['안유진', '권수경', '박은진'], - frontends: ['이동현', '이도윤', '황예나'], - backends: ['최영권', '서명현', '이연희', '김민수'], - }, - { - order: 35, - generation: 12, - title: '꼬깃', - team: '동규밭 과수원샷', - prize: 'Default', - catchphrase: '진심을 표현하고 싶을 때, 꼬깃 접어 전해보세요', - description: `소중한 사람들에게 마음을 표현하고 싶을 때 꼬깃이 도와드릴게요. 쉽고 - 재미있게 편지를 작성하고, 주고 받은 편지를 아카이빙하며 색다른 추억을 - 남겨 보세요!`, - web: 'https://www.ggo-geet.com', - behance: 'https://url.kr/qd3ijo', - image: 'details/꼬깃.png', - thumbnail: 'thumbnails/꼬깃.png', - designers: ['김나영', '김혜진', '정지원'], - frontends: ['김가은', '김동규', '김민수', '최영광'], - backends: ['김문규', '유희수', '정성훈'], - }, - { - order: 34, - generation: 11, - title: '비어에어', - team: '술술이들', - catchphrase: '편의점 세계 맥주로 세계 여행도장깨기', - description: `해외여행 한 번 가기 쉽지 않은 시대, - 저희 비어에어는 편의점 세계 맥주와 함께 여행을 떠나는 듯한 경험을 제공합니다. - 원하는 맥주를 검색하고, 여행지를 고르듯 맥주를 골라보세요. - 간단한 기록을 남기면 티켓으로 보관할 수 있어요. 다양한 나라와 맥주에 여러분의 발자취를 남겨보세요!`, - web: 'https://beerair.kr', - behance: 'https://www.behance.net/gallery/147281821/Beer-Air-UXUI-Design-Mobile-App-Service', - image: 'details/비어에어.png', - icon: 'icons/비어에어.png', - thumbnail: 'thumbnails/비어에어.png', - prize: 'Default', - designers: ['김영서', '정선하', '전혜원'], - frontends: ['김효진', '조찬영', '고서영'], - backends: ['김태호', '류찬', '김소정', '김민수'], - }, - { - order: 33, - generation: 11, - title: '영감탱', - team: '7ㅏ즈아', - catchphrase: '영감을 모아 통통튀는 아이디어로, 영감탱', - description: `어? 영감이다! 여기저기 흩어져있는 넘치는 영감. - 세상의 모든 것은 영감이 될 수 있고, 영감탱에서 기억할 수 있어요. - 글, 이미지(사진, 스크린샷), 웹링크를 첨부하여 나의 통통튀는 영감을 빠르게 태그, 메모와 함께 차곡차곡 아카이빙해봐요.`, - ios: 'https://apps.apple.com/kr/app/%EC%98%81%EA%B0%90%ED%83%B1/id1626598770', - android: 'https://play.google.com/store/apps/details?id=kr.ygtang', - behance: 'https://www.behance.net/gallery/147207859/TANG-Inspiration-Archiving-App', - image: 'details/영감탱.png', - icon: 'icons/영감탱.png', - thumbnail: 'thumbnails/영감탱.png', - prize: '대상', - designers: ['김자영', '박수연', '정미숙'], - frontends: ['고은정', '오혜성', '정대윤', '정도현'], - backends: ['김자연', '문인우', '정형일'], - }, - { - order: 32, - generation: 11, - title: '바통', - team: '안쓸거면 나조', - catchphrase: '운동 회원권 양도 거래 서비스 , 바통', - description: `야심차게 등록한 헬스장, 야근, 학업, 출장 등의 이유로 장기 결석하시나요? - 필라테스 다니고 싶은데 할인을 놓쳐 부담스러운 금액으로 고민이신가요? - 운동 회원권 양도 거래 플랫폼 바통에서 더 이상 사용하지 않는 회원권은 개인 거래로 빠르게 판매하고, 평소 눈여겨 보던 다양한 운동을 저렴한 가격에 구매해보세요!`, - android: 'https://play.google.com/store/apps/details?id=com.depromeet.baton', - behance: 'https://www.behance.net/gallery/147261349/Baton', - image: 'details/바통.png', - icon: 'icons/바통.png', - thumbnail: 'thumbnails/바통.png', - prize: 'Default', - designers: ['강창모', '배희영', '이설희'], - frontends: ['신승민', '김다빈', '김효민'], - backends: ['최용호', '박민재', '임정섭'], - }, - { - order: 31, - generation: 11, - title: '무드픽', - team: '5GZOO', - catchphrase: '부정적 감정의 기록, 퍼스널 아카이빙 서비스', - description: `나를 괴롭히는 부정적인 감정들을 회피하기보다는 정면으로 맞서 우리의 삶을 성장시킬 수 있는 지표로 볼 수 있다면 어떨까요? - 무드픽은 부정적 감정을 기록하며 감정의 발자취를 따라가고 스스로 해결의 실마리를 찾는 주도적인 방법을 제공하고자 합니다.`, - ios: 'https://apps.apple.com/kr/app/%EB%AC%B4%EB%93%9C%ED%94%BD/id1642343841', - android: 'https://play.google.com/store/apps/details?id=com.depromeet_5team.moodpicapp', - web: 'https://www.moodpic.kr/', - behance: 'https://www.behance.net/gallery/147271219/Archiving-My-Personal-Emotions-Moodpic', - image: 'details/무드픽.png', - icon: 'icons/무드픽.png', - thumbnail: 'thumbnails/무드픽.png', - prize: 'Default', - designers: ['임효연', '이승희', '박소현'], - frontends: ['박수진', '조기문', '박상범'], - backends: ['이건', '이솔', '양형욱', '박수호'], - }, - { - order: 30, - generation: 11, - title: '티키타카', - team: '팀가치4조', - catchphrase: '위치 기반 실시간 채팅 서비스, 티키타카', - description: `👥 🗣장소에 대한 많은 기억과 이야기들, 나만 알기 아깝다구요?🗣👥 - 해당 장소에 있는 사람들과 그 곳에서 일어나는 다양한 일들을 티키타카에서 실시간으로 공유해요! 💬 실시간 위치 기반 채팅방 탐색🔎은 물론 카테고리별 장소 기반으로 개설된 채팅방에서 사람들과 대화를 나눠보세요!🐤`, - ios: 'https://apps.apple.com/kr/app/%ED%8B%B0%ED%82%A4%ED%83%80%EC%B9%B4-tikitaka/id1617831823?l=en', - behance: - 'https://www.behance.net/gallery/145307681/Tikitaka-Location-based-real-time-chat-Q-A-app', - image: 'details/티키타카.png', - icon: 'icons/티키타카.png', - thumbnail: 'thumbnails/티키타카.png', - prize: '최우수상', - designers: ['고유진', '이병호', '홍서희'], - frontends: ['강민석', '김록원', '송하경'], - backends: ['김우진', '이찬진'], - }, - { - order: 29, - generation: 11, - title: '몽실', - team: '벽력일삼', - catchphrase: '흐릿했던 꿈을 선명하게', - description: `아리송한 꿈을 꾸고 해몽을 검색해 본 적이 있나요? - 몽실으로 궁금한 꿈에 대해 검색하고 보관할 수 있어요. 내가 꾼 꿈을 기록하고, 꿈의 키워드로 해몽을 바로 확인할 수도 있답니다. 귀여운 그래픽과 함께 제공되는 해몽을 지금 바로 확인해보세요!`, - ios: 'https://apps.apple.com/kr/app/%EB%AA%BD%EC%8B%A4-mong-seal/id1622154270?l=kr', - behance: - 'https://www.behance.net/gallery/147282295/%28Mongseal%29Archive-Your-Dream?tracking_source=search_projects%7Cdream', - image: 'details/몽실.png', - icon: 'icons/몽실.png', - thumbnail: 'thumbnails/몽실.png', - prize: 'Default', - designers: ['정진아', '김나영', '이영희'], - frontends: ['조찬우', '이승후'], - backends: ['이건웅', '이석호'], - }, - { - order: 28, - generation: 11, - title: '페어러', - team: '도와조!홈즈', - catchphrase: '페어러와 함께 평화롭게 집안일 하기', - description: `여럿이서 함께 생활을 하다보면 집안일로 인해 갈등이 빚어지는 경우들이 생깁니다. 페어러는 이러한 집안일에 대한 어려움을 해소하고자 합니다. 집안일을 쉽게 관리하고 분담할 수 있도록 도와 모든 사람이 평화롭게 집안일을 하는 날까지 페어러가 함께합니다.`, - android: 'https://play.google.com/store/search?q=fairer&c=apps', - behance: 'https://www.behance.net/gallery/147276499/fairerPeacemaker-for-Houseworker', - image: 'details/페어러.png', - icon: 'icons/페어러.png', - thumbnail: 'thumbnails/페어러.png', - prize: 'Default', - designers: ['권진혁', '최지혜', '고가혜'], - frontends: ['김수연', '박정준', '임수진'], - backends: ['김승윤', '김다슬', '신동빈', '곽다은'], - }, - { - order: 27, - generation: 11, - title: '개미는 툰툰', - team: '디프만 1번 출구', - catchphrase: '주식 용어로 즐기는 웹툰의 새로운 덕질 문화, 개미는 툰툰', - description: `개미는 툰툰은 주식 컨셉을 바탕으로 웹툰의 새로운 덕질 문화를 만들고자 합니다. - 평소 즐겨보는 웹툰의 재미있는 주제에 대한 투표, 웹툰 속 인물과 커플에 탑승과 하차, 다른 사람들과 소통할 수 있는 댓글 등 재미있게 즐길 수 있는 다양한 콘텐츠와 기능을 제공합니다.`, - web: 'https://antoon.fun/', - android: 'https://play.google.com/store/apps/details?id=com.antoon_app', - behance: 'https://www.behance.net/gallery/147262623/-ANTOON-l-Webtoon-Community-Service', - image: 'details/개미는툰툰.png', - icon: 'icons/개미는툰툰.png', - thumbnail: 'thumbnails/개미는툰툰.png', - prize: '우수상', - designers: ['박정연', '이홍빈', '이혜린'], - frontends: ['이병현', '김민지', '최푸름'], - backends: ['윤영', '이하늘', '염지원', '김동건'], - }, - { - order: 26, - generation: 10, - title: 'noonbody', - team: '일조권 침해', - catchphrase: '건강한 눈바디 다이어트', - description: `눈바디를 통해 신체 변화를 보다 직관적으로 파악하고, 신체 변화를 확실하게 체감할 수 있을뿐더러 더 나아가 건강한 다이어트 습관까지 잡을 수 있습니다.`, - android: 'https://play.google.com/store/apps/details?id=com.def.everybody_android', - image: 'details/noonbody.png', - icon: 'icons/noonbody.png', - thumbnail: 'thumbnails/noonbody.png', - prize: 'Default', - designers: ['심준연', '박정연', '조혜림'], - frontends: ['윤예지', '안유경(iOS)'], - backends: ['유기태', '박진수', '안태건'], - }, - { - order: 25, - generation: 10, - title: 'IMGOING', - team: '9조를 벌었조', - catchphrase: '나만의 준비 루틴', - description: `나만의 준비 루틴을 설정하고, 약속까지 늦지 않게 일정을 관리하세요! - 홈 화면에서 다가오는 일정을 간편하게 확인할 수 있습니다. - 간단한 프로세스로 다가오는 약속 일정을 등록하세요.`, - android: 'https://play.google.com/store/apps/details?id=com.dpm.imgoing', - image: 'details/imgoing.png', - icon: 'icons/imgoing.png', - thumbnail: 'thumbnails/imgoing.png', - prize: 'Default', - backends: ['송정우', '이유진', '황종훈'], - designers: ['김고은', '곽진', '이여빈'], - frontends: ['이은성', '유경상', '안은결(iOS)'], - }, - { - order: 24, - generation: 10, - title: 'BBOXX', - team: '돈벌어야조', - catchphrase: '당신의 부정적인 감정을 대신 먹어주는 친구', - description: `당신의 부정적인 감정들을 소리치기로 순간의 빡침을 풀어냅니다. - 감정일기로 현재 감정을 정리합니다. - 성장일기로 이전 감정을 회고합니다.`, - android: 'https://play.google.com/store/apps/details?id=com.depromeet.bboxx', - ios: 'https://apps.apple.com/kr/app/%EB%B9%A1%EC%93%B0/id1597106306', - image: 'details/bboxx.png', - icon: 'icons/bboxx.png', - thumbnail: 'thumbnails/bboxx.png', - prize: 'Default', - backends: ['김수빈', '박중수', '이경석'], - designers: ['이지은', '김소연'], - frontends: ['김은우', '이근나(iOS)', '이중근', '구해린(Android)'], - }, - { - order: 23, - generation: 10, - title: '나나공', - team: '신동빈센조', - catchphrase: '나보다 나무늘보가 공부 열심히 한다', - description: `나나공은 완강 데드라인에 맞춰 주차별로 자동으로 적정 진도를 계산해줍니다. 매주 들었던 강의 수를 입력하면, 나공이가 진도별로 새로운 메시지를 주곤 합니다. 강의 상세페이지에 들어가면 내가 적정 진도를 맞추지 못할 때마다 날아간 금액을 확인할 수 있습니다.`, - android: 'https://play.google.com/store/apps/details?id=com.depromeet.sloth', - - image: 'details/나나공.png', - icon: 'icons/나나공.png', - thumbnail: 'thumbnails/나나공.png', - prize: 'Default', - backends: ['변구훈', '김율희', '신동빈'], - designers: ['임효연', '이종찬', '박준영'], - frontends: ['신한섭', '임승혁(iOS)', '최철훈', '이지훈(Android)'], - }, - { - order: 22, - generation: 10, - title: 'Archive', - team: '머선 12조', - catchphrase: '나만의 전시보관소', - description: `나만의 전시 보관소, 아카이브 - 차곡차곡 아카이빙되는 전시 기록, 서랍 어딘가에서 티켓과 함께 잊혀지는 감상 감정들을 이제는 아카이브에서 차곡차곡 보관해보세요.`, - ios: 'https://apps.apple.com/kr/app/archive/id1599941822', - image: 'details/archive.png', - icon: 'icons/archive.png', - thumbnail: 'thumbnails/archive.png', - prize: 'Default', - backends: ['김보배', '김준석', '배연주'], - designers: ['이경주', '이송민', '정미숙'], - frontends: ['이한위'], - }, - { - order: 21, - generation: 10, - title: '대동빵지도', - team: '칠색조', - catchphrase: '빵순이들의 빵지도', - description: `동네에서 도시. 더나아가 전국의 빵집까지 ! - 여러분이 알고있는 빵집을 모두와 함께 공유하여 빵을 즐겨요!`, - android: 'https://play.google.com/store/apps/details?id=app.daedongbread.twa', - image: 'details/대동빵지도.png', - icon: 'icons/대동빵지도.png', - thumbnail: 'thumbnails/대동빵지도.png', - prize: 'Default', - backends: ['이지은', '황지수', '이해인'], - designers: ['민윤기', '지예나', '이정민'], - frontends: ['김유진', '소석진', '김한철', '이재욱'], - }, - { - order: 20, - generation: 10, - title: '오맵땡', - team: '물좀조', - catchphrase: '오늘 당신은 매운게 땡긴다!', - description: `오맵떙은 사용자의 매운 맛 레벨을 기반으로 매운 음식을 추천해줘요! 대표적인 매운 음식으로 나의 맵기 레벨을 테스트해봐요!`, - web: 'https://ohmebddeng.kr/', - image: 'details/오맵땡.png', - icon: 'icons/오맵땡.png', - thumbnail: 'thumbnails/오맵땡.png', - prize: 'Default', - backends: ['김성민', '공채원', '이혜연'], - designers: ['이가인', '정은주', '김영환'], - frontends: ['이성용', '홍영준', '김문희', '김은수(Web)'], - }, - { - order: 19, - generation: 10, - title: 'Bodymood', - team: '잊지말아조', - catchphrase: '운동 내용을 기록하고 오늘의 감정을 담은 포스터', - description: `Bodymood는 오늘의 운동 루틴과 감정을 한 장의 포스터로 만들어 더욱 재밌고 지속적으로 기록할 수 있게 도와주는 아카이빙 서비스입니다. 운동 내용을 기록하고 오늘의 감정을 담아 포스터로 만들어주는 이미지 제작 툴입니다`, - android: 'https://play.google.com/store/apps/details?id=com.depromeet.bodymood', - ios: 'https://apps.apple.com/kr/app/bodymood/id1588818384', - image: 'details/bodymood.png', - icon: 'icons/bodymood.png', - thumbnail: 'thumbnails/bodymood.png', - prize: 'Default', - backends: ['이유진', '강승호', '전혜수'], - designers: ['권진혁', '남수진', '박서진'], - frontends: ['허예은', '조기현(iOS)', '오기환', '이민현(Android)'], - }, - { - order: 18, - generation: 10, - title: 'OMO', - team: '우리는 사랑과 행복을 팔조', - catchphrase: '오마카세의 모든 것', - description: `내가 다녀간 오마카세 목록을 인증받고 자랑하자! 오모는 오마카세를 카테고리(클래식/미들/하이엔드)별로 확인하고 내가 다녀간 오마카세를 도장을 찍는 방법으로 남들에게 자랑할 수 있는 서비스입니다.`, - android: 'https://play.google.com/store/apps/details?id=com.wesellloveandhappiness.omo', - web: 'https://omo-deployment.vercel.app/', - image: 'details/omo.png', - icon: 'icons/omo.png', - thumbnail: 'thumbnails/omo.png', - prize: 'Default', - backends: ['윤영', '이승윤'], - designers: ['이병호', '조어진', '구세빈'], - frontends: ['박종호', '이강열', '김효진(Web)'], - }, - { - order: 17, - generation: 10, - title: '영차', - team: '무야호', - catchphrase: - '영차는 투자 자산 모아보기 직접 입력한 정보를 기반으로 현재 투자 상황을 모아볼 수 있습니다.', - description: `수익률 계산기로 수익률을 예상하고 물타기 계산기로 목표 평단까지 낮추려면 얼마나 물타야 할지 알아보세요!`, - ios: 'https://apps.apple.com/.../%EC%98%81%EC%B0%A8/id1571507288', - - image: 'details/영차.png', - icon: 'icons/영차.png', - thumbnail: 'thumbnails/영차.png', - prize: 'Default', - backends: ['박영준', '강승호'], - designers: ['이병호', '이윤이', '민윤기'], - frontends: ['유현식', '이현호(iOS)', '장명준', '강승호(Android)'], - }, - { - order: 16, - generation: 9, - title: 'TOONI TOONI', - team: '-', - catchphrase: '세상의 모든 웹툰', - description: `웹툰 정보를 확인하고 사용자들과 댓글로 소통해보세요. - 내가 보는 웹툰, 좋아하는 웹툰을 편리하게 관리하세요. - 보고 싶은 웹툰을 검색하고, 새로운 추천도 받아보세요.`, - android: 'https://play.google.com/store/apps/details?id=kr.tooni.tooni', - image: 'details/tooni.png', - icon: 'icons/tooni.png', - thumbnail: 'thumbnails/tooni.png', - prize: 'Default', - backends: ['박세종', '김종하'], - designers: ['여해주', '김나영'], - frontends: ['문지윤', '김승진(iOS)', '이오형', '이정민', '최현정(Android)'], - }, - { - order: 15, - generation: 9, - title: '마이레시픽', - team: '철이없었조', - catchphrase: '취향대로 골라 만드는 나만의 레시피', - description: `마이레시픽은 원하는 재료를 직접 커스텀하여 나만의 레시피를 만들어 공유할 수 있는 앱입니다. 서브웨이, 스타벅스 등 프랜차이즈 브랜드에서 제공하는 메뉴를 선택하고 자신의 취향대로 다양한 재료를 조합할 수 있습니다.`, - android: - 'https://play.google.com/store/apps/details?id=com.def.custom&fbclid=IwAR01nq8JiuvvGdpnxFZEOJXef5EiOVP929GCGtHvv3-uiXkLVhIv2R9YS_c', - ios: 'https://apps.apple.com/kr/app/%EB%A7%88%EC%9D%B4%EB%A0%88%EC%8B%9C%ED%94%BD/id1569961091?fbclid=IwAR2Bu-JPXUcUiCY6dUPv6kq2KwoD97p8jl2Rf2lqY_o59pyKQbHVccPweOE', - image: 'details/마이레시픽.png', - icon: 'icons/마이레시픽.png', - thumbnail: 'thumbnails/마이레시픽.png', - prize: 'Default', - backends: ['이기승', '이예린'], - designers: ['정진아', '부자영'], - frontends: ['정진용', '김서진(iOS)', '이한위', '김성민(Android)'], - }, - { - order: 14, - generation: 9, - title: '오늘의 테스트', - team: '이그조', - catchphrase: '쉽고 빠른 나만의 테스트 만들기', - description: `유행하는 심리테스트, 성격테스트 내가 직접 만들어볼 수 있다면 어떨까? - 오늘의테스트는 객관식 테스트, mbti 테스트 등 다양한 테스트를 직접 - 만들 수 있게 도와드려요.`, - web: 'https://todaytest.netlify.app/', - image: 'details/오늘의테스트.png', - icon: 'icons/오늘의테스트.png', - thumbnail: 'thumbnails/오늘의테스트.png', - prize: 'Default', - backends: ['이규원', '백선혜', '장효택'], - designers: ['노은종', '이슬이'], - frontends: ['최재은', '천승아', '정현정(Web)'], - }, - { - order: 13, - generation: 9, - title: 'Hush', - team: '삼시세끼', - catchphrase: '익명 소통 플랫폼', - description: `허쉬는 MZ세대의 익명 소통 플랫폼 입니다. - 상대방에게 부분익명과 완전익명을 선택해서 질문할 수 있어요. - 부분익명은 답변이 등록되고 24시간 후에 피드 주인에게만 - 질문자의 이름이 공개됩니다!`, - web: 'www.hush-it.com', - image: 'details/hush.png', - icon: 'icons/hush.png', - thumbnail: 'thumbnails/hush.png', - prize: 'Default', - backends: ['이경석', '오민석', '최은석'], - designers: ['심준연', '임효연', '박소진'], - frontends: ['한영수', '정진리', '이윤현(Web)'], - }, - { - order: 12, - generation: 9, - title: '링크줍줍', - team: '칠성파', - catchphrase: '아티클 스크랩 리마인드 서비스', - description: `링크줍줍은 '아티클을 읽어야지'라고 생각만 하고 잊어버린 사람들을 위한 서비스입니다. - 링크를 스크랩하고 사용자가 설정한 시간에 - 아티클을 읽을 수 있도록 알려주며, - 동기부여를 가질 수 있는 귀여운 문구들을 제공합니다.`, - image: 'details/링크줍줍.png', - icon: 'icons/링크줍줍.png', - thumbnail: 'thumbnails/링크줍줍.png', - prize: 'Default', - backends: ['최예진', '오준석'], - designers: ['박은지', '김영환'], - frontends: ['권지혜', '조수환(iOS)', '이민수', '김나경(Android)'], - }, - { - order: 11, - generation: 9, - title: '제로우쥬', - team: '지구를 지켜조', - catchphrase: '친환경 용사가 되어 우쥬를 지키는 제로웨이스트 서비스', - description: `친환경 용사가 되어 우쥬를 지키는 제로웨이스트 서비스 - 제로우쥬모두가 할 수 있지만 누구나 하지 않는 제로웨이스트,단순히 환경 윤리적 책임으로 수행하는 것이 아닌친 환경 활동을 게임처럼 즐기고 인증 뱃지를 모으는 서비스에요.`, - image: 'details/제로우쥬.png', - icon: 'icons/제로우쥬.png', - thumbnail: 'thumbnails/제로우쥬.png', - prize: 'Default', - backends: ['권주희', '이경희'], - designers: ['김민효', '방유진', '김종훈'], - frontends: ['국윤수', '한상진(iOS)', '황견주', '진승언(Android)'], - }, - { - order: 10, - generation: 9, - title: '크래커북', - team: '빈센조', - catchphrase: '내일을 바꾸는 오늘의 북스터디', - description: `크래커북은 책을 중심으로 스터디를 주최하고 참여하는 모바일 웹 서비스입니다. 간편한 북스터디 주최, - 내가 원하는 책으로 스터디 참여, 재미있고 효율적인 스터디 관리를 통해 크래커를 먹듯이 쉽고 재밌게 북 스터디에 빠져들 수 있습니다.`, - image: 'details/크래커북.png', - icon: 'icons/크래커북.png', - thumbnail: 'thumbnails/크래커북.png', - prize: 'Default', - backends: ['김민태', '이유진', '김준홍'], - designers: ['이경주', '손주리'], - frontends: ['유상원', '이성용', '지주연(Web)'], - }, - { - order: 9, - generation: 8, - title: '3대 얼마', - team: '-', - catchphrase: '헬린이 철 들기 프로젝트', - description: `'3대 얼마'는 보디빌딩 3대 종목인 벤치프레스, 데드리프트, 스쿼트의 총 합 무게를 증명하는 공간입니다. 점진적 과부화를 위해 꾸준한 3대 기록으로 근육을 성장시키고 서로 피드백을 받아 헬스 친구를 만들 수 있습니다.`, - image: 'details/3대얼마.png', - icon: 'icons/3대얼마.png', - thumbnail: 'thumbnails/3대얼마.png', - prize: 'Default', - designers: ['김민효', '김종훈', '추지효'], - backends: ['조민국', '최문경'], - frontends: ['오기환 (iOS)', '유영평 (Android)', '황견주 (Android)'], - }, - { - order: 8, - generation: 7, - title: '가슴속 3천원', - team: '청일점', - catchphrase: '길거리 음식 찾기', - description: `가슴속 3천원"은 우리 가슴속에 지니고 다니는 3천원을 털어가는 붕어빵, 타꼬야끼, 계란빵, 호떡 등의 길거리 음식을 파는 곳을 알려드립니다. 가슴속 3천원은 사용자 참여형 서비스인 만큼 직접 가게를 제보하여 사용자들과 함께 가게 정보를 채워나갈 수 있습니다."`, - android: 'https://play.google.com/store/apps/details?id=com.zion830.threedollars', - ios: 'https://apps.apple.com/kr/app/%EA%B0%80%EC%8A%B4%EC%86%8D3%EC%B2%9C%EC%9B%90-%EB%82%98%EC%99%80-%EA%B0%80%EA%B9%8C%EC%9A%B4-%EB%B6%95%EC%96%B4%EB%B9%B5/id1496099467', - image: 'details/가슴속3천원.png', - icon: 'icons/가슴속3천원.png', - thumbnail: 'thumbnails/가슴속3천원.png', - prize: 'Default', - backends: ['전해성', '손지수', '이유리'], - designers: ['이윤이', '양효정'], - frontends: ['유현식 (iOS)', '이윤지 (Android)'], - }, - { - order: 7, - generation: 8, - title: '북쪽으로', - team: '다해조', - catchphrase: '독서 기록. 특별한 책을 남기는 순간', - description: `특별한 장소에 의미있는 책을 남기세요. 당신의 독서 발자취를 한 눈에 확인하세요. 이제, 마음을 움직이는 책을 따라가보세요.`, - - image: 'details/북쪽으로.png', - icon: 'icons/북쪽으로.png', - thumbnail: 'thumbnails/북쪽으로.png', - prize: 'Default', - backends: ['김예슬', '손지수'], - designers: ['황예리', '정보영', '양정안'], - frontends: ['김지은 (iOS)', '이규현 (iOS)'], - }, - { - order: 6, - generation: 8, - title: 'Avocado', - team: '방탄채소단', - catchphrase: '열어봐야 진짜를 만날 수 있는, 채소 가격들의 단면을 분석해서 제공', - description: `대표커머스들의 채소가격, 마트별 배송료, 마트별 최저가 등을 제공해주어 사람들의 스마트한 베지라이프를 도와주는 서비스입니다. 구매하고자 하는 채소들의 이름을 장바구니에 담으면 각 커머스별로 최적의 조합을 찾아줍니다.`, - - image: 'details/avocado.png', - icon: 'icons/avocado.png', - thumbnail: 'thumbnails/avocado.png', - prize: 'Default', - backends: ['하재권'], - designers: ['윤정민', '황예리'], - frontends: ['심재철', '심문성', '이정민 (Web)'], - }, - { - order: 5, - generation: 6, - title: 'Therto', - team: '-', - catchphrase: '편지를 보낸곳에서 읽는 서비스', - description: `지금 여기, 이 공간에서 친구, 연인에게 편지를 써보세요. 친구는 내가 편지를 쓴 공간에 가야만 편지를 열어볼 수 있습니다. 편지를 작성할 때 작성자의 위치도 편지에 같이 담겨 전달됩니다. 수신자는 편지가 작성된 공간 300m 근처로 가야 편지를 열 수 있답니다.`, - ios: 'https://apps.apple.com/kr/app/thereto-%ED%8E%B8%EC%A7%80%EB%A5%BC-%EC%97%AC%EB%8A%94-%EA%B3%B5%EA%B0%84/id1500364832', - - image: 'details/therto.png', - icon: 'icons/therto.png', - thumbnail: 'thumbnails/therto.png', - prize: 'Default', - backends: ['유현식'], - designers: ['박은지', '김민경', '한지윤'], - frontends: ['유현식 (iOS)'], - }, - { - order: 4, - generation: 6, - title: '쿨피스', - team: '-', - catchphrase: '에어컨 사용 요금 측정 서비스', - description: `원룸러분들 방에서 에어컨 킬 때 전기세가 많이 나올까 걱정되지 않나요? 에어컨 사용량에 따른 예상 전기 요금을 알려드립니다. 캘린더에 하루 사용시간을 입력하면 이번 달 전기 요금을 알 수 있습니다. 또한 지난 과거에 나온 전기 요금도 알 수 있습니다.`, - android: 'https://play.google.com/store/apps/details?id=com.depromeet.tmj.cool_fees', - - image: 'details/쿨피스.png', - icon: 'icons/쿨피스.png', - thumbnail: 'thumbnails/쿨피스.png', - prize: 'Default', - designers: ['노경래', '서수민'], - frontends: ['유현식 (Android)'], - }, - { - order: 3, - generation: 6, - title: '칼퇴요정', - team: '-', - catchphrase: '칼퇴를 하고싶게 도와주는 요정녀석', - description: `아직도 회사에서 야근을 자주하십니까? 자신이 얼마나 야근을 하는지 알고 계십니까? 회사에서 내가 얼마나 야근을 했는지 알려드립니다! 올바른 정시퇴근 문화를 도와주기위한 칼퇴요정의 등장.`, - ios: 'https://apps.apple.com/kr/app/%EC%B9%BC%ED%87%B4%EC%9A%94%EC%A0%95/id1467381865', - - image: 'details/칼퇴요정.png', - icon: 'icons/칼퇴요정.png', - thumbnail: 'thumbnails/칼퇴요정.png', - prize: 'Default', - designers: ['박은지', '김혜리'], - frontends: ['유현식 (Android)', '유은비 (Android)', '오기환 (iOS)'], - }, - { - order: 2, - generation: 8, - title: '아무거나', - team: '불타오르네', - catchphrase: '오늘 뭐 먹지?', - description: `직장인의 점심식사, 오늘도 한끼를 때워야 하는데. 점심 뭐먹을래요? 돌아오는 대답은 아무거나요... 점심 메뉴 고르기 힘드시다구요? 이제 저희가 골라드릴게요!`, - android: 'https://play.google.com/store/apps/details?id=com.levin.depromeet3t_anything', - ios: 'https://apps.apple.com/kr/app/%EC%95%84%EB%AC%B4%EA%B1%B0%EB%82%98-%EC%98%A4%EB%8A%98-%EB%AD%90-%EB%A8%B9%EC%A7%80/id1542442642', - web: 'https://depromeet.github.io/8th-final-3team-front/', - image: 'details/아무거나.png', - icon: 'icons/아무거나.png', - thumbnail: 'thumbnails/아무거나.png', - prize: '대상', - designers: ['노은종', '이윤이'], - frontends: ['곽소영', '유영평 (Android)', '이규현 (iOS)'], - backends: ['조민국'], - }, - { - order: 1, - generation: 5, - title: '뜻밖의 퀴즈', - team: '-', - catchphrase: '인싸력을 키워주는 이모티콘 퀴즈', - description: `이모티콘 퀴즈를 통해 자신의 인싸력을 테스트해보세요. 다맞추면 진정한 인싸!`, - image: 'details/뜻밖의퀴즈.png', - icon: 'icons/뜻밖의퀴즈.png', - thumbnail: 'thumbnails/뜻밖의퀴즈.png', - prize: 'Default', - designers: ['양지윤'], - frontends: ['김민우', '김성진', '유현식 (Android)'], - }, -]; diff --git a/src/components/recruit-detail/DescriptionSection.tsx b/src/components/recruit-detail/DescriptionSection.tsx deleted file mode 100644 index c4591af5..00000000 --- a/src/components/recruit-detail/DescriptionSection.tsx +++ /dev/null @@ -1,164 +0,0 @@ -import { css } from '@emotion/react'; - -import { colors, mediaQuery } from '~/styles/constants'; - -import { - POSITION_DESCRIPTION, - POSITION_DISPLAY_NAME, - POSITION_PREFER_LIST, - POSITION_TYPE, - POSITION_WITH_CATEGORY_NAME, - PositionType, -} from './constants'; -import { sectionCss, sectionHeadingCss } from './RecruitDetail.style'; -import { AndPersentCircleIcon } from '../common/icons/AndPersentCircleIcon'; -import { BraceCircleIcon } from '../common/icons/BraceCircleIcon'; -import { SharpInCircleIcon } from '../common/icons/SharpInCircleIcon'; - -export default function DescriptionSection({ positionType }: { positionType: PositionType }) { - return ( -
    -
    -

    {POSITION_DISPLAY_NAME[positionType]}

    -
    -
    -
    -
    - - {positionType === POSITION_TYPE.DESIGN ? ( - - ) : ( - - )} - {POSITION_WITH_CATEGORY_NAME[positionType]}는 이런 일을 해요 - -
    -
    -
    -
    -
    - - - 이런 분들과 함께하고 싶어요 - -
    -
    -
      - {POSITION_PREFER_LIST[positionType].map((content, index) => ( -
    • {content}
    • - ))} -
    -
    -
    -
    -
    - ); -} - -const flexBoxCss = css` - display: flex; - flex-direction: column; - - width: 100%; - border-top: solid 1px ${colors.black}; -`; - -const flexRowCss = css` - display: flex; - - min-height: 390px; - width: 100%; - padding: 20px 0; - border-bottom: solid 1px ${colors.black}; - - font-weight: 600; - font-size: 20px; - line-height: 28px; - letter-spacing: -0.3px; - color: ${colors.black}; - - dt { - flex-shrink: 0; - position: relative; - padding: 20px 0; - width: 408px; - border-right: solid 1px ${colors.black}; - - span { - display: flex; - align-items: center; - } - - svg { - margin-right: 10px; - } - } - - dd { - padding: 20px 20px 0 80px; - width: 100%; - - ul { - list-style: disc; - } - li { - margin-bottom: 16px; - } - } - - ${mediaQuery('xs')} { - flex-direction: column; - min-height: fit-content; - padding: 0; - - dt, - dd { - width: 100%; - padding: 20px 0; - } - - dt { - border-right: none; - border-bottom: solid 1px ${colors.black}; - } - - dd { - font-weight: 500; - font-size: 14px; - line-height: 180%; - - ul { - padding-left: 20px; - } - } - } -`; - -const circleHeadingCss = css` - display: inline-block; - width: fit-content; - - display: flex; - align-items: center; - justify-content: center; - - padding: 24px 50px; - margin: 0 auto; - - border: 1px solid #121212; - border-radius: 50%; - - font-weight: 600; - font-size: 36px; - line-height: 43px; - color: ${colors.black}; - - ${mediaQuery('xs')} { - font-weight: 600; - font-size: 24px; - line-height: 43px; - letter-spacing: -1px; - - padding: 10px 35px; - } -`; diff --git a/src/components/recruit-detail/HeaderSection.tsx b/src/components/recruit-detail/HeaderSection.tsx deleted file mode 100644 index 02e261d8..00000000 --- a/src/components/recruit-detail/HeaderSection.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import Image from 'next/image'; -import { css } from '@emotion/react'; - -import { mediaQuery } from '~/styles/constants'; - -import { POSITION_DISPLAY_NAME, PositionType } from './constants'; - -const RECRUIT_DETAIL_IMAGE_BASE = '/images/recruit-detail'; - -export default function HeaderSection({ positionType }: { positionType: PositionType }) { - return ( -
    - {POSITION_DISPLAY_NAME[positionType]} -
    - ); -} - -const sectionCss = css` - position: relative; - width: 100%; - height: 598px; - - ${mediaQuery('xs')} { - height: 200px; - } -`; - -const imageCss = css` - position: absolute; - top: 0; - left: 0; - object-fit: cover; - z-index: -1; -`; diff --git a/src/components/recruit-detail/PreviousSection.tsx b/src/components/recruit-detail/PreviousSection.tsx deleted file mode 100644 index c0dc9070..00000000 --- a/src/components/recruit-detail/PreviousSection.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { useRouter } from 'next/router'; -import { css } from '@emotion/react'; - -import { colors, mediaQuery } from '~/styles/constants'; - -import { ClickableButton } from '../common/Clickable'; -import { ArrowIcon } from '../common/icons'; - -export default function PreviousSection() { - const router = useRouter(); - - return ( -
    - { - router.back(); - }} - > - - 이전 - -
    - ); -} - -const sectionCss = css` - max-width: 1200px; - margin: 10px auto; - - button { - display: flex; - align-items: center; - - font-size: 16px; - line-height: 140%; - letter-spacing: -0.3px; - color: ${colors.black}; - } - - svg { - transform: rotate(180deg); - margin-right: 10px; - } - - ${mediaQuery('xs')} { - display: none; - } -`; diff --git a/src/components/recruit-detail/RecruitDetail.style.tsx b/src/components/recruit-detail/RecruitDetail.style.tsx deleted file mode 100644 index 4fd57f50..00000000 --- a/src/components/recruit-detail/RecruitDetail.style.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { css } from '@emotion/react'; - -import { mediaQuery } from '~/styles/constants'; - -const sectionCss = css` - margin: 0 auto 180px; - max-width: 1200px; - - ${mediaQuery('xs')} { - padding: 0 16px; - margin-bottom: 100px; - } -`; - -const sectionHeadingCss = css` - text-align: center; - - margin-bottom: 80px; - - ${mediaQuery('xs')} { - margin-bottom: 40px; - } -`; - -export { sectionCss, sectionHeadingCss }; diff --git a/src/components/recruit-detail/TipSection.tsx b/src/components/recruit-detail/TipSection.tsx deleted file mode 100644 index 53a2ff0c..00000000 --- a/src/components/recruit-detail/TipSection.tsx +++ /dev/null @@ -1,232 +0,0 @@ -import Image from 'next/image'; -import { css } from '@emotion/react'; -import { Carousel } from 'react-responsive-carousel'; - -import { colors, mediaQuery } from '~/styles/constants'; -import { section40HeadingCss, sectionSmallCss } from '~/styles/css'; - -import { POSITION_TIPS, POSITION_TYPE, PositionType, TIP_BASE_IMAGE_URL } from './constants'; -import { sectionCss, sectionHeadingCss } from './RecruitDetail.style'; -import { ClickableButton } from '../common/Clickable'; -import { ArrowIcon } from '../common/icons'; - -import 'react-responsive-carousel/lib/styles/carousel.min.css'; - -export default function TipSection({ positionType }: { positionType: PositionType }) { - const isNeedController = POSITION_TIPS[POSITION_TYPE[positionType]].length > 1; - - return ( -
    -
    - TIP -

    디프만 전 멤버들의 지원 꿀팁

    -
    - RenderArrowPrev(clickHandler, isNeedController)} - renderArrowNext={clickHandler => RenderArrowNext(clickHandler, isNeedController)} - renderIndicator={RenderIndicator} - > - {POSITION_TIPS[POSITION_TYPE[positionType]].map(item => ( -
    -
    -
    - {`${item.name}의 -
    -

    - {item.name} {item.position} -

    - - {item.classList.map(classIndex => ( - {classIndex}기 - ))} - -

    {item.tip}

    -
    -
    - ))} -
    -
    - ); -} - -const RenderArrowPrev = (clickHandler: () => void, isNeedController: boolean) => { - return ( - <> - {isNeedController && ( - - - - )} - - ); -}; -const RenderArrowNext = (clickHandler: () => void, isNeedController: boolean) => { - return ( - <> - {isNeedController && ( - - - - )} - - ); -}; -const RenderIndicator = ( - clickHandler: (e: React.MouseEvent | React.KeyboardEvent) => void, - isSelected: boolean -) => { - return ( - - {isSelected} - - ); -}; - -const CarouselCss = css` - position: relative; - height: 380px; - width: 100%; - - ${mediaQuery('xs')} { - height: 460px; - } -`; - -const CarouselBoxCss = css` - padding-top: 42px; - display: flex; - flex-direction: column; - align-items: center; - - margin: 0 auto; - width: 100%; - min-height: 250px; - max-width: 1080px; - - font-weight: 600; - font-size: 20px; - line-height: 140%; - letter-spacing: -0.3px; - color: ${colors.black}; - - h3 { - margin-bottom: 6px; - } - - small { - display: flex; - - margin-bottom: 32px; - - font-weight: 500; - font-size: 18px; - line-height: 22px; - color: ${colors.gray600}; - - & > span { - display: flex; - align-items: center; - &::after { - display: inline-block; - margin: 0 8px; - content: ''; - width: 3px; - height: 3px; - border-radius: 50%; - background-color: ${colors.gray600}; - } - - &:last-of-type { - &::after { - display: none; - } - } - } - } - - p { - max-width: 800px; - white-space: pre-wrap; - } - - ${mediaQuery('xs')} { - h3 { - margin-bottom: 10px; - } - small { - margin-bottom: 30px; - } - - p { - font-weight: 500; - font-size: 14px; - line-height: 140%; - } - } -`; - -const carouselImageCss = css` - width: 80px; - margin-bottom: 24px; -`; - -const baseArrowCss = css` - position: absolute; - z-index: 10; - top: 50%; - transform: translateY(-50%); - - ${mediaQuery('xs')} { - display: none; - } - - &:hover { - svg { - border-radius: 50%; - background-color: ${colors.black}; - & > * { - stroke: ${colors.gray100}; - } - & > circle { - stroke: ${colors.black}; - } - } - } -`; - -const prevCss = css` - left: 0; - transform: translateY(-50%) rotate(180deg); - ${mediaQuery('xs')} { - display: none; - } -`; - -const nextCss = css` - right: 0; -`; - -const indicatorCss = (isSelected: boolean) => css` - display: inline-block; - width: 10px; - height: 10px; - border-radius: 50%; - background-color: ${isSelected ? colors.black : '#e7e8e9'}; - - margin-right: 8px; - - &:last-of-type { - margin-right: 0; - } -`; diff --git a/src/components/recruit-detail/constants.ts b/src/components/recruit-detail/constants.ts deleted file mode 100644 index 3abf56cf..00000000 --- a/src/components/recruit-detail/constants.ts +++ /dev/null @@ -1,208 +0,0 @@ -export const POSITION_TYPE = { - IOS: 'IOS', - ANDROID: 'ANDROID', - WEB: 'WEB', - SERVER: 'SERVER', - DESIGN: 'DESIGN', -} as const; - -export type PositionType = keyof typeof POSITION_TYPE; - -export const POSITION_DISPLAY_NAME = { - IOS: 'iOS', - ANDROID: 'ANDROID', - WEB: 'WEB', - SERVER: 'SERVER', - DESIGN: 'UXUI', -} as const; - -export const POSITION_WITH_CATEGORY_NAME = { - IOS: `${POSITION_DISPLAY_NAME.IOS} DEVELOPER`, - ANDROID: `${POSITION_DISPLAY_NAME.ANDROID} DEVELOPER`, - WEB: `${POSITION_DISPLAY_NAME.WEB} DEVELOPER`, - SERVER: `${POSITION_DISPLAY_NAME.SERVER} DEVELOPER`, - DESIGN: `${POSITION_DISPLAY_NAME.DESIGN} DESIGNER`, -} as const; - -export const ICON_POSITION_PATH = { - DESIGN: '/svg/icon-design.svg', - IOS: '/svg/icon-ios.svg', - ANDROID: '/svg/icon-android.svg', - WEB: '/svg/icon-web.svg', - SERVER: '/svg/icon-backend.svg', -}; - -export const ICON_CATEGORY_PATH = { - DESIGN: '/svg/icon-designer.svg', - IOS: '/svg/icon-developer.svg', - ANDROID: '/svg/icon-developer.svg', - WEB: '/svg/icon-developer.svg', - SERVER: '/svg/icon-developer.svg', -}; - -export const BANNER_IMG_PATH = { - DESIGN: '/images/position/banner-design.png', - IOS: '/images/position/banner-ios.png', - ANDROID: '/images/position/banner-android.png', - WEB: '/images/position/banner-web.png', - SERVER: '/images/position/banner-backend.png', -}; - -export const MOBILE_BANNER_IMG_PATH = { - DESIGN: '/images/position/mobile-banner-design.png', - IOS: '/images/position/mobile-banner-ios.png', - ANDROID: '/images/position/mobile-banner-android.png', - WEB: '/images/position/mobile-banner-web.png', - SERVER: '/images/position/mobile-banner-backend.png', -}; - -export const POSITION_DESCRIPTION = { - DESIGN: `서비스 설계부터 UXUI 전반을 맡게 돼요.

    디자이너들과 함께 의견을 나누며 하나의 멋진 서비스가 만들어지는 경험을 하고 싶다면?
    디자인 외에도 마케팅, 브랜딩, 기획 등에도 관심이 있는 디자이너라면?
    21세기 디자이너에게 가장 필요한 역량, 개발자와의 커뮤니케이션! 부족하다고 느낀다면?

    디프만 13기 디자이너로 바로 지원하세요 !`, - IOS: `뛰어나고 열정이 많은 디자이너와 서버 개발자들과 함께 디프만 기간 동안 치열하게 커뮤니케이션을 하며 iOS 앱 개발 역량은 물론이고 전체적인 시야를 넓힐 수 있어요.
    특히 iOS 포지션 상 디자인과 서버의 중간 다리 역할을 하게 됨으로 만들어가는 서비스에 대해 모든 부분에 있어 주도적이고 핵심적인 참여를 할 수 있어요.

    거기에 완성도 높은 앱스토어 런칭 앱을 개발 할 수 있는 최적의 환경까지!`, - ANDROID: `열정과 능력을 함께 갖춘 동료들과 긴밀하게 협업하며 안드로이드 네이티브 애플리케이션을 개발해요. 개발뿐만 아니라 동료들과 자유롭게 커뮤니케이션 하며 기획부터 런칭 및 운영까지 모바일 서비스에 대한 A to Z를 얻어갈 수 있어요!

    다양한 직군의 사람들과 지식과 경험을 공유하며 완성도 높은 모바일 서비스를 만들어 볼 수 있는 최고의 환경이에요.`, - WEB: `성장을 목표로 하는 디자이너분들과 서버 엔지니어분들과 함께 플랫폼에 국한되지 않고 웹 그리고 웹뷰 형태의 클라이언트 애플리케이션을 개발해요. 개발 역량은 물론, 타 직군과의 의사소통과 같은 소프트 스킬을 키울 수 있어요.

    또한 의욕이 넘치시는 다른 WEB 엔지니어분들과 함께 평소에 사용하거나 배워보고 싶었던 스택들을 사용하거나 스터디하기 최적의 환경이에요.`, - SERVER: `실제 서비스를 운영하기 위해 설계부터 운영까지 전반적인 시스템 인프라를 구축 및 관리해요. 다양한 클라이언트 개발자분들과 협업을 진행하면서, 의사소통 능력을 키울 수 있어요.

    다른 Backend 엔지니어분들과 기술적으로 건강한 토론을 진행하면서, 우리 서비스에 대한 기술적 고도화를 진행할 수 있어요.`, -}; - -export const POSITION_PREFER_LIST = { - IOS: [ - '불확실성에 도전할 수 있는 용기를 가진 분', - 'iOS 최신 트렌드를 습득하고 공유하는 것에 즐거움을 느끼시는 분', - '서비스에 대해 애정을 갖고 주도적으로 진행할 수 있는 분', - '모두의 의견에 대해 존중하고 서로 발전 할 수 있는 열린 마인드를 가지신 분', - '디자이너와 소통하며 좋은 UX/UI 개발에 관심이 많으신 분', - ], - ANDROID: [ - 'Android 개발 환경에 관심을 갖고 다양한 직군의 사람들과 소통할 수 있는 분', - '좋은 서비스를 위해 고민하고, 주도적으로 의견을 펼칠 수 있는 분', - '디자이너와 소통하며 좋은 UX/UI 개발에 관심이 많으신 분', - '성장에 목마른 다른 Android 엔지니어 분들과 함께 새로운 기술을 공유하고 Android 최신 트렌드를 습득하는데 즐거움을 느끼시는 분', - ], - WEB: [ - '유연한 사고방식과 소통 방식을 가진 분', - '건강한 토론을 할 수 있는 분 (침묵은 노노)', - '프로젝트에 있어 어떻게 하면 성공할지를 고민하시는 분', - '주도적 참여에 대한 의욕/열정을 가진 분', - '우리 모두가 선생이자 학생! 서로에게 배우고 발전할 수 있는 분', - ], - SERVER: [ - '서버 배포에 대한 경험을 가진 분', - '주도적으로 서비스 개발이 가능한 분', - '책임감을 가지고 팀 프로젝트를 진행할 수 있는 분', - ], - DESIGN: [ - '본인의 디자인을 논리적으로 표현하고 설득할 수 있는 분', - '긍정적인 마인드를 가지고 새로운 일에 도전하기 좋아하는 분', - '아이디어를 구체화/시각화하는 것에 재미를 느끼는 분', - '서비스 런칭을 위한 유저 니즈 이해 및 문제 정의가 가능하신 분', - '팀 내 디자이너, 개발자와의 원활한 커뮤니케이션이 가능하신 분', - ], -} as const; - -export const TIP_BASE_IMAGE_URL = '/images/recruit-detail'; - -const TIPS: Array<{ - name: string; - position: PositionType; - classList: number[]; - tip: string; -}> = [ - { - name: '임효연', - position: POSITION_TYPE.DESIGN, - classList: [9, 10, 11, 12], - tip: '책임감을 가지고 프로젝트를 진행해본 경험을 어필하는 것을 추천드립니다.\n 또한 자신의 작업물을 어떤 생각을 가지고 만들었는지, 근거를 논리적으로 말할 수 있으면 좋을 것 같아요.', - }, - { - name: '박수연', - position: POSITION_TYPE.DESIGN, - classList: [11, 12], - tip: '자신의 강점을 포트폴리오에 잘 녹여내서 면접에서 어필할 수 있어야해요.\n 그리고 협업에 대해서도 생각해보시길 추천드립니다.', - }, - { - name: '이승희', - position: POSITION_TYPE.DESIGN, - classList: [11, 12], - tip: '사이드 프로젝트를 경험하며 이룬 결과 이외에도 그 과정에서 얻은 인사이트를 진솔하게 공유했었어요.\n 협업의 가치에 대해 깊게 생각해 보시고 본인만의 정답을 만들면 좋을 것 같습니다.', - }, - { - name: '이종원', - position: POSITION_TYPE.DESIGN, - classList: [11, 12], - tip: '포트폴리오에서의 기획적인 의도나 이유들을 조리있게 설명할 수 있어야 해요!\n 프로젝트 끝까지 참여할 수 있다는 본인의 열정을 어필해주시면 좋을 것 같아요.', - }, - { - name: '차요셉', - position: POSITION_TYPE.IOS, - classList: [12], - tip: '이전에 진행했던 개발 프로젝트를 통해 배웠던 점들을 자소서에 녹여내시길 추천합니다. 디프만을 통해 경험하고 싶은 점들과 앞으로의 다짐을 보여주시면 좋을 것 같습니다. 또한 iOS 개발에 대한 관심을 자소서 혹은 깃헙, 블로그를 통해 나타내시면 도움이 될 것 같습니다!', - }, - { - name: '김주환', - position: POSITION_TYPE.ANDROID, - classList: [12], - tip: '동아리는 면접 시간이 시간이 짧으니 주어진 시간 안에 나의 장점을 보여줄 수 있도록 전략을 잘 짜셔야 해요. 또, 동아리에는 어떤 사람이 필요할까 고민해 보시면 좋을 거예요!', - }, - { - name: '김혜인', - position: POSITION_TYPE.ANDROID, - classList: [12], - tip: '디프만에서 어떤 가치관과 협업 자세로 꼭 무언가를 해보고 싶다는 열정이 합격의 키포인트가 됐다고 생각합니다. 그 열정을 서류와 면접에서 녹여낼 수 있다면 합격할 수 있을 겁니다.', - }, - { - name: '전해성', - position: POSITION_TYPE.ANDROID, - classList: [12], - tip: '디프만 활동 및 프로젝트에 참여하면서 제가 얻고싶은 것과 기여할 수 있는 것을\n 구체적으로 적었던 것이 도움이 되었습니다.', - }, - { - name: '황규일', - position: POSITION_TYPE.ANDROID, - classList: [12], - tip: '면접때 얼마나 참여를 하고 싶은지 협업 및 프로젝트에 대해서 얼마나 열정이 있는지에 대해서 말했던 것 같아요!! 기술질문은 내가 맡은 파트에 대해서 얼마나 관심을 가지고 살펴 봤는지 간단하게 말했었어요.', - }, - { - name: '김민수', - position: POSITION_TYPE.WEB, - classList: [12], - tip: '꾸준히 성장하기 위한 발자취를 많이 보여주시면 좋을 것 같아요. 그리고 무엇보다도 중요한 건 책임감이라고 생각합니다.\n 지속적 성장을 위한 꾸준함과 책임감 꼭 기억해주세요!', - }, - { - name: '오혜성', - position: POSITION_TYPE.WEB, - classList: [11, 12], - tip: '꾸밈없이 고민했던 경험을 녹이고, 디프만 활동 참여에 열정을 보여주시길 추천해요. 기술적으로는 웹 플랫폼뿐이 아닌 다양한 플랫폼에 웹 기술을 이용한 경험을 어필하신다면 좋을 거 같아요.', - }, - { - name: '정대윤', - position: POSITION_TYPE.WEB, - classList: [11], - tip: '디프만은 동아리이다 보니 프로젝트와 활동에 참여할 시간, 육체, 정신적 여유가 되는 분을 선호해요!\n 동아리 활동과 프로젝트에 기여할 수 있는 것들을 어필하면 좋을 것 같아요!\n ex) 스터디 활동을 잘해요! 기술적 숙련도가 높아서 리딩할 수 있어요!', - }, - { - name: '김동규', - position: POSITION_TYPE.WEB, - classList: [12], - tip: '개발자이기 전에, 프로젝트에 참여하는 팀원이라는 것에 공감대를 가지고 있으면 좋아요! “기술”을 “프로젝트의 성공”과 연결 지어 본 경험이 있다면 어필해보시는 것을 추천해 드려요.', - }, - { - name: '이성태', - position: POSITION_TYPE.SERVER, - classList: [12], - tip: '저는 디프만이 첫 개발 경험이었습니다. 그래서 경험이 부족하고 어필할 부분이 책임감과 열정뿐이었는데, 이런 부분이 오히려 확실한 메리트가 됐어요. 물론 개발 경험도 중요하지만, 내가 얼마나 개발을 좋아하고 우리 디프만에 얼마나 적극적으로 참여할 수 있는지 그런 ‘진심’이 있다면 바로 지원해보세요 :)', - }, - { - name: '이찬진', - position: POSITION_TYPE.SERVER, - classList: [11, 12], - tip: '코딩에 대한 열정을 녹여낼려고 노력했어요. 디프만을 통해 얻어가고 싶은 점도 생각 했었고요. 그 외 자소서에 적기 힘든 부분들은 블로그, 깃허브 링크로 좀 더 보완을 했던것 같아요!', - }, -]; - -export const POSITION_TIPS = { - IOS: TIPS.filter(({ position }) => position === POSITION_TYPE.IOS), - ANDROID: TIPS.filter(({ position }) => position === POSITION_TYPE.ANDROID), - WEB: TIPS.filter(({ position }) => position === POSITION_TYPE.WEB), - SERVER: TIPS.filter(({ position }) => position === POSITION_TYPE.SERVER), - DESIGN: TIPS.filter(({ position }) => position === POSITION_TYPE.DESIGN), -} as const; diff --git a/src/components/recruit/FAQSection.tsx b/src/components/recruit/FAQSection.tsx deleted file mode 100644 index ec1be0ba..00000000 --- a/src/components/recruit/FAQSection.tsx +++ /dev/null @@ -1,229 +0,0 @@ -import { useState } from 'react'; -import Link from 'next/link'; -import { css } from '@emotion/react'; - -import { colors, mediaQuery } from '~/styles/constants'; -import { section40HeadingCss, sectionSmallCss } from '~/styles/css'; - -import { FAQ, FAQ_TYPE, FAQ_TYPE_LABEL, FaqType } from './contstants'; -import { sectionCss, sectionHeadingCss } from './Recurit.style'; -import { ClickableButton } from '../common/Clickable'; -import { AnswerIcon, DropdownIcon, QuestionIcon } from '../common/icons'; - -const faqTypes = Object.keys(FAQ_TYPE) as FaqType[]; - -export default function FAQSection() { - const [faqType, setFaqType] = useState(FAQ_TYPE.REQUIREMENT); - const [selectedFaqItem, setSelectedFaqItem] = useState(0); - - return ( -
    -
    -

    FAQ

    -

    자주 묻는 질문

    -
    -
    -
      - {faqTypes.map(key => ( -
    • - { - setFaqType(FAQ_TYPE[key]); - setSelectedFaqItem(0); - }} - > - {FAQ_TYPE_LABEL[key]} - -
    • - ))} -
    -
      - {FAQ[faqType].map((item, index) => ( -
    • { - setSelectedFaqItem(index); - }} - > - -
      - - {item.title} -
      - -
      -
      -
      - {item.description} -
      -
      -
    • - ))} -
    -
    -
    *
    -

    - 찾으시는 내용이 없으신가요? -
    - 카카오톡 채널 - -  @depromeet  - - 으로
    궁금한 점을 전달해 주세요. -

    - (18시 이후 답변) -
    -
    -
    - ); -} - -const faqLayoutBox = css` - position: relative; - display: flex; - width: 100%; - - ${mediaQuery('xs')} { - flex-direction: column; - } -`; - -const faqLayoutAside = css` - display: flex; - flex-direction: column; - row-gap: 24px; - width: calc((1200 - 876) / 1200 * 100%); - - ${mediaQuery('xs')} { - justify-content: center; - flex-direction: row; - column-gap: 40px; - width: 100%; - - margin-bottom: 30px; - } -`; - -const faqDescription = css` - position: absolute; - left: 0; - top: 247px; - width: calc((1200 - 876) / 1200 * 100%); - padding-right: 30px; - - font-weight: 400; - font-size: 16px; - line-height: 140%; - letter-spacing: -0.3px; - color: ${colors.gray900}; - - a { - color: ${colors.point}; - text-decoration: underline; - } - - small { - color: ${colors.gray500}; - } - - ${mediaQuery('xs')} { - width: 100%; - margin-top: 30px; - padding-right: 0; - position: unset; - text-align: center; - } -`; - -const faqDescriptionIcon = css` - font-weight: 500; - font-size: 26px; - line-height: 31px; - letter-spacing: -0.3px; - color: ${colors.point}; -`; - -const faqLayoutContent = css` - border-top: solid 1px ${colors.black}; - width: calc(876 / 1200 * 100%); - - ${mediaQuery('xs')} { - width: 100%; - } -`; - -const faqItem = (selected = false) => css` - position: relative; - padding: 20px 10px; - border-bottom: solid 1px ${colors.black}; - height: fit-content; - min-height: 65px; - - dt { - display: flex; - align-items: flex-start; - text-align: left; - - padding-right: 38px; - font-weight: 600; - font-size: 18px; - line-height: 140%; - letter-spacing: -0.3px; - color: ${colors.black}; - } - - dd { - display: ${selected ? 'flex' : 'none'}; - align-items: flex-start; - text-align: left; - - margin-top: 11px; - - font-weight: 600; - font-size: 18px; - line-height: 140%; - letter-spacing: -0.3px; - color: #71727a; - } - - svg { - margin-right: 12px; - flex-shrink: 0; - } - - ${mediaQuery('xs')} { - dd { - margin-top: 22px; - } - } -`; - -const faqItemDrowpdownIcon = (selected = false) => css` - position: absolute; - top: 20px; - right: 10px; - transform: rotate(${selected ? '180deg' : '0deg'}); - line-height: 0; - - svg { - margin: 0; - } -`; - -const faqCategoryButtonCss = (selected = false) => css` - font-weight: 600; - font-size: ${selected ? '24px' : '20px'}; - line-height: 28px; - letter-spacing: -0.3px; - color: ${colors.black}; - text-decoration: ${selected ? 'underline' : 'none'}; - - ${mediaQuery('xs')} { - font-weight: 500; - font-size: 16px; - line-height: 22px; - color: ${selected ? colors.point : colors.black}; - } -`; diff --git a/src/components/recruit/HeaderSection.tsx b/src/components/recruit/HeaderSection.tsx deleted file mode 100644 index 008d4681..00000000 --- a/src/components/recruit/HeaderSection.tsx +++ /dev/null @@ -1,91 +0,0 @@ -import Image from 'next/image'; -import { css } from '@emotion/react'; - -import useIsInProgress from '~/hooks/use-is-in-progress'; -import { colors, mediaQuery } from '~/styles/constants'; - -import { BigArrowIcon } from '../home/BigArrowIcon'; - -export default function HeaderSection() { - const { remainDay, isInProgress } = useIsInProgress(); - - return ( -
    -
    -
    - {isInProgress ? ( - <> -

    서류 접수 마감까지

    - -

    D-{remainDay === 0 ? 'Day' : remainDay}

    -
    - - ) : ( -

    서류 접수 마감

    - )} -
    - - {'리쿠르트 -
    - -
    - ); -} - -const headerCss = css` - display: flex; - justify-content: center; - position: relative; - overflow: hidden; - width: 100%; - height: 780px; - - ${mediaQuery('xs')} { - height: 650px; - } -`; - -const headingCss = css` - position: absolute; - left: 50%; - transform: translate(-50%, -50%); - - text-align: center; - - font-weight: 600; - font-size: 40px; - color: ${colors.black}; - line-height: 48px; - letter-spacing: -1px; -`; - -const headImageWrapperCss = css` - position: absolute; - left: 50%; - top: 50%; - transform: translate(-50%, -50%); - - /* width: calc(770.79 / 1440 * 100%); */ - height: calc(488.97 / 720 * 100%); - - width: 770.79px; - /* max-width: 1920px; */ - min-height: 488.97px; -`; - -const iconCss = css` - position: absolute; - bottom: 120px; - - ${mediaQuery('xs')} { - bottom: 107px; - } -`; diff --git a/src/components/recruit/JobGroupSection.tsx b/src/components/recruit/JobGroupSection.tsx deleted file mode 100644 index 0f1b162a..00000000 --- a/src/components/recruit/JobGroupSection.tsx +++ /dev/null @@ -1,95 +0,0 @@ -import { css } from '@emotion/react'; - -import { colors, mediaQuery } from '~/styles/constants'; -import { section40HeadingCss, sectionSmallCss } from '~/styles/css'; - -import { POSITION_TYPE_LABEL, PositionType } from './contstants'; -import { sectionCss, sectionHeadingCss } from './Recurit.style'; -import { ClickableLink } from '../common/Clickable'; -import { ArrowIcon } from '../common/icons'; -import { POSITION_TYPE } from '../recruit-detail/constants'; - -const positionTypes = Object.keys(POSITION_TYPE_LABEL) as PositionType[]; - -export default function JobGroupSection() { - return ( -
    -
    -

    POSITIONS

    -

    모집 직군

    -
    -
      - {positionTypes.map(key => ( - -
    • - {POSITION_TYPE_LABEL[key]} - - 자세히 보기 - -
    • -
      - ))} -
    -
    - ); -} - -const jobGroupFlexBox = css` - display: flex; - flex-wrap: wrap; - justify-content: center; - column-gap: 24px; - row-gap: 28px; - - width: 100%; - max-width: 1200px; - - ${mediaQuery('xs')} { - flex-direction: column; - row-gap: 20px; - } -`; - -const jobGroupItem = css` - display: flex; - flex-direction: column; - row-gap: 2px; - - padding: 20px 24px; - border: 1px solid ${colors.black}; - width: 384px; - height: 98px; - - font-weight: 600; - font-size: 20px; - line-height: 28px; - letter-spacing: -0.3px; - color: ${colors.black}; - - span { - display: flex; - align-items: center; - } - - svg { - margin-left: 8px; - & > * { - stroke: ${colors.black}; - } - } - - &:hover { - color: ${colors.gray100}; - background-color: ${colors.black}; - - svg { - & > * { - stroke: ${colors.gray100}; - } - } - } - - ${mediaQuery('xs')} { - width: 100%; - } -`; diff --git a/src/components/recruit/QualificationSection.tsx b/src/components/recruit/QualificationSection.tsx deleted file mode 100644 index f27f0667..00000000 --- a/src/components/recruit/QualificationSection.tsx +++ /dev/null @@ -1,160 +0,0 @@ -import { css } from '@emotion/react'; - -import { colors, mediaQuery } from '~/styles/constants'; -import { section40HeadingCss, sectionSmallCss } from '~/styles/css'; - -import { RECRUIT_QUALIFICATIONS } from './contstants'; -import { sectionCss, sectionHeadingCss } from './Recurit.style'; - -export default function QualificationSection() { - return ( -
    -
    -

    QUALIFICATIONS

    -

    공통 자격 요건

    -
    -
      - {RECRUIT_QUALIFICATIONS.map((item, index) => ( -
    • - {index + 1} - {item} -
    • - ))} -
    -
    - ); -} - -const qualificationGridBox = css` - display: grid; - background: black; - width: 100%; - gap: 1px; - grid-template-columns: repeat(3, 1fr); - grid-template-rows: repeat(2, minmax(126px, max-content)); - ${mediaQuery('xs')} { - grid-template-columns: repeat(2, 1fr); - grid-template-rows: repeat(3, 140px); - } -`; -const qualificationGridItem = css` - background: ${colors.gray100}; - em { - font-weight: 400; - font-size: 20px; - line-height: 23px; - letter-spacing: -0.3px; - color: ${colors.gray600}; - } - - strong { - display: block; - margin-top: 4px; - font-weight: 600; - font-size: 18px; - line-height: 140%; - letter-spacing: -0.3px; - color: ${colors.black}; - white-space: pre-wrap; - } - - ${mediaQuery('sm')} { - strong { - white-space: normal; - } - } - ${mediaQuery('xs')} { - strong { - font-size: 14px; - } - } -`; - -const qualificationGridItemResponsiveLayoutCss = css` - padding-top: 34px; - padding-left: 40px; - padding-right: 40px; - - :nth-of-type(-n + 3) { - padding-top: 9px; - } - :nth-of-type(3n + 1) { - padding-left: 0; - } - - :nth-of-type(2) { - position: relative; - &::before { - display: block; - content: ''; - position: absolute; - left: 0; - bottom: 0; - transform: translate(-50%, 50%); - width: 28px; - height: 28px; - background-color: ${colors.gray100}; - } - &::after { - display: block; - content: ''; - position: absolute; - right: 0; - bottom: 0; - transform: translate(50%, 50%); - width: 28px; - height: 28px; - background-color: ${colors.gray100}; - } - } - ${mediaQuery('xs')} { - padding-top: 20px; - padding-left: 20px; - padding-right: 15px; - - :nth-of-type(-n + 3) { - padding-top: 20px; - } - :nth-of-type(3n + 1) { - padding-left: 20px; - } - :nth-of-type(-n + 2) { - padding-top: 0; - } - &:nth-of-type(2) { - &::before, - &::after { - display: none; - } - } - - :nth-of-type(4) { - position: relative; - &::before { - display: block; - content: ''; - position: absolute; - left: 0; - top: 0; - transform: translate(-50%, -50%); - width: 23px; - height: 40px; - background-color: ${colors.gray100}; - } - &::after { - display: block; - content: ''; - position: absolute; - left: 0; - bottom: 0; - transform: translate(-50%, 50%); - width: 23px; - height: 40px; - background-color: ${colors.gray100}; - } - } - } -`; diff --git a/src/components/recruit/Recurit.style.tsx b/src/components/recruit/Recurit.style.tsx deleted file mode 100644 index 73fa5d8a..00000000 --- a/src/components/recruit/Recurit.style.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { css } from '@emotion/react'; - -import { mediaQuery } from '~/styles/constants'; - -const sectionCss = css` - margin: 0 auto; - max-width: 1200px; - - margin-bottom: 180px; - - ${mediaQuery('xs')} { - margin-bottom: 100px; - padding: 0 16px; - } -`; - -const sectionHeadingCss = css` - width: 100%; - text-align: center; - - margin-bottom: 80px; - - ${mediaQuery('xs')} { - margin-bottom: 40px; - } -`; - -export { sectionCss, sectionHeadingCss }; diff --git a/src/components/recruit/ScheduleSection.tsx b/src/components/recruit/ScheduleSection.tsx deleted file mode 100644 index 5b7342c7..00000000 --- a/src/components/recruit/ScheduleSection.tsx +++ /dev/null @@ -1,135 +0,0 @@ -import { css } from '@emotion/react'; - -import { colors, mediaQuery } from '~/styles/constants'; -import { section40HeadingCss, sectionSmallCss } from '~/styles/css'; - -import { sectionCss, sectionHeadingCss } from './Recurit.style'; - -export default function ScheduleSection() { - return ( -
    -
    -

    RECRUITMENT SCHEDULE

    -

    모집 일정

    -
    -
    -

    맴버 모집 기간

    -
    - 3.6 - 서류 접수 시작 -
    -
    - 3.12 - 서류 접수 마감 -
    -
    - 3.25/26 - 온라인 면접 -
    -
    - 4.3 - 최종 합격 안내 -
    -
    -
    -

    정규 세션 기간

    -
    - 4.8 - 13기 OT -
    -
    - 5.27 - 중간발표 -
    -
    - 7.22 - 최종 - DEMO DAY -
    -
    -
    -
    - ); -} - -const periodFlexBoxCss = css` - display: flex; - gap: 56px; - align-items: center; - justify-content: center; - overflow: hidden; - - padding: 0 calc(100% / 10); - - height: 104px; - width: 100%; - - border-top: solid 1px ${colors.black}; - - &:last-of-type { - border-bottom: solid 1px ${colors.black}; - } - - h4 { - flex-shrink: 0; - display: flex; - align-items: center; - justify-content: center; - flex-wrap: nowrap; - white-space: nowrap; - - width: 160px; - max-width: 160px; - height: 43px; - border-radius: 50%; - - color: ${colors.gray100}; - - background: ${colors.black}; - } - - ${mediaQuery('xs')} { - padding: 30px 40px; - gap: 20px; - flex-direction: column; - height: fit-content; - - h4 { - width: 100%; - margin-bottom: 10px; - } - } -`; - -const periodCss = css` - display: flex; - gap: 4px; - flex-direction: column; - - width: calc((100% - 160px) / 4); - - em { - font-family: 'Pretendard'; - font-weight: 400; - font-size: 20px; - line-height: 23px; - letter-spacing: -0.3px; - color: ${colors.black}; - } - - span { - font-weight: 600; - font-size: 20px; - line-height: 140%; - letter-spacing: -0.3px; - color: ${colors.black}; - white-space: nowrap; - } - - ${mediaQuery('xs')} { - flex-direction: row-reverse; - justify-content: space-between; - gap: auto; - - width: 100%; - } -`; diff --git a/src/components/recruit/contstants.ts b/src/components/recruit/contstants.ts deleted file mode 100644 index 74132416..00000000 --- a/src/components/recruit/contstants.ts +++ /dev/null @@ -1,147 +0,0 @@ -export const FAQ_TYPE = { - REQUIREMENT: 'REQUIREMENT', - INTERVIEW: 'INTERVIEW', - ACTIVITY: 'ACTIVITY', -} as const; - -export type FaqType = keyof typeof FAQ_TYPE; - -interface FaqItem { - title: string; - description: string; -} - -interface FaqMap { - [key: string]: FaqItem[]; -} - -export const REQUIREMENT_LIST = [ - { - title: '지원 가능한 나이가 어떻게 되나요?', - description: '디프만은 20세 이상부터 지원 가능합니다.', - }, - { - title: '관련 경험이 없어도 지원 가능한가요?', - description: - '관련 직무 경험이 없어도 지원 가능하지만 UIUX DESIGNER 직군은 지원 시 포트폴리오를 필수로 제출해야 합니다.', - }, - { - title: '실력이 뛰어나야만 참여할 수 있나요?', - description: - '아뇨! 디프만은 실력보다 개인의 성장 가능성, 열정, 책임감 등에 더 큰 비중을 두고 지원자 분들을 심사할 예정입니다.\n멋진 서비스를 런칭하고 같은 팀 멤버들과 협업할 수 있을 정도의 실력이면 충분해요.', - }, - { - title: '외국 거주자도 지원할 수 있나요??', - description: '디프만 13기는 온/오프라인으로 진행되므로 국내 거주자에 한해 지원 가능합니다.', - }, - { - title: '서울/경기/인천 외 비수도권 거주자(미취업 청년)인데, 지원할 수 있나요?', - description: - '금번 디프만 13기는 커리어 개발 플랫폼 임팩트캠퍼스의 지원을 받아 진행됩니다.\n비수도권 거주자에게 여러가지 지원이 가능하니 망설이지 말고 얼른 지원하세요!', - }, - { - title: '직군간 중복지원이 가능한가요?', - description: - '직군간 중복 지원은 불가능합니다. 중복 지원자의 경우 지원 내역 모두 무효 처리할 예정입니다.', - }, - { - title: '지원 결과는 언제 어디서 확인 가능한가요?', - description: '3월 12일 서류 지원 기간 마감 후, 3월 22일 중으로 안내 메일 발송 예정입니다.', - }, -]; - -export const INTERVIEW_LIST = [ - { - title: '인터뷰는 언제 진행되나요?', - description: - '3월 25일 (토) / 3월 26일 (일) 양일간 진행됩니다. 서류 지원 시 원하는 시간대를 설정해주세요.', - }, - { - title: '인터뷰는 어떻게 진행되나요? ', - description: '디프만 13기 운영진과 지원자 다대다 온라인 인터뷰로 진행될 예정입니다.', - }, - { - title: '인터뷰는 어디서 진행되나요?', - description: '디프만 13기 인터뷰는 온라인으로 진행될 예정입니다. ', - }, - { - title: '인터뷰는 얼마나 걸릴까요?', - description: '한 타임당 약 30~40분 정도 소요될 예정입니다.', - }, - { - title: '인터뷰 일정을 조정하고 싶은데, 가능할까요?', - description: - '인터뷰 일정은 조정이 불가합니다.\n서류 확인 시 일정을 반드시 확인하신 뒤 1~3순위까지 가능한 시간대를 기입해주세요.', - }, - { - title: '인터뷰 관련한 세부 내용들은 어디서 볼 수 있나요?', - description: '서류 합격자에 한해 지원서에 기재한 이메일로 자세한 내용들을 발송할 예정입니다.', - }, - { - title: '인터뷰 결과는 언제 받아볼 수 있나요?', - description: - '꼼꼼히 인터뷰 내용 확인 후. 4월 3일 중으로 최종 합격자들에게 안내 메일 발송 예정입니다.', - }, -]; - -export const ACTIVITY_LIST = [ - { - title: '디프만 13기 정규 세션은 어떻게 진행되나요?', - description: - '디프만은 매주 토요일 오후 2시부터 5시까지 정규 세션을 가집니다.\n총 16주간 온라인과 오프라인으로 번갈아가며 만날 예정이에요.\n정규 세션외에도 팀원들과 함께 작업하는 시간이 요구됨을 반드시 염두에 두고 지원해주세요.', - }, - { - title: '활동 기간은 어떻게 되나요? ', - description: '디프만 13기는 4월 8일 오리엔테이션을 기점으로 16주 진행될 예정입니다. (7월 22일)', - }, - { - title: '디프만 13기는 어떻게 진행되나요?', - description: - '디프만은 총 8개의 팀으로 나뉘어 디자이너, 개발자들이 함께 하나의 서비스를 위해 작업하게 됩니다.', - }, - { - title: '정규 세션에서는 어떤 활동을 하나요?', - description: - '팀별 작업 외에도 멤버들 간의 교류와 네트워킹을 위해 다양하고 재미있는 이벤트들이 가득!\n개미지옥 디프만으로 어서 들어오세요. ', - }, - { - title: '활동비가 있나요?', - description: - '디프만은 비영리 IT 커뮤니티로, 13기 운영에 필요한 비용 조달 및\n13기 멤버들의 보다 적극적인 활동 참여 장려를 위해 최종 합격 멤버에 한해 활동비를 걷습니다.', - }, - { - title: '활동비는 얼마인가요?', - description: - '활동비는 회비와 보증금으로 이루어져 있으며, 아직 책정 중에 있어요.\n알뜰살뜰하게 비용을 계산하여 부담가지 않는 금액으로 전달드릴게요.', - }, -]; - -export const FAQ: FaqMap = { - [FAQ_TYPE.REQUIREMENT]: REQUIREMENT_LIST, - [FAQ_TYPE.INTERVIEW]: INTERVIEW_LIST, - [FAQ_TYPE.ACTIVITY]: ACTIVITY_LIST, -}; - -export const FAQ_TYPE_LABEL = { - REQUIREMENT: '지원 자격', - INTERVIEW: '면접 관련', - ACTIVITY: '활동 관련', -}; - -export const RECRUIT_QUALIFICATIONS = [ - '매주 토요일, 오후 2-5시에 진행되는\n정규 세션에 참여할 수 있는 분', - '디자이너와 개발자의 동반 성장에\n공감하며, 이를 실천하고자 하는 분', - '디프만 기간 동안 맡은 역할을 충실히\n이행할 수 있는 책임감 있는 분', - '매사에 주도적으로 참여하거나,\n문제를 능동적으로 해결한 경험이 있는 분', - '무엇인가에 꾸준히 몰입해본\n열정이 있는 분', - '좋은 결과만 추구하는 것이 아닌\n모든 과정을 즐기는 태도를 가지신 분', -]; - -export const POSITION_TYPE_LABEL = { - DESIGN: 'UIUX DESIGN', - IOS: 'iOS', - ANDROID: 'ANDROID', - WEB: 'WEB', - SERVER: 'SERVER', -} as const; -export type PositionType = keyof typeof POSITION_TYPE_LABEL; diff --git a/src/constant/aboutInfo.ts b/src/constant/aboutInfo.ts new file mode 100644 index 00000000..639c2b41 --- /dev/null +++ b/src/constant/aboutInfo.ts @@ -0,0 +1,21 @@ +const PASSPORT_IMAGE = `/images/about/passport.png`; +const AIRPLANE_IMAGE = `/images/about/airplane.png`; + +export const ABOUT_INFO = [ + { + label: 'passport', + image: PASSPORT_IMAGE, + title: '디자이너, 개발자의\n 커리어 패스 여정', + description: + '14기는 매주 토요일, 총 16주간 진행되며 \n다양한 오프라인 세션과 네트워킹이 준비되어 있습니다', + reverse: false, + }, + { + label: 'airplane', + image: AIRPLANE_IMAGE, + title: '서비스 런칭 후\n유저에게 도착하는 순간까지', + description: + 'UT, 런칭데이 등 실제 서비스를 구현하고\n타켓 유저에게 도달하는 전 과정을 경험합니다', + reverse: true, + }, +]; diff --git a/src/constants/common/common.ts b/src/constant/common.ts similarity index 56% rename from src/constants/common/common.ts rename to src/constant/common.ts index 819aed97..b6074a1e 100644 --- a/src/constants/common/common.ts +++ b/src/constant/common.ts @@ -1,7 +1,7 @@ export const IS_PRODUCTION = process.env.NODE_ENV === 'production'; -export const GA_ID = 'G-VZ0Q43XDPN'; -export const HOTJAR_ID = '3115834'; +export const GA_ID = process.env.NEXT_PUBLIC_GA_ID; +export const HOTJAR_ID = process.env.NEXT_PUBLIC_HOTJAR_ID; export const BASE_URL = 'https://www.depromeet.com'; @@ -9,8 +9,10 @@ export const NOTION_RECRUIT_PATH = 'https://depromeet.notion.site/DEPROMEET-13th-f1e931cf073e43c4aeca44a4521b44be'; // NOTE: UTC 타임존에 맞추기 위해 9시간을 뺌 -export const START_DATE = '2023-10-02T19:00:00.000Z'; -export const END_DATE = '2023-10-08T14:59:59.000Z'; +export const START_DATE = '2023-10-01T15:00:00.000Z'; // 10.02 00:00 +export const END_DATE = '2023-10-07T14:59:59.000Z'; // 10.08 11:59:59 // export const START_DATE = '2023-08-18T22:21:59.000Z'; // test // export const END_DATE = '2023-03-04T20:00:00.000Z'; // test + +export const DEADLINE_DATE = '2023-10-17T14:59:59.000Z'; // NOTE: 마감일 10.18 diff --git a/src/constant/contactInfo.ts b/src/constant/contactInfo.ts new file mode 100644 index 00000000..1b92e637 --- /dev/null +++ b/src/constant/contactInfo.ts @@ -0,0 +1,27 @@ +import { + DEPROMEET_BEHANCE, + DEPROMEET_EMAIL, + DEPROMEET_GITHUB, + DEPROMEET_INSTAGRAM, + DEPROMEET_KAKAO_PLUS_FRIEND, + DEPROMEET_LINKEDIN, + DEPROMEET_MEDIUM, +} from '~/constant/depromeet'; + +export const FIRST_ROW_FOOTER_INFOS = [ + { name: 'Instagram', href: DEPROMEET_INSTAGRAM }, + { name: 'Behance', href: DEPROMEET_BEHANCE }, + { name: 'Github', href: DEPROMEET_GITHUB }, + { name: 'Medium', href: DEPROMEET_MEDIUM }, + { name: 'LinkedIn', href: DEPROMEET_LINKEDIN }, +]; + +export const SECOND_ROW_FOOTER_INFOS = [ + { name: 'Kakao channel', detail: '@depromeet', href: DEPROMEET_KAKAO_PLUS_FRIEND }, + { name: 'E-mail', detail: 'depromeet@gmail', href: DEPROMEET_EMAIL }, +]; + +export const CONTACT_INFO = [ + { name: 'Kakao channel', detail: '@depromeet', href: DEPROMEET_KAKAO_PLUS_FRIEND }, + { name: 'E-mail', detail: 'depromeet@gmail', href: DEPROMEET_EMAIL }, +]; diff --git a/src/constants/common/depromeet.ts b/src/constant/depromeet.ts similarity index 61% rename from src/constants/common/depromeet.ts rename to src/constant/depromeet.ts index a93631ab..0dc6c269 100644 --- a/src/constants/common/depromeet.ts +++ b/src/constant/depromeet.ts @@ -1,8 +1,9 @@ -export const DEPROMEET_EMAIL = 'depromeet@gmail.com'; +export const DEPROMEET_EMAIL = 'mailto:depromeet@gmail.com'; export const DEPROMEET_MEDIUM = 'https://depromeet.medium.com/'; export const DEPROMEET_FACEBOOK = 'https://www.facebook.com/depromeet/'; export const DEPROMEET_INSTAGRAM = 'https://www.instagram.com/depromeet/'; export const DEPROMEET_GITHUB = 'https://github.com/depromeet/'; export const DEPROMEET_BEHANCE = 'https://www.behance.net/Depromeet'; -export const KAKAO_PLUS_FRIEND = 'http://pf.kakao.com/_xoxmcxed'; +export const DEPROMEET_KAKAO_PLUS_FRIEND = 'http://pf.kakao.com/_xoxmcxed'; +export const DEPROMEET_LINKEDIN = 'https://www.linkedin.com/company/depromeet/'; diff --git a/src/constant/faq.ts b/src/constant/faq.ts new file mode 100644 index 00000000..c08184f9 --- /dev/null +++ b/src/constant/faq.ts @@ -0,0 +1,113 @@ +export type FAQGroupType = '지원자격' | '면접' | '활동'; + +export type FAQType = { + group: FAQGroupType; + question: string; + answer: string; +}; + +export const FAQ_GROUP: FAQGroupType[] = ['지원자격', '면접', '활동']; + +export const FAQS: FAQType[] = [ + { + group: '지원자격', + question: '지원 가능한 나이가 어떻게 되나요?', + answer: '디프만은 20세 이상부터 지원 가능합니다.', + }, + { + group: '지원자격', + question: '관련 경험이 없어도 지원 가능한가요?', + answer: + '관련 직무 경험이 없어도 지원 가능하지만 UIUX Designer 직군은 지원 시 포트폴리오 제출이 필수입니다.', + }, + { + group: '지원자격', + question: '실력이 뛰어나야만 참여할 수 있나요?', + answer: + '디프만은 직무 경험과 실력보다 적극적인 태도, 책임감, 커뮤니케이션 능력 등에 더 큰 비중을 두고 지원자를 모집하고 있어요. 서비스를 런칭하고 팀과 협업할 수 있다면 충분해요.', + }, + { + group: '지원자격', + question: '외국 거주자도 지원할 수 있나요?', + answer: '디프만 14기는 온/오프라인으로 진행되므로 국내 거주자에 한해 지원 가능합니다.', + }, + { + group: '지원자격', + question: '직군간 중복지원이 가능한가요?', + answer: + '직군간 중복 지원은 불가능합니다. 중복 지원자의 경우 지원 내역 모두 무효처리되니 하나의 직군에 지원해주세요.', + }, + { + group: '지원자격', + question: '지원 결과는 언제 어디서 확인 가능한가요?', + answer: '10월 8일 서류 지원 마감 후, 10월 19일 중으로 결과 메일을 발송할 예정입니다.', + }, + { + group: '면접', + question: '인터뷰는 언제 진행되나요?', + answer: + '10월 21일 (토) ~ 10월 22일 (일) 이틀간 진행됩니다. 서류 지원 시 원하는 시간대를 고를 수 있어요.', + }, + { + group: '면접', + question: '인터뷰는 어디서, 어떻게 진행되나요?', + answer: + '디프만 14기 운영진과 지원자 다대다 온라인 인터뷰로 진행되며 자세한 사항은 서류 합격자에게 안내될 예정입니다.', + }, + { + group: '면접', + question: '인터뷰는 얼마나 걸릴까요?', + answer: '한 타임당 약 30분~40분 정도 진행될 예정입니다.', + }, + { + group: '면접', + question: '인터뷰 일정을 조정하고 싶은데, 가능할까요?', + answer: + '인터뷰 일정은 조정이 불가합니다. 서류 확인 시 일정을 반드시 확인하신 뒤 1~3순위까지 가능한 시간대를 적어주세요.', + }, + { + group: '면접', + question: '인터뷰 관련한 세부 내용들은 어디서 볼 수 있나요?', + answer: '서류 합격자에 한해 지원서에 기재한 이메일로 자세한 안내사항을 발송할 예정입니다.', + }, + { + group: '면접', + question: '인터뷰 결과는 언제 받아볼 수 있나요?', + answer: '꼼꼼히 인터뷰 내용을 확인한 후, 10월 29일 ~ 31일 사이 순차적으로 발송될 예정입니다.', + }, + { + group: '활동', + question: '디프만 14기 정규 세션은 어떻게 진행되나요?', + answer: + '디프만은 매주 토요일 오후 2시부터 5시까지 정규 세션을 가집니다. 총 16주간 온라인과 오프라인을 병행하여 만날 에정이에요. 정규 세션외에도 팀원들과 함께 작업하는 시간이 필요하니 반드시 참여 가능한 일정을 확인하고 지원해주세요.', + }, + { + group: '활동', + question: '활동 기간은 어떻게 되나요?', + answer: + '디프만 14기는 11월 4일 토요일 OT를 시작으로 16주 동안 진행될 예정입니다. (2월 17일 종료)', + }, + { + group: '활동', + question: '디프만 14기의 팀 구성이 궁금해요', + answer: + '디프만은 총 6개의 팀으로 나뉘어 디자이너, 개발자들이 함께 하나의 서비스를 위해 협업합니다. 팀은 제출하신 서류와 역량을 토대로 14기 운영진이 구성할 예정입니다.', + }, + { + group: '활동', + question: '정규 세션에서 어떤 활동을 하나요?', + answer: + '팀별 작업 외에도 멤버들 간의 교류와 네트워킹을 위해 다양한 세션을 기획하고 있어요. 자세한 내용은 홈페이지 상단 About 페이지를 참고해주세요.', + }, + { + group: '활동', + question: '활동비가 있나요?', + answer: + '디프만은 비영리 IT 커뮤니티로 14기 운영에 필요한 비용 조달 및 활동 지원을 위해 최종 합격 멤버에 한해 활동비를 걷습니다.', + }, + { + group: '활동', + question: '활동비는 얼마인가요?', + answer: '활동비는 회비와 보증금으로 이루어져 있으며 아직 논의중에 있습니다.', + }, +]; diff --git a/src/constant/gnb.ts b/src/constant/gnb.ts new file mode 100644 index 00000000..d3070842 --- /dev/null +++ b/src/constant/gnb.ts @@ -0,0 +1,28 @@ +export type GNBMenu = { + name: 'About' | '모집안내' | '프로젝트' | '지원하기'; + href: '/about' | '/recruit' | '/project' | '/apply'; + type: 'text' | 'button'; +}; +// TODO: 지원하기 url 넣기 +export const GNB_MENU_NAME: GNBMenu[] = [ + { + name: 'About', + href: '/about', + type: 'text', + }, + { + name: '모집안내', + href: '/recruit', + type: 'text', + }, + { + name: '프로젝트', + href: '/project', + type: 'text', + }, + { + name: '지원하기', + href: '/apply', + type: 'button', + }, +]; diff --git a/src/constant/image.ts b/src/constant/image.ts new file mode 100644 index 00000000..e62ec766 --- /dev/null +++ b/src/constant/image.ts @@ -0,0 +1 @@ +export const POSITION_BASE = '/images/position'; diff --git a/src/constant/motion.ts b/src/constant/motion.ts new file mode 100644 index 00000000..e195ceb4 --- /dev/null +++ b/src/constant/motion.ts @@ -0,0 +1,28 @@ +import { Variants } from 'framer-motion'; + +export const defaultEasing = [0.6, -0.05, 0.01, 0.99]; + +export const defaultFadeInVariants: Variants = { + initial: { + opacity: 0, + y: 40, + transition: { duration: 0.5, ease: defaultEasing }, + willChange: 'opacity, transform', + }, + animate: { + opacity: 1, + y: 0, + transition: { duration: 0.8, ease: defaultEasing }, + willChange: 'opacity, transform', + }, + exit: { + opacity: 0, + y: 40, + transition: { duration: 0.5, ease: defaultEasing }, + willChange: 'opacity, transform', + }, +}; + +export const staggerHalf: Variants = { + animate: { transition: { staggerChildren: 0.05 } }, +}; diff --git a/src/constant/offline.ts b/src/constant/offline.ts new file mode 100644 index 00000000..b1f07f6e --- /dev/null +++ b/src/constant/offline.ts @@ -0,0 +1,38 @@ +export const OFFLINE_SESSIONS = [ + { + title: '오리엔테이션', + subTitle: 'Orientation', + description: '디프만의 첫 시작, 서로를 알아갈 수 있는 오리엔테이션에 모두가 함께 해요.', + img: '/images/session/orientation.png', + }, + { + title: '네트워킹 데이', + subTitle: 'Networking Day', + description: '다른 팀, 직군의 멤버들을 만나요. TMI부터 커리어 토크까지 친해지는 시간을 가져요.', + img: '/images/session/networking.png', + }, + { + title: '사용성 테스트', + subTitle: 'Usability Test', + description: '사용성 테스트를 통해 문제를 발견하고 개선하여 더 가치있는 서비스를 만들어요.', + img: '/images/session/usability.png', + }, + { + title: '중간발표', + subTitle: 'Midterm announce', + description: '각 팀의 진행 상황을 공유하며 실질적인 피드백을 주고 받을 수 있어요.', + img: '/images/session/midterm.png', + }, + { + title: '런칭데이', + subTitle: 'Launching Day', + description: '런칭된 서비스를 팀 부스에서 공개해요. 모든 팀의 서비스를 사용해볼 수 있어요.', + img: '/images/session/launching.png', + }, + { + title: '최종발표', + subTitle: 'Final announce', + description: '서비스의 성과와 그 과정을 공유 및 회고하며 프로젝트를 마무리해요.', + img: '/images/session/final.png', + }, +]; diff --git a/src/constant/position.ts b/src/constant/position.ts new file mode 100644 index 00000000..1ee68c0f --- /dev/null +++ b/src/constant/position.ts @@ -0,0 +1,11 @@ +import { ComponentProps } from 'react'; + +import { PositionsItem } from '~/components/Positions/PositionsItem'; + +export const POSITIONS: Array> = [ + { type: 'design', title: 'UX/UI DESIGN', link: process.env.NEXT_PUBLIC_GREETING_DESIGN ?? '' }, + { type: 'ios', title: 'IOS', link: process.env.NEXT_PUBLIC_GREETING_IOS ?? '' }, + { type: 'aos', title: 'ANDROID', link: process.env.NEXT_PUBLIC_GREETING_AOS ?? '' }, + { type: 'web', title: 'WEB', link: process.env.NEXT_PUBLIC_GREETING_WEB ?? '' }, + { type: 'server', title: 'SERVER', link: process.env.NEXT_PUBLIC_GREETING_SERVER ?? '' }, +]; diff --git a/src/constant/project.ts b/src/constant/project.ts new file mode 100644 index 00000000..def8b904 --- /dev/null +++ b/src/constant/project.ts @@ -0,0 +1,648 @@ +import { Link } from '~/components/Thumbnail/Thumbnail'; + +export type Project = { + title: string; + subTitle: string; + description: string; + links?: Link[]; +}; + +export const TAB_LIST = ['전체', '13기', '12기', '11기', '-10기']; +export const PROJECT_LIST: Project[] = [ + { + title: '자린고비', + subTitle: '13기', + description: '거지들의 이야기로 쌓이는
    소비습관 개선 서비스', + links: [ + { + type: 'Behance', + href: 'https://www.behance.net/gallery/175690517/-Improve-your-spending-habit-with-people', + }, + { type: 'Github', href: 'https://github.com/depromeet/jalingobi-client' }, + { type: 'Web', href: 'https://jalingobi.com' }, + ], + }, + { + title: '오버스윗', + subTitle: '13기', + description: '카페 음료의 당을
    기록하고 관리하는 서비스', + links: [ + { + type: 'Behance', + href: 'https://www.behance.net/gallery/175685591/-(Over-Sweet)-', + }, + { type: 'Github', href: 'https://github.com/depromeet/oversweet-core' }, + { type: 'Web', href: 'https://oversweet.vercel.app' }, + ], + }, + { + title: 'Na Lab(나랩)', + subTitle: '13기', + description: '동료의 익명 피드백으로
    발견하는 나만의 커리어 DNA', + links: [ + { + type: 'Behance', + href: ' https://www.behance.net/gallery/175696341/Na-Lab-', + }, + { type: 'Github', href: ' https://github.com/depromeet/na-lab-client' }, + { type: 'Web', href: 'https://nalab.me' }, + ], + }, + { + title: '인사이트아웃', + subTitle: '13기', + description: 'AI 기반 직무역량 키워드 추천 및
    자기소개서 작성 서비스', + links: [ + { + type: 'Behance', + href: 'https://www.behance.net/gallery/175702481/insight-out', + }, + { type: 'Github', href: 'https://github.com/depromeet/InsightOut-client' }, + { type: 'Web', href: 'https://insightout.kr' }, + ], + }, + { + title: 'Street Drop', + subTitle: '13기', + description: '길을 걸으며 음악을 드랍하는
    음악 공유 소셜 서비스', + links: [ + { + type: 'Behance', + href: 'https://www.behance.net/gallery/175696753/Street-Drop-Location-based-music-community-services', + }, + { type: 'Github', href: 'https://github.com/depromeet/street-drop-iOS' }, + { + type: 'IOS', + href: 'https://apps.apple.com/kr/app/%EC%8A%A4%ED%8A%B8%EB%A6%BF%EB%93%9C%EB%9E%8D-street-drop/id6450315928', + }, + ], + }, + { + title: 'Whatnow (왔나)', + subTitle: '13기', + description: '약속 가는 중 친구들과 즐기는
    Share-play 서비스', + links: [ + { + type: 'Behance', + href: 'https://www.behance.net/gallery/175647815/WHATNOW-Share-Play', + }, + { type: 'Github', href: 'https://github.com/depromeet/whatnow-android' }, + { + type: 'Android', + href: 'https://play.google.com/store/apps/details?id=com.depromeet.whatnow&hl=ko-KR', + }, + ], + }, + { + title: 'Ding-Dong (딩동)', + subTitle: '13기', + description: '서로의 TMI를 공유하고
    친해지고 싶은 마음을 전하세요!', + links: [ + { + type: 'Behance', + href: 'https://www.behance.net/gallery/175602565/DingDong-TMI-', + }, + { type: 'Github', href: 'https://github.com/depromeet/Ding-dong-fe' }, + { type: 'Web', href: 'https://www.ding-dong-planet.com' }, + ], + }, + { + title: 'Pumping (펌핑)', + subTitle: '13기', + description: '크루원과 함께
    운동 경쟁하는 서비스', + links: [ + { + type: 'Behance', + href: 'https://www.behance.net/gallery/175706595/Pumping', + }, + { type: 'Github', href: 'https://github.com/depromeet/Pumping-iOS' }, + { type: 'IOS', href: 'https://apps.apple.com/app/id6451131066' }, + ], + }, + { + title: '짝심삼일', + subTitle: '12기', + description: '나를 바꾸는 작은 습관의 힘,
    습관 관리 서비스', + links: [ + { + type: 'Behance', + href: 'https://url.kr/pyhgze', + }, + { type: 'Github', href: 'https://github.com/depromeet12th/three-days-android' }, + { type: 'Android', href: 'https://c11.kr/19ln2' }, + ], + }, + { + title: 'KNOCKNOCK', + subTitle: '12기', + description: '내 친구가 보내는 생생한
    푸시알림 서비스', + links: [ + { + type: 'Behance', + href: 'https://www.behance.net/gallery/161848521/KNOCKNOCK-PUSH-NOTIFICATION-CUSTOM-SERVICE', + }, + { type: 'Github', href: 'https://github.com/depromeet/12th-KnockKnock-Android' }, + { + type: 'Android', + href: 'https://play.google.com/store/apps/details?id=com.depromeet.knockknock', + }, + ], + }, + { + title: 'TICLEMOA', + subTitle: '12기', + description: '아티클을 모아 지식을 태산처럼,
    아티클 스크랩 서비스', + links: [ + { + type: 'Behance', + href: 'https://www.behance.net/gallery/161983453/TICLEMOA-Article-clipping-service-', + }, + { type: 'Github', href: 'https://github.com/depromeet/ticlemoa-backend' }, + { + type: 'IOS', + href: 'https://apps.apple.com/kr/app/ticlemoa/id1659267166', + }, + ], + }, + { + title: '똑스', + subTitle: '12기', + description: '내가 만든 퀴즈로
    스터디를 재미있게, 똑스', + links: [ + { + type: 'Behance', + href: 'https://www.behance.net/gallery/161231589/Toks-Quiz-Study-Service-', + }, + { type: 'Github', href: 'https://github.com/depromeet/toks-web' }, + { + type: 'Web', + href: 'https://tokstudy.com/', + }, + ], + }, + { + title: '코퀄리티', + subTitle: '12기', + description: '지식을 공유하고, 후원하며
    함께 성장하는 블로깅 플랫폼', + links: [ + { + type: 'Behance', + href: 'https://www.behance.net/gallery/161841129/-Coquality-High-Quality-Blogging-', + }, + { + type: 'Web', + href: 'https://coquality.vercel.app', + }, + ], + }, + { + title: '아맞다', + subTitle: '12기', + description: '대신 외쳐주는 소지품 리스트', + links: [ + { + type: 'Behance', + href: 'https://www.behance.net/gallery/161161601/-Ahmatda-Checklist-for-Your-Belongings', + }, + { + type: 'Web', + href: 'https://ahmatda.notion.site/ahmatda/3202c2a4e2dd440eb95ae3345a130fc4', + }, + { + type: 'IOS', + href: 'https://apps.apple.com/kr/app/%EC%95%84%EB%A7%9E%EB%8B%A4/id1660192508', + }, + { + type: 'Android', + href: 'https://play.google.com/store/apps/details?id=com.ahmatda&hl=ko', + }, + ], + }, + { + title: 'PING-PONG!', + subTitle: '12기', + description: '재능을 교환하고 나누며
    성장하는 플랫폼, 핑퐁', + links: [ + { + type: 'Behance', + href: 'https://www.behance.net/gallery/161783411/Ping-Pong', + }, + { + type: 'IOS', + href: 'https://apps.apple.com/kr/app/%ED%95%91%ED%90%81-pingpong/id1662351621', + }, + ], + }, + { + title: '꼬깃', + subTitle: '12기', + description: '진심을 표현하고 싶을 때,
    꼬깃 접어 전해보세요', + links: [ + { + type: 'Behance', + href: 'https://url.kr/qd3ijo', + }, + { + type: 'Web', + href: 'https://www.ggo-geet.com', + }, + ], + }, + { + title: '비어에어', + subTitle: '11기', + description: '편의점 세계 맥주로
    세계 여행도장깨기', + links: [ + { + type: 'Behance', + href: 'https://www.behance.net/gallery/147281821/Beer-Air-UXUI-Design-Mobile-App-Service', + }, + { + type: 'Web', + href: 'https://beerair.kr', + }, + ], + }, + { + title: '영감탱', + subTitle: '11기', + description: '영감을 모아 통통튀는 아이디어로,
    영감탱', + links: [ + { + type: 'Behance', + href: 'https://www.behance.net/gallery/147207859/TANG-Inspiration-Archiving-App', + }, + { + type: 'IOS', + href: 'https://apps.apple.com/kr/app/%EC%98%81%EA%B0%90%ED%83%B1/id1626598770', + }, + { + type: 'Android', + href: 'https://play.google.com/store/apps/details?id=kr.ygtang', + }, + ], + }, + { + title: '바통', + subTitle: '11기', + description: '운동 회원권 양도 거래 서비스,
    바통', + links: [ + { + type: 'Behance', + href: 'https://www.behance.net/gallery/147261349/Baton', + }, + { + type: 'Android', + href: 'https://play.google.com/store/apps/details?id=com.depromeet.baton', + }, + ], + }, + { + title: '무드픽', + subTitle: '11기', + description: '부정적 감정의 기록,
    퍼스널 아카이빙 서비스', + links: [ + { + type: 'Behance', + href: 'https://www.behance.net/gallery/147271219/Archiving-My-Personal-Emotions-Moodpic', + }, + { + type: 'Web', + href: 'https://www.moodpic.kr/', + }, + { + type: 'IOS', + href: 'https://apps.apple.com/kr/app/%EB%AC%B4%EB%93%9C%ED%94%BD/id1642343841', + }, + { + type: 'Android', + href: 'https://play.google.com/store/apps/details?id=com.depromeet_5team.moodpicapp', + }, + ], + }, + { + title: '티키타카', + subTitle: '11기', + description: '위치 기반 실시간 채팅 서비스,
    티키타카', + links: [ + { + type: 'Behance', + href: 'https://www.behance.net/gallery/145307681/Tikitaka-Location-based-real-time-chat-Q-A-ap', + }, + { + type: 'IOS', + href: 'https://apps.apple.com/kr/app/%ED%8B%B0%ED%82%A4%ED%83%80%EC%B9%B4-tikitaka/id1617831823?l=en', + }, + ], + }, + { + title: '몽실', + subTitle: '11기', + description: '흐릿했던 꿈을 선명하게', + links: [ + { + type: 'Behance', + href: 'https://www.behance.net/gallery/147282295/%28Mongseal%29Archive-Your-Dream?tracking_source=search_projects%7Cdream', + }, + { + type: 'IOS', + href: 'https://apps.apple.com/kr/app/%EB%AA%BD%EC%8B%A4-mong-seal/id1622154270?l=kr', + }, + ], + }, + { + title: '페어러', + subTitle: '11기', + description: '페어러와 함께 평화롭게
    집안일 하기', + links: [ + { + type: 'Behance', + href: 'https://www.behance.net/gallery/147276499/fairerPeacemaker-for-Houseworker', + }, + { + type: 'Android', + href: 'https://play.google.com/store/search?q=fairer&c=apps', + }, + ], + }, + { + title: '개미는 툰툰', + subTitle: '11기', + description: '주식 용어로 즐기는 웹툰의
    새로운 덕질 문화, 개미는 툰툰', + links: [ + { + type: 'Behance', + href: 'https://www.behance.net/gallery/147262623/-ANTOON-l-Webtoon-Community-Service', + }, + { + type: 'Web', + href: 'https://antoon.fun/', + }, + { + type: 'Android', + href: 'https://play.google.com/store/apps/details?id=com.antoon_app', + }, + ], + }, + { + title: 'noonbody', + subTitle: '10기', + description: '건강한 눈바디 다이어트', + links: [ + { + type: 'Android', + href: 'https://play.google.com/store/apps/details?id=com.def.everybody_android', + }, + ], + }, + { + title: 'IMGOING', + subTitle: '10기', + description: '나만의 준비 루틴', + links: [ + { + type: 'Android', + href: 'https://play.google.com/store/apps/details?id=com.dpm.imgoing', + }, + ], + }, + { + title: 'BBOXX', + subTitle: '10기', + description: '당신의 부정적인 감정을 대신
    먹어주는 친구', + links: [ + { + type: 'Android', + href: 'https://play.google.com/store/apps/details?id=com.depromeet.bboxx', + }, + { + type: 'IOS', + href: 'https://apps.apple.com/kr/app/%EB%B9%A1%EC%93%B0/id1597106306', + }, + ], + }, + { + title: '나나공', + subTitle: '10기', + description: '나보다 나무늘보가 공부 열심히 한다', + links: [ + { + type: 'Android', + href: 'https://play.google.com/store/apps/details?id=com.depromeet.sloth', + }, + ], + }, + { + title: 'Archive', + subTitle: '10기', + description: '나만의 전시보관소', + links: [ + { + type: 'IOS', + href: 'https://apps.apple.com/kr/app/archive/id1599941822', + }, + ], + }, + { + title: '대동빵지도', + subTitle: '10기', + description: '빵순이들의 빵지도', + links: [ + { + type: 'Android', + href: 'https://play.google.com/store/apps/details?id=app.daedongbread.twa', + }, + ], + }, + { + title: '오맵땡', + subTitle: '10기', + description: '오늘 당신은 매운게 땡긴다!', + links: [ + { + type: 'Web', + href: 'https://ohmebddeng.kr/', + }, + ], + }, + { + title: 'Bodymood', + subTitle: '10기', + description: '운동 내용을 기록하고
    오늘의 감정을 담은 포스터', + links: [ + { + type: 'Android', + href: 'https://play.google.com/store/apps/details?id=com.depromeet.bodymood', + }, + { + type: 'IOS', + href: 'https://apps.apple.com/kr/app/bodymood/id1588818384', + }, + ], + }, + { + title: 'OMO', + subTitle: '10기', + description: '오마카세의 모든 것', + links: [ + { + type: 'Android', + href: 'https://play.google.com/store/apps/details?id=com.wesellloveandhappiness.omo', + }, + { + type: 'Web', + href: 'https://omo-deployment.vercel.app/', + }, + ], + }, + { + title: '영차', + subTitle: '10기', + description: + '영차는 투자 자산 모아보기 직접 입력한 정보를
    기반으로 현재 투자 상황을 모아볼 수 있습니다.', + links: [ + { + type: 'IOS', + href: 'https://apps.apple.com/.../%EC%98%81%EC%B0%A8/id1571507288', + }, + ], + }, + { + title: 'TOONI TOONI', + subTitle: '9기', + description: '세상의 모든 웹툰', + links: [ + { + type: 'Android', + href: 'https://play.google.com/store/apps/details?id=kr.tooni.tooni', + }, + ], + }, + { + title: '마이레시픽', + subTitle: '9기', + description: '취향대로 골라 만드는
    나만의 레시피', + links: [ + { + type: 'Android', + href: 'https://play.google.com/store/apps/details?id=com.def.custom&fbclid=IwAR01nq8JiuvvGdpnxFZEOJXef5EiOVP929GCGtHvv3-uiXkLVhIv2R9YS_c', + }, + { + type: 'IOS', + href: 'https://apps.apple.com/kr/app/%EB%A7%88%EC%9D%B4%EB%A0%88%EC%8B%9C%ED%94%BD/id1569961091?fbclid=IwAR2Bu-JPXUcUiCY6dUPv6kq2KwoD97p8jl2Rf2lqY_o59pyKQbHVccPweOE', + }, + ], + }, + { + title: '오늘의 테스트', + subTitle: '9기', + description: '쉽고 빠른 나만의 테스트 만들기', + links: [ + { + type: 'Web', + href: 'https://todaytest.netlify.app/', + }, + ], + }, + { + title: 'Hush', + subTitle: '9기', + description: '익명 소통 플랫폼', + links: [ + { + type: 'Web', + href: 'https://www.hush-it.com', + }, + ], + }, + { + title: '링크줍줍', + subTitle: '9기', + description: '아티클 스크랩 리마인드 서비스', + }, + { + title: '제로우쥬', + subTitle: '9기', + description: '친환경 용사가 되어 우쥬를 지키는
    제로웨이스트 서비스', + }, + { + title: '크래커북', + subTitle: '9기', + description: '내일을 바꾸는 오늘의 북스터디', + }, + { + title: '3대 얼마', + subTitle: '9기', + description: '헬린이 철 들기 프로젝트', + }, + { + title: '가슴속 3천원', + subTitle: '7기', + description: '길거리 음식 찾기', + links: [ + { + type: 'Android', + href: 'https://play.google.com/store/apps/details?id=com.zion830.threedollars', + }, + { + type: 'IOS', + href: 'https://apps.apple.com/kr/app/%EA%B0%80%EC%8A%B4%EC%86%8D3%EC%B2%9C%EC%9B%90-%EB%82%98%EC%99%80-%EA%B0%80%EA%B9%8C%EC%9A%B4-%EB%B6%95%EC%96%B4%EB%B9%B5/id1496099467', + }, + ], + }, + { + title: '북쪽으로', + subTitle: '8기', + description: '독서 기록
    특별한 책을 남기는 순간', + }, + { + title: 'Avocado', + subTitle: '8기', + description: '열어봐야 진짜를 만날 수 있는,
    채소 가격들의 단면을 분석해서 제공', + }, + { + title: 'Therto', + subTitle: '6기', + description: '편지를 보낸곳에서 읽는 서비스', + }, + { + title: '쿨피스', + subTitle: '6기', + description: '에어컨 사용 요금 측정 서비스', + }, + { + title: '칼퇴요정', + subTitle: '6기', + description: '칼퇴를 하고싶게 도와주는 요정녀석', + links: [ + { + type: 'IOS', + href: 'https://apps.apple.com/kr/app/%EC%B9%BC%ED%87%B4%EC%9A%94%EC%A0%95/id1467381865', + }, + ], + }, + { + title: '아무거나', + subTitle: '8기', + description: '오늘 뭐 먹지?', + links: [ + { + type: 'IOS', + href: 'https://apps.apple.com/kr/app/%EC%95%84%EB%AC%B4%EA%B1%B0%EB%82%98-%EC%98%A4%EB%8A%98-%EB%AD%90-%EB%A8%B9%EC%A7%80/id1542442642', + }, + { + type: 'Android', + href: 'https://play.google.com/store/apps/details?id=com.levin.depromeet3t_anything', + }, + { + type: 'Web', + href: 'https://depromeet.github.io/8th-final-3team-front/', + }, + ], + }, + { + title: '뜻밖의 퀴즈', + subTitle: '5기', + description: '인싸력을 키워주는 이모티콘 퀴즈', + }, +]; diff --git a/src/constant/qualification.ts b/src/constant/qualification.ts new file mode 100644 index 00000000..be4f1e4e --- /dev/null +++ b/src/constant/qualification.ts @@ -0,0 +1,26 @@ +export const QUALIFICATIONS = [ + { + index: 1, + description: '매주 토요일, 오후 2-5시에 진행되는 정규 세션에 참여할 수 있는 사람', + }, + { + index: 2, + description: '개인보다는 팀에 어우러져서 공동의 목표를 위해 노력해본 사람', + }, + { + index: 3, + description: '우리 모두가 선생님이자 학생, 서로에게 배우고 발전할 수 있는 사람', + }, + { + index: 4, + description: '주도적으로 참여하거나 능동적으로 문제를 해결한 경험이 있는 사람', + }, + { + index: 5, + description: '한 가지 프로젝트 혹은 무언가에 3개월 이상 몰입한 경험이 있는 사람', + }, + { + index: 6, + description: '책임감 있게 프로젝트를 끝까지 완성할 수 있는 사람', + }, +]; diff --git a/src/constant/review.ts b/src/constant/review.ts new file mode 100644 index 00000000..0b374542 --- /dev/null +++ b/src/constant/review.ts @@ -0,0 +1,103 @@ +export type ReadMoreLink = { + type: 'blog' | 'project'; + url: string; + label: string; +}; +export type ReviewItemType = { + name: string; + /** + * 기수 + * ex) 14기 + */ + group: string; + /** + * 파트 + * ex) WEB + */ + part: string; + summary: string; + links: ReadMoreLink[]; +}; + +export const REVIEWS: ReviewItemType[] = [ + { + name: '이상조', + group: '13기', + part: 'WEB', + summary: + '프로덕트 개발의 AtoZ를 체험해볼 수 있는 좋은 기회였어요. 여러 기술적 도전과 네트워킹을 통해 한 단계 성장할 수 있었던 것 같습니다. 무엇보다 좋은 팀원들을 만날 수 있다는 것이 가장 큰 장점 아닐까요?', + links: [ + { + type: 'blog', + label: '블로그 후기', + url: 'https://velog.io/@sjoleee_/디프만-13기를-추억하며', + }, + ], + }, + { + name: '이다래', + group: '13기', + part: 'WEB', + summary: + '기획부터 배포까지 경험해 볼 수 있는 동아리였습니다. 같은 직군, 타직군 분들과 협업하며 배울수 있는 점이 좋았습니다. 결과물을 남길수 있도록 체계적인 시스템으로 서포트 해줘서 잘 런칭할 수 있었습니다!', + links: [ + { type: 'project', label: '프로젝트', url: 'https://github.com/depromeet/Ding-dong-fe' }, + ], + }, + { + name: '이혜린', + group: '13기', + part: 'DESIGN', + summary: + '디프만 프로젝트를 통해 서비스 기획부터 배포까지 전 과정에 참여하고, 다양한 네트워킹 활동으로 즐겁게 성장할 수 있었어요. 열정적인 분들과 빠른 호흡으로 진행했던 잊지 못할 경험이었습니다.', + links: [ + { type: 'blog', label: '블로그 후기', url: 'https://blog.naver.com/hye_duck/223114158145' }, + ], + }, + { + name: '정영경', + group: '13기', + part: 'DESIGN', + summary: + '서비스 릴리즈, 개발자 협업 경험, 모든 팀원이 제몫을 할 수 있게 체계적인 시스템이 좋았어요. 노션, 슬랙, 피그마에 선배 기수가 쌓아둔 데이터로 운영되기에 나만 잘하면 성장하는 동아리구나! 싶을만큼 좋았습니다!', + links: [ + { + type: 'project', + label: '프로젝트', + url: 'https://www.behance.net/gallery/175690517/-Improve-your-spending-habit-with-people', + }, + ], + }, + { + name: '김정윤', + group: '13기', + part: 'SERVER', + summary: + '항상 프로젝트를 진행할 때 기술적인 부분만 고려하면서 진행해 왔는데, 이번 프로젝트에서는 디자이너, 개발자가 함께 기획부터 개발까지 하는 것이기 때문에 정말 제대로 된 서비스를 만들고 싶은 욕심이 생겼어요.', + links: [ + { type: 'blog', label: '블로그 후기', url: 'https://hello-judy-world.tistory.com/203' }, + ], + }, + { + name: '정성훈', + group: '13기', + part: 'SERVER', + summary: + '적절한 기간 내 프로젝트 기획부터 배포까지 경험해 볼 수 있는 동아리였습니다. 다양한 직군과 협업하며 배울수 있는 점이 좋았습니다. 체계적인 시스템으로 서포트 해줘서 잘 런칭할 수 있었습니다!', + links: [ + { + type: 'project', + label: '프로젝트', + url: 'https://github.com/depromeet/street-drop-server', + }, + ], + }, + { + name: '이준영', + group: '13기', + part: 'SERVER', + summary: + '동아리를 통해 슬럼프를 극복하려고 했던거 같아요. 특히, 디프만은 현업 개발자와 사이드 프로젝트를 함께 할 수 있다는 장점 외에도 만드는 프로덕트의 질이 높아서 가장 가고싶었던 동아리 였습니다.', + links: [{ type: 'blog', label: '블로그 후기', url: 'https://dlwnsdud205.tistory.com/353' }], + }, +]; diff --git a/src/constant/schedule.ts b/src/constant/schedule.ts new file mode 100644 index 00000000..0e9ac831 --- /dev/null +++ b/src/constant/schedule.ts @@ -0,0 +1,68 @@ +import { theme } from '~/styles/theme'; + +interface Schedule { + label: string; + title: string; + schedule: Array<{ + date: string; + content: string; + }>; + + titleBgColor: keyof typeof theme.colors; +} + +export const MEMBER_SCHEDULE: Schedule = { + label: 'members', + title: '멤버 모집', + titleBgColor: 'blue400', + schedule: [ + { + date: '10.02', + content: '서류 접수 시작', + }, + { + date: '10.08', + content: '서류 마감', + }, + { + date: '10.21-22', + content: '온라인 면접', + }, + { + date: '10.31', + content: '최종 합격 안내', + }, + ], +}; + +export const SESSION_SCHEDULES: Schedule = { + label: 'sessions', + title: '정기 세션', + titleBgColor: 'yellow400', + schedule: [ + { + date: '11.04', + content: 'OT', + }, + { + date: '11.25', + content: '네트워킹', + }, + { + date: '12.09', + content: 'UT', + }, + { + date: '12.23', + content: '중간 발표', + }, + { + date: '01.20', + content: '런칭데이', + }, + { + date: '02.17', + content: '최종 발표', + }, + ], +}; diff --git a/src/constant/supports.ts b/src/constant/supports.ts new file mode 100644 index 00000000..8b4e209e --- /dev/null +++ b/src/constant/supports.ts @@ -0,0 +1,30 @@ +import { Link } from '~/components/OfflineSession/OfflineThumbnail'; + +export type Support = { + title: string; + subTitle: string; + description: string; + img: string; + links?: Link[]; +}; + +export const SUPPORTS: Support[] = [ + { + title: '네이버클라우드', + subTitle: 'Navercloud', + description: '‘Ncloud’ 최대 100만원 크레딧과
    커뮤니티 참여 혜택을 제공합니다.', + img: '/images/support/naver-cloud.png', + }, + { + title: '인프런', + subTitle: 'Inflearn', + description: '인프런 강의 30% 할인쿠폰과 강의 수강을
    위해 총 48만 포인트를 제공합니다.', + img: '/images/support/inflearn.png', + }, + { + title: '모두의연구소', + subTitle: 'Modulabs', + description: '오프라인 세션 운영을 위한
    공간을 지원합니다.', + img: '/images/support/모두의연구소.png', + }, +]; diff --git a/src/constants/common/index.ts b/src/constants/common/index.ts deleted file mode 100644 index 688c346c..00000000 --- a/src/constants/common/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './common'; -export * from './depromeet'; diff --git a/src/constants/images/images.ts b/src/constants/images/images.ts deleted file mode 100644 index 610fa47f..00000000 --- a/src/constants/images/images.ts +++ /dev/null @@ -1,11 +0,0 @@ -export const ABOUT_IMAGE_BASE = '/images/about'; - -export const SPONSOR_IMAGE_BASE = '/images/sponsor'; - -export const HOME_IMAGE_BASE = '/images/home'; - -export const PROJECTS_IMAGE_BASE = '/projects'; - -export const POSITION_ICON_BASE = '/images/position/icon'; - -export const ORGANIZER_IMAGE_BASE = '/images/organizer'; diff --git a/src/constants/images/index.ts b/src/constants/images/index.ts deleted file mode 100644 index 67e4bd30..00000000 --- a/src/constants/images/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './images'; diff --git a/src/constants/motions/index.ts b/src/constants/motions/index.ts deleted file mode 100644 index 3ef1c759..00000000 --- a/src/constants/motions/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -export { - defaultEasing, - defaultFadeInScaleVariants, - defaultFadeInUpVariants, - defaultFadeInVariants, - staggerHalf, - staggerOne, -} from './motions'; diff --git a/src/constants/motions/motions.ts b/src/constants/motions/motions.ts deleted file mode 100644 index d0bf3aaa..00000000 --- a/src/constants/motions/motions.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { Variants } from 'framer-motion'; - -export const defaultEasing = [0.6, -0.05, 0.01, 0.99]; - -export const staggerOne: Variants = { - animate: { transition: { staggerChildren: 0.1 } }, -}; - -export const staggerHalf: Variants = { - animate: { transition: { staggerChildren: 0.05 } }, -}; - -export const defaultFadeInVariants: Variants = { - initial: { - opacity: 0, - transition: { duration: 0.6, ease: defaultEasing }, - willChange: 'opacity', - }, - animate: { - opacity: 1, - transition: { duration: 0.6, ease: defaultEasing }, - willChange: 'opacity', - }, - exit: { - opacity: 0, - transition: { duration: 0.6, ease: defaultEasing }, - willChange: 'opacity', - }, -}; - -export const defaultFadeInUpVariants: Variants = { - initial: { - opacity: 0, - y: 30, - transition: { duration: 0.6, ease: defaultEasing }, - willChange: 'opacity, transform', - }, - animate: { - opacity: 1, - y: 0, - transition: { duration: 0.6, ease: defaultEasing }, - willChange: 'opacity, transform', - }, - exit: { - opacity: 0, - y: 30, - transition: { duration: 0.6, ease: defaultEasing }, - willChange: 'opacity, transform', - }, -}; - -export const defaultFadeInScaleVariants: Variants = { - initial: { - opacity: 0, - scale: 0.85, - transition: { duration: 0.6, ease: defaultEasing }, - willChange: 'opacity, transform', - }, - animate: { - opacity: 1, - scale: 1, - transition: { duration: 0.6, ease: defaultEasing }, - willChange: 'opacity, transform', - }, - exit: { - opacity: 0, - scale: 0.85, - transition: { duration: 0.6, ease: defaultEasing }, - willChange: 'opacity, transform', - }, -}; - -export const defaultFadeInSlideToRightVariants: Variants = { - initial: { - opacity: 0, - x: -30, - transition: { duration: 0.6, ease: defaultEasing }, - willChange: 'opacity, transform', - }, - animate: { - opacity: 1, - x: 0, - transition: { duration: 0.6, ease: defaultEasing }, - willChange: 'opacity, transform', - }, - exit: { - opacity: 0, - x: 30, - transition: { duration: 0.6, ease: defaultEasing }, - willChange: 'opacity, transform', - }, -}; - -export const defaultFadeInSlideToLeftVariants: Variants = { - initial: { - opacity: 0, - x: 30, - transition: { duration: 0.6, ease: defaultEasing }, - willChange: 'opacity, transform', - }, - animate: { - opacity: 1, - x: 0, - transition: { duration: 0.6, ease: defaultEasing }, - willChange: 'opacity, transform', - }, - exit: { - opacity: 0, - x: -30, - transition: { duration: 0.6, ease: defaultEasing }, - willChange: 'opacity, transform', - }, -}; diff --git a/src/hooks/use-effect-once/index.ts b/src/hooks/use-effect-once/index.ts deleted file mode 100644 index 2992f55f..00000000 --- a/src/hooks/use-effect-once/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from './use-effect-once'; diff --git a/src/hooks/use-effect-once/use-effect-once.ts b/src/hooks/use-effect-once/use-effect-once.ts deleted file mode 100644 index 41d48bdf..00000000 --- a/src/hooks/use-effect-once/use-effect-once.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { EffectCallback, useEffect } from 'react'; - -const useEffectOnce = (effect: EffectCallback) => { - useEffect(effect, [effect]); -}; - -export default useEffectOnce; diff --git a/src/hooks/use-ga-event/index.ts b/src/hooks/use-ga-event/index.ts deleted file mode 100644 index 55168ea6..00000000 --- a/src/hooks/use-ga-event/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from './use-ga-event'; diff --git a/src/hooks/use-ga-event/use-ga-event.ts b/src/hooks/use-ga-event/use-ga-event.ts deleted file mode 100644 index 8d1f93d4..00000000 --- a/src/hooks/use-ga-event/use-ga-event.ts +++ /dev/null @@ -1,18 +0,0 @@ -interface GaEventProps { - action: string; - category?: string; - label?: string; - value?: string; -} - -export default function useGaEvent() { - const gaEvent = ({ action, category, label, value }: GaEventProps) => { - if (typeof window.gtag === 'undefined') return; - window.gtag('event', action, { event_category: category, event_label: label, value }); - }; - - const recordApplyEvent = () => { - gaEvent({ action: 'apply' }); - }; - return { gaEvent, recordApplyEvent }; -} diff --git a/src/hooks/use-is-in-progress/index.ts b/src/hooks/use-is-in-progress/index.ts deleted file mode 100644 index a4127946..00000000 --- a/src/hooks/use-is-in-progress/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from './use-is-in-progress'; diff --git a/src/hooks/use-media-query/index.ts b/src/hooks/use-media-query/index.ts deleted file mode 100644 index a7ee85d3..00000000 --- a/src/hooks/use-media-query/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from './use-media-query'; diff --git a/src/hooks/use-media-query/use-media-query.ts b/src/hooks/use-media-query/use-media-query.ts deleted file mode 100644 index 816ab895..00000000 --- a/src/hooks/use-media-query/use-media-query.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { useCallback, useEffect, useState } from 'react'; - -import { SIZE, size, SizeKey } from '~/styles/constants'; - -import { useUserAgent } from '../use-user-agent'; - -export function useMediaQuery(width: number): boolean; - -export function useMediaQuery(sizeKey: SizeKey): boolean; - -export default function useMediaQuery(width: number | SizeKey) { - const { isMobileAgent } = useUserAgent(); - const targetWidth = typeof width === 'number' ? `${width}px` : size[width]; - const isMobileSize = (width <= SIZE.xs || targetWidth === size.xs) && isMobileAgent; - - const [targetReached, setTargetReached] = useState(isMobileSize); - - const updateTarget = useCallback((e: MediaQueryListEvent) => { - if (e.matches) { - setTargetReached(true); - } else { - setTargetReached(false); - } - }, []); - - useEffect(() => { - const media = window.matchMedia(`(max-width: ${targetWidth})`); - media.addEventListener('change', updateTarget); - - if (media.matches) { - setTargetReached(true); - } else { - setTargetReached(false); - } - - return () => media.removeEventListener('change', updateTarget); - }, [updateTarget, targetWidth]); - - return targetReached; -} diff --git a/src/hooks/use-record-pageview/index.ts b/src/hooks/use-record-pageview/index.ts deleted file mode 100644 index f50f1274..00000000 --- a/src/hooks/use-record-pageview/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from './use-record-pageview'; diff --git a/src/hooks/use-toggle/index.ts b/src/hooks/use-toggle/index.ts deleted file mode 100644 index ffd33d99..00000000 --- a/src/hooks/use-toggle/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from './use-toggle'; diff --git a/src/hooks/use-user-agent/index.ts b/src/hooks/use-user-agent/index.ts deleted file mode 100644 index 87113314..00000000 --- a/src/hooks/use-user-agent/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { useUserAgent } from './use-user-agent'; -export { UserAgentContext } from './user-agent-context'; diff --git a/src/hooks/use-user-agent/use-user-agent.ts b/src/hooks/use-user-agent/use-user-agent.ts deleted file mode 100644 index 1f937843..00000000 --- a/src/hooks/use-user-agent/use-user-agent.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { useContext, useState } from 'react'; - -import { UserAgentContext } from './user-agent-context'; -import useEffectOnce from '../use-effect-once'; - -export const useUserAgent = () => { - const userAgent = useContext(UserAgentContext); - const [isMobileAgent, setIsMobileAgent] = useState(/iPhone|iPod|iPad|Android/i.test(userAgent)); - - useEffectOnce(() => { - if (navigator.maxTouchPoints > 1) { - setIsMobileAgent(true); - } - }); - - if (userAgent === undefined) { - throw new Error('useUserAgent should be used within UserAgentContext.Provider'); - } - - return { userAgent, isMobileAgent }; -}; diff --git a/src/hooks/use-user-agent/user-agent-context.ts b/src/hooks/use-user-agent/user-agent-context.ts deleted file mode 100644 index fe1328ca..00000000 --- a/src/hooks/use-user-agent/user-agent-context.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { createContext } from 'react'; - -export const UserAgentContext = createContext(''); diff --git a/src/hooks/useCheckWindowSize.ts b/src/hooks/useCheckWindowSize.ts new file mode 100644 index 00000000..0be36173 --- /dev/null +++ b/src/hooks/useCheckWindowSize.ts @@ -0,0 +1,26 @@ +import { useEffect, useState } from 'react'; + +import { SIZE, SizeKey } from '~/styles/media'; + +type UseCheckWindowSizeProps = SizeKey; + +export const useCheckWindowSize = (size: UseCheckWindowSizeProps) => { + const [isTargetSize, setIsTargetSize] = useState(false); + + const checkWindowSize = () => { + setIsTargetSize(window.innerWidth <= SIZE[size]); + }; + + useEffect(() => { + checkWindowSize(); + window.addEventListener('resize', checkWindowSize); + return () => { + window.removeEventListener('resize', checkWindowSize); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + return { + isTargetSize, + }; +}; diff --git a/src/hooks/useDropdown.ts b/src/hooks/useDropdown.ts new file mode 100644 index 00000000..48667228 --- /dev/null +++ b/src/hooks/useDropdown.ts @@ -0,0 +1,45 @@ +import { useCallback, useEffect, useRef, useState } from 'react'; + +interface ComposedMouseEvent extends MouseEvent { + composedPath: () => EventTarget[]; +} + +export const useDropDown = () => { + const containerRef = useRef(null); + const [isDropdownOpen, setIsDropdownOpen] = useState(false); + + const closeDropdown = useCallback(() => { + setIsDropdownOpen(false); + }, []); + + const openDropdown = useCallback(() => { + setIsDropdownOpen(true); + }, []); + + const shouldCloseDropdown = useCallback( + (event: ComposedMouseEvent) => { + const isParentExistInComposedPath = + containerRef.current && event.composedPath().includes(containerRef.current); + + if (!isParentExistInComposedPath) { + closeDropdown(); + } + }, + [closeDropdown] + ); + + useEffect(() => { + window.addEventListener('click', shouldCloseDropdown); + + return () => { + window.removeEventListener('click', shouldCloseDropdown); + }; + }, [containerRef, shouldCloseDropdown]); + + return { + containerRef, + isDropdownOpen, + openDropdown, + closeDropdown, + }; +}; diff --git a/src/hooks/use-is-in-progress/use-is-in-progress.ts b/src/hooks/useIsInProgress.tsx similarity index 93% rename from src/hooks/use-is-in-progress/use-is-in-progress.ts rename to src/hooks/useIsInProgress.tsx index e904d816..f87a025e 100644 --- a/src/hooks/use-is-in-progress/use-is-in-progress.ts +++ b/src/hooks/useIsInProgress.tsx @@ -1,4 +1,4 @@ -import { END_DATE, START_DATE } from '~/constants/common'; +import { END_DATE, START_DATE } from '~/constant/common'; export type RecruitState = 'PREVIOUS' | 'IN_PROGRESS' | 'FINISH'; diff --git a/src/hooks/useMounted.ts b/src/hooks/useMounted.ts new file mode 100644 index 00000000..11a1243a --- /dev/null +++ b/src/hooks/useMounted.ts @@ -0,0 +1,11 @@ +import { useEffect, useState } from 'react'; + +export default function useMounted() { + const [mounted, setMounted] = useState(false); + + useEffect(() => { + setMounted(true); + }, []); + + return mounted; +} diff --git a/src/hooks/use-record-pageview/use-record-pageview.ts b/src/hooks/useRecordPageView.ts similarity index 69% rename from src/hooks/use-record-pageview/use-record-pageview.ts rename to src/hooks/useRecordPageView.ts index 0997d9c0..40eea48e 100644 --- a/src/hooks/use-record-pageview/use-record-pageview.ts +++ b/src/hooks/useRecordPageView.ts @@ -1,19 +1,19 @@ import { useEffect } from 'react'; import { useRouter } from 'next/router'; -import { GA_ID, IS_PRODUCTION } from '~/constants/common'; +import { GA_ID, IS_PRODUCTION } from '~/constant/common'; -export default function useRecordPageview() { +export function useRecordPageView() { const router = useRouter(); useEffect(() => { - const recordPageview = (url: string) => { - gaPageview(url); + const recordPageView = (url: string) => { + gaPageView(url); }; - if (IS_PRODUCTION) router.events.on('routeChangeComplete', recordPageview); + if (IS_PRODUCTION) router.events.on('routeChangeComplete', recordPageView); return () => { - if (IS_PRODUCTION) router.events.off('routeChangeComplete', recordPageview); + if (IS_PRODUCTION) router.events.off('routeChangeComplete', recordPageView); }; }, [router.events]); } @@ -24,7 +24,7 @@ declare global { } } -function gaPageview(url: string) { +function gaPageView(url: string) { if (typeof window.gtag === 'undefined') return; window.gtag('config', GA_ID, { page_path: url }); } diff --git a/src/hooks/use-toggle/use-toggle.ts b/src/hooks/useToggle.ts similarity index 100% rename from src/hooks/use-toggle/use-toggle.ts rename to src/hooks/useToggle.ts diff --git a/src/pages/404.tsx b/src/pages/404.tsx index 51d9577c..2de3e3fb 100644 --- a/src/pages/404.tsx +++ b/src/pages/404.tsx @@ -1,127 +1,51 @@ import Image from 'next/image'; -import { css } from '@emotion/react'; +import { useRouter } from 'next/router'; +import { css, Theme } from '@emotion/react'; -import { ClickableLink } from '~/components/common/Clickable'; -import { HOME_IMAGE_BASE } from '~/constants/images'; -import useMediaQuery from '~/hooks/use-media-query'; -import { colors, mediaQuery } from '~/styles/constants'; - -const HEADER_BACK_IMAGE = `${HOME_IMAGE_BASE}/header-back.webp`; -const MOBILE_HEADER_BACK_IMAGE = `${HOME_IMAGE_BASE}/mobile-header-back.webp`; -const HEADER_FRONT_IMAGE = `${HOME_IMAGE_BASE}/header-front.png`; -const MOBILE_HEADER_FRONT_IMAGE = `${HOME_IMAGE_BASE}/mobile-header-front.webp`; +import { Button } from '~/components/Button'; +import { mediaQuery } from '~/styles/media'; +const ERROR_IMAGE = `/images/error/career.png`; export default function NotFound() { - const isMobile = useMediaQuery('xs'); + const router = useRouter(); + + const onButtonClick = () => { + router.push('/'); + }; return ( -
    - 디프만 - 404 - NOT FOUND - depromeet - +
    + error image +

    404 ERROR

    +

    디프만 이륙 중 문제가 생겼어요

    +
    ); } -const mainCss = css` - position: relative; - width: 100%; - height: 780px; - +const errorContainerCss = css` display: flex; - flex-direction: column; - justify-content: flex-end; + gap: 24px; align-items: center; - - padding-bottom: 14vh; -`; - -const linkCss = css` - border-radius: 2px; - padding: 16px 98px; - background-color: ${colors.black}; - - font-weight: 600; - font-size: 20px; - line-height: 24px; - color: ${colors.gray100}; - - ${mediaQuery('xs')} { - padding: 18px 60px; - font-size: 16px; - line-height: 19px; + flex-direction: column; + margin: 150px 0; + ${mediaQuery('mobile')} { + margin: 50px 0; } `; -const imageCss = css` - position: absolute; - top: 0; - left: 0; - object-fit: cover; - z-index: -1; -`; - -const graphicTextCss = css` - position: absolute; - font-weight: 600; - font-size: 150px; - z-index: -1; - - ${mediaQuery('sm')} { - font-size: 100px; - } - - ${mediaQuery('xs')} { - font-size: 50px; - } +const errorTitleCss = (theme: Theme) => css` + ${theme.typos.decimal.title2}; + color: white; `; -const designerTextCss = css` - ${graphicTextCss}; - top: 165px; - left: 14vw; - - ${mediaQuery('sm')} { - left: 7vw; - } - - ${mediaQuery('xs')} { - top: 113px; - } +const errorDescriptionCss = (theme: Theme) => css` + ${theme.typos.pretendard.subTitle2}; + color: white; `; -const programmerTextCss = css` - ${graphicTextCss}; - top: 327px; - left: 24vw; - - ${mediaQuery('sm')} { - left: 9vw; - } - - ${mediaQuery('xs')} { - top: 182px; - } +const homeButtonCss = css` + width: 130px; `; diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 7eacb81d..590ec4a2 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -1,47 +1,44 @@ import type { AppContext, AppProps } from 'next/app'; import Head from 'next/head'; import { useRouter } from 'next/router'; +import { ThemeProvider } from '@emotion/react'; import { domMax, LazyMotion } from 'framer-motion'; -import { Provider } from 'jotai'; -import CustomCursor from '~/components/common/CustomCursor'; -import Footer from '~/components/common/Footer'; -import GNB from '~/components/common/GNB'; -import { BASE_URL } from '~/constants/common'; -import useRecordPageview from '~/hooks/use-record-pageview'; -import { UserAgentContext } from '~/hooks/use-user-agent'; -import GlobalStyle from '~/styles/GlobalStyle'; +import { Footer } from '~/components/Footer'; +import { GNB } from '~/components/GNB'; +import { Sign } from '~/components/Sign'; +import { BASE_URL } from '~/constant/common'; +import { useRecordPageView } from '~/hooks/useRecordPageView'; +import GlobalStyle from '~/styles/globalStyle'; +import { theme } from '~/styles/theme'; interface InitialProps { userAgent: string; } -export default function App({ Component, pageProps, userAgent }: AppProps & InitialProps) { +export default function App({ Component, pageProps }: AppProps & InitialProps) { const router = useRouter(); const currentUrl = BASE_URL + router.route; - useRecordPageview(); + useRecordPageView(); return ( - - - - - - - - - - - - - -