From 2cb21b1d2b287068e676fb58b1a81c4c5b4a6f8f Mon Sep 17 00:00:00 2001 From: lydiacho <81505421+lydiacho@users.noreply.github.com> Date: Mon, 12 Aug 2024 12:43:49 +0900 Subject: [PATCH] =?UTF-8?q?[Design]=20Mobile=20ver.=20-=20=EA=B2=B0?= =?UTF-8?q?=EA=B3=BC=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EB=B0=98=EC=9D=91?= =?UTF-8?q?=ED=98=95=20=20(#370)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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: 테스트용 코드 삭제 --- src/common/constants/zIndex.ts | 2 + src/views/MyPage/index.tsx | 1 + .../ResultPage/components/FinalResult.tsx | 92 +++++++++++++----- .../ResultPage/components/ScreeningResult.tsx | 95 ++++++++++-------- src/views/ResultPage/components/style.css.ts | 97 ++++++++++++++++--- src/views/SignedInPage/index.tsx | 1 - 6 files changed, 209 insertions(+), 79 deletions(-) diff --git a/src/common/constants/zIndex.ts b/src/common/constants/zIndex.ts index 6097901d..0ba68481 100644 --- a/src/common/constants/zIndex.ts +++ b/src/common/constants/zIndex.ts @@ -7,4 +7,6 @@ export const Z_INDEX = { applyCategory: 99, applyHeader: 99, resultContent: 2, + resultGrad: 3, + resultAnim: 4, }; diff --git a/src/views/MyPage/index.tsx b/src/views/MyPage/index.tsx index ef735d22..f8718150 100644 --- a/src/views/MyPage/index.tsx +++ b/src/views/MyPage/index.tsx @@ -36,6 +36,7 @@ const StatusButton = ({ label, to, trackingEvent }: { label: string; to: string; const handlePreventMobile = (e: MouseEvent) => { track(trackingEvent); + if (label === '지원상태') return; const isMobile = /Mobi/i.test(window.navigator.userAgent); if (isMobile) { diff --git a/src/views/ResultPage/components/FinalResult.tsx b/src/views/ResultPage/components/FinalResult.tsx index 05a70aaa..2460840c 100644 --- a/src/views/ResultPage/components/FinalResult.tsx +++ b/src/views/ResultPage/components/FinalResult.tsx @@ -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 ? ( -

- {`안녕하세요. ${season}기 ${soptName} 입니다.\n\n`} +

+ {`안녕하세요. ${SOPT_NAME}입니다.\n\n`} {`축하드립니다!`} {` - ${name}님은 ${season}기 ${soptName} ${!isMakers ? group : ''} 신입회원 모집에 최종 합격하셨습니다. + ${name}님은 ${season}기 ${SOPT_NAME} ${!isMakers ? group : ''} 신입회원 모집에 최종 합격하셨습니다. ${name}님과 함께하게 되어 진심으로 기쁩니다. - 향후 활동은 ${soptName} 공식 노션과 카카오톡 단체 대화방, SOPT 공식 디스코드를 통해 - 운영 및 진행됩니다. + 향후 활동은 ${SOPT_NAME} 공식 노션과 슬랙,카카오톡 단체 대화방, ${SOPT_NAME} 공식 디스코드 등을 통해 운영 및 진행됩니다. - 오늘 중으로 카카오톡 단체 대화방에 초대해드릴 예정이니 참고 부탁드립니다.\n + 아래 구글 폼으로 각 워크스페이스 이메일 계정 및 필수 정보를 제출해주시길 바랍니다. + ( 제출 마감 : ${formattedFinalPassConfirmStart} 오후 11:59 ) + `} + + {`( 구글폼 : `} + + {`https://${DEVICE_TYPE !== 'DESK' && '\n'}${import.meta.env.VITE_FINAL_PASS_LINK}`} + + {` )\n`} +
+ + {` + 제출해주신 구글 폼을 통해 순차적으로 워크스페이스 초대해드릴 예정이며 + 금일 중으로 카카오톡 단체 대화방에 초대해드릴 예정이니 참고 부탁드립니다. + + 다시 한 번 ${SOPT_NAME} ${season}기 합류를 진심으로 축하드립니다! + + ${SOPT_NAME} 운영진 드림 `} - {`SOPT의 ${season}번째 열정이 되신 것을 축하드립니다!`}

) : ( -

- {`안녕하세요. ${soptName} 입니다. - - ${name}님은 ${season}기 ${soptName} ${!isMakers ? group : ''} 신입회원 모집에 불합격하셨습니다. +

+ {`안녕하세요, ${SOPT_NAME}입니다. + + ${SOPT_NAME}에 관심을 갖고 지원해 주셔서 감사드립니다. - 지원자님의 뛰어난 역량과 잠재력에도 불구하고 안타깝게도 귀하의 최종 합격 소식을 - 전해드리지 못하게 되었습니다. + ${name}님의 뛰어난 역량과 잠재력에도 불구하고 안타깝게도 귀하의 합격 소식을 전해드리지 못하게 되었습니다. - 한 분 한 분에게 개별적인 피드백을 드리기는 어렵겠으나 저희 SOPT에 지원하셨던 - 경험이 한 사람의 IT 창업인으로서 멋진 역할을 해나가시는 데 큰 도움이 되기를 바랍니다. + 비록 이번 ${season}기 ${soptName}에 모시지 못하게 되었으나, ${soptName}에 지원하시고자 쓰인 소중한 시간과 노력이 지원자님께서 IT 창업인으로서 멋진 역할을 해나가시는 데 작게나마 도움이 되는 경험이 되시길 바랍니다. + + ${SOPT_NAME}에 귀한 시간을 내어주셔서 다시 한 번 깊이 감사드립니다 :) + 향후에 더 좋은 인연으로 뵙기를 기다리겠습니다. + 감사합니다. + + ${SOPT_NAME} 운영진 드림 `}

)} @@ -58,6 +98,7 @@ const Content = ({ pass }: { pass?: boolean }) => { }; const FinalResult = () => { + const DEVICE_TYPE = useDevice(); const { finalResult, finalResultIsLoading } = useGetFinalResult(); const { recruitingInfo: { isMakers }, @@ -76,11 +117,13 @@ const FinalResult = () => { return (
-
- 결과 확인 - +
+
+ 결과 확인 + +
- {pass && ( + {DEVICE_TYPE !== 'MOB' && pass && ( <>
{isMakers ? ( @@ -95,6 +138,7 @@ const FinalResult = () => { )} )} +
); }; diff --git a/src/views/ResultPage/components/ScreeningResult.tsx b/src/views/ResultPage/components/ScreeningResult.tsx index 81d91478..e2e17ed4 100644 --- a/src/views/ResultPage/components/ScreeningResult.tsx +++ b/src/views/ResultPage/components/ScreeningResult.tsx @@ -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'; @@ -11,9 +12,10 @@ import { bottomImg, bottomSvg, container, - content, - contentWrapper, + contentVar, + contentWrapperVar, link, + scrollBottomGradVar, strongText, } from './style.css'; import IconMakersLogo from '../assets/IconMakersLogo'; @@ -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; @@ -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 ? ( -

- {`안녕하세요. ${season}기 ${soptName} 입니다.\n\n`} +

+ {`안녕하세요. ${SOPT_NAME} 입니다.\n\n`} {`축하드립니다!`} {` - 서류 검토 결과, ${name}님은 면접 대상자로 선정되셨습니다. + 서류 검토 결과, ${name}님은 인터뷰 대상자로 선정되셨습니다. + + ${season}기 ${SOPT_NAME} 인터뷰는 ${formattedInterviewStart} ~ ${formattedInterviewEnd} 기간 중 진행될 예정입니다. - ${season}기 ${soptName} ${!isMakers ? group : ''} 면접은 ${formattedInterviewStart} ~ ${formattedInterviewEnd} 양일 간 오프라인 으로 진행될 예정입니다. - 모든 면접 대상자 분들은 아래 구글폼을 제출해주세요. + 원할한 면접 진행을 위해, 아래 구글 폼에 불가능한 시간대를 모두 선택해 제출 부탁드립니다. + ( 제출 마감 : ${formattedApplicationPassConfirmStart} 오후 8시 ) `} - - {import.meta.env.VITE_PASS_LINK} + {`( 구글폼 : `} + + {`https://${DEVICE_TYPE !== 'DESK' && '\n'}${import.meta.env.VITE_SCREENING_PASS_LINK}`} + {` )\n`}
{` - 위 구글폼은 금일 20시 정각(${formattedApplicationPassConfirmStart} 오후 8시)까지 제출해주셔야 합니다. - 면접 안내 사항 및 폼 제출 내용을 기반으로 한 면접 시간표를 - 내일(${formattedApplicationPassConfirmNextDay}) 오후 12시 전으로 이메일을 통해 전해드리겠습니다. - + 제출해주신 폼 내용을 기반으로 확정된 면접 일정 및 면접 안내를 내일(${formattedApplicationPassConfirmNextDay}) 오후 12시 전으로 이메일을 통해 공유드리겠습니다. + + 다시 한 번 진심으로 축하드리며, 인터뷰에서 뵙겠습니다! + + 문의 사항 및 궁금한 점은 아래 연락처로 문의 부탁드립니다. + 정동규 : 010-8696-3713 + 감사합니다. + + ${SOPT_NAME} 운영진 드림 `} - {`다시 한 번 진심으로 축하드리며, 면접에서 뵙도록 하겠습니다. :)`}

) : ( -

- {`안녕하세요. ${soptName}입니다. - - ${name}님은 ${season}기 ${soptName} ${!isMakers ? group : ''} 신입회원 서류 모집에 불합격하셨습니다. +

+ {`안녕하세요, ${SOPT_NAME}입니다. + + ${SOPT_NAME}에 관심을 갖고 지원해 주셔서 감사드립니다. + + ${name}님의 뛰어난 역량과 잠재력에도 불구하고 안타깝게도 귀하의 합격 소식을 전해드리지 못하게 되었습니다. - 지원자님의 뛰어난 역량과 잠재력에도 불구하고 안타깝게도 귀하의 합격 소식을 - 전해드리지 못하게 되었습니다. + 비록 이번 ${season}기 ${soptName}에 모시지 못하게 되었으나, ${soptName}에 지원하시고자 쓰인 소중한 시간과 노력이 지원자님께서 IT 창업인으로서 멋진 역할을 해나가시는 데 작게나마 도움이 되는 경험이 되시길 바랍니다. - 한 분 한 분에게 개별적인 피드백을 드리기는 어렵겠으나 저희 SOPT에 지원하셨던 - 경험이 한 사람의 IT 창업인으로서 멋진 역할을 해나가시는 데 큰 도움이 되기를 바랍니다. + ${SOPT_NAME}에 귀한 시간을 내어주셔서 다시 한 번 깊이 감사드립니다 :) + 향후에 더 좋은 인연으로 뵙기를 기다리겠습니다. + 감사합니다. + + ${SOPT_NAME} 운영진 드림 `}

)} @@ -97,6 +108,7 @@ const Content = ({ pass }: { pass?: boolean }) => { }; const ScreeningResult = () => { + const DEVICE_TYPE = useDevice(); const { recruitingInfo: { isMakers }, handleSaveRecruitingInfo, @@ -117,11 +129,13 @@ const ScreeningResult = () => { return (
-
- 결과 확인 - +
+
+ 결과 확인 + +
- {pass && ( + {DEVICE_TYPE !== 'MOB' && pass && ( <>
{isMakers ? ( @@ -136,6 +150,7 @@ const ScreeningResult = () => { )} )} +
); }; diff --git a/src/views/ResultPage/components/style.css.ts b/src/views/ResultPage/components/style.css.ts index e381b865..de2907b1 100644 --- a/src/views/ResultPage/components/style.css.ts +++ b/src/views/ResultPage/components/style.css.ts @@ -1,6 +1,5 @@ import { colors } from '@sopt-makers/colors'; import { keyframes, style, styleVariants } from '@vanilla-extract/css'; -import { calc } from '@vanilla-extract/css-utils'; import { Z_INDEX } from '@constants/zIndex'; import { theme } from 'styles/theme.css'; @@ -8,32 +7,70 @@ import { theme } from 'styles/theme.css'; export const container = style({ position: 'relative', width: '100%', - height: calc.subtract('100vh', '74px'), minHeight: 700, overflow: 'hidden', - - '@supports': { - '(height: 100dvh)': { - height: calc.subtract('100dvh', '74px'), - }, - }, }); -export const contentWrapper = style({ +const contentWrapper = style({ display: 'flex', flexDirection: 'column', - width: 720, - gap: 50, - margin: '90px auto 0', color: theme.color.baseText, ...theme.font.BODY_1_18_M, }); -export const content = style({ +export const contentWrapperVar = styleVariants({ + DESK: [ + contentWrapper, + { + margin: '90px auto 0', + width: 720, + gap: 50, + }, + ], + TAB: [ + contentWrapper, + { + margin: '90px auto 0', + width: 367, + gap: 50, + }, + ], + MOB: [ + contentWrapper, + { + margin: '43px auto 0', + width: 312, + gap: 30, + }, + ], +}); + +const content = style({ whiteSpace: 'pre-line', zIndex: Z_INDEX.resultContent, }); +export const contentVar = styleVariants({ + DESK: [ + content, + { + paddingBottom: 202, + }, + ], + TAB: [ + content, + { + paddingBottom: 170, + }, + ], + MOB: [ + content, + { + paddingBottom: 107, + }, + ], +}); + export const strongText = styleVariants({ sopt: { color: theme.color.primary, @@ -50,6 +87,7 @@ const bottomAnimationBase = style({ transform: 'translateX(-50%)', height: 100, borderRadius: '100%', + zIndex: Z_INDEX.resultAnim, }); const animatedGradient = (bgColor: string) => @@ -90,10 +128,41 @@ export const bottomSvg = style({ position: 'absolute', bottom: 0, right: 0, - margin: '0px 130px 140px 0px', + marginBottom: 'calc(56px + (64 * ((100vw - 768px) / 672)))', + marginRight: 'calc(40px + (60 * ((100vw - 768px) / 672)))', width: 584, }); export const link = style({ borderBottom: '1px solid currentColor', }); + +const scrollBottomGrad = style({ + position: 'fixed', + bottom: 0, + left: 0, + right: 0, + background: 'linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 1) 100%);', + zIndex: Z_INDEX.resultGrad, +}); + +export const scrollBottomGradVar = styleVariants({ + DESK: [ + scrollBottomGrad, + { + height: 220, + }, + ], + TAB: [ + scrollBottomGrad, + { + height: 170, + }, + ], + MOB: [ + scrollBottomGrad, + { + height: 110, + }, + ], +}); diff --git a/src/views/SignedInPage/index.tsx b/src/views/SignedInPage/index.tsx index b0ae5723..6323fb49 100644 --- a/src/views/SignedInPage/index.tsx +++ b/src/views/SignedInPage/index.tsx @@ -33,7 +33,6 @@ const SignedInPage = () => { return ( <> - {isComplete && } {!isComplete && submit && } {!isComplete && !submit && }