-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add dev-test draft #22
base: main
Are you sure you want to change the base?
Changes from 17 commits
3644102
cf38722
4e43b67
544c64c
ff07208
64f6196
5092f7c
8e79f75
7b4f980
a4a5534
9029cd1
dc97fcc
b7aa0f8
db62045
1c65c1e
6d18e79
6b6cbd8
9f79c93
20369b1
d299b47
4557271
1fb23c0
0cb2a72
b166518
9aa6685
a0bf7ea
d2e4f8a
1563edb
80dab9c
f382802
4d08f40
89e41d1
a38b00e
7cec2fe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import DevTestPage from './playground/DevTest'; | ||
|
||
export { DevTestPage }; | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import { questions } from '@/resources/devTestQustions'; | ||
import { Dispatch, SetStateAction, useState } from 'react'; | ||
import { Button, TitleBox } from '../common'; | ||
import { COLORS } from '../common/token'; | ||
|
||
interface Props { | ||
setStage: Dispatch<SetStateAction<number>>; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🥝 setter 자체를 넘겨주면 외부 로직에 너무 의존성이 높아질 것 같은데, 단순히 '이 스텝이 끝날 때 실행된다'는 의미로 const goToNextStep = () => {
setState(prev => prev + 1);
};
return (
<PlayPage onEnd={goToNextStep} />
); 이런 느낌으로 하면 더 유연하게 짤 수 있지 않을까요? 그리고 이렇게 한다면 모든 step에 쓰이는 컴포넌트들이 동일한 interface를 가지도록 할 수 있을 것 같아요. 예를 들어서 // src/components/community/playground/DevTest/types.ts
export interface StepProps {
onEnd?: () => void;
} // src/components/community/playground/DevTest/PlayPage.tsx
import type { StepProps } from './types';
interface Props extends StepProps {} 이렇게 짜도 좋을 것 같아요! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 오홍...!! 뭔가 함수 넘겨주기보다 setter 넘겨주는게 편하다고 생각해서 아무 생각없이 이렇게 해왔는데 인터페이스도 통일할 수 있고 의존성 문제도 해결할 수 있겠네요... |
||
} | ||
|
||
const PlayPage = (props: Props) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 혹시 props를 spread하지 않는 이유가 따로 있을까요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ㅋㅋㅋㅋㅋ앗 props가 하나라 귀..찮아서 안했던건데 들켰네효...ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ |
||
const [idx, setIdx] = useState(0); | ||
const [answers, setAnswers] = useState<Array<number>>( | ||
Array(questions.length).fill(0), | ||
); | ||
|
||
return ( | ||
<div className="devtest__play-page"> | ||
<div className="devtest__play-page--question"> | ||
<TitleBox title={`Q${idx + 1}`} subtitle={questions[idx].question} /> | ||
</div> | ||
<div className="devtest__play-page--select"> | ||
{questions[idx].select.map((s, aIdx) => ( | ||
<Button | ||
backgroundColor={ | ||
answers[idx] === aIdx | ||
? COLORS.grayscale.Black | ||
: COLORS.grayscale.white | ||
} | ||
color={ | ||
answers[idx] === aIdx | ||
? COLORS.grayscale.white | ||
: COLORS.grayscale.Black | ||
} | ||
title={s} | ||
onClickHandler={() => | ||
setAnswers((prev) => prev.map((p, pi) => (idx === pi ? aIdx : p))) | ||
} | ||
key={s} | ||
/> | ||
))} | ||
</div> | ||
<Button | ||
backgroundColor="white" | ||
color={COLORS.SSU.DeepBlue} | ||
title="다음 질문으로!" | ||
onClickHandler={ | ||
() => | ||
idx !== questions.length - 1 //마지막 질문이 아니라면 | ||
? setIdx((prev) => prev + 1) //다음 질문으로 | ||
: props.setStage((prev) => prev + 1) //마지막 질문이라면 -> 다음 스테이지로 | ||
} | ||
/> | ||
<style jsx>{` | ||
.devtest__play-page { | ||
width: 100%; | ||
height: 100%; | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
justify-content: center; | ||
gap: 50px; | ||
} | ||
.devtest__play-page--question, | ||
.devtest__play-page--select { | ||
width: 100%; | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
gap: 15px; | ||
} | ||
`}</style> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🍌 저희는 이번 프로젝트에서 스타일링 라이브러리로 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 넵!! 변경하겠습니당 |
||
</div> | ||
); | ||
}; | ||
|
||
export default PlayPage; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import { StartButton, TitleBox, VisitorBox } from '../common'; | ||
import { | ||
COLORS, | ||
TEXT_STYLE_BODY_PC, | ||
TEXT_STYLE_BODY_MOBILE, | ||
} from '../common/token'; | ||
import { devTestLogo } from '@/resources/communityRes'; | ||
import { Dispatch, SetStateAction } from 'react'; | ||
|
||
interface Props { | ||
setStage: Dispatch<SetStateAction<number>>; | ||
} | ||
|
||
/** | ||
* 시작하기 버튼이 있는 테스트 시작 페이지 | ||
*/ | ||
const StartPage = (props: Props) => { | ||
return ( | ||
<div className="devtest__first-page"> | ||
<TitleBox | ||
title="개발자 성향테스트" | ||
subtitle="과연 나는 어떤 개발자일까? " | ||
/> | ||
<VisitorBox today={10} sum={100} /> | ||
<StartButton | ||
color={COLORS.SSU.DeepBlue} | ||
title="시작하기" | ||
onClickHandler={() => props.setStage((prev) => prev + 1)} | ||
/> | ||
<span>GDSC Soongsil Univ.</span> | ||
<img src={devTestLogo} alt="devtest-logo" /> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🍌 앗 리뷰하다가 깜빡했는데, 그냥 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아 헐 Image 까먹고있었어요...ㅋㅋㅋㅋㅋㅋ 수정하겠씁니다! |
||
<style jsx>{` | ||
.devtest__first-page { | ||
width: 100%; | ||
height: 100%; | ||
position: relative; | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
justify-content: flex-start; | ||
gap: 30px; | ||
padding-top: 80px; | ||
} | ||
span { | ||
color: white; | ||
font-size: ${TEXT_STYLE_BODY_PC.body2B.fontSize}; | ||
font-weight: ${TEXT_STYLE_BODY_PC.body2B.fontWeight}; | ||
} | ||
img { | ||
width: 65%; | ||
height: auto; | ||
position: absolute; | ||
bottom: 0px; | ||
left: 50%; | ||
transform: translateX(-50%); | ||
} | ||
|
||
@media screen and (max-width: 500px) { | ||
span { | ||
color: white; | ||
font-size: ${TEXT_STYLE_BODY_MOBILE.body2B.fontSize}; | ||
font-weight: ${TEXT_STYLE_BODY_MOBILE.body2B.fontWeight}; | ||
} | ||
} | ||
|
||
@media screen and (min-height: 800px) { | ||
.devtest__first-page { | ||
padding-top: 120px; | ||
} | ||
} | ||
`}</style> | ||
</div> | ||
); | ||
}; | ||
|
||
export default StartPage; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import Wrapper from '../Wrapper'; | ||
import StartPage from './StartPage'; | ||
import PlayPage from './PlayPage'; | ||
import { useState } from 'react'; | ||
|
||
/** | ||
* 개발자 성향테스트 페이지 최상위 Wrapper | ||
*/ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🍌 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 앗 넵!! 저도 이 부분 작성하면서 잘못된것 같다고 생각하고있었는데... 감사해요! 수정하겠습니다!! |
||
const DevTestPage = () => { | ||
const [stage, setStage] = useState(0); | ||
|
||
return ( | ||
<div className="devtest__page"> | ||
<Wrapper topColor="#00A4CA" bottomColor="#58C4C4"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 컬러들은 혹시 이 페이지에서만 사용되는 컬러인가요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 허걱 아뇨... 토큰에서 가져오는걸로 바꿀게요! |
||
{stage === 0 ? ( | ||
<StartPage setStage={setStage} /> | ||
) : ( | ||
<PlayPage setStage={setStage} /> | ||
)} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🥝 const STAGES = [
StartPage,
PlayPage,
] as const;
const DevTestPage = () => {
// ...
const CurrentPage = STAGES[stage];
return (
<div className="devtest__page">
<Wrapper topColor="#00A4CA" bottomColor="#58C4C4">
<CurrentPage setStage={setStage} />
{/* ... */}
);
}; There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 오홍... 훨씬 직관적이네요! 감사합니다~! |
||
</Wrapper> | ||
<style jsx>{` | ||
.devtest__page { | ||
padding: 0; | ||
margin: 0; | ||
background-color: black; | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
} | ||
`}</style> | ||
</div> | ||
); | ||
}; | ||
|
||
export default DevTestPage; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
interface Props { | ||
children: React.ReactNode; | ||
topColor: string; | ||
bottomColor: string; | ||
} | ||
|
||
/** | ||
* 모바일 중심형 페이지 Wrapper Component | ||
* @param topColor 왼쪽 상단 색상 헥사코드(eg. #00A4CA) | ||
* @param bottomColor 우측 하단 색상 헥사코드 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🍌 이렇게 하면 아마 주석이 제대로 적용이 안 될 텐데, 아래처럼 하면 prop에 마우스를 올렸을 때 주석이 같이 보일 것 같아요! interface Props {
children: React.ReactNode;
/** 왼쪽 상단 색상 헥사코드(eg. #00A4CA) */
topColor: string;
/** 우측 하단 색상 헥사코드 */
bottomColor: string;
} 🥝 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아아 넵!! 수정하겠습니다!! |
||
*/ | ||
const Wrapper = (props: Props) => { | ||
return ( | ||
<div className="container"> | ||
{props.children} | ||
<style jsx>{` | ||
.container { | ||
width: 31.2vw; | ||
min-height: 100vh; | ||
height: 100vh; | ||
background: linear-gradient( | ||
135deg, | ||
${props.topColor}, | ||
${props.bottomColor} | ||
); | ||
overflow-x: hidden; | ||
} | ||
|
||
@media screen and (min-width: 500px) { | ||
.container { | ||
min-width: 500px; | ||
} | ||
} | ||
|
||
@media screen and (max-width: 500px) { | ||
.container { | ||
width: 100vw; | ||
height: calc(var(--var, 1vh) * 100); | ||
} | ||
} | ||
`}</style> | ||
</div> | ||
); | ||
}; | ||
|
||
export default Wrapper; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { TEXT_STYLE_BUTTON_PC, TEXT_STYLE_BUTTON_MOBILE } from '../token'; | ||
|
||
interface Props { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🍌 어차피 내부에서 interface Props extends React.ComponentProps<'button'> {
backgroundColor: string;
color: string;
title: string;
}
const Button = ({ backgroundColor, color, title, ...buttonProps }: Props) => {
return (
<button {...buttonProps}>
{/* ... */}
);
}; 이렇게 하면 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아 헐... 너무 좋은 것 같아요.... 대박 |
||
backgroundColor: string; | ||
color: string; | ||
title: string; | ||
onClickHandler: () => void; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🍌 const handleClick = () => {
console.log("clicked!");
};
return (
<button onClick={handleClick} />
); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아..!!!! 왜인지 모르겠지만 저는 오히려 onClick이랑 구분해야한다고 생각을 하고있었네요... |
||
} | ||
/** | ||
* 테스트 중 사용될 일반 버튼 | ||
* @param backgroundColor 배경색 | ||
* @param color 글자색 | ||
* @param title 버튼 텍스트 | ||
* @param onClickHandler 클릭 이벤트핸들러 | ||
*/ | ||
const Button = (props: Props) => { | ||
return ( | ||
<button onClick={props.onClickHandler}> | ||
{props.title} | ||
<style jsx>{` | ||
button { | ||
border: none; | ||
background-color: ${props.backgroundColor}; | ||
width: 90%; | ||
min-width: 270px; | ||
min-height: 50px; | ||
border-radius: 500px; | ||
cursor: pointer; | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
box-shadow: rgba(0, 0, 0, 0.05) 0px 10px 50px; | ||
|
||
font-size: ${TEXT_STYLE_BUTTON_PC.button4B.fontSize}px; | ||
font-weight: ${TEXT_STYLE_BUTTON_PC.button4B.fontWeight}; | ||
font-family: 'SUIT Variable', sans-serif; | ||
white-space: pre-line; | ||
word-break: keep-all; | ||
text-align: center; | ||
color: ${props.color}; | ||
} | ||
|
||
@media screen and (max-width: 500px) { | ||
button { | ||
font-size: ${TEXT_STYLE_BUTTON_MOBILE.button4B.fontSize}px; | ||
font-weight: ${TEXT_STYLE_BUTTON_MOBILE.button4B.fontWeight}; | ||
} | ||
} | ||
`}</style> | ||
</button> | ||
); | ||
}; | ||
|
||
export default Button; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { TEXT_STYLE_BUTTON_PC, TEXT_STYLE_BUTTON_MOBILE } from '../token'; | ||
|
||
interface Props { | ||
color: string; //글자색 | ||
title: string; //버튼 텍스트 | ||
onClickHandler: () => void; | ||
} | ||
|
||
/** | ||
* 플레이그라운드에서 사용하는 시작버튼 | ||
* @param color 글자색 | ||
* @param title 버튼 텍스트 | ||
* @param onClickHandler 클릭 이벤트핸들러 | ||
*/ | ||
const StartButton = (props: Props) => { | ||
return ( | ||
<button onClick={props.onClickHandler}> | ||
{props.title} | ||
<style jsx>{` | ||
button { | ||
border: none; | ||
background-color: white; | ||
width: 65%; | ||
min-width: 220px; | ||
height: 55px; | ||
border-radius: 20px; | ||
cursor: pointer; | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
box-shadow: rgba(0, 0, 0, 0.05) 0px 10px 50px; | ||
|
||
font-size: ${TEXT_STYLE_BUTTON_PC.button1B.fontSize}px; | ||
font-weight: 800; | ||
font-family: 'SUIT Variable', sans-serif; | ||
white-space: pre-line; | ||
word-break: keep-all; | ||
text-align: center; | ||
color: ${props.color}; | ||
} | ||
|
||
@media screen and (max-width: 500px) { | ||
button { | ||
font-size: ${TEXT_STYLE_BUTTON_MOBILE.button1B.fontSize}px; | ||
font-weight: 800; | ||
} | ||
} | ||
`}</style> | ||
</button> | ||
); | ||
}; | ||
|
||
export default StartButton; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🍎 폴더 이름 community인데 comuunity로 오타났어요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
헉 수정하겠습니다! 감사해요!!!