Skip to content

Commit

Permalink
[Feat] CompletePage 사용자 만족도 조사 추가 (#343)
Browse files Browse the repository at this point in the history
* design: 설문조사 박스 구현

* feat: 클릭 시 효과

* fix: 영역 좁히도록 수정

* feat: 점수 클릭 후 렌더링 상태 변경

* design: 애니메이션 추가

* feat: postSatisfaction API 연결

* fix: 코드리뷰 반영 및 전체width 확장

* fix: interface naming 통일

* feat: onSuccess 추가

* chore: 테스트용 코드 복구
  • Loading branch information
lydiacho authored Aug 5, 2024
1 parent 02c0240 commit f93aa11
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 6 deletions.
7 changes: 7 additions & 0 deletions src/views/CompletePage/apis.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import tokenInstance from '@apis/tokenInstance';

export const postSatisfaction = (satisfaction: number) => {
return tokenInstance.post('/recruiting-applicant/satisfaction', {
satisfaction,
});
};
50 changes: 50 additions & 0 deletions src/views/CompletePage/components/Survey.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { useState } from 'react';

import useMutateSatisfaction from '../hooks/useMutateSatisfaction';
import { pointBoxVar, pointContainerVar, surveyBox, thanksTextVar } from '../style.css';

const Survey = () => {
const [point, setPoint] = useState<number | 'CHANGED'>(-1);

const handleSatisfaction = () => {
setTimeout(() => {
setPoint('CHANGED');
}, 200);
setTimeout(() => {
setPoint(-1);
}, 2200);
};

const { mutate } = useMutateSatisfaction({ onSuccess: handleSatisfaction });

const handleClickPoint = (i: number) => {
if (point === 'CHANGED') return;
mutate({ satisfaction: i });
setPoint(i);
};

return (
<div className={surveyBox}>
<span
style={{
textAlign: 'center',
whiteSpace: 'pre-line',
}}>{`지원서 이용 만족도를 0-10점 중에 선택해주세요.\n의견을 주시면 프로덕트 개선에 도움이 됩니다.`}</span>
<div style={{ position: 'relative', width: 348, height: 36 }}>
<span className={thanksTextVar[point === 'CHANGED' ? 'in' : 'out']}>소중한 의견 감사합니다 :&#41;</span>
<ul className={pointContainerVar[point !== 'CHANGED' ? 'in' : 'out']}>
{Array.from({ length: 11 }, (_, i) => i).map((v) => (
<li
key={v}
className={pointBoxVar[point === 'CHANGED' ? 'changed' : v === point ? 'selected' : 'default']}
onClick={() => handleClickPoint(v)}>
<span style={{ paddingTop: 5 }}>{v}</span>
</li>
))}
</ul>
</div>
</div>
);
};

export default Survey;
22 changes: 22 additions & 0 deletions src/views/CompletePage/hooks/useMutateSatisfaction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { useMutation } from '@tanstack/react-query';
import { AxiosError, AxiosResponse } from 'axios';

import { ErrorResponse } from '@type/errorResponse';

import { postSatisfaction } from '../apis';
import { PostSatisfactionRequest, PostSatisfactionResponse } from '../types';

const useMutateSatisfaction = ({ onSuccess }: { onSuccess?: () => void }) => {
const { mutate } = useMutation<
AxiosResponse<PostSatisfactionResponse, PostSatisfactionRequest>,
AxiosError<ErrorResponse, PostSatisfactionRequest>,
PostSatisfactionRequest
>({
mutationFn: ({ satisfaction }) => postSatisfaction(satisfaction),
onSuccess,
});

return { mutate };
};

export default useMutateSatisfaction;
4 changes: 3 additions & 1 deletion src/views/CompletePage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Button from '@components/Button';
import Callout from '@components/Callout';
import { RecruitingInfoContext } from '@store/recruitingInfoContext';

import Survey from './components/Survey';
import IconCheckmark from './icons/IconCheckmark';
import { container, icon, mainText, subText } from './style.css';

Expand All @@ -28,9 +29,10 @@ const CompletePage = () => {
<p className={subText}>이메일로 지원 접수 완료 알림이 발송되었습니다.</p>
<Callout
style={{
marginBottom: 50,
marginBottom: 35,
}}>{`이메일 도착 시점에 차이가 있을 수 있습니다.\n이메일이 오지 않으면 스팸 메일함을 확인해주세요.`}</Callout>
<Button onClick={handleClickMyPage}>마이페이지로 이동하기</Button>
<Survey />
</section>
);
};
Expand Down
115 changes: 110 additions & 5 deletions src/views/CompletePage/style.css.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { style } from '@vanilla-extract/css';
import { style, styleVariants } from '@vanilla-extract/css';
import { calc } from '@vanilla-extract/css-utils';

import { theme } from 'styles/theme.css';
Expand All @@ -8,7 +8,7 @@ export const container = style({
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
width: 466,
width: 550,
height: calc.subtract('100vh', '74px'),
minHeight: 700,

Expand All @@ -23,24 +23,129 @@ export const icon = style({
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
marginBottom: '32px',
marginBottom: 20,
width: 66,
height: 66,
borderRadius: '50%',
background: theme.color.primaryLinear,
});

export const mainText = style({
marginBottom: 24,
marginBottom: 8,
color: theme.color.baseText,
textAlign: 'center',
whiteSpace: 'pre-line',
...theme.font.HEADING_2_32_B,
});

export const subText = style({
marginBottom: 50,
marginBottom: 30,
color: theme.color.baseText,
textAlign: 'center',
...theme.font.BODY_1_18_M,
});

export const surveyBox = style({
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
gap: 12,
width: 466,
padding: '22px 0px',
marginTop: 35,
color: theme.color.lightestText,
...theme.font.BODY_2_16_M,
border: `1px solid ${theme.color.border}`,
borderRadius: 15,
});

export const pointContainer = style({
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
display: 'flex',
gap: 4,
transition: 'all 0.3s ease',
});

export const pointContainerVar = styleVariants({
in: [
pointContainer,
{
opacity: 1,
},
],
out: [
pointContainer,
{
opacity: 0,
},
],
});

const pointBox = style({
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
width: 28,
height: 36,
borderRadius: 6,
transition: 'all 0.3s ease',
cursor: 'pointer',
});

export const pointBoxVar = styleVariants({
default: [
pointBox,
{
backgroundColor: theme.color.subBackground,
color: theme.color.baseText,
},
],
selected: [
pointBox,
{
backgroundColor: theme.color.primary,
color: theme.color.white,
},
],
changed: [
pointBox,
{
cursor: 'default',
},
],
});

export const thanksText = style({
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
paddingTop: 5,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
...theme.font.TITLE_6_16_SB,
color: theme.color.lighterText,
transition: 'all 0.3s ease',
});

export const thanksTextVar = styleVariants({
in: [
thanksText,
{
opacity: 1,
},
],
out: [
thanksText,
{
opacity: 0,
},
],
});
8 changes: 8 additions & 0 deletions src/views/CompletePage/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export interface PostSatisfactionRequest {
satisfaction: number;
}

export interface PostSatisfactionResponse {
err: boolean;
userMessage: string;
}

0 comments on commit f93aa11

Please sign in to comment.