Skip to content

Commit

Permalink
[Design] Mobile ver. - 결과 페이지 반응형 (#370)
Browse files Browse the repository at this point in the history
* fix: SOPT makers 전용 결과 문구 반영

* design: contentWrapper 반응형

* design: 합격페이지 배경 로고 margin반응형

* design: content 스크롤 추가 및 paddingBottom

* design: 스크롤 bottom 그라데이션 구현

* design: 구글폼 주소 개행 관련 작업

* chore: 누락된 코드 추가

* chore: 누락된 코드 추가

* chore: 누락된 코드 추가

* design: SOPT makers 조건부 수정 및 서류페이지 누락된 스크롤 작업 추가

* design: 합격페이지 애니메이션 zIndex 최상위 이동

* chore: 테스트를 위한 조건수정 복구

* chore: 잘못들어간 코드 삭제

* fix: 결과확인 버튼에 모바일접속제한 해제

* fix: 스크롤 이슈 해결

* chore: 테스트용 코드 삭제
  • Loading branch information
lydiacho authored Aug 12, 2024
1 parent 3d1d79f commit 2cb21b1
Show file tree
Hide file tree
Showing 6 changed files with 209 additions and 79 deletions.
2 changes: 2 additions & 0 deletions src/common/constants/zIndex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ export const Z_INDEX = {
applyCategory: 99,
applyHeader: 99,
resultContent: 2,
resultGrad: 3,
resultAnim: 4,
};
1 change: 1 addition & 0 deletions src/views/MyPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const StatusButton = ({ label, to, trackingEvent }: { label: string; to: string;

const handlePreventMobile = (e: MouseEvent<HTMLButtonElement>) => {
track(trackingEvent);
if (label === '지원상태') return;

const isMobile = /Mobi/i.test(window.navigator.userAgent);
if (isMobile) {
Expand Down
92 changes: 68 additions & 24 deletions src/views/ResultPage/components/FinalResult.tsx
Original file line number Diff line number Diff line change
@@ -1,55 +1,95 @@
import { format } from 'date-fns';
import { ko } from 'date-fns/locale';
import { useContext, useEffect } from 'react';

import Title from '@components/Title';
import { useDevice } from '@hooks/useDevice';
import { RecruitingInfoContext } from '@store/recruitingInfoContext';
import BigLoading from 'views/loadings/BigLoding';

import { bottomAnimation, bottomImg, bottomSvg, container, content, contentWrapper, strongText } from './style.css';
import {
bottomAnimation,
bottomImg,
bottomSvg,
container,
contentVar,
contentWrapperVar,
link,
scrollBottomGradVar,
strongText,
} from './style.css';
import IconMakersLogo from '../assets/IconMakersLogo';
import imgSoptLogo from '../assets/imgSoptLogo.png';
import imgSoptLogoWebp from '../assets/imgSoptLogo.webp';
import useGetFinalResult from '../hooks/useGetFinalResult';

const Content = ({ pass }: { pass?: boolean }) => {
const DEVICE_TYPE = useDevice();
const {
recruitingInfo: { name, soptName, season, group, isMakers },
recruitingInfo: { name, soptName, season, group, isMakers, finalPassConfirmStart },
} = useContext(RecruitingInfoContext);

if (!name) return;

const finalDate = new Date(finalPassConfirmStart || '');
const formattedFinalPassConfirmStart = format(finalDate, 'M월 dd일 EEEE', {
locale: ko,
});

const SOPT_NAME = isMakers ? `SOPT ${soptName}` : soptName;
return (
<>
{pass ? (
<p className={content}>
<span>{`안녕하세요. ${season}${soptName} 입니다.\n\n`}</span>
<p className={contentVar[DEVICE_TYPE]}>
<span>{`안녕하세요. ${SOPT_NAME}입니다.\n\n`}</span>
<strong className={strongText[isMakers ? 'makers' : 'sopt']}>{`축하드립니다!`}</strong>
<span>
{`
${name}님은 ${season}${soptName} ${!isMakers ? group : ''} 신입회원 모집에 최종 합격하셨습니다.
${name}님은 ${season}${SOPT_NAME} ${!isMakers ? group : ''} 신입회원 모집에 최종 합격하셨습니다.
${name}님과 함께하게 되어 진심으로 기쁩니다.
향후 활동은 ${soptName} 공식 노션과 카카오톡 단체 대화방, SOPT 공식 디스코드를 통해
운영 및 진행됩니다.
향후 활동은 ${SOPT_NAME} 공식 노션과 슬랙,카카오톡 단체 대화방, ${SOPT_NAME} 공식 디스코드 등을 통해 운영 및 진행됩니다.
오늘 중으로 카카오톡 단체 대화방에 초대해드릴 예정이니 참고 부탁드립니다.\n
아래 구글 폼으로 각 워크스페이스 이메일 계정 및 필수 정보를 제출해주시길 바랍니다.
( 제출 마감 : ${formattedFinalPassConfirmStart} 오후 11:59 )
`}
</span>
<span>{`( 구글폼 : `}</span>
<a
className={link}
href={`https://${import.meta.env.VITE_FINAL_PASS_LINK}`}
target="_blank"
rel="noreferrer noopener">
{`https://${DEVICE_TYPE !== 'DESK' && '\n'}${import.meta.env.VITE_FINAL_PASS_LINK}`}
</a>
<span>{` )\n`}</span>
<br />
<span>
{`
제출해주신 구글 폼을 통해 순차적으로 워크스페이스 초대해드릴 예정이며
금일 중으로 카카오톡 단체 대화방에 초대해드릴 예정이니 참고 부탁드립니다.
다시 한 번 ${SOPT_NAME} ${season}기 합류를 진심으로 축하드립니다!
${SOPT_NAME} 운영진 드림
`}
</span>
<strong
className={
strongText[isMakers ? 'makers' : 'sopt']
}>{`SOPT의 ${season}번째 열정이 되신 것을 축하드립니다!`}</strong>
</p>
) : (
<p className={content}>
{`안녕하세요. ${soptName} 입니다.
${name}님은 ${season}${soptName} ${!isMakers ? group : ''} 신입회원 모집에 불합격하셨습니다.
<p className={contentVar[DEVICE_TYPE]}>
{`안녕하세요, ${SOPT_NAME}입니다.
${SOPT_NAME}에 관심을 갖고 지원해 주셔서 감사드립니다.
지원자님의 뛰어난 역량과 잠재력에도 불구하고 안타깝게도 귀하의 최종 합격 소식을
전해드리지 못하게 되었습니다.
${name}님의 뛰어난 역량과 잠재력에도 불구하고 안타깝게도 귀하의 합격 소식을 전해드리지 못하게 되었습니다.
한 분 한 분에게 개별적인 피드백을 드리기는 어렵겠으나 저희 SOPT에 지원하셨던
경험이 한 사람의 IT 창업인으로서 멋진 역할을 해나가시는 데 큰 도움이 되기를 바랍니다.
비록 이번 ${season}${soptName}에 모시지 못하게 되었으나, ${soptName}에 지원하시고자 쓰인 소중한 시간과 노력이 지원자님께서 IT 창업인으로서 멋진 역할을 해나가시는 데 작게나마 도움이 되는 경험이 되시길 바랍니다.
${SOPT_NAME}에 귀한 시간을 내어주셔서 다시 한 번 깊이 감사드립니다 :)
향후에 더 좋은 인연으로 뵙기를 기다리겠습니다.
감사합니다.
${SOPT_NAME} 운영진 드림
`}
</p>
)}
Expand All @@ -58,6 +98,7 @@ const Content = ({ pass }: { pass?: boolean }) => {
};

const FinalResult = () => {
const DEVICE_TYPE = useDevice();
const { finalResult, finalResultIsLoading } = useGetFinalResult();
const {
recruitingInfo: { isMakers },
Expand All @@ -76,11 +117,13 @@ const FinalResult = () => {

return (
<section className={container}>
<div className={contentWrapper}>
<Title>결과 확인</Title>
<Content pass={pass} />
<div style={{ overflow: 'auto', height: '100%' }}>
<div className={contentWrapperVar[DEVICE_TYPE]}>
<Title>결과 확인</Title>
<Content pass={pass} />
</div>
</div>
{pass && (
{DEVICE_TYPE !== 'MOB' && pass && (
<>
<div className={bottomAnimation[isMakers ? 'makers' : 'sopt']} />
{isMakers ? (
Expand All @@ -95,6 +138,7 @@ const FinalResult = () => {
)}
</>
)}
<div className={scrollBottomGradVar[DEVICE_TYPE]} />
</section>
);
};
Expand Down
95 changes: 55 additions & 40 deletions src/views/ResultPage/components/ScreeningResult.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ko } from 'date-fns/locale';
import { useContext, useEffect } from 'react';

import Title from '@components/Title';
import { useDevice } from '@hooks/useDevice';
import { RecruitingInfoContext } from '@store/recruitingInfoContext';
import BigLoading from 'views/loadings/BigLoding';

Expand All @@ -11,9 +12,10 @@ import {
bottomImg,
bottomSvg,
container,
content,
contentWrapper,
contentVar,
contentWrapperVar,
link,
scrollBottomGradVar,
strongText,
} from './style.css';
import IconMakersLogo from '../assets/IconMakersLogo';
Expand All @@ -22,17 +24,9 @@ import imgSoptLogoWebp from '../assets/imgSoptLogo.webp';
import useGetScreeningResult from '../hooks/useGetScreeningResult';

const Content = ({ pass }: { pass?: boolean }) => {
const DEVICE_TYPE = useDevice();
const {
recruitingInfo: {
name,
soptName,
season,
group,
interviewStart,
interviewEnd,
applicationPassConfirmStart,
isMakers,
},
recruitingInfo: { name, soptName, season, interviewStart, interviewEnd, applicationPassConfirmStart, isMakers },
} = useContext(RecruitingInfoContext);

if (!name) return;
Expand All @@ -41,54 +35,71 @@ const Content = ({ pass }: { pass?: boolean }) => {
const applicationPassConfirmNextDay = new Date(applicationDate);
applicationPassConfirmNextDay.setDate(applicationDate.getDate() + 1);

const formattedInterviewStart = format(new Date(interviewStart || ''), 'M/dd(E)', { locale: ko });
const formattedInterviewEnd = format(new Date(interviewEnd || ''), 'M/dd(E)', { locale: ko });
const formattedApplicationPassConfirmStart = format(applicationDate, 'dd일 EEEE', {
const formattedInterviewStart = format(new Date(interviewStart || ''), 'M월 dd일', { locale: ko });
const formattedInterviewEnd = format(new Date(interviewEnd || ''), 'M월 dd일', { locale: ko });
const formattedApplicationPassConfirmStart = format(applicationDate, 'M월 dd일 EEEE', {
locale: ko,
});
const formattedApplicationPassConfirmNextDay = format(new Date(applicationPassConfirmNextDay || ''), 'dd일 EEEE', {
const formattedApplicationPassConfirmNextDay = format(new Date(applicationPassConfirmNextDay || ''), 'M월 dd일', {
locale: ko,
});

const SOPT_NAME = isMakers ? `SOPT ${soptName}` : soptName;
return (
<>
{pass ? (
<p className={content}>
<span>{`안녕하세요. ${season}${soptName} 입니다.\n\n`}</span>
<p className={contentVar[DEVICE_TYPE]}>
<span>{`안녕하세요. ${SOPT_NAME} 입니다.\n\n`}</span>
<strong className={strongText[isMakers ? 'makers' : 'sopt']}>{`축하드립니다!`}</strong>
<span>
{`
서류 검토 결과, ${name}님은 면접 대상자로 선정되셨습니다.
서류 검토 결과, ${name}님은 인터뷰 대상자로 선정되셨습니다.
${season}${SOPT_NAME} 인터뷰는 ${formattedInterviewStart} ~ ${formattedInterviewEnd} 기간 중 진행될 예정입니다.
${season}${soptName} ${!isMakers ? group : ''} 면접은 ${formattedInterviewStart} ~ ${formattedInterviewEnd} 양일 간 오프라인 으로 진행될 예정입니다.
모든 면접 대상자 분들은 아래 구글폼을 제출해주세요.
원할한 면접 진행을 위해, 아래 구글 폼에 불가능한 시간대를 모두 선택해 제출 부탁드립니다.
( 제출 마감 : ${formattedApplicationPassConfirmStart} 오후 8시 )
`}
</span>
<a className={link} href="https://sopt.org" target="_blank" rel="noreferrer noopener">
{import.meta.env.VITE_PASS_LINK}
<span>{`( 구글폼 : `}</span>
<a
className={link}
href={`https://${import.meta.env.VITE_SCREENING_PASS_LINK}`}
target="_blank"
rel="noreferrer noopener">
{`https://${DEVICE_TYPE !== 'DESK' && '\n'}${import.meta.env.VITE_SCREENING_PASS_LINK}`}
</a>
<span>{` )\n`}</span>
<br />
<span>
{`
위 구글폼은 금일 20시 정각(${formattedApplicationPassConfirmStart} 오후 8시)까지 제출해주셔야 합니다.
면접 안내 사항 및 폼 제출 내용을 기반으로 한 면접 시간표를
내일(${formattedApplicationPassConfirmNextDay}) 오후 12시 전으로 이메일을 통해 전해드리겠습니다.
제출해주신 폼 내용을 기반으로 확정된 면접 일정 및 면접 안내를 내일(${formattedApplicationPassConfirmNextDay}) 오후 12시 전으로 이메일을 통해 공유드리겠습니다.
다시 한 번 진심으로 축하드리며, 인터뷰에서 뵙겠습니다!
문의 사항 및 궁금한 점은 아래 연락처로 문의 부탁드립니다.
정동규 : 010-8696-3713
감사합니다.
${SOPT_NAME} 운영진 드림
`}
</span>
<span>{`다시 한 번 진심으로 축하드리며, 면접에서 뵙도록 하겠습니다. :)`}</span>
</p>
) : (
<p className={content}>
{`안녕하세요. ${soptName}입니다.
${name}님은 ${season}${soptName} ${!isMakers ? group : ''} 신입회원 서류 모집에 불합격하셨습니다.
<p className={contentVar[DEVICE_TYPE]}>
{`안녕하세요, ${SOPT_NAME}입니다.
${SOPT_NAME}에 관심을 갖고 지원해 주셔서 감사드립니다.
${name}님의 뛰어난 역량과 잠재력에도 불구하고 안타깝게도 귀하의 합격 소식을 전해드리지 못하게 되었습니다.
지원자님의 뛰어난 역량과 잠재력에도 불구하고 안타깝게도 귀하의 합격 소식을
전해드리지 못하게 되었습니다.
비록 이번 ${season}${soptName}에 모시지 못하게 되었으나, ${soptName}에 지원하시고자 쓰인 소중한 시간과 노력이 지원자님께서 IT 창업인으로서 멋진 역할을 해나가시는 데 작게나마 도움이 되는 경험이 되시길 바랍니다.
한 분 한 분에게 개별적인 피드백을 드리기는 어렵겠으나 저희 SOPT에 지원하셨던
경험이 한 사람의 IT 창업인으로서 멋진 역할을 해나가시는 데 큰 도움이 되기를 바랍니다.
${SOPT_NAME}에 귀한 시간을 내어주셔서 다시 한 번 깊이 감사드립니다 :)
향후에 더 좋은 인연으로 뵙기를 기다리겠습니다.
감사합니다.
${SOPT_NAME} 운영진 드림
`}
</p>
)}
Expand All @@ -97,6 +108,7 @@ const Content = ({ pass }: { pass?: boolean }) => {
};

const ScreeningResult = () => {
const DEVICE_TYPE = useDevice();
const {
recruitingInfo: { isMakers },
handleSaveRecruitingInfo,
Expand All @@ -117,11 +129,13 @@ const ScreeningResult = () => {

return (
<section className={container}>
<div className={contentWrapper}>
<Title>결과 확인</Title>
<Content pass={pass} />
<div style={{ overflow: 'auto', height: '100%' }}>
<div className={contentWrapperVar[DEVICE_TYPE]}>
<Title>결과 확인</Title>
<Content pass={pass} />
</div>
</div>
{pass && (
{DEVICE_TYPE !== 'MOB' && pass && (
<>
<div className={bottomAnimation[isMakers ? 'makers' : 'sopt']} />
{isMakers ? (
Expand All @@ -136,6 +150,7 @@ const ScreeningResult = () => {
)}
</>
)}
<div className={scrollBottomGradVar[DEVICE_TYPE]} />
</section>
);
};
Expand Down
Loading

0 comments on commit 2cb21b1

Please sign in to comment.