├── .eslintrc.js
├── .gitignore
├── .vscode
└── settings.json
├── README.md
├── package-lock.json
├── package.json
├── public
├── Data
│ ├── question1.json
│ ├── question2.json
│ ├── question3.json
│ ├── question4.json
│ ├── question5.json
│ ├── result 2.json
│ └── result.json
├── Fonts
│ └── DungGeunMo.ttf
├── Logo.png
├── Logo3.png
├── Logo5.png
├── favicon.ico
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
└── robots.txt
├── pull_request_template.md
├── src
├── Components
│ ├── About
│ │ ├── About.js
│ │ ├── AboutData.js
│ │ └── AboutDetail.js
│ ├── Nav.js
│ ├── ProgressBar.js
│ ├── Question
│ │ ├── QuestionMain.js
│ │ └── QuestionWindow.js
│ └── ResultWindow
│ │ ├── Alert.js
│ │ ├── Footer.js
│ │ ├── Result.js
│ │ └── WindowNav.js
├── Images
│ ├── About
│ │ ├── click.svg
│ │ └── members.jpg
│ ├── AboutDetail
│ │ ├── Aiden.jpg
│ │ ├── BG.png
│ │ ├── Carmin.jpg
│ │ ├── Hong.jpg
│ │ ├── Kay.jpg
│ │ ├── Sol.jpg
│ │ ├── Sunny.jpg
│ │ └── Whybein.jpg
│ ├── Group6.png
│ ├── Main
│ │ ├── Record.png
│ │ ├── WeTV.png
│ │ ├── computer.png
│ │ ├── quiz.png
│ │ └── trash.png
│ ├── Nav
│ │ ├── BF Blue Logo.png
│ │ ├── BTR.png
│ │ ├── Moon.png
│ │ ├── SUN.png
│ │ ├── close.png
│ │ ├── expand.png
│ │ ├── min.png
│ │ └── wecode black logo.png
│ ├── Progress
│ │ ├── Dog.png
│ │ ├── home.png
│ │ └── home_bf.png
│ ├── ReadMe.png
│ ├── art1.png
│ ├── art1.svg
│ ├── grain.png
│ └── logo.png
├── Pages
│ ├── Intro.js
│ └── Main
│ │ └── Main.js
├── Redux
│ ├── Actions
│ │ └── index.js
│ ├── Reducers
│ │ ├── controlAbout.js
│ │ ├── controlDetail.js
│ │ ├── controlQuestion.js
│ │ ├── controlResult.js
│ │ └── getResult.js
│ └── rootReducer.js
├── Routes.js
├── Styles
│ └── Fonts
│ │ ├── DungGeunMo.ttf
│ │ └── monospace.ttf
├── config.js
└── index.js
└── yarn.lock
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['react-app', 'prettier'],
3 | plugins: ['prettier'],
4 | rules: {
5 | 'prettier/prettier': ['error']
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
25 | .vscode
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.formatOnSave": true,
3 | "editor.codeActionsOnSave": {
4 | "source.fixAll.eslint": true
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### Project
2 |
3 | + Wecode 6기 졸업생들의 토이 프로젝트
4 | + 프론트엔드와 백엔드 중에 당신에 성향에 맞는 포지션이 무엇인지 알아보는 테스트 사이트
5 |
6 | ---------
7 |
8 | ### 개발 인원 및 기간
9 |
10 | + 개발기간 : 2020/4/20 ~ 2020/4/28
11 | + 개발 인원 : Front-End 4명, Back-End 3명
12 |
13 | ---------
14 |
15 | ### 데모 영상(이미지 클릭)
16 |
17 | 
18 |
19 | ---------
20 |
21 | ### 적용 기술
22 |
23 | + Front-End : React.js, Redux, Styled Component
24 | + Back-End : Python, Django
25 | + Common : AWS, Google Analytics
26 |
27 | ---------
28 |
29 | ### 구현 기능
30 |
31 | #### COMMON
32 | + 프로젝트 기획 및 디자인
33 | + 모바일, 태블릿 사이즈 반응형 구현
34 | + 리덕스 사용하여 전역 상태 관리
35 | + Open Graph 적용
36 | + Google Analytics 적용
37 |
38 | #### Intro & Loading
39 | + React-typing-animation 사용하여 Typing 효과 구현
40 | + figlet 사용하여 ASCII Art 구현
41 | + setInterval 사용하여 progress bar 구현
42 |
43 | #### Main & Contributors
44 | + setInterval 사용하여 nav bar 시계 구현
45 | + contributor에서 클릭 시, 개인 프로필 모달 구현
46 |
47 | #### Question
48 | + React-typing-animation 사용하여 Typing 효과 구현
49 | + TEST에서 선택되는 선택지에 따라 성향 및 타입분류
50 |
51 | #### Result
52 | + 유형 결과에 따른 full, front, back 결과 체크
53 |
54 |
55 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bftest",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^4.2.4",
7 | "@testing-library/react": "^9.3.2",
8 | "@testing-library/user-event": "^7.1.2",
9 | "axios": "^0.19.2",
10 | "figlet": "^1.3.0",
11 | "html2canvas": "^1.0.0-rc.5",
12 | "react": "^16.13.1",
13 | "react-dom": "^16.13.1",
14 | "react-redux": "^7.2.0",
15 | "react-router-dom": "^5.1.2",
16 | "react-scripts": "3.4.1",
17 | "react-typing-animation": "^1.6.2",
18 | "redux": "^4.0.5",
19 | "styled-components": "^5.1.0",
20 | "styled-icons": "^10.2.1",
21 | "styled-reset": "^4.1.3",
22 | "typewriter-effect": "^2.13.0"
23 | },
24 | "scripts": {
25 | "start": "NODE_PATH=src/ react-scripts start",
26 | "build": "NODE_PATH=src/ react-scripts build",
27 | "test": "react-scripts test",
28 | "eject": "react-scripts eject"
29 | },
30 | "eslintConfig": {
31 | "extends": "react-app"
32 | },
33 | "browserslist": {
34 | "production": [
35 | ">0.2%",
36 | "not dead",
37 | "not op_mini all"
38 | ],
39 | "development": [
40 | "last 1 chrome version",
41 | "last 1 firefox version",
42 | "last 1 safari version"
43 | ]
44 | },
45 | "devDependencies": {
46 | "eslint-config-prettier": "^6.10.1",
47 | "eslint-plugin-prettier": "^3.1.3",
48 | "prettier": "^2.0.4"
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/public/Data/question1.json:
--------------------------------------------------------------------------------
1 | {
2 | "question_data": {
3 | "choice": [
4 | {
5 | "choice": "나는 베이스 할래!",
6 | "id": 11
7 | },
8 | {
9 | "choice": "나느 보컬 할래!",
10 | "id": 12
11 | }
12 | ],
13 | "id": 1,
14 | "image_url": null,
15 | "question": "밴드에 들어가기로 했어요. (실력은 동일하다고 했을 때) 심영보 유경희 홍수연 권태솔 황은지 정성혜 권기현?"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/public/Data/question2.json:
--------------------------------------------------------------------------------
1 | {
2 | "question_data": {
3 | "choice": [
4 | {
5 | "choice": "이게 왜? 잠기기만 하면 된다",
6 | "id": 1
7 | },
8 | {
9 | "choice": "신경쓰인다",
10 | "id": 2
11 | }
12 | ],
13 | "id": 2,
14 | "image_url": null,
15 | "question": "배가 아파서 화장실에 간 당신, 눈 앞에 보이는 문고리의 모습"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/public/Data/question3.json:
--------------------------------------------------------------------------------
1 | {
2 | "question_data": {
3 | "choice": [
4 | {
5 | "choice": "ㅁㄴㅇㄹㅇㄴㅁㄹㄴㅁㄹㅇㄹㅇㄹㅇㄹㅇㄹ",
6 | "id": 1
7 | },
8 | {
9 | "choice": "ㄴㅇㄹㄴㄹㄴㅇㄹㄴㅇㄹㄴ",
10 | "id": 2
11 | }
12 | ],
13 | "id": 3,
14 | "image_url": null,
15 | "question": "1+1은 양준식은 양 준식이는 식케이는 무슨말이냐"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/public/Data/question4.json:
--------------------------------------------------------------------------------
1 | {
2 | "question_data": {
3 | "choice": [
4 | {
5 | "choice": "ㅁㄴㅇㄹㅁㄴㅇ",
6 | "id": 1
7 | },
8 | {
9 | "choice": "ㅁㄴㅇㄹㄴㅁㅇㄹ",
10 | "id": 2
11 | }
12 | ],
13 | "id": 4,
14 | "image_url": null,
15 | "question": "이게뭐냐 뭐가 뭐긴 뭐냐"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/public/Data/question5.json:
--------------------------------------------------------------------------------
1 | {
2 | "question_data": {
3 | "choice": [
4 | {
5 | "choice": "이게 왜? 잠기기만 하면 된다",
6 | "id": 1
7 | },
8 | {
9 | "choice": "신경쓰인다",
10 | "id": 2
11 | }
12 | ],
13 | "id": 5,
14 | "image_url": null,
15 | "question": "가나다라마바사 아자차카 타파하 거너더러 머버서 어저처커 터퍼허"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/public/Data/result 2.json:
--------------------------------------------------------------------------------
1 | {
2 | "result": {
3 | "name": "기브미관심 귀여운 답정너 프론트엔드",
4 | "description": "css는 미안해ㅜㅜ 대신 기능은 내가 책임져보겠다구우~!눈으로 무언가를 만들어 내는 것도 좋지만 로직을 생각하면 마음이 설레이는 당신.새로운 웹 사이트를 보면 빨리 저 기능을 구현해보고 싶어 마음이 콩닥콩닥 합니다.기능은 좋지만 css 만질 생각에 머리가 지끈거린다구요? 너무 걱정하지 마세요~ 지금은 완벽하지 않아도 괜찮아요~ css는 하다보면 익숙해 질 거예요.",
5 | "image_url": "https://user-images.githubusercontent.com/53595582/80205034-ed0b1700-8664-11ea-96c5-d4d6ec7075d8.png",
6 | "audio_url": null,
7 | "dev_fit": "천사표, 나는 다 좋아요 백엔드"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/public/Data/result.json:
--------------------------------------------------------------------------------
1 | {
2 | "result": {
3 | "name": "기브미관심 귀여운 답정너 프론트엔드",
4 | "description": "css는 미안해ㅜㅜ 대신 기능은 내가 책임져보겠다구우~!눈으로 무언가를 만들어 내는 것도 좋지만 로직을 생각하면 마음이 설레이는 당신.새로운 웹 사이트를 보면 빨리 저 기능을 구현해보고 싶어 마음이 콩닥콩닥 합니다.기능은 좋지만 css 만질 생각에 머리가 지끈거린다구요? 너무 걱정하지 마세요~ 지금은 완벽하지 않아도 괜찮아요~ css는 하다보면 익숙해 질 거예요.",
5 | "image_url": "https://user-images.githubusercontent.com/53595582/80205034-ed0b1700-8664-11ea-96c5-d4d6ec7075d8.png",
6 | "audio_url": null,
7 | "dev_fit": "천사표, 나는 다 좋아요 백엔드"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/public/Fonts/DungGeunMo.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/public/Fonts/DungGeunMo.ttf
--------------------------------------------------------------------------------
/public/Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/public/Logo.png
--------------------------------------------------------------------------------
/public/Logo3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/public/Logo3.png
--------------------------------------------------------------------------------
/public/Logo5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/public/Logo5.png
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
14 |
18 |
19 |
20 |
21 |
22 | BF-TEST
23 |
24 |
25 |
26 |
27 |
31 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/public/logo192.png
--------------------------------------------------------------------------------
/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/public/logo512.png
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/pull_request_template.md:
--------------------------------------------------------------------------------
1 | FB_test PR message template 및 체크 리스트 입니다.
2 | 아래 사항들을 전부 작성/체크 하시고 PR 해주세요!
3 |
4 | ## 수정 사항 간략한 한줄 요약
5 |
6 |
7 | ## 수정 사항들 자세한 내용
8 |
9 |
10 |
11 | ## 체크 리스트 (아래 사항들이 전부 체크되어야만 merge가 됩니다!)
12 | - [ ] 필요한 test들을 완료하였고 기능이 제대로 실행되는지 확인 하였습니다.
13 | - [ ] Airbnb의 코드 스타일 가이드에 맞추어 코드를 작성 하였습니다.
14 | - [ ] 제가 의도한 파일들과 수정 사항들만 커밋이 된 것을 확인 하였습니다.
15 | - [ ] 본 수정 사항들을 팀원들과 사전에 상의하였고 팀원들 모두 해당 PR에 대하여 알고 있습니다.
16 |
--------------------------------------------------------------------------------
/src/Components/About/About.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import { connect } from "react-redux";
3 | import { openDetail } from "Redux/Actions";
4 | import styled, { keyframes } from "styled-components";
5 | import WindowNav from "Components/ResultWindow/WindowNav";
6 | import AboutDetail from "Components/About/AboutDetail";
7 | import InfoData from "./AboutData";
8 | import MEMBERS from "Images/About/members.jpg";
9 | import CLICK from "Images/About/click.svg";
10 | import Footer from "Components/ResultWindow/Footer";
11 |
12 | const About = (props) => {
13 | const { detail, openDetail } = props;
14 | const [info, setInfo] = useState({});
15 |
16 | const Data = { InfoData }.InfoData;
17 |
18 | const handleOpenDetail = (id) => {
19 | setInfo(Data[id]);
20 | openDetail();
21 | };
22 |
23 | return (
24 |
25 |
26 |
27 |
28 |
29 | 안녕하세요!
30 |
31 | BF Test는 위코드 6기 수강생 7명이 모여 진행한 토이 프로젝트입니다.
32 |
33 |
34 | 코딩의 코자도 모르던 저희는 위코드를 통해 처음 코딩을 배우게 되었고,
35 | 백엔드와 프론트엔드를 선택하는 과정에서 어려움을 겪었습니다.
36 |
37 |
38 | 저희뿐만 아니라 코딩을 배우고자 결심하신 많은 분이 같은 고민을 겪었을
39 | 거라 생각했습니다. 그런 여러분들의 고민을 조금이나마 덜어드리고자 이번
40 | 프로젝트를 준비하게 됐습니다.
41 |
42 |
43 | 단순히 개인의 성향을 알아보는 심리 테스트이기 때문에 크게 의미 부여는
44 | 삼가해주세요! 참고용으로 가볍게 즐겨주시길 바랍니다.
45 |
46 |
47 | 그럼 다들 멋진 개발자로 성장하시길 응원합니다!!
48 |
49 |
50 |
51 |
52 |
53 | {Data.map((card) => {
54 | return (
55 | handleOpenDetail(card.id)}
59 | >
60 | {card.name}
61 |
62 | );
63 | })}
64 |
65 |
66 | click here
67 |
68 |
69 |
70 | {detail && }
71 |
72 |
73 |
74 | );
75 | };
76 |
77 | //내가 사용하고 싶은 state값 불러오기
78 | // ex) detail오픈하려면 reducer -> controlDetail에 있는 detail state값 가져와야해
79 | const mapStateToProps = (state) => {
80 | return {
81 | detail: state.controlDetail.detail,
82 | };
83 | };
84 |
85 | export default connect(mapStateToProps, { openDetail })(About);
86 |
87 | const AboutWrapper = styled.div`
88 | width: 750px;
89 | height: auto;
90 | border: 2px solid #000000;
91 | box-shadow: 13px 10px 0px -1px rgba(74, 79, 79, 1);
92 | position: absolute;
93 | top: 50%;
94 | left: 50%;
95 | transform: translate(-50%, -50%);
96 | z-index: 99;
97 |
98 | @media only screen and (max-width: 415px) {
99 | width: 100vw;
100 | height: 100vh;
101 | margin: 0;
102 | }
103 | `;
104 |
105 | const Section = styled.div`
106 | width: 100%;
107 | height: auto;
108 | background: #244c88;
109 | display: flex;
110 | flex-direction: column;
111 | align-items: center;
112 |
113 | @media only screen and (max-width: 415px) {
114 | height: 100%;
115 | }
116 | `;
117 |
118 | const Text = styled.div`
119 | width: 95%;
120 | font-size: 15px;
121 | color: #ffffff;
122 | line-height: 1.2;
123 | letter-spacing: 1px;
124 |
125 | @media only screen and (max-width: 415px) {
126 | height: 42%;
127 | overflow: scroll;
128 | }
129 |
130 | @media only screen and (max-width: 320px) {
131 | font-size: 0.8rem;
132 | }
133 | `;
134 |
135 | const ImgWrapper = styled.div`
136 | width: 60%;
137 |
138 | img {
139 | width: 100%;
140 | height: auto;
141 | margin: 20px auto 0;
142 | }
143 |
144 | @media only screen and (max-width: 420px) {
145 | width: 80%;
146 | }
147 | `;
148 |
149 | const Rainbow = styled.div`
150 | width: 100%;
151 | height: 20px;
152 | margin-bottom: 10px;
153 | display: flex;
154 |
155 | @media only screen and (max-width: 420px) {
156 | margin-bottom: 0;
157 | }
158 | `;
159 |
160 | const Color = styled.div`
161 | width: calc(100% / 7);
162 | height: 100%;
163 | text-align: center;
164 | cursor: pointer;
165 |
166 | @media only screen and (max-width: 420px) {
167 | font-size: 0.7rem;
168 | line-height: 1.7;
169 | }
170 |
171 | @media only screen and (max-width: 380px) {
172 | font-size: 0.6rem;
173 | line-height: 1.9;
174 | }
175 |
176 | &.red {
177 | background: red;
178 | }
179 | &.orange {
180 | background: orange;
181 | }
182 | &.yellow {
183 | background: yellow;
184 | }
185 | &.green {
186 | background: green;
187 | }
188 | &.blue {
189 | background: blue;
190 | }
191 | &.navy {
192 | background: navy;
193 | }
194 | &.purple {
195 | background: purple;
196 | }
197 | `;
198 |
199 | const drop = keyframes`
200 | from {
201 | opacity: 1;
202 | }
203 | to {
204 | opacity: 0;
205 | }
206 | `;
207 |
208 | const Click = styled.div`
209 | position: absolute;
210 | bottom: 25px;
211 | left: 100px;
212 | animation: ${drop} 1.5s linear infinite;
213 |
214 | h3 {
215 | color: #ffffff;
216 | transform: rotate(-30deg);
217 | }
218 |
219 | img {
220 | width: 40px;
221 | height: auto;
222 | }
223 |
224 | @media only screen and (max-width: 420px) {
225 | display: none;
226 | }
227 | `;
228 |
--------------------------------------------------------------------------------
/src/Components/About/AboutData.js:
--------------------------------------------------------------------------------
1 | const AboutData = [
2 | {
3 | id: 0,
4 | name: "HONG_DEV",
5 | img: "Hong.jpg",
6 | position: "Back-end",
7 | git: "https://github.com/hong-dev",
8 | insta: "https://www.instagram.com/hong._.dev",
9 | color: "red",
10 | },
11 | {
12 | id: 1,
13 | name: "CARMIN",
14 | img: "Carmin.jpg",
15 | position: "Front-end",
16 | git: "https://github.com/carminchameleon",
17 | insta: "https://instagram.com/hwanggee20",
18 | color: "orange",
19 | },
20 | {
21 | id: 2,
22 | name: "SUNNY",
23 | img: "Sunny.jpg",
24 | position: "Front-end",
25 | git: "https://github.com/sunghaeJoung",
26 | insta: "https://instagram.com/_sunghae__",
27 | color: "yellow",
28 | },
29 | {
30 | id: 3,
31 | name: "WHYBEIN",
32 | img: "Whybein.jpg",
33 | position: "Back-end",
34 | git: "https://github.com/whybein",
35 | insta: "https://instagram.com/whybein",
36 | color: "green",
37 | },
38 | {
39 | id: 4,
40 | name: "SOL",
41 | img: "Sol.jpg",
42 | position: "Front-end",
43 | git: "https://github.com/Wanderlust-sol",
44 | insta: "https://instagram.com/wanderlust_sol",
45 | color: "blue",
46 | },
47 | {
48 | id: 5,
49 | name: "AIDEN",
50 | img: "Aiden.jpg",
51 | position: "Front-end",
52 | git: "https://github.com/ki-hyeonkwon",
53 | insta: "https://www.instagram.com/1hr_1min/?hl=ko",
54 | color: "navy",
55 | },
56 | {
57 | id: 6,
58 | name: "KAY",
59 | img: "Kay.jpg",
60 | position: "Back-end",
61 | git: "https://github.com/k904808",
62 | insta: "https://www.instagram.com/kaaaaaaay_yoo/",
63 | color: "purple",
64 | },
65 | ];
66 |
67 | export default AboutData;
68 |
--------------------------------------------------------------------------------
/src/Components/About/AboutDetail.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styled from "styled-components";
3 | import { Github } from "@styled-icons/boxicons-logos";
4 | import { Instagram } from "@styled-icons/boxicons-logos";
5 | import WindowNav from "Components/ResultWindow/WindowNav";
6 | import BG from "Images/AboutDetail/BG.png";
7 |
8 | const AboutDetail = ({ data }) => {
9 | return (
10 |
11 |
12 |
40 |
41 | );
42 | };
43 |
44 | export default AboutDetail;
45 |
46 | const DetailWrapper = styled.div`
47 | width: 350px;
48 | border: 2px solid #000000;
49 | background: #699584;
50 | position: absolute;
51 | top: 15%;
52 | right: -35%;
53 | z-index: 999;
54 |
55 | @media only screen and (max-width: 1025px) {
56 | right: 5%;
57 | }
58 |
59 | @media only screen and (max-width: 420px) {
60 | right: 50%;
61 | transform: translateX(50%);
62 | }
63 |
64 | @media only screen and (max-width: 380px) {
65 | width: 90%;
66 | top: 8%;
67 | }
68 | `;
69 |
70 | const Section = styled.div`
71 | width: 100%;
72 | height: auto;
73 | background: url(${BG}) no-repeat center center;
74 | background-size: cover;
75 | display: flex;
76 | flex-direction: column;
77 | align-items: center;
78 | `;
79 |
80 | const Image = styled.img`
81 | width: 230px;
82 | height: 230px;
83 | border-radius: 50%;
84 | margin-top: 50px;
85 | `;
86 |
87 | const TextWrapper = styled.div`
88 | display: flex;
89 | flex-direction: column;
90 | align-items: center;
91 | margin: 20px 0 40px;
92 | width: 100%;
93 | min-width: 230px;
94 | `;
95 |
96 | const Name = styled.div`
97 | font-size: 50px;
98 | `;
99 |
100 | const Position = styled.div`
101 | font-size: 25px;
102 | margin-top: 10px;
103 | `;
104 |
105 | const LinkWrapper = styled.div`
106 | font-size: 20px;
107 | margin-top: 5px;
108 | display: flex;
109 | flex-direction: column;
110 | align-items: center;
111 | width: 100%;
112 | min-width: 230px;
113 | `;
114 |
115 | const Link = styled.div`
116 | margin-top: 3px;
117 | display: flex;
118 | justify-content: center;
119 | width: 100%;
120 | min-width: 230px;
121 | max-height: 20px;
122 |
123 | a {
124 | cursor: pointer;
125 | }
126 | .github {
127 | margin-left: 3px;
128 | }
129 | `;
130 |
131 | const GithubIcon = styled(Github)`
132 | width: 20px;
133 | height: auto;
134 | cursor: pointer;
135 | `;
136 |
137 | const InstaIcon = styled(Instagram)`
138 | width: 20px;
139 | height: auto;
140 | cursor: pointer;
141 | `;
142 |
--------------------------------------------------------------------------------
/src/Components/Nav.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import styled from "styled-components";
3 | import LOGO from "Images/Group6.png";
4 | import BTR from "Images/Nav/BTR.png";
5 | import SUN from "Images/Nav/SUN.png";
6 | import MOON from "Images/Nav/Moon.png";
7 |
8 | const Nav = () => {
9 | const [time, setTime] = useState("");
10 |
11 | let date = new Date();
12 | let hour = date.getHours();
13 | let minute = date.getMinutes();
14 | let second = date.getSeconds();
15 |
16 | // eslint-disable-next-line react-hooks/exhaustive-deps
17 | const timeCheck = () => {
18 | setTime(
19 | `${hour < 10 ? `0${hour}` : hour}:${
20 | minute < 10 ? `0${minute}` : minute
21 | }:${second < 10 ? `0${second}` : second}`
22 | );
23 | };
24 |
25 | useEffect(() => {
26 | const interval = setInterval(() => {
27 | timeCheck();
28 | }, 1000);
29 | return () => clearInterval(interval);
30 | }, [timeCheck]);
31 |
32 | return (
33 |
34 |
35 |
36 | Test
37 |
38 |
39 | {hour >= 7 && hour < 18 ? (
40 |
41 | ) : (
42 |
43 | )}
44 |
45 | {time}
46 |
47 |
48 | );
49 | };
50 |
51 | export default Nav;
52 |
53 | const NavWrapper = styled.div`
54 | width: 100%;
55 | height: 35px;
56 | font-size: 26px;
57 | background: #fdfd96;
58 | border-bottom: 2px solid #000000;
59 | display: flex;
60 | justify-content: space-between;
61 | align-items: center;
62 |
63 | @media only screen and (max-width: 415px) {
64 | height: 30px;
65 | }
66 | `;
67 |
68 | const NavLeft = styled.div`
69 | margin-left: 10px;
70 | display: flex;
71 | align-items: center;
72 |
73 | .logo {
74 | width: 25px;
75 | height: auto;
76 | cursor: pointer;
77 | }
78 |
79 | div {
80 | margin-left: 10px;
81 | }
82 |
83 | @media only screen and (max-width: 415px) {
84 | margin-left: 2px;
85 |
86 | .logo {
87 | width: 1.3rem;
88 | }
89 | div {
90 | font-size: 1.3rem;
91 | margin-left: 5px;
92 | margin-bottom: 2px;
93 | }
94 | }
95 | `;
96 |
97 | const NavRight = styled.div`
98 | font-size: 26px;
99 | margin-right: 10px;
100 | display: flex;
101 | align-items: center;
102 |
103 | .sun {
104 | width: 25px;
105 | height: auto;
106 | }
107 |
108 | .moon {
109 | width: 10px;
110 | height: auto;
111 | transform: rotate(45deg);
112 | margin-right: 5px;
113 | }
114 |
115 | .battery {
116 | width: 40px;
117 | height: auto;
118 | margin: 0 10px;
119 | }
120 |
121 | @media only screen and (max-width: 415px) {
122 | margin-right: 5px;
123 | .sun {
124 | width: 1.3rem;
125 | }
126 |
127 | .moon {
128 | width: 0.4rem;
129 | }
130 |
131 | .battery {
132 | width: 2.3rem;
133 | margin: 0 3px;
134 | }
135 | div {
136 | font-size: 1.3rem;
137 | margin-bottom: 2px;
138 | }
139 | }
140 | `;
141 |
--------------------------------------------------------------------------------
/src/Components/ProgressBar.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useLayoutEffect } from "react";
2 | import axios from "axios";
3 | import { URL } from "config";
4 | import { connect } from "react-redux";
5 | import { showResult, addResult, closeQuestion } from "Redux/Actions";
6 | import styled from "styled-components";
7 | import Dog from "Images/Progress/Dog.png";
8 | import HomeBF from "Images/Progress/home_bf.png";
9 | import Home from "Images/Progress/home.png";
10 |
11 | const ProgressBar = (props) => {
12 | const { res, showResult, addResult, closeQuestion } = props;
13 | const [progress, setProgress] = useState(0);
14 | const [popupResult, setPopupResult] = useState(false);
15 |
16 | const clickResult = async () => {
17 | try {
18 | const res = await axios.post(`${URL}/poll/result`, {
19 | answer: props.postData[0][0],
20 | type: props.postData[1],
21 | });
22 | addResult(res.data.result);
23 | } catch (err) {
24 | console.log("err", err);
25 | }
26 | showResult();
27 | closeQuestion();
28 | };
29 |
30 | useLayoutEffect(() => {
31 | const interval =
32 | progress < 100 &&
33 | setInterval(() => {
34 | setProgress(progress + 1);
35 | }, 50);
36 | progress === 100 && setPopupResult(true);
37 | return () => clearInterval(interval);
38 | }, [progress]);
39 |
40 | return (
41 | <>
42 |
43 | 잠시만 기다려주세요...!
44 |
45 |
46 |
47 |
48 |
49 |
50 | 결과보기
51 |
52 |
53 | >
54 | );
55 | };
56 |
57 | const mapStateToProps = (state) => {
58 | return {
59 | res: state.controlResult.res,
60 | ques: state.controlQuestion.res,
61 | };
62 | };
63 |
64 | export default connect(mapStateToProps, {
65 | showResult,
66 | addResult,
67 | closeQuestion,
68 | })(ProgressBar);
69 |
70 | const Wrapper = styled.div`
71 | width: 100%;
72 | height: 100%;
73 | display: flex;
74 | justify-content: center;
75 | align-items: center;
76 | flex-direction: column;
77 | `;
78 |
79 | const Title = styled.div`
80 | width: 80%;
81 | height: 50px;
82 | font-size: 20px;
83 | color: white;
84 | border: 2px solid white;
85 | display: flex;
86 | justify-content: center;
87 | align-items: center;
88 | margin-bottom: 100px;
89 | `;
90 |
91 | const ProgressBox = styled.div`
92 | width: 80%;
93 | height: 30px;
94 | border: 2px solid white;
95 | position: relative;
96 | `;
97 |
98 | const MovingDog = styled.div`
99 | width: 40px;
100 | height: 40px;
101 | background: url('${Dog}') no-repeat;
102 | background-position-x: ${(props) =>
103 | props.progress % 2 ? "5px" : "-35.5px"};
104 | background-size: 75px;
105 | position: absolute;
106 | top: -35px;
107 | left: ${(props) => props.progress * 5}px;
108 | z-index: 5;
109 |
110 | @media only screen and (max-width: 720px) {
111 | left: ${(props) => props.progress - 11}%;
112 | }
113 |
114 | @media only screen and (max-width: 415px) {
115 | left: ${(props) => props.progress - 14}%;
116 | }
117 | `;
118 | const HomeDog = styled.div`
119 | width: 60px;
120 | height: 60px;
121 | background: url('${(props) =>
122 | props.progress % 2 ? Home : HomeBF}') no-repeat;
123 | background-size: cover;
124 | position: absolute;
125 | top: -52px;
126 | right: -11px;
127 | z-index: 10;
128 |
129 | `;
130 | const InProgress = styled.div`
131 | width: ${(props) => props.progress && props.progress}%;
132 | height: 100%;
133 | position: absolute;
134 | background-color: white;
135 | left: 0;
136 | top: 0;
137 | `;
138 |
139 | const Result = styled.div`
140 | width: 100px;
141 | height: 50px;
142 | font-size: 20px;
143 | color: white;
144 | border: 2px solid white;
145 | display: flex;
146 | justify-content: center;
147 | align-items: center;
148 | margin-top: 30px;
149 | cursor: pointer;
150 |
151 | visibility: ${(props) => (props.popupResult ? "visible" : "hidden")};
152 | `;
153 |
--------------------------------------------------------------------------------
/src/Components/Question/QuestionMain.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import axios from "axios";
3 | import { URL } from "config";
4 | import styled from "styled-components";
5 |
6 | const QuestionMain = (props) => {
7 | const [quesData, setData] = useState({});
8 | const [quesNum, setQuesNum] = useState(1);
9 | const [quesNumUrl, setQuesNumUrl] = useState(1);
10 | // const [pickedData, setPickData] = useState({});
11 | const [type, setType] = useState();
12 | const [sendResult, setSendResult] = useState(false);
13 |
14 | const clickChoice = (index) => {
15 | // setFinished(false);
16 | // 밑에 두 줄은 마지막 문제일 때, 결과보내는 용
17 | setSendResult(true);
18 |
19 | setQuesNum(quesNum + 1);
20 | //quesNumUrl를 이용해서 데이터 통신을 해야힘
21 | setQuesNumUrl(quesNumUrl + 1);
22 |
23 | // setPickData({ ...pickedData, [quesData.id]: quesData.choice[index].id });
24 | props.getKeyValue(quesData.id, quesData.choice[index].id);
25 |
26 | if (quesNum === 13) {
27 | if (quesNumUrl === 14) {
28 | if (index === 0) {
29 | setType("A");
30 | props.getData(type);
31 | props.getLoadingStatus(true);
32 | } else {
33 | setType("B");
34 | props.getData(type);
35 | props.getLoadingStatus(true);
36 | }
37 | } else if (quesNumUrl === 15) {
38 | setType("A");
39 | props.getData(type);
40 | props.getLoadingStatus(true);
41 | } else {
42 | setType("C");
43 | props.getData(type);
44 | props.getLoadingStatus(true);
45 | }
46 | } else {
47 | if (quesNumUrl === 11) {
48 | if (index === 0) {
49 | setQuesNumUrl(quesNumUrl + 1);
50 | // console.log("11번문제 1번 선택", quesNumUrl + 1);
51 | } else {
52 | setQuesNumUrl(quesNumUrl + 2);
53 | // console.log("11번문제 2번 선택", quesNumUrl + 2);
54 | }
55 | } else if (quesNumUrl === 12) {
56 | if (index === 0) {
57 | setQuesNumUrl(quesNumUrl + 2);
58 | // console.log("12번문제 1번 선택", quesNumUrl + 3);
59 | } else {
60 | setQuesNumUrl(quesNumUrl + 3);
61 | // console.log("12번문제 2번 선택", quesNumUrl + 2);
62 | }
63 | } else if (quesNumUrl === 13) {
64 | if (index === 0) {
65 | setQuesNumUrl(quesNumUrl + 1);
66 | // console.log("13번문제 1번 선택", quesNumUrl + 1);
67 | } else {
68 | setQuesNumUrl(quesNumUrl + 3);
69 | // console.log("12번문제 2번 선택", quesNumUrl + 3);
70 | }
71 | }
72 | }
73 | };
74 |
75 | // console.log("타입들어가는지 확인중", pickedData);
76 | const fetchFirstQuestion = async () => {
77 | try {
78 | const gotFirstQues = await axios.get(`${URL}/poll/${quesNumUrl}`);
79 | const data = await gotFirstQues.data.question_data;
80 |
81 | setData(data);
82 | // setAppearChoice(false);
83 | } catch (error) {
84 | console.log(error);
85 | alert("다시 시도 바랍니다.");
86 | }
87 | };
88 |
89 | // setTimeout을 데이터 통신에 사용하는 것이 아닌 id값을 가지고 1일때, setTimeout을 해준다.
90 | useEffect(() => {
91 | if (quesNum === 1) {
92 | setTimeout(() => {
93 | fetchFirstQuestion();
94 | }, 13500);
95 | } else if (quesNum === 14) {
96 | props.getData(type);
97 | props.getLoadingStatus(true);
98 | } else {
99 | fetchFirstQuestion();
100 | }
101 | // eslint-disable-next-line react-hooks/exhaustive-deps
102 | }, [quesNum]);
103 |
104 | return quesData.choice ? (
105 |
106 |
107 |
108 |
109 | {quesNum}. {quesData.question}
110 |
111 |
112 | {quesData.image_url ? (
113 |
114 |
115 |
116 | ) : (
117 | ""
118 | )}
119 |
120 | clickChoice(0)}>
121 | {quesData.choice[0].choice}
122 |
123 | clickChoice(1)}>
124 | {quesData.choice[1].choice}
125 |
126 |
127 |
128 |
129 | ) : (
130 |
131 | );
132 | };
133 | export default QuestionMain;
134 |
135 | const QBoxWrapper = styled.div`
136 | width: 90%;
137 | margin: 35px auto 0 auto;
138 | display: ${(props) => (props.loading ? "none" : "block")};
139 |
140 | @media only screen and (max-width: 415px) {
141 | margin: 20px auto 0 auto;
142 | }
143 | @media only screen and (max-width: 330px) {
144 | margin: 10px auto 0 auto;
145 | }
146 | `;
147 |
148 | const QBoxContainer = styled.div`
149 | width: 100%;
150 | display: flex;
151 | flex-direction: column;
152 | `;
153 |
154 | const QuestionBox = styled.div`
155 | font-size: 22px;
156 | color: white;
157 | line-height: 35px;
158 |
159 | @media only screen and (max-width: 415px) {
160 | font-size: 1.2rem;
161 | }
162 | @media only screen and (max-width: 320px) {
163 | font-size: 16px;
164 | }
165 | `;
166 |
167 | const QImgBox = styled.div`
168 | margin: 10px auto 0;
169 | text-align: center;
170 | @media only screen and (max-width: 415px) {
171 | margin: 20px auto 10px;
172 | }
173 | @media only screen and (max-width: 330px) {
174 | margin: 20px auto 10px;
175 | }
176 | `;
177 |
178 | const QImg = styled.img`
179 | width: 60%;
180 |
181 | @media only screen and (max-width: 415px) {
182 | width: 80%;
183 | }
184 | `;
185 |
186 | const TextSelectBox = styled.div``;
187 |
188 | const SelectOutLineDiv = styled.div`
189 | width: 100%;
190 | border: 1px solid white;
191 | margin-top: 20px;
192 | padding: 2px;
193 | display: ${(props) => (props.display ? "block" : "none")};
194 | display: block;
195 | `;
196 |
197 | const TextSelect = styled.div`
198 | color: white;
199 | border: 1px solid white;
200 | font-size: 18px;
201 | padding: 13px;
202 | &:hover {
203 | color: #244c88;
204 | background-color: white;
205 | }
206 | cursor: pointer;
207 |
208 | @media only screen and (max-width: 800px) {
209 | &:hover {
210 | color: white;
211 | background-color: #244c88;
212 | }
213 | -webkit-autofill:hover {
214 | color: white;
215 | background-color: #244c88;
216 | }
217 | }
218 |
219 | @media only screen and (max-width: 320px) {
220 | font-size: 16px;
221 | &:hover {
222 | color: white;
223 | background-color: #244c88;
224 | }
225 | }
226 | `;
227 |
--------------------------------------------------------------------------------
/src/Components/Question/QuestionWindow.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import styled from "styled-components";
3 | import Typing from "react-typing-animation";
4 | import QuestionMain from "Components/Question/QuestionMain";
5 | import WindowNav from "Components/ResultWindow/WindowNav";
6 | import ProgressBar from "Components/ProgressBar";
7 | import Footer from "Components/ResultWindow/Footer";
8 |
9 | const typeSpeed = 20;
10 |
11 | const QuestionWindow = (props) => {
12 | const [loading, setLoading] = useState(false);
13 | // const [postData, setPostData] = useState([]);
14 | const [practice, setPractice] = useState([]);
15 |
16 | const getLoadingStatus = (status) => {
17 | setTimeout(setLoading(status), 2000);
18 | };
19 |
20 | const getData = (typeData) => {
21 | //postData 는 문제(키:벨류)/ type는 type
22 | const result = [practice, typeData];
23 | setPractice(result);
24 | };
25 |
26 | const getKeyValue = (quesData, id) => {
27 | setPractice({ ...practice, [quesData]: id });
28 | };
29 |
30 | return (
31 |
32 |
33 |
34 |
35 |
36 | 준비되셨나요 . . . ?
37 |
42 |
43 |
44 |
45 |
46 | 자, 그럼 당신의 성향을 알려줄 BF - TEST 를 시작하겠습니다. . . !!!
47 |
48 |
53 |
54 |
55 |
56 |
57 | ⚠️ 선택 시 다시 선택하실 수 없으니 신중히 선택해주시기 바랍니다.
58 | ⚠️
59 |
60 |
65 |
66 |
67 | getLoadingStatus(status)}
69 | getData={(type) => {
70 | getData(type);
71 | }}
72 | loading={loading}
73 | getKeyValue={(quesData, id) => getKeyValue(quesData, id)}
74 | >
75 | {loading && }
76 |
77 |
78 |
79 |
80 | );
81 | };
82 |
83 | export default QuestionWindow;
84 |
85 | // 추후에 컴포넌트로 사용될 시 이 컴포넌트를 감싸는 div는 position:relative 를 가지고 있어야한다.
86 |
87 | const QuestionsWrapper = styled.div`
88 | position: absolute;
89 | top: 50%;
90 | left: 50%;
91 | border: 2px solid #000000;
92 | box-shadow: 13px 10px 0px -1px rgba(74, 79, 79, 1);
93 | transform: translate(-50%, -50%);
94 |
95 | @media only screen and (max-width: 720px) {
96 | width: 100vw;
97 | height: 100vh;
98 | }
99 | `;
100 |
101 | const QuestionsContainer = styled.div`
102 | width: 700px;
103 |
104 | @media only screen and (max-width: 720px) {
105 | width: 100vw;
106 | box-shadow: none;
107 | border: none;
108 | }
109 | `;
110 |
111 | // window header
112 |
113 | // window
114 | const QuestionMainDiv = styled.div`
115 | width: 100%;
116 | height: 626px;
117 | // border: 3px solid black;
118 | border-top: 3px;
119 | background-color: #244c88;
120 | position: relative;
121 | padding: 10px;
122 | span {
123 | color: white;
124 | font-size: 18px;
125 | }
126 | @media only screen and (max-width: 720px) {
127 | width: 100vw;
128 | height: 100vh;
129 | }
130 | span {
131 | @media only screen and (max-width: 320px) {
132 | font-size: 16px;
133 | }
134 | }
135 | `;
136 |
--------------------------------------------------------------------------------
/src/Components/ResultWindow/Alert.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styled from "styled-components";
3 |
4 | const Alert = () => {
5 | return (
6 |
7 | ⚠️ 테스트를 진행해주세요 ⚠️
8 |
9 | );
10 | };
11 | export default Alert;
12 |
13 | const AlertWindow = styled.div`
14 | margin: 10px;
15 | color: white;
16 | display: flex;
17 | flex-direction: column;
18 |
19 | @media only screen and (max-width: 415px) {
20 | margin: 0px;
21 | width: 100%;
22 | height: 100%;
23 | box-shadow: none;
24 | padding-top: 55%;
25 | display: block;
26 | }
27 | `;
28 |
29 | const AlertMessage = styled.div`
30 | margin: 10px;
31 | text-align: center;
32 | line-height: 1.4rem;
33 | font-size: 1.2rem;
34 | `;
35 |
--------------------------------------------------------------------------------
/src/Components/ResultWindow/Footer.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styled from "styled-components";
3 |
4 | const Footer = (data) => {
5 | const goToWecode = () => {
6 | window.open("https://wecode.co.kr/");
7 | };
8 |
9 | return (
10 | goToWecode()}>
11 |
12 |
13 |
14 |
15 | );
16 | };
17 |
18 | export default Footer;
19 |
20 | const FooterContainer = styled.div`
21 | display: none;
22 | @media only screen and (max-width: 415px) {
23 | border-top: 2px solid black;
24 | width: 100%;
25 | height: 30px;
26 | display: block;
27 | background-color: #0312ef;
28 | display: flex;
29 | flex-direction: row;
30 | justify-content: center;
31 | position: relative;
32 | z-index: 99999;
33 | }
34 | `;
35 |
36 | const WecodeIconBox = styled.div`
37 | display: flex;
38 | flex-direction: column;
39 | justify-content: center;
40 | margin: 0 auto;
41 | `;
42 | const WecodeIcon = styled.img`
43 | width: 70px;
44 | height: 13px;
45 | `;
46 |
--------------------------------------------------------------------------------
/src/Components/ResultWindow/Result.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import { connect } from "react-redux";
3 | import styled, { keyframes } from "styled-components";
4 | import WindowNav from "./WindowNav";
5 | import About from "Components/About/About";
6 | import Footer from "./Footer";
7 | import Alert from "./Alert";
8 | const Result = (props) => {
9 | const { type } = props;
10 | const [typeName, setTypeName] = useState("");
11 | const [about, setAbout] = useState(false);
12 | const [data, getData] = useState(false);
13 | useEffect(() => {
14 | if (props.type.name !== undefined) {
15 | getData(true);
16 | handleType(type.name);
17 | } else {
18 | }
19 | // eslint-disable-next-line react-hooks/exhaustive-deps
20 | }, [type.name]);
21 |
22 | const handleType = (name) => {
23 | const lastLetter = name[name.length - 3];
24 | if (lastLetter === "풀") {
25 | setTypeName("Full-Stack Developer");
26 | } else if (lastLetter === "트") {
27 | setTypeName("Front-End Developer");
28 | } else {
29 | setTypeName("Back-End Developer");
30 | }
31 | };
32 |
33 | return (
34 |
35 |
36 | {data ? (
37 |
38 |
39 |
40 |
41 | Your BF test result is:
42 |
43 |
44 | →
45 | ~
46 | {typeName}
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | {type.name}
59 | {type.description}
60 |
61 |
62 |
63 |
64 |
65 |
66 | Your ideal project team member is:
67 |
68 |
69 | →
70 | ~
71 | {type.dev_fit}
72 |
73 |
74 |
75 |
76 | {
78 | setAbout(true);
79 | }}
80 | src="https://user-images.githubusercontent.com/53595582/80459619-94da5a80-896d-11ea-804c-ebecc535d637.png"
81 | >
82 |
83 |
84 | ) : (
85 |
86 | )}
87 |
88 | {about && }
89 |
90 |
91 | );
92 | };
93 |
94 | const mapStateToProps = (state) => {
95 | return {
96 | type: state.getResult,
97 | };
98 | };
99 |
100 | export default connect(mapStateToProps)(Result);
101 |
102 | const Container = styled.div`
103 | margin: 0 auto;
104 | width: 700px;
105 | border: 2px solid black;
106 | background-color: black;
107 | display: flex;
108 | flex-direction: column;
109 | justify-content: start;
110 | box-shadow: 13px 10px 0px -1px rgba(74, 79, 79, 1);
111 | z-index: 10;
112 |
113 | @media only screen and (max-width: 415px) {
114 | width: 100vw;
115 | height: 100vh;
116 | box-shadow: none;
117 | margin: 0;
118 | padding: 0;
119 | overflow: hidden;
120 | overflow-y: scroll;
121 | border-left: 0;
122 | border-right: 0;
123 | }
124 | `;
125 |
126 | const BodyWrapper = styled.div`
127 | @media only screen and (max-width: 415px) {
128 | display: flex;
129 | flex-direction: column;
130 | justify-content: space-between;
131 | height: 100%;
132 | }
133 | `;
134 |
135 | const Body = styled.div`
136 | display: flex;
137 | flex-direction: column;
138 | justify-content: flex-start;
139 | @media only screen and (max-width: 415px) {
140 | }
141 | `;
142 |
143 | const TypeContainer = styled.div`
144 | margin-top: 10px;
145 | margin-left: 10px;
146 | font-size: 22px;
147 | line-height: 1.9rem;
148 | color: white;
149 | position: relative;
150 | @media only screen and (max-width: 415px) {
151 | margin-top: 0px;
152 | font-size: 1.2rem;
153 | line-height: 1rem;
154 | }
155 | `;
156 | const TypeTitleBox = styled.div``;
157 |
158 | const TitleName = styled.span`
159 | font-size: 22px;
160 | @media only screen and (max-width: 415px) {
161 | font-size: 1.1rem;
162 | line-height: 1.2rem;
163 | }
164 | @media only screen and (max-width: 320px) and (min-height: 568px) {
165 | font-size: 0.8rem;
166 | line-height: 1rem;
167 | }
168 | @media only screen and (max-width: 320px) and (min-height: 568px) {
169 | font-size: 0.8rem;
170 | }
171 | `;
172 | const TypeResultBox = styled.span``;
173 |
174 | const Arrow = styled.span`
175 | margin-right: 4px;
176 | `;
177 |
178 | const Wave = styled.span`
179 | font-family: Arial, Helvetica, sans-serif;
180 | font-size: 19px;
181 | color: #39dbaa;
182 | `;
183 |
184 | const ResultContainer = styled.div`
185 | margin-top: 10px;
186 | width: 100%;
187 | display: flex;
188 | flex-direction: row;
189 | justify-content: start;
190 | @media only screen and (max-width: 700px) {
191 | flex-direction: column;
192 | justify-content: center;
193 | }
194 | @media only screen and (max-width: 415px) {
195 | display: block;
196 | }
197 | @media only screen and (max-width: 375px) and (max-height: 667px) {
198 | display: block;
199 | }
200 | `;
201 |
202 | const CardContainer = styled.div`
203 | margin-left: 2%;
204 | @media only screen and (max-width: 415px) {
205 | margin: 0;
206 | }
207 | `;
208 |
209 | const CardBox = styled.div`
210 | display: flex;
211 | flex-direction: row;
212 | @media only screen and (max-width: 700px) {
213 | justify-content: center;
214 | margin-bottom: 10px;
215 | }
216 | @media only screen and (max-width: 415px) {
217 | justify-content: center;
218 | margin-bottom: 10px;
219 | }
220 | `;
221 |
222 | const CardImg = styled.img`
223 | width: 246px;
224 | height: 326px;
225 | @media only screen and (max-width: 700px) {
226 | width: 226px;
227 | height: 306px;
228 | }
229 | @media only screen and (max-width: 415px) {
230 | width: 50%;
231 | height: 50%;
232 | }
233 | @media only screen and (max-height: 667px) and (max-width: 375px) {
234 | width: 44%;
235 | height: 44%;
236 | }
237 | @media only screen and (max-width: 375px) and (min-height: 668px) {
238 | width: 226px;
239 | height: 306px;
240 | }
241 | @media only screen and (max-width: 320px) and (min-height: 568px) {
242 | width: 40%;
243 | height: 40%;
244 | }
245 | `;
246 |
247 | const ContentContainer = styled.div`
248 | color: white;
249 | width: 100%;
250 | position: relative;
251 | display: flex;
252 | flex-direction: row;
253 | justify-content: center;
254 | position: relative;
255 | max-height: 326px;
256 | @media only screen and (max-width: 415px) {
257 | }
258 | /* iphone 6/7/8 size */
259 | @media only screen and (max-width: 375px) and (max-height: 667px) {
260 | min-height: 198px;
261 | }
262 | /* iphone X size */
263 | @media only screen and (max-width: 375px) and (min-height: 668px) {
264 | min-height: 214px;
265 | }
266 | `;
267 | const ContentWrapper = styled.div`
268 | width: 93%;
269 | border: 1.5px solid white;
270 | display: flex;
271 | flex-direction: column;
272 | justify-content: start;
273 | padding: 2px;
274 | `;
275 |
276 | const ContentInner = styled.div`
277 | height: 100%;
278 | border: 1.5px solid white;
279 | text-align: center;
280 | @media only screen and (max-width: 415px) {
281 | }
282 | `;
283 |
284 | const TypeName = styled.div`
285 | border: 2px dotted white;
286 | margin: 10px;
287 | line-height: 2rem;
288 | font-size: 18px;
289 | @media only screen and (max-width: 415px) {
290 | font-size: 0.9rem;
291 | line-height: 1.5rem;
292 | }
293 | /* iphone 6/7/8 size */
294 | @media only screen and (max-width: 375px) and (max-height: 667px) {
295 | font-size: 0.8rem;
296 | line-height: 1.6rem;
297 | }
298 | /* iphone X size */
299 | @media only screen and (max-width: 375px) and (min-height: 668px) {
300 | }
301 | @media only screen and (max-width: 320px) and (min-height: 568px) {
302 | font-size: 0.6rem;
303 | line-height: 0.9rem;
304 | }
305 | `;
306 |
307 | const TypeContents = styled.div`
308 | text-align: justify;
309 | font-size: 17px;
310 | margin: 10px;
311 | line-height: 1.4rem;
312 | letter-spacing: 0.4px;
313 | @media only screen and (max-width: 415px) {
314 | font-size: 0.9rem;
315 | line-height: 1.1rem;
316 | }
317 | /* iphone 6/7/8 size */
318 | @media only screen and (max-width: 375px) and (max-height: 667px) {
319 | font-size: 0.8rem;
320 | }
321 | /* iphone X size */
322 | @media only screen and (max-width: 375px) and (min-height: 668px) {
323 | font-size: 1rem;
324 | }
325 | /* iphone se, 5 */
326 | @media only screen and (max-width: 320px) and (min-height: 568px) {
327 | font-size: 0.6rem;
328 | margin-bottom: 0px;
329 | margin-top: 0px;
330 | }
331 | `;
332 |
333 | const RecommendContainer = styled.div`
334 | margin-top: 10px;
335 | margin-left: 10px;
336 | font-size: 1.6rem;
337 | line-height: 2rem;
338 | color: white;
339 | position: relative;
340 | margin-bottom: 10px;
341 | @media only screen and (max-width: 415px) {
342 | font-size: 1.2rem;
343 | line-height: 1.2rem;
344 | margin-bottom: 0px;
345 | }
346 |
347 | @media only screen and (max-width: 320px) and (min-height: 568px) {
348 | margin-top: 4px;
349 | }
350 | `;
351 |
352 | const FitTypeName = styled.span`
353 | font-size: 19px;
354 | @media only screen and (max-width: 970px) {
355 | font-size: 1.1rem;
356 | }
357 | @media only screen and (max-width: 415px) {
358 | font-size: 0.9rem;
359 | }
360 | @media only screen and (max-width: 320px) and (min-height: 568px) {
361 | font-size: 0.7rem;
362 | line-height: 0.8rem;
363 | }
364 | `;
365 |
366 | const drop = keyframes`
367 | from {
368 | opacity: 1;
369 | }
370 | to {
371 | opacity: 0;
372 | }
373 | `;
374 |
375 | const ShareBox = styled.div`
376 | display: none;
377 | @media only screen and (max-width: 415px) {
378 | /* position: absolute;
379 | right: -10px; */
380 | /* bottom: 3px; */
381 | display: inline-block;
382 | color: white;
383 | display: flex;
384 | flex-direction: row;
385 | justify-content: flex-end;
386 | cursor: pointer;
387 | animation: ${drop} 1.5s linear infinite;
388 | }
389 | `;
390 |
391 | const GlobeIcon = styled.img`
392 | width: 55px;
393 | margin-right: 10px;
394 | height: 55px;
395 | @media only screen and (max-width: 415px) {
396 | width: 65px;
397 | height: 65px;
398 | }
399 | @media only screen and (max-width: 375px) and (max-height: 667px) {
400 | width: 65px;
401 | height: 65px;
402 | }
403 | /* iphone X size */
404 | @media only screen and (max-width: 375px) and (min-height: 668px) {
405 | width: 65px;
406 | height: 65px;
407 | }
408 | `;
409 |
--------------------------------------------------------------------------------
/src/Components/ResultWindow/WindowNav.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { connect } from "react-redux";
3 | import {
4 | closeDetail,
5 | closeAbout,
6 | closeResult,
7 | closeQuestion,
8 | } from "Redux/Actions";
9 | import styled from "styled-components";
10 | import LOGO from "Images/Group6.png";
11 | import CLOSEICON from "Images/Nav/close.png";
12 | import EXPANDICON from "Images/Nav/expand.png";
13 | import MINICON from "Images/Nav/min.png";
14 |
15 | const WindowNav = (props) => {
16 | const {
17 | detail,
18 | about,
19 | title,
20 | res,
21 | ques,
22 | closeDetail,
23 | closeAbout,
24 | closeResult,
25 | closeQuestion,
26 | } = props;
27 |
28 | const handleClose = () => {
29 | if (detail) {
30 | closeDetail();
31 | } else if (about) {
32 | closeAbout();
33 | } else if (res) {
34 | closeResult();
35 | } else if (ques) {
36 | closeQuestion();
37 | }
38 | };
39 |
40 | return (
41 |
42 |
43 |
44 | {title}
45 |
46 |
47 |
48 |
49 | {
52 | handleClose();
53 | }}
54 | >
55 |
56 |
57 | );
58 | };
59 |
60 | const mapStateToProps = (state) => {
61 | return {
62 | detail: state.controlDetail.detail,
63 | about: state.controlAbout.about,
64 | res: state.controlResult.res,
65 | ques: state.controlQuestion.ques,
66 | };
67 | };
68 |
69 | export default connect(mapStateToProps, {
70 | closeDetail,
71 | closeAbout,
72 | closeResult,
73 | closeQuestion,
74 | })(WindowNav);
75 |
76 | const NavContainer = styled.nav`
77 | width: 100%;
78 | height: 30px;
79 | font-size: 26px;
80 | background-color: #fdfd96;
81 | border-bottom: 2px solid black;
82 | display: flex;
83 | justify-content: space-between;
84 | align-items: center;
85 | `;
86 |
87 | const NavLeft = styled.div`
88 | margin-left: 10px;
89 | display: flex;
90 | align-items: center;
91 |
92 | .logo {
93 | width: 23px;
94 | height: auto;
95 | cursor: pointer;
96 | }
97 |
98 | div {
99 | font-size: 24px;
100 | margin-left: 10px;
101 | }
102 |
103 | @media only screen and (max-width: 415px) {
104 | margin-left: 2px;
105 |
106 | .logo {
107 | width: 1.3rem;
108 | }
109 | div {
110 | font-size: 1.3rem;
111 | margin-left: 5px;
112 | margin-bottom: 2px;
113 | }
114 | }
115 | `;
116 |
117 | const NavRight = styled.div`
118 | margin-right: 10px;
119 | display: flex;
120 | align-items: center;
121 |
122 | @media only screen and (max-width: 415px) {
123 | margin-right: 5px;
124 | }
125 | `;
126 |
127 | const Min = styled.img`
128 | width: 23px;
129 | height: auto;
130 | cursor: pointer;
131 |
132 | @media only screen and (max-width: 415px) {
133 | width: 21px;
134 | }
135 | `;
136 |
137 | const Expand = styled.img`
138 | width: 23px;
139 | height: auto;
140 | margin: 0 5px;
141 | cursor: pointer;
142 |
143 | @media only screen and (max-width: 415px) {
144 | width: 21px;
145 | }
146 | `;
147 | const Close = styled.img`
148 | width: 23px;
149 | height: auto;
150 | cursor: pointer;
151 |
152 | @media only screen and (max-width: 415px) {
153 | width: 21px;
154 | }
155 | `;
156 |
--------------------------------------------------------------------------------
/src/Images/About/click.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/Images/About/members.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/About/members.jpg
--------------------------------------------------------------------------------
/src/Images/AboutDetail/Aiden.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/AboutDetail/Aiden.jpg
--------------------------------------------------------------------------------
/src/Images/AboutDetail/BG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/AboutDetail/BG.png
--------------------------------------------------------------------------------
/src/Images/AboutDetail/Carmin.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/AboutDetail/Carmin.jpg
--------------------------------------------------------------------------------
/src/Images/AboutDetail/Hong.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/AboutDetail/Hong.jpg
--------------------------------------------------------------------------------
/src/Images/AboutDetail/Kay.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/AboutDetail/Kay.jpg
--------------------------------------------------------------------------------
/src/Images/AboutDetail/Sol.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/AboutDetail/Sol.jpg
--------------------------------------------------------------------------------
/src/Images/AboutDetail/Sunny.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/AboutDetail/Sunny.jpg
--------------------------------------------------------------------------------
/src/Images/AboutDetail/Whybein.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/AboutDetail/Whybein.jpg
--------------------------------------------------------------------------------
/src/Images/Group6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/Group6.png
--------------------------------------------------------------------------------
/src/Images/Main/Record.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/Main/Record.png
--------------------------------------------------------------------------------
/src/Images/Main/WeTV.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/Main/WeTV.png
--------------------------------------------------------------------------------
/src/Images/Main/computer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/Main/computer.png
--------------------------------------------------------------------------------
/src/Images/Main/quiz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/Main/quiz.png
--------------------------------------------------------------------------------
/src/Images/Main/trash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/Main/trash.png
--------------------------------------------------------------------------------
/src/Images/Nav/BF Blue Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/Nav/BF Blue Logo.png
--------------------------------------------------------------------------------
/src/Images/Nav/BTR.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/Nav/BTR.png
--------------------------------------------------------------------------------
/src/Images/Nav/Moon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/Nav/Moon.png
--------------------------------------------------------------------------------
/src/Images/Nav/SUN.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/Nav/SUN.png
--------------------------------------------------------------------------------
/src/Images/Nav/close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/Nav/close.png
--------------------------------------------------------------------------------
/src/Images/Nav/expand.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/Nav/expand.png
--------------------------------------------------------------------------------
/src/Images/Nav/min.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/Nav/min.png
--------------------------------------------------------------------------------
/src/Images/Nav/wecode black logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/Nav/wecode black logo.png
--------------------------------------------------------------------------------
/src/Images/Progress/Dog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/Progress/Dog.png
--------------------------------------------------------------------------------
/src/Images/Progress/home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/Progress/home.png
--------------------------------------------------------------------------------
/src/Images/Progress/home_bf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/Progress/home_bf.png
--------------------------------------------------------------------------------
/src/Images/ReadMe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/ReadMe.png
--------------------------------------------------------------------------------
/src/Images/art1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/art1.png
--------------------------------------------------------------------------------
/src/Images/art1.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
96 |
--------------------------------------------------------------------------------
/src/Images/grain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/grain.png
--------------------------------------------------------------------------------
/src/Images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Images/logo.png
--------------------------------------------------------------------------------
/src/Pages/Intro.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import { withRouter } from "react-router-dom";
3 | import styled from "styled-components";
4 | import figlet from "figlet";
5 | import standard from "figlet/importable-fonts/Standard.js";
6 | import Typing from "react-typing-animation";
7 | import Grain from "Images/grain.png";
8 | import Mono from "Styles/Fonts/monospace.ttf";
9 |
10 | const Intro = props => {
11 | const [mainText, setMainText] = useState("");
12 | const [count, setCount] = useState(5);
13 | const [finishType, setFinishType] = useState(false);
14 | const [finishCount, setFinishCount] = useState(false);
15 |
16 | const getText = () => {
17 | figlet.parseFont("Standard", standard);
18 |
19 | figlet.text(
20 | "BF-TEST",
21 | {
22 | font: "Standard"
23 | },
24 | function (err, data) {
25 | console.log(data);
26 | setMainText(data);
27 | }
28 | );
29 | };
30 |
31 | const countingNum = () => {
32 | setCount(count - 1);
33 |
34 | if (count === 0) {
35 | setFinishCount(true);
36 | }
37 | };
38 |
39 | const delayTime = () => {
40 | setTimeout(() => {
41 | setFinishType(true);
42 | }, 500);
43 | };
44 | const startClick = () => {
45 | props.history.push("/main");
46 | };
47 |
48 | useEffect(() => getText(), []);
49 | return (
50 | <>
51 |
52 |
53 |
54 | {!finishCount && (
55 | {
58 | delayTime();
59 | }}
60 | className="tying-text"
61 | >
62 |
63 | 옛날 옛적에, 코딩의 코자도 모르던 사람들이 위코드를 통해 처음
64 | 코딩을 배우게 되었습니다.
65 |
66 |
67 | 그런데 시련은 생각보다 빨리 찾아왔습니다.
68 |
69 | 백엔드와 프론트엔드를 선택하는 갈림길에 서고야 만 것이죠...
70 |
71 |
72 | 서로를 부둥켜 안고 눈물 흘렸던 이들은 길고 긴 고민 끝에 한 가지
73 | 결심을 하고 각자 길을 떠납니다.
74 |
75 |
76 | 휼륭한 개발자가 되어 다시 만나서 이 어려움을 해결할 전설의
77 | 테스트를 만들겠다는 결심이었죠.
78 |
79 |
80 | .
81 | .
82 | .
83 |
84 | 2020년 4월, 훌륭한 프론트엔드와 백엔드 개발자로 성장한 이들이
85 | 결심을 이루기 위해 모였습니다.
86 |
87 |
88 | 기대되지 않나요?
89 |
90 | 프론트엔드와 백엔드 중 당신의 성향에 맞는 포지션을 찾아주는
91 | 전설의 심리테스트!
92 |
93 |
94 | 지금 바로 BF 테스트의 세계로 여러분을 초대합니다!
95 |
96 |
97 | )}
98 | {finishType && (
99 | {
103 | countingNum();
104 | }}
105 | >
106 | {count}
107 |
108 |
109 | )}
110 |
111 | {finishCount && (
112 |
113 |
114 | {mainText}
115 |
116 | START
117 |
118 | )}
119 |
120 | >
121 | );
122 | };
123 |
124 | export default withRouter(Intro);
125 |
126 | const IntroWrapper = styled.div`
127 | background-color: black;
128 | width: 100%;
129 | height: 100vh;
130 | overflow: hidden;
131 |
132 | @media only screen and (max-width: 415px) {
133 | font-size: 1rem;
134 | }
135 | `;
136 |
137 | const GrainBg = styled.div`
138 | width: 100%;
139 | height: 100vh;
140 | background: url(${Grain});
141 | z-index: 2;
142 | animation: grainAnimation 1s steps(4) infinite;
143 |
144 | @keyframes grainAnimation {
145 | 0% {
146 | -webkit-transform: translate(0, 0);
147 | transform: translate(0, 0);
148 | }
149 | 10% {
150 | -webkit-transform: translate(-5%, -5%);
151 | transform: translate(-5%, -5%);
152 | }
153 | 20% {
154 | -webkit-transform: translate(-10%, 5%);
155 | transform: translate(-10%, 5%);
156 | }
157 | 30% {
158 | -webkit-transform: translate(5%, -10%);
159 | transform: translate(5%, -10%);
160 | }
161 | 40% {
162 | -webkit-transform: translate(-5%, 15%);
163 | transform: translate(-5%, 15%);
164 | }
165 | 50% {
166 | -webkit-transform: translate(-10%, 5%);
167 | transform: translate(-10%, 5%);
168 | }
169 | 60% {
170 | -webkit-transform: translate(15%, 0);
171 | transform: translate(15%, 0);
172 | }
173 | 70% {
174 | -webkit-transform: translate(0, 10%);
175 | transform: translate(0, 10%);
176 | }
177 | 80% {
178 | -webkit-transform: translate(-15%, 0);
179 | transform: translate(-15%, 0);
180 | }
181 | 90% {
182 | -webkit-transform: translate(10%, 5%);
183 | transform: translate(10%, 5%);
184 | }
185 | 100% {
186 | -webkit-transform: translate(5%, 0);
187 | transform: translate(5%, 0);
188 | }
189 | }
190 | `;
191 |
192 | const TypingBox = styled.div`
193 | width: 100%;
194 | height: 100vh;
195 | display: flex;
196 | flex-direction: column;
197 | justify-content: flex-start;
198 | `;
199 |
200 | const TypedText = styled.p`
201 | color: #60bb5e;
202 | font-size: 20px;
203 | line-height: 30px;
204 | position: absolute;
205 | left: 20px;
206 | top: 20px;
207 | z-index: 100;
208 |
209 | @media only screen and (max-width: 415px) {
210 | display: ${props => props.finishType && "none"};
211 | font-size: 15px;
212 | width: 90%;
213 | line-height: 1rem;
214 | }
215 |
216 | @media only screen and (min-width: 416px) and (max-width: 970px) {
217 | display: ${props => props.finishType && "none"};
218 | font-size: 15px;
219 | width: 90%;
220 | line-height: 1rem;
221 | }
222 | `;
223 |
224 | const TypedNum = styled.span`
225 | color: #60bb5e;
226 | font-size: 23px;
227 | line-height: 30px;
228 | position: absolute;
229 | left: 520px;
230 | top: 560px;
231 | z-index: 100;
232 |
233 | @media only screen and (max-width: 415px) {
234 | font-size: 145px;
235 | left: 42%;
236 | top: 46%;
237 | line-height: 20px;
238 | }
239 |
240 | @media only screen and (min-width: 416px) and (max-width: 970px) {
241 | display: ${props => props.finishType && "none"};
242 | font-size: 145px;
243 | left: 45%;
244 | top: 46%;
245 | line-height: 20px;
246 | }
247 | `;
248 |
249 | const MainWrapper = styled.div`
250 | position: absolute;
251 | left: 50%;
252 | top: 50%;
253 | transform: translate(-50%, -50%);
254 | z-index: 100;
255 | display: flex;
256 | flex-direction: column;
257 | align-items: center;
258 | `;
259 |
260 | const MainText = styled.pre`
261 | color: #60bb5e;
262 | font-size: 30px;
263 | font-family: monospace Mono;
264 | animation: blinker 0.4s infinite;
265 |
266 | @font-face {
267 | font-family: Mono;
268 | font-weight: 400;
269 | src: url(${Mono});
270 | }
271 |
272 | @media only screen and (max-width: 415px) {
273 | font-size: 1rem;
274 | }
275 |
276 | @media only screen and (min-width: 416px) and (max-width: 970px) {
277 | font-size: 1.5rem;
278 | }
279 |
280 | @keyframes blinker {
281 | from {
282 | opacity: 0;
283 | }
284 | to {
285 | opacity: 1;
286 | }
287 | }
288 | `;
289 |
290 | const StartBox = styled.div`
291 | width: 150px;
292 | height: 45px;
293 | color: #60bb5e;
294 | font-size: 35px;
295 | border: 2px solid #60bb5e;
296 | display: flex;
297 | justify-content: center;
298 | align-items: center;
299 | margin-top: 40px;
300 | cursor: pointer;
301 | animation: startblinker 0.4s infinite;
302 |
303 | @keyframes startblinker {
304 | 0% {
305 | color: #60bb5e;
306 | border: 2px solid #60bb5e;
307 | }
308 | 50% {
309 | color: black;
310 | background-color: #60bb5e;
311 | }
312 | 100% {
313 | color: #60bb5e;
314 | border: 2px solid #60bb5e;
315 | }
316 | }
317 | `;
318 |
--------------------------------------------------------------------------------
/src/Pages/Main/Main.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import { connect } from "react-redux";
3 | import {
4 | openAbout,
5 | openQuestion,
6 | closeAbout,
7 | closeDetail,
8 | closeResult,
9 | showResult,
10 | } from "Redux/Actions";
11 | import styled from "styled-components";
12 | import Nav from "Components/Nav";
13 | import Question from "Components/Question/QuestionWindow";
14 | import Result from "Components/ResultWindow/Result";
15 | import About from "Components/About/About";
16 | import Footer from "Components/ResultWindow/Footer";
17 | import QUIZ from "Images/Main/quiz.png";
18 | import COMPUTER from "Images/Main/computer.png";
19 | import WECODE from "Images/Main/WeTV.png";
20 | import RECORD from "Images/Main/Record.png";
21 | import { type } from "os";
22 |
23 | const Main = (props) => {
24 | const {
25 | res,
26 | openQuestion,
27 | ques,
28 | about,
29 | openAbout,
30 | closeAbout,
31 | closeDetail,
32 | closeResult,
33 | showResult,
34 | } = props;
35 |
36 | const [postData, setPostData] = useState({});
37 |
38 | const getData = (postData) => {
39 | setPostData(postData);
40 | };
41 |
42 | const goToWecode = () => {
43 | window.open("https://wecode.co.kr/");
44 | };
45 |
46 | console.log(
47 | "❤️으이구우 또 열어봤네 또 열어봤어!! 뭐가 그렇게 궁금한데? 콘솔 닫고 테스트에 집중해 ❤️"
48 | );
49 | return (
50 |
51 |
52 |
53 |
54 | {
56 | openQuestion();
57 | closeDetail();
58 | closeAbout();
59 | closeResult();
60 | }}
61 | >
62 |
63 | Test
64 |
65 | showResult()}>
66 |
67 | Result
68 |
69 | openAbout()}>
70 |
71 | Contributors
72 |
73 | goToWecode()}>
74 |
75 | Wecode
76 |
77 |
78 | {ques && }
79 | {res && }
80 | {about && }
81 |
82 |
83 |
84 | );
85 | };
86 |
87 | const mapStateToProps = (state) => {
88 | return {
89 | res: state.controlResult.res,
90 | about: state.controlAbout.about,
91 | ques: state.controlQuestion.ques,
92 | };
93 | };
94 |
95 | export default connect(mapStateToProps, {
96 | openAbout,
97 | openQuestion,
98 | closeAbout,
99 | closeDetail,
100 | closeResult,
101 | showResult,
102 | })(Main);
103 |
104 | const MainWrapper = styled.div`
105 | width: 100vw;
106 | height: 100vh;
107 | border: 2px solid #000000;
108 | overflow: hidden;
109 | `;
110 |
111 | const Section = styled.div`
112 | width: 100%;
113 | height: 100%;
114 | background: #29bbbb;
115 | position: relative;
116 | display: flex;
117 | justify-content: center;
118 | align-items: center;
119 |
120 | @media only screen and (max-width: 415px) {
121 | height: calc(100% - 60px);
122 | }
123 | `;
124 |
125 | const IconWrapper = styled.div`
126 | position: absolute;
127 | top: 100px;
128 | left: 40px;
129 |
130 | @media only screen and (min-width: 500px) and (max-width: 780px) {
131 | top: 50px;
132 | display: flex;
133 | justify-content: center;
134 | align-items: flex-end;
135 | }
136 |
137 | @media only screen and (max-width: 415px) {
138 | top: 20px;
139 | left: 10px;
140 | }
141 | `;
142 |
143 | const Icon = styled.div`
144 | display: flex;
145 | flex-direction: column;
146 | align-items: center;
147 | margin-bottom: 20px;
148 |
149 | @media only screen and (min-width: 500px) and (max-width: 780px) {
150 | margin-right: 10px;
151 | }
152 |
153 | .test {
154 | width: 70px;
155 | height: auto;
156 | margin-bottom: 5px;
157 | cursor: pointer;
158 |
159 | @media only screen and (max-width: 420px) {
160 | width: 50px;
161 | }
162 | }
163 |
164 | .record {
165 | width: 60px;
166 | height: auto;
167 | margin-bottom: 7px;
168 | cursor: pointer;
169 |
170 | @media only screen and (max-width: 420px) {
171 | width: 45px;
172 | }
173 | }
174 |
175 | .computer {
176 | width: 80px;
177 | height: auto;
178 | cursor: pointer;
179 |
180 | @media only screen and (max-width: 420px) {
181 | width: 60px;
182 | }
183 | }
184 |
185 | .wecode {
186 | width: 70px;
187 | height: auto;
188 | margin-bottom: 5px;
189 | cursor: pointer;
190 |
191 | @media only screen and (max-width: 420px) {
192 | width: 50px;
193 | }
194 | }
195 | `;
196 |
197 | const Text = styled.div`
198 | width: 100px;
199 | height: 19px;
200 | font-size: 14px;
201 | text-align: center;
202 | line-height: 19px;
203 | background: #fabdfc;
204 | border: 1px solid #000000;
205 | cursor: pointer;
206 |
207 | @media only screen and (max-width: 420px) {
208 | width: 80px;
209 | font-size: 12px;
210 | line-height: 17px;
211 | }
212 | `;
213 |
--------------------------------------------------------------------------------
/src/Redux/Actions/index.js:
--------------------------------------------------------------------------------
1 | export const showResult = () => {
2 | return {
3 | type: "SHOW_RESULT",
4 | };
5 | };
6 |
7 | export const closeResult = () => {
8 | return {
9 | type: "CLOSE_RESULT",
10 | };
11 | };
12 |
13 | export const addResult = (data) => {
14 | return {
15 | type: "ADD",
16 | payload: data,
17 | };
18 | };
19 |
20 | export const openQuestion = () => {
21 | return {
22 | type: "OPEN_QUESTION",
23 | };
24 | };
25 |
26 | export const closeQuestion = () => {
27 | return {
28 | type: "CLOSE_QUESTION",
29 | };
30 | };
31 |
32 | export const openDetail = () => {
33 | return {
34 | type: "OPEN_DETAIL",
35 | };
36 | };
37 |
38 | export const closeDetail = () => {
39 | return {
40 | type: "CLOSE_DETAIL",
41 | };
42 | };
43 |
44 | export const openAbout = () => {
45 | return {
46 | type: "OPEN_ABOUT",
47 | };
48 | };
49 |
50 | export const closeAbout = () => {
51 | return {
52 | type: "CLOSE_ABOUT",
53 | };
54 | };
55 |
--------------------------------------------------------------------------------
/src/Redux/Reducers/controlAbout.js:
--------------------------------------------------------------------------------
1 | const INITIAL_STATE = {
2 | about: false,
3 | };
4 |
5 | export default function controlAbout(state = INITIAL_STATE, action) {
6 | switch (action.type) {
7 | case "OPEN_ABOUT":
8 | return { ...state, about: true };
9 | case "CLOSE_ABOUT":
10 | return { ...state, about: false };
11 | default:
12 | return state;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/Redux/Reducers/controlDetail.js:
--------------------------------------------------------------------------------
1 | const INITIAL_STATE = {
2 | detail: false,
3 | };
4 |
5 | export default function controlDetail(state = INITIAL_STATE, action) {
6 | switch (action.type) {
7 | case "OPEN_DETAIL":
8 | return { ...state, detail: true };
9 | case "CLOSE_DETAIL":
10 | return { ...state, detail: false };
11 | default:
12 | return state;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/Redux/Reducers/controlQuestion.js:
--------------------------------------------------------------------------------
1 | const INITIAL_STATE = {
2 | ques: false,
3 | };
4 |
5 | export default function controlQuestion(state = INITIAL_STATE, action) {
6 | switch (action.type) {
7 | case "OPEN_QUESTION":
8 | return { ...state, ques: true };
9 | case "CLOSE_QUESTION":
10 | return { ...state, ques: false };
11 | default:
12 | return state;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/Redux/Reducers/controlResult.js:
--------------------------------------------------------------------------------
1 | const INITIAL_STATE = {
2 | res: false,
3 | ques: false,
4 | };
5 |
6 | export default function controlResult(state = INITIAL_STATE, action) {
7 | switch (action.type) {
8 | case "SHOW_RESULT":
9 | return { ...state, res: true };
10 | case "CLOSE_RESULT":
11 | return { ...state, res: false };
12 | default:
13 | return state;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/Redux/Reducers/getResult.js:
--------------------------------------------------------------------------------
1 | export default function controlResult(state = {}, action) {
2 | switch (action.type) {
3 | case "ADD":
4 | return { ...state, ...action.payload };
5 | default:
6 | return state;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/Redux/rootReducer.js:
--------------------------------------------------------------------------------
1 | import { combineReducers } from "redux";
2 | import controlResult from "Redux/Reducers/controlResult";
3 | import getResult from "Redux/Reducers/getResult";
4 | import controlQuestion from "Redux/Reducers/controlQuestion";
5 | import controlDetail from "Redux/Reducers/controlDetail";
6 | import controlAbout from "Redux/Reducers/controlAbout";
7 |
8 | const rootReducer = combineReducers({
9 | controlResult,
10 | getResult,
11 | controlQuestion,
12 | controlDetail,
13 | controlAbout,
14 | });
15 |
16 | export default rootReducer;
17 |
--------------------------------------------------------------------------------
/src/Routes.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
3 | import Intro from "Pages/Intro";
4 | import Main from "Pages/Main/Main";
5 |
6 | class Routes extends React.Component {
7 | render() {
8 | return (
9 |
10 |
11 |
12 |
13 |
14 |
15 | );
16 | }
17 | }
18 |
19 | export default Routes;
20 |
--------------------------------------------------------------------------------
/src/Styles/Fonts/DungGeunMo.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Styles/Fonts/DungGeunMo.ttf
--------------------------------------------------------------------------------
/src/Styles/Fonts/monospace.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wanderlust-sol/BF_test_front-end/0c0c48db40bf7dc337a320a7d1093312be80810f/src/Styles/Fonts/monospace.ttf
--------------------------------------------------------------------------------
/src/config.js:
--------------------------------------------------------------------------------
1 | export const URL = "http://52.78.241.65:8000";
2 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom";
3 | import { Provider } from "react-redux";
4 | import { createStore } from "redux";
5 | import rootReducer from "Redux/rootReducer";
6 | import { createGlobalStyle } from "styled-components";
7 | import reset from "styled-reset";
8 | import Routes from "./Routes";
9 | import DungGeunMo from "Styles/Fonts/DungGeunMo.ttf";
10 |
11 | const GlobalStyle = createGlobalStyle`
12 | @font-face {
13 | font-family: DungGuenMo;
14 | font-weight: 400;
15 | src: url(${DungGeunMo});
16 | }
17 |
18 | ${reset}
19 | *{
20 | box-sizing: border-box ;
21 | cursor: default;
22 | }
23 | body {
24 | font-family: DungGuenMo, 'Noto Sans KR', sans-serif;
25 | };
26 | a {
27 | text-decoration: none;
28 | color: #000000
29 | }
30 | `;
31 | ReactDOM.render(
32 |
33 |
34 |
35 |
36 |
37 | ,
38 | document.getElementById("root")
39 | );
40 |
--------------------------------------------------------------------------------