Skip to content
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

[FE] feat: 질문 작성 페이지 QuestionCard, ReviewWritingCard 공통 컴포넌트를 만들고, 슬라이더 방식의 기능 추가 #247

Merged
1 change: 0 additions & 1 deletion frontend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@ dist

yarn-error.log
.env
# Sentry Config File
.env.sentry-build-plugin
6 changes: 5 additions & 1 deletion frontend/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,13 @@
rel="stylesheet"
/>
<link href="https://hangeul.pstatic.net/hangeul_static/css/nanum-gothic.css" rel="stylesheet" />
<link
rel="stylesheet"
type="text/css"
href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css"
/>
<title>✉️REVIEW ME</title>
</head>

<body>
<div id="root"></div>
</body>
Expand Down
14 changes: 14 additions & 0 deletions frontend/src/components/QuestionCard/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { QuestionCardStyleType } from '@/types';

import * as S from './styles';

interface QuestionCardProps {
questionType: QuestionCardStyleType;
question: string;
}

const QuestionCard = ({ questionType, question }: QuestionCardProps) => {
return <S.QuestionCard questionType={questionType}>{question}</S.QuestionCard>;
};

export default QuestionCard;
8 changes: 8 additions & 0 deletions frontend/src/components/QuestionCard/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import styled from '@emotion/styled';

import { QuestionCardStyleType } from '@/types';

export const QuestionCard = styled.span<{ questionType: QuestionCardStyleType }>`
font-size: ${({ theme }) => theme.fontSize.basic};
color: ${({ questionType, theme }) => (questionType === 'guideline' ? theme.colors.placeholder : theme.colors.black)};
`;
20 changes: 20 additions & 0 deletions frontend/src/components/ReviewWritingCard/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { EssentialPropsWithChildren } from '@/types';

import * as S from './styles';

interface ReviewWritingCardProps {
title: string;
}

const ReviewWritingCard = ({ title, children }: EssentialPropsWithChildren<ReviewWritingCardProps>) => {
return (
<S.Container>
<S.Header>
<S.Title>{title}</S.Title>
</S.Header>
<S.Main>{children}</S.Main>
</S.Container>
);
};

export default ReviewWritingCard;
23 changes: 23 additions & 0 deletions frontend/src/components/ReviewWritingCard/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import styled from '@emotion/styled';

export const Container = styled.div`
display: flex;
flex-direction: column;
`;

export const Header = styled.div`
width: 100%;
height: 5rem;
background-color: ${({ theme }) => theme.colors.lightPurple};

padding: 1rem;
`;

export const Main = styled.div`
padding: 1rem;
`;

export const Title = styled.span`
margin-bottom: 2rem;
font-size: ${({ theme }) => theme.fontSize.mediumSmall};
`;
1 change: 1 addition & 0 deletions frontend/src/components/common/Input/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const Input = styled.input<InputStyleProps>`
border-radius: ${({ theme }) => theme.borderRadius.basic};

padding: 1.2rem 1.6rem;

font-size: 1.3rem;

::placeholder {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ const Logo = () => {
<S.Logo>
<img src={LogoIcon} alt="로고 아이콘" />
<S.LogoText>
<span>review</span>
<span>me</span>
<span>REVIEW</span>
<span>ME</span>
</S.LogoText>
</S.Logo>
);
Expand Down
5 changes: 4 additions & 1 deletion frontend/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import LandingPage from './pages/LandingPage';
import ReviewListPage from './pages/ReviewListPage';
import ReviewWritingPage from './pages/ReviewWriting';
import ReviewWritingCompletePage from './pages/ReviewWritingCompletePage';
import ReviewWritingFormPage from './pages/ReviewWritingFormPage';
import globalStyles from './styles/globalStyles';
import theme from './styles/theme';

Expand Down Expand Up @@ -54,7 +55,9 @@ const router = createBrowserRouter([
},
{
path: 'user/review-writing/:reviewRequestId',
element: <ReviewWritingPage />,
// NOTE: 리뷰 작성 페이지 UI 변경으로 인해 일단 주석 처리
// element: <ReviewWritingPage />,
element: <ReviewWritingFormPage />,
},
{ path: 'user/review-writing-complete', element: <ReviewWritingCompletePage /> },
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@ import styled from '@emotion/styled';
export const FormLayout = styled.form`
display: flex;
flex-direction: column;

width: 40rem;
`;

export const Title = styled.h2`
font-size: ${({ theme }) => theme.fontSize.basic};

margin-bottom: 2.2rem;
font-size: ${({ theme }) => theme.fontSize.basic};
`;
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,17 @@ import styled from '@emotion/styled';
export const ReviewAccessFormContent = styled.div`
display: flex;
flex-direction: column;

width: 100%;
`;

export const ReviewAccessFormBody = styled.div`
display: flex;
justify-content: space-between;

width: 100%;
`;

export const ErrorMessage = styled.p`
padding-left: 0.7rem;
font-size: 1.3rem;

color: ${({ theme }) => theme.colors.red};

padding-left: 0.7rem;
`;
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ export const ReviewGroupDataModal = styled.div`
`;

export const ReviewGroupDataTitle = styled.h3`
font-weight: ${({ theme }) => theme.fontWeight.bold};
font-size: 2rem;
font-weight: ${({ theme }) => theme.fontWeight.bold};
`;

export const ReviewGroupDataContainer = styled.div`
Expand All @@ -19,9 +19,8 @@ export const ReviewGroupDataContainer = styled.div`

export const ReviewGroupDataItem = styled.div`
display: flex;
justify-content: space-between;
gap: 2.1rem;

justify-content: space-between;
font-size: 1.5rem;
`;

Expand All @@ -35,21 +34,19 @@ export const Data = styled.span`

export const CheckContainer = styled.div`
display: flex;

font-size: 1.5rem;
`;

export const Checkbox = styled.input`
height: 1rem;
cursor: pointer;
width: 1rem;
height: 1rem;
margin-right: 0.5rem;

cursor: pointer;
`;

export const CheckMessage = styled.p``;

export const Warning = styled.p`
color: ${({ theme }) => theme.colors.red};
font-size: smaller;
color: ${({ theme }) => theme.colors.red};
`;
1 change: 0 additions & 1 deletion frontend/src/pages/LandingPage/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,5 @@ export const LandingPage = styled.div`
display: flex;
flex-direction: column;
gap: 7.7rem;

margin-top: 4rem;
`;
76 changes: 76 additions & 0 deletions frontend/src/pages/ReviewWritingFormPage/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { useEffect, useRef, useState } from 'react';

import { Button } from '@/components';
import QuestionCard from '@/components/QuestionCard';
import ReviewWritingCard from '@/components/ReviewWritingCard';
import { ButtonStyleType } from '@/types';

import * as S from './styles';

const REVIEWEE = '쑤쑤';

const QUESTIONS = [
{
title: `💡${REVIEWEE}와 함께 한 기억을 떠올려볼게요.`,
question: `프로젝트 기간 동안, ${REVIEWEE}의 강점이 드러났던 순간을 선택해주세요. (1~2개)`,
},
{
title: `선택한 순간들을 바탕으로 ${REVIEWEE}에 대한 리뷰를 작성해볼게요.`,
question: `커뮤니케이션, 협업 능력에서 어떤 부분이 인상 깊었는지 선택해주세요. (1개 이상)`,
},
{
title: ``,
question: `앞으로의 성장을 위해서 ${REVIEWEE}가 어떤 목표를 설정하면 좋을까요?`,
},
];

const ReviewWritingFormPage = () => {
const [currentIndex, setCurrentIndex] = useState(0);
const [slideWidth, setSlideWidth] = useState(0);

const wrapperRef = useRef<HTMLDivElement | null>(null);

useEffect(() => {
if (wrapperRef.current) setSlideWidth(wrapperRef.current.clientWidth);
}, [wrapperRef]);

const handlePrev = () => {
if (currentIndex > 0) {
setCurrentIndex(currentIndex - 1);
}
};

const handleNext = () => {
if (currentIndex < QUESTIONS.length - 1) {
setCurrentIndex(currentIndex + 1);
}
};

const buttons = [
{ styleType: 'secondary' as ButtonStyleType, onClick: handlePrev, text: '이전' },
{ styleType: 'primary' as ButtonStyleType, onClick: handleNext, text: '다음' },
];

return (
<S.CardLayout>
<S.SliderContainer ref={wrapperRef} translateX={currentIndex * slideWidth}>
{QUESTIONS.map(({ question, title }, index) => (
<S.Slide key={index}>
<ReviewWritingCard title={title}>
<QuestionCard questionType="normal" question={question} />
</ReviewWritingCard>
</S.Slide>
))}
</S.SliderContainer>
<S.ButtonContainer>
{buttons.map((button, index) => (
<Button key={index} styleType={button.styleType} onClick={button.onClick}>
{button.text}
</Button>
))}
</S.ButtonContainer>
</S.CardLayout>
);
};

export default ReviewWritingFormPage;
32 changes: 32 additions & 0 deletions frontend/src/pages/ReviewWritingFormPage/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import styled from '@emotion/styled';

export const CardLayout = styled.div`
position: relative;
overflow: hidden;
width: ${({ theme }) => theme.formWidth};

border-radius: ${({ theme }) => theme.borderRadius.basic};
border: 0.1rem solid ${({ theme }) => theme.colors.lightPurple};
`;

export const SliderContainer = styled.div<{ translateX: number }>`
transform: ${({ translateX }) => `translateX(-${translateX}px)`};
display: flex;
width: 100%;
transition: transform 0.5s ease-in-out;
`;

export const Slide = styled.div`
flex: 0 0 100%;
box-sizing: border-box;
`;

export const ButtonContainer = styled.div`
display: flex;
justify-content: flex-end;
gap: 2rem;

button {
width: 10rem;
}
`;
2 changes: 1 addition & 1 deletion frontend/src/styles/globalStyles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const globalStyles = css`
}

body {
font-family: 'NanumGothic', 'Noto Sans', sans-serif;
font-family: 'Pretendard-Regular', 'NanumGothic', 'Noto Sans', sans-serif;
margin: 0;
padding: 0;
box-sizing: border-box;
Expand Down
1 change: 1 addition & 0 deletions frontend/src/styles/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export const breakpoints: ThemeProperty<string> = {
export const fontSize: ThemeProperty<CSSProperties['fontSize']> = {
small: '1.4rem',
basic: '1.6rem',
mediumSmall: '2.0rem',
medium: '2.4rem',
large: '3.2rem',
h2: '4.8rem',
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/types/styles.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export type ButtonStyleType = 'primary' | 'secondary' | 'disabled';

export type QuestionCardStyleType = 'normal' | 'guideline';