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

[Design] Mobile ver. - Dialog 구현 #392

Merged
merged 4 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import Layout from '@components/Layout';
import { RecruitingInfoContext, RecruitingInfoType } from '@store/recruitingInfoContext';
import { ModeType, ThemeContext } from '@store/themeContext';
import { dark, light } from 'styles/theme.css';
import SessionExpiredDialog from 'views/dialogs/SessionExpiredDialog';
import ErrorPage from 'views/ErrorPage';
import MainPage from 'views/MainPage';
import PasswordPage from 'views/PasswordPage';
Expand All @@ -21,6 +20,7 @@ import ReviewPage from 'views/ReviewPage';
import SignupPage from 'views/SignupPage';

import 'styles/reset.css';
import { SessionExpiredDialog } from 'views/dialogs';

const router = createBrowserRouter([
{
Expand Down
8 changes: 6 additions & 2 deletions src/common/components/Dialog/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import { forwardRef, type DialogHTMLAttributes, type ReactNode } from 'react';
import { createPortal } from 'react-dom';

import { container } from './style.css';
import { useDevice } from '@hooks/useDevice';

import { containerVar } from './style.css';

interface DialogProps extends DialogHTMLAttributes<HTMLDialogElement> {
children?: ReactNode;
}

const Dialog = forwardRef<HTMLDialogElement, DialogProps>(({ children, ...dialogElementProps }: DialogProps, ref) => {
const DEVICE_TYPE = useDevice();

return createPortal(
<dialog ref={ref} className={container} {...dialogElementProps}>
<dialog ref={ref} className={containerVar[DEVICE_TYPE]} {...dialogElementProps}>
{children}
</dialog>,
document.getElementById('modal')!,
Expand Down
26 changes: 23 additions & 3 deletions src/common/components/Dialog/style.css.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { colors } from '@sopt-makers/colors';
import { style } from '@vanilla-extract/css';
import { style, styleVariants } from '@vanilla-extract/css';

export const container = style({
width: 400,
const container = style({
padding: 24,
backgroundColor: colors.white, // subBackground
borderRadius: 14,
Expand All @@ -12,3 +11,24 @@ export const container = style({
backgroundColor: colors.grayAlpha500, // backgroundDimmed
},
});

export const containerVar = styleVariants({
DESK: [
container,
{
width: 400,
},
],
TAB: [
container,
{
width: 400,
},
],
MOB: [
container,
{
width: 313,
},
],
});
3 changes: 1 addition & 2 deletions src/views/ApplyPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import Button from '@components/Button';
import useCheckBrowser from '@hooks/useCheckBrowser';
import useDate from '@hooks/useDate';
import useScrollToHash from '@hooks/useScrollToHash';
import { DraftDialog, SubmitDialog } from 'views/dialogs';
import PreventApplyDialog from 'views/dialogs/PreventApplyDialog';
import { DraftDialog, PreventApplyDialog, SubmitDialog } from 'views/dialogs';
import NoMore from 'views/ErrorPage/components/NoMore';
import BigLoading from 'views/loadings/BigLoding';

Expand Down
2 changes: 1 addition & 1 deletion src/views/ReviewPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import PartSection from 'views/ApplyPage/components/PartSection';
import useGetDraft from 'views/ApplyPage/hooks/useGetDraft';
import useGetQuestions from 'views/ApplyPage/hooks/useGetQuestions';
import { container, formContainer } from 'views/ApplyPage/style.css';
import PreventReviewDialog from 'views/dialogs/PreventReviewDialog';
import { PreventReviewDialog } from 'views/dialogs';
import NoMore from 'views/ErrorPage/components/NoMore';
import BigLoading from 'views/loadings/BigLoding';

Expand Down
2 changes: 1 addition & 1 deletion src/views/SignupPage/components/SignupForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { PRIVACY_POLICY } from '@constants/policy';
import { VALIDATION_CHECK } from '@constants/validationCheck';
import useVerificationStatus from '@hooks/useVerificationStatus';
import { RecruitingInfoContext } from '@store/recruitingInfoContext';
import ExistingApplicantDialog from 'views/dialogs/ExistingApplicantDialog';
import { ExistingApplicantDialog } from 'views/dialogs';
import useMutateSignUp from 'views/SignupPage/hooks/useMutateSignUp';

import { formWrapper } from './style.css';
Expand Down
13 changes: 9 additions & 4 deletions src/views/dialogs/CompleteDialog/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,20 @@ import { forwardRef } from 'react';
import { Link } from 'react-router-dom';

import Dialog from '@components/Dialog';
import { useDevice } from '@hooks/useDevice';

import { buttonInside, buttonOutside, buttonWrapper, mainText, subText } from '../style.css';
import { buttonInside, buttonOutside, buttonOutsideVar, buttonWrapperVar, mainTextVar, subTextVar } from '../style.css';

const CompleteDialog = forwardRef<HTMLDialogElement>((_, ref) => {
const DEVICE_TYPE = useDevice();

return (
<Dialog ref={ref}>
<p className={mainText}>비밀번호 재설정이 완료되었어요.</p>
<p className={subText}>&apos;로그인&apos; 페이지로 이동할게요.</p>
<form method="dialog" className={`${buttonWrapper} ${buttonOutside.solid}`}>
<p className={mainTextVar[DEVICE_TYPE]}>비밀번호 재설정이 완료되었어요.</p>
<p className={subTextVar[DEVICE_TYPE]}>&apos;로그인&apos; 페이지로 이동할게요.</p>
<form
method="dialog"
className={`${buttonWrapperVar[DEVICE_TYPE]} ${buttonOutside.solid} ${buttonOutsideVar[DEVICE_TYPE]}`}>
<Link to="/" className={buttonInside.solid}>
확인
</Link>
Expand Down
11 changes: 8 additions & 3 deletions src/views/dialogs/DraftDialog/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import { forwardRef } from 'react';

import Dialog from '@components/Dialog';
import { useDevice } from '@hooks/useDevice';

import { buttonInside, buttonOutside, buttonWrapper, mainText } from '../style.css';
import { buttonInside, buttonOutside, buttonOutsideVar, buttonWrapperVar, mainTextVar } from '../style.css';

const DraftDialog = forwardRef<HTMLDialogElement>((_, ref) => {
const DEVICE_TYPE = useDevice();

return (
<Dialog ref={ref}>
<p className={mainText}>임시 저장이 완료되었어요.</p>
<form method="dialog" className={`${buttonWrapper} ${buttonOutside.solid}`}>
<p className={mainTextVar[DEVICE_TYPE]}>임시 저장이 완료되었어요.</p>
<form
method="dialog"
className={`${buttonWrapperVar[DEVICE_TYPE]} ${buttonOutside.solid} ${buttonOutsideVar[DEVICE_TYPE]}`}>
<button className={buttonInside.solid}>확인</button>
</form>
</Dialog>
Expand Down
11 changes: 7 additions & 4 deletions src/views/dialogs/ExistingApplicantDialog/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@ import { forwardRef } from 'react';
import { Link } from 'react-router-dom';

import Dialog from '@components/Dialog';
import { useDevice } from '@hooks/useDevice';

import { buttonInside, buttonOutside, buttonWrapper, mainText } from '../style.css';
import { buttonInside, buttonOutside, buttonOutsideVar, buttonWrapperVar, mainTextVar } from '../style.css';

const ExistingApplicantDialog = forwardRef<HTMLDialogElement>((_, ref) => {
const DEVICE_TYPE = useDevice();

return (
<Dialog ref={ref}>
<p className={mainText}>이미 가입된 계정이 있어요.</p>
<div className={buttonWrapper}>
<form method="dialog" className={buttonOutside.line}>
<p className={mainTextVar[DEVICE_TYPE]}>이미 가입된 계정이 있어요.</p>
<div className={buttonWrapperVar[DEVICE_TYPE]}>
<form method="dialog" className={`${buttonOutside.line} ${buttonOutsideVar[DEVICE_TYPE]}`}>
<button className={buttonInside.line}>다시 입력하기</button>
</form>
<div className={buttonOutside.solid}>
Expand Down
15 changes: 9 additions & 6 deletions src/views/dialogs/ExitDialog/index.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
import { forwardRef } from 'react';

import Dialog from '@components/Dialog';
import { useDevice } from '@hooks/useDevice';

import { buttonInside, buttonOutside, buttonWrapper, mainText, subText } from '../style.css';
import { buttonInside, buttonOutside, buttonOutsideVar, buttonWrapperVar, mainTextVar, subTextVar } from '../style.css';

const ExitDialog = forwardRef<HTMLDialogElement>((_, ref) => {
const DEVICE_TYPE = useDevice();

return (
<Dialog ref={ref}>
<p className={mainText}>이대로 나가시겠어요?</p>
<p className={subText}>변경사항이 있는 경우 임시저장을 해주세요.</p>
<div className={buttonWrapper}>
<form method="dialog" className={buttonOutside.line}>
<p className={mainTextVar[DEVICE_TYPE]}>이대로 나가시겠어요?</p>
<p className={subTextVar[DEVICE_TYPE]}>변경사항이 있는 경우 임시저장을 해주세요.</p>
<div className={buttonWrapperVar[DEVICE_TYPE]}>
<form method="dialog" className={`${buttonOutside.line} ${buttonOutsideVar[DEVICE_TYPE]}`}>
<button className={buttonInside.line}>머물기</button>
</form>
<div className={buttonOutside.solid}>
<div className={`${buttonOutside.solid} ${buttonOutsideVar[DEVICE_TYPE]}`}>
<button className={buttonInside.solid}>나가기</button>
</div>
</div>
Expand Down
11 changes: 8 additions & 3 deletions src/views/dialogs/PreventApplyDialog/index.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
import { forwardRef, type KeyboardEvent } from 'react';

import Dialog from '@components/Dialog';
import { useDevice } from '@hooks/useDevice';

import { buttonInside, buttonOutside, buttonWrapper, mainText } from '../style.css';
import { buttonInside, buttonOutside, buttonOutsideVar, buttonWrapperVar, mainTextVar } from '../style.css';

const PreventApplyDialog = forwardRef<HTMLDialogElement>((_, ref) => {
const DEVICE_TYPE = useDevice();

const handlePreventESCKeyPress = (e: KeyboardEvent<HTMLDialogElement>) => {
if (e.key === 'Escape') e.preventDefault();
};

return (
<Dialog ref={ref} onKeyDown={handlePreventESCKeyPress}>
<p className={mainText}>지원서 제출 기한이 지났어요.</p>
<form method="dialog" className={`${buttonWrapper} ${buttonOutside.solid}`}>
<p className={mainTextVar[DEVICE_TYPE]}>지원서 제출 기한이 지났어요.</p>
<form
method="dialog"
className={`${buttonWrapperVar[DEVICE_TYPE]} ${buttonOutside.solid} ${buttonOutsideVar[DEVICE_TYPE]}`}>
<button className={buttonInside.solid}>확인</button>
</form>
</Dialog>
Expand Down
13 changes: 9 additions & 4 deletions src/views/dialogs/PreventReviewDialog/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,24 @@ import { forwardRef, type KeyboardEvent } from 'react';
import { Link } from 'react-router-dom';

import Dialog from '@components/Dialog';
import { useDevice } from '@hooks/useDevice';

import { buttonInside, buttonOutside, buttonWrapper, mainText, subText } from '../style.css';
import { buttonInside, buttonOutside, buttonOutsideVar, buttonWrapperVar, mainTextVar, subTextVar } from '../style.css';

const PreventReviewDialog = forwardRef<HTMLDialogElement>((_, ref) => {
const DEVICE_TYPE = useDevice();

const handlePreventESCKeyPress = (e: KeyboardEvent<HTMLDialogElement>) => {
if (e.key === 'Escape') e.preventDefault();
};

return (
<Dialog ref={ref} onKeyDown={handlePreventESCKeyPress}>
<p className={mainText}>지원서 제출을 먼저 해주세요.</p>
<p className={subText}>&apos;지원서&apos; 페이지로 이동할게요.</p>
<form method="dialog" className={`${buttonWrapper} ${buttonOutside.solid}`}>
<p className={mainTextVar[DEVICE_TYPE]}>지원서 제출을 먼저 해주세요.</p>
<p className={subTextVar[DEVICE_TYPE]}>&apos;지원서&apos; 페이지로 이동할게요.</p>
<form
method="dialog"
className={`${buttonWrapperVar[DEVICE_TYPE]} ${buttonOutside.solid} ${buttonOutsideVar[DEVICE_TYPE]}`}>
<Link to="/" className={buttonInside.solid}>
확인
</Link>
Expand Down
13 changes: 9 additions & 4 deletions src/views/dialogs/SessionExpiredDialog/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ import { track } from '@amplitude/analytics-browser';
import { forwardRef, type KeyboardEvent } from 'react';

import Dialog from '@components/Dialog';
import { useDevice } from '@hooks/useDevice';

import { buttonInside, buttonOutside, buttonWrapper, mainText, subText } from '../style.css';
import { buttonInside, buttonOutside, buttonOutsideVar, buttonWrapperVar, mainTextVar, subTextVar } from '../style.css';

const SessionExpiredDialog = forwardRef<HTMLDialogElement>((_, ref) => {
const DEVICE_TYPE = useDevice();

const handlePreventESCKeyPress = (e: KeyboardEvent<HTMLDialogElement>) => {
if (e.key === 'Escape') e.preventDefault();
};
Expand All @@ -23,9 +26,11 @@ const SessionExpiredDialog = forwardRef<HTMLDialogElement>((_, ref) => {

return (
<Dialog ref={ref} onKeyDown={handlePreventESCKeyPress}>
<p className={mainText}>로그인을 다시 해주세요.</p>
<p className={subText}>세션이 만료되었거나 비정상적인 로그인이에요.</p>
<form method="dialog" className={`${buttonWrapper} ${buttonOutside.solid}`}>
<p className={mainTextVar[DEVICE_TYPE]}>로그인을 다시 해주세요.</p>
<p className={subTextVar[DEVICE_TYPE]}>세션이 만료되었거나 비정상적인 로그인이에요.</p>
<form
method="dialog"
className={`${buttonWrapperVar[DEVICE_TYPE]} ${buttonOutside.solid} ${buttonOutsideVar[DEVICE_TYPE]}`}>
<button className={buttonInside.solid} onClick={handleLogout}>
확인
</button>
Expand Down
49 changes: 30 additions & 19 deletions src/views/dialogs/SubmitDialog/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,34 @@ import { track } from '@amplitude/analytics-browser';
import { type ChangeEvent, forwardRef, useState } from 'react';

import Dialog from '@components/Dialog';
import { useDevice } from '@hooks/useDevice';
import ButtonLoading from 'views/loadings/ButtonLoading';

import {
checkboxContainer,
checkboxWrapper,
checkmark,
hiddenCheckbox,
infoContainer,
infoLabel,
infoValue,
infoWrapper,
infoContainerVar,
infoLabelVar,
infoValueVar,
infoWrapperVar,
} from './style.css';
import { buttonInside, buttonOutside, buttonWrapper, mainText, subText } from '../style.css';
import { buttonInside, buttonOutside, buttonOutsideVar, buttonWrapperVar, mainTextVar, subTextVar } from '../style.css';

const MyInfoItem = ({ label, value }: { label: string; value: string }) => {
const MyInfoItem = ({
DEVICE_TYPE,
label,
value,
}: {
DEVICE_TYPE: 'MOB' | 'TAB' | 'DESK';
label: string;
value: string;
}) => {
return (
<li className={infoWrapper}>
<label className={infoLabel}>{label}</label>
<span className={infoValue}>{value}</span>
<li className={infoWrapperVar[DEVICE_TYPE]}>
<label className={infoLabelVar[DEVICE_TYPE]}>{label}</label>
<span className={infoValueVar[DEVICE_TYPE]}>{value}</span>
</li>
);
};
Expand All @@ -40,19 +49,21 @@ const SubmitDialog = forwardRef<HTMLDialogElement, SubmitDialogProps>(
({ userInfo: { name, email, phone, part }, dataIsPending, onSendData }, ref) => {
const [isChecked, setIsChecked] = useState(false);

const DEVICE_TYPE = useDevice();

const handleCheck = (e: ChangeEvent<HTMLInputElement>) => {
setIsChecked(e.target.checked);
};

return (
<Dialog ref={ref}>
<p className={mainText}>이대로 제출하시겠어요?</p>
<p className={subText}>제출 완료하신 지원서는 수정하실 수 없어요.</p>
<ol className={infoContainer}>
<MyInfoItem label="이름" value={name} />
<MyInfoItem label="이메일" value={email} />
<MyInfoItem label="전화번호" value={phone} />
<MyInfoItem label="지원파트" value={part} />
<p className={mainTextVar[DEVICE_TYPE]}>이대로 제출하시겠어요?</p>
<p className={subTextVar[DEVICE_TYPE]}>제출 완료하신 지원서는 수정하실 수 없어요.</p>
<ol className={infoContainerVar[DEVICE_TYPE]}>
<MyInfoItem DEVICE_TYPE={DEVICE_TYPE} label="이름" value={name} />
<MyInfoItem DEVICE_TYPE={DEVICE_TYPE} label="이메일" value={email} />
<MyInfoItem DEVICE_TYPE={DEVICE_TYPE} label="전화번호" value={phone} />
<MyInfoItem DEVICE_TYPE={DEVICE_TYPE} label="지원파트" value={part} />
</ol>
<div className={checkboxContainer}>
<label className={checkboxWrapper}>
Expand All @@ -66,16 +77,16 @@ const SubmitDialog = forwardRef<HTMLDialogElement, SubmitDialogProps>(
<span>확인했습니다.</span>
</label>
</div>
<div className={buttonWrapper}>
<div className={buttonWrapperVar[DEVICE_TYPE]}>
<form
method="dialog"
className={dataIsPending ? buttonOutside.disabled : buttonOutside.line}
className={`${dataIsPending ? buttonOutside.disabled : buttonOutside.line} ${buttonOutsideVar[DEVICE_TYPE]}`}
onSubmit={() => setIsChecked(false)}>
<button className={buttonInside.line} disabled={dataIsPending} onClick={() => track('click-apply-cancel')}>
{dataIsPending ? <ButtonLoading width={48} height={18} /> : '검토하기'}
</button>
</form>
<div className={buttonOutside[!isChecked ? 'disabled' : 'solid']}>
<div className={`${buttonOutside[!isChecked ? 'disabled' : 'solid']} ${buttonOutsideVar[DEVICE_TYPE]}`}>
<button className={buttonInside.solid} onClick={onSendData} disabled={!isChecked || dataIsPending}>
{dataIsPending ? <ButtonLoading width={48} height={18} /> : '제출하기'}
</button>
Expand Down
Loading