Skip to content

Commit

Permalink
[Feat] Login, Singup 페이지 GUI 반영 (#317)
Browse files Browse the repository at this point in the history
* chore: gui style 반영

* feat: term page gui

* feat: univ form publishing

* feat: useTermForm으로 분리

* feat: page로 분리

* chore: 불필요 파일 삭제

* chore: datepicker style 수정

* refactor: input -> datepicker

* feat: lazy 처리
  • Loading branch information
wuzoo authored Nov 17, 2024
1 parent cc67172 commit 6efb7bc
Show file tree
Hide file tree
Showing 31 changed files with 482 additions and 711 deletions.
16 changes: 8 additions & 8 deletions src/common/asset/svg/logo_tiki_md.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/common/component/DatePicker/Calendar/Calendar.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ export const containerStyle = css({

width: '25.6rem',

zIndex: theme.zIndex.overlayMiddle,

padding: '1.6rem',

border: `1px solid ${theme.colors.gray_300}`,
Expand Down
7 changes: 3 additions & 4 deletions src/common/component/DatePicker/Trigger/DatePickerTrigger.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,18 @@ interface DatePickerTriggerProps {
selectedDate: Date | null;
endDate?: Date | null;
onClick: () => void;
width?: string;
variant: 'single' | 'range';
}

const DatePickerTrigger = ({ selectedDate, endDate, onClick, width, variant }: DatePickerTriggerProps) => {
const DatePickerTrigger = ({ selectedDate, endDate, onClick, variant }: DatePickerTriggerProps) => {
return (
<Flex styles={{ direction: 'row', align: 'center', gap: '0.4rem' }}>
<Input
value={selectedDate ? format(selectedDate, 'yyyy.MM.dd') : ''}
placeholder="YYYY.MM.DD"
readOnly
onClick={onClick}
css={{ cursor: 'pointer', width, ...theme.text.body08, '::placeholder': { ...theme.text.body08 } }}
css={{ cursor: 'pointer', width: '100%', ...theme.text.body08, '::placeholder': { ...theme.text.body08 } }}
/>
{variant === 'range' && (
<>
Expand All @@ -34,7 +33,7 @@ const DatePickerTrigger = ({ selectedDate, endDate, onClick, width, variant }: D
placeholder="YYYY.MM.DD"
readOnly
onClick={onClick}
css={{ cursor: 'pointer', width, ...theme.text.body08, '::placeholder': { ...theme.text.body08 } }}
css={{ cursor: 'pointer', width: '100%', ...theme.text.body08, '::placeholder': { ...theme.text.body08 } }}
/>
</>
)}
Expand Down
14 changes: 9 additions & 5 deletions src/common/component/DatePicker/index.style.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { css } from '@emotion/react';

export const containerStyle = css({
display: 'flex',
flexDirection: 'column',
position: 'relative',
});
export const containerStyle = (width: string) =>
css({
display: 'flex',
flexDirection: 'column',
gap: '1.2rem',
position: 'relative',

width,
});
15 changes: 6 additions & 9 deletions src/common/component/DatePicker/index.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import DatePickerCalendar from '@/common/component/DatePicker/Calendar/DatePickerCalendar';
import DatePickerTrigger from '@/common/component/DatePicker/Trigger/DatePickerTrigger';
import { containerStyle } from '@/common/component/DatePicker/index.style';
import Label from '@/common/component/Label/Label';
import { useDatePicker } from '@/common/hook/useDatePicker';
import { useOutsideClick } from '@/common/hook/useOutsideClick';
import { useOverlay } from '@/common/hook/useOverlay';

interface DatePickerProps {
label?: string;
variant: 'single' | 'range';
triggerWidth?: string;
}

const DatePicker = ({ variant, triggerWidth = '10.3rem' }: DatePickerProps) => {
const DatePicker = ({ label, variant, triggerWidth = '10.3rem' }: DatePickerProps) => {
const { isOpen, close, toggle } = useOverlay();
const ref = useOutsideClick<HTMLDivElement>(close);
const { selectedDate, endDate, handleSelectDate, clearDates } = useDatePicker(variant);
Expand All @@ -24,14 +26,9 @@ const DatePicker = ({ variant, triggerWidth = '10.3rem' }: DatePickerProps) => {
};

return (
<div ref={ref} css={containerStyle}>
<DatePickerTrigger
selectedDate={selectedDate}
endDate={endDate}
onClick={handleInputClick}
variant={variant}
width={triggerWidth}
/>
<div ref={ref} css={containerStyle(triggerWidth)}>
{label && <Label id={label}>{label}</Label>}
<DatePickerTrigger selectedDate={selectedDate} endDate={endDate} onClick={handleInputClick} variant={variant} />
{isOpen && (
<DatePickerCalendar
selectedDate={selectedDate || new Date()}
Expand Down
6 changes: 3 additions & 3 deletions src/common/component/Modal/Modal.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ export const dialogStyle = css({
position: 'fixed',
top: '50%',
left: '50%',
width: '51.1rem',

zIndex: theme.zIndex.overlayTop,
paddingTop: '4.8rem',
paddingBottom: '4.8rem',

padding: '3.2rem 2rem',

borderRadius: '16px',
border: 'none',
outline: 'none',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const textStyle = (isError: boolean, isSuccess: boolean) => {
? theme.colors.sementic_red
: isSuccess
? theme.colors.sementic_success
: theme.colors.gray_400;
: theme.colors.gray_500;

return css({
color: textColor,
Expand Down
10 changes: 5 additions & 5 deletions src/common/router/Router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import ErrorBoundary from '@/common/component/ErrorBoundary/ErrorBoundary';
import {
ArchivingPage,
ComingsoonPage,
DashboardPage,
DrivePage,
ErrorPage,
HandoverNotePage,
Expand All @@ -17,10 +18,9 @@ import {
PasswordResetPage,
ShowcasePage,
TermPage,
UnivFormPage,
} from '@/common/router/lazy';

import DashboardPage from '@/page/dashboard/DashboardPage';

import { PATH } from '@/shared/constant/path';

const Public = () => {
Expand Down Expand Up @@ -70,15 +70,15 @@ const router = createBrowserRouter([
),
},
{
path: PATH.SIGNUP_INFO,
path: PATH.SIGNUP_UNIV,
element: (
<Suspense>
<InfoFormPage />
<UnivFormPage />
</Suspense>
),
},
{
path: PATH.SIGNUP_PASSWORD,
path: PATH.SIGNUP_INFO,
element: (
<Suspense>
<InfoFormPage />
Expand Down
2 changes: 2 additions & 0 deletions src/common/router/lazy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ export const ErrorPage = lazy(() => import('@/shared/page/errorPage/ErrorPage'))
export const ComingsoonPage = lazy(() => import('@/shared/page/comingsoonPage/ComingsoonPage'));
export const DrivePage = lazy(() => import('@/page/drive/index'));
export const HandoverNotePage = lazy(() => import('@/page/handover/note/NotePage'));
export const DashboardPage = lazy(() => import('@/page/dashboard/DashboardPage'));
export const UnivFormPage = lazy(() => import('@/page/signUp/info/UnivFormPage'));
7 changes: 2 additions & 5 deletions src/page/login/index/LoginPage.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,11 @@ export const formStyle = css({
display: 'flex',
flexDirection: 'column',

width: '51.1rem',
height: '53rem',
width: '60rem',

padding: '6rem',
padding: '6rem 10.5rem',
alignItems: 'center',
justifyContent: 'center',

gap: '3.2rem',
});

export const findPasswordButtonStyle = css({
Expand Down
11 changes: 8 additions & 3 deletions src/page/login/index/LoginPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const LoginPage = () => {

return (
<section css={pageStyle}>
<Logo width={108} height={40} />
<Logo css={{ flexShrink: 0 }} width={108} height={40} />
<form onSubmit={handleLogin} css={formStyle}>
<Flex styles={{ direction: 'column', gap: '0.8rem', width: '100%' }}>
<Input value={email} onChange={(e) => setEmail(e.target.value)} placeholder="아이디" />
Expand All @@ -47,10 +47,15 @@ const LoginPage = () => {
/>
</Flex>
<Flex styles={{ marginTop: '3.6rem', direction: 'column', width: '100%', gap: '1.2rem' }}>
<Button type="submit" variant="primary">
<Button size="xLarge" css={{ width: '100%' }} type="submit" variant="primary">
로그인
</Button>
<Button type="button" variant="secondary" onClick={회원가입페이지로이동}>
<Button
size="xLarge"
css={{ width: '100%' }}
type="button"
variant="secondary"
onClick={회원가입페이지로이동}>
학교 메일로 회원가입
</Button>
</Flex>
Expand Down
118 changes: 38 additions & 80 deletions src/page/signUp/index/TermPage.tsx
Original file line number Diff line number Diff line change
@@ -1,102 +1,60 @@
import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';

import Button from '@/common/component/Button/Button';
import Flex from '@/common/component/Flex/Flex';
import Heading from '@/common/component/Heading/Heading';
import Text from '@/common/component/Text/Text';
import { scrollStyle } from '@/common/style/scroll';

import { detailStyle } from '@/page/signUp/index/TermPage.style';
import TermArea from '@/page/signUp/index/component/TermArea/TermArea';
import TermItem from '@/page/signUp/index/component/TermItem/TermItem';
import TermsAgreeButton from '@/page/signUp/index/component/TermsAgreeButton/TermsAgreeButton';
import { pageStyle } from '@/page/signUp/info/InfoFormPage.style';
import { formStyle } from '@/page/signUp/info/component/InfoForm/InfoForm.style';
import { useTermForm } from '@/page/signUp/index/hook/useTermForm';
import { formStyle, pageStyle } from '@/page/signUp/info/InfoFormPage.style';

import { PATH } from '@/shared/constant/path';

import { PERSONAL, TERM } from '@/mock/data/term';

const TermPage = () => {
const [totalAgreeClicked, setTotalAgreeClicked] = useState(false);
const [requiredTermsStatus, setRequiredTermsStatus] = useState({
serviceTerm: false,
privatePolicy: false,
});
const [optionalTermsStatus, setOptionalTermsStatus] = useState({ collectionAgree: false });
const { isTotalAgreeClicked, termStatus, isConfirmed, handleAllTermsAgree, handleTermAgree } = useTermForm();

const navigate = useNavigate();

const isConfirmed = Object.values(requiredTermsStatus).every((item) => item === true);

useEffect(() => {
if (
!requiredTermsStatus.serviceTerm ||
!requiredTermsStatus.privatePolicy ||
!optionalTermsStatus.collectionAgree
) {
setTotalAgreeClicked(false);
}
}, [optionalTermsStatus, requiredTermsStatus, totalAgreeClicked]);

const 약관전체동의클릭 = () => {
setTotalAgreeClicked((prev) => !prev);

setRequiredTermsStatus({
serviceTerm: totalAgreeClicked ? false : true,
privatePolicy: totalAgreeClicked ? false : true,
});

setOptionalTermsStatus({ collectionAgree: !optionalTermsStatus.collectionAgree });
};

const handleNextStep = () => {
navigate(PATH.SIGNUP_INFO);
};
const handleNextStep = () => navigate(PATH.SIGNUP_UNIV);

return (
<Flex tag="main" css={pageStyle}>
<Flex tag="section" styles={{ direction: 'column', width: '51.1rem', gap: '3.2rem' }}>
<Heading tag="H3" css={{ padding: '1.6rem 0' }}>
이용 약관 동의
</Heading>
<form css={formStyle}>
<Flex styles={{ direction: 'column', width: '100%', gap: '3.2rem' }}>
<TermsAgreeButton isClicked={totalAgreeClicked} onClick={약관전체동의클릭} />

<TermArea
term="이용 약관"
onCheck={() => setRequiredTermsStatus((prev) => ({ ...prev, serviceTerm: !prev.serviceTerm }))}
isChecked={requiredTermsStatus.serviceTerm}>
<Text tag="body5" css={[detailStyle, scrollStyle]}>
{TERM}
</Text>
</TermArea>

<TermArea
term="개인정보 처리방침"
onCheck={() => setRequiredTermsStatus((prev) => ({ ...prev, privatePolicy: !prev.privatePolicy }))}
isChecked={requiredTermsStatus.privatePolicy}>
<Text tag="body5" css={[detailStyle, scrollStyle]}>
{PERSONAL}
</Text>
</TermArea>

<TermArea
term="개인정보 수집 및 이용"
onCheck={() => setOptionalTermsStatus((prev) => ({ ...prev, collectionAgree: !prev.collectionAgree }))}
isChecked={optionalTermsStatus.collectionAgree}
isRequired={false}>
<Text tag="body4" css={{ fontWeight: 400, marginLeft: '3.2rem' }}>
이벤트 혜택 정보 수신
</Text>
</TermArea>
</Flex>
<Button disabled={!isConfirmed} onClick={handleNextStep} variant="primary" size="large">
다음
</Button>
</form>
</Flex>
<form css={formStyle}>
<Heading tag="H4">이용 약관 동의</Heading>
<Flex styles={{ direction: 'column', width: '100%', gap: '1.6rem' }}>
<TermsAgreeButton isClicked={isTotalAgreeClicked} onClick={handleAllTermsAgree} />

<TermItem
term="이용 약관"
content={TERM}
description="티키 서비스 이용약관은 다음과 같은 내용을 담고 있습니다."
isRequired
isSelected={termStatus.serviceTerm}
onSelect={() => handleTermAgree('serviceTerm')}
/>
<TermItem
term="개인정보 처리 방침"
content={PERSONAL}
description="티키 서비스 이용약관은 다음과 같은 내용을 담고 있습니다."
isRequired
isSelected={termStatus.privatePolicy}
onSelect={() => handleTermAgree('privatePolicy')}
/>
<TermItem
term="개인정보 수집 및 이용"
content={PERSONAL}
description="티키 서비스 이용약관은 다음과 같은 내용을 담고 있습니다."
isSelected={termStatus.personalInfo}
onSelect={() => handleTermAgree('personalInfo')}
/>
</Flex>
<Button disabled={!isConfirmed} onClick={handleNextStep} variant="primary" size="xLarge">
다음
</Button>
</form>
</Flex>
);
};
Expand Down
20 changes: 0 additions & 20 deletions src/page/signUp/index/component/TermArea/TermArea.style.ts

This file was deleted.

Loading

0 comments on commit 6efb7bc

Please sign in to comment.