Skip to content

Commit

Permalink
feat: 프로필 페이지 뷰 추가 (#59)
Browse files Browse the repository at this point in the history
  • Loading branch information
cos18 committed May 22, 2020
1 parent 3023b45 commit 9d8a6e4
Show file tree
Hide file tree
Showing 11 changed files with 344 additions and 17 deletions.
4 changes: 4 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import SignIn from 'frameworks/web/components/pages/SignIn/SignIn';
import SignUp from 'frameworks/web/components/pages/SignUp/SignUp';
import Footer from 'frameworks/web/components/organisms/Footer/Footer';
import SpeakerApply from 'frameworks/web/components/pages/SpeakerApply/SpeakerApply';
import Profile from 'frameworks/web/components/pages/Profile/Profile';
import StatusPage from 'frameworks/web/components/pages/StatusPage/StatusPage';

import apolloClient, { initStorage } from 'frameworks/web/apollo';
Expand Down Expand Up @@ -48,6 +49,9 @@ function App() {
<Route path={ROUTES.STATUS}>
<StatusPage />
</Route>
<Route path={ROUTES.PROFILE}>
<Profile email="[email protected]" name="테스트" phone="010-1234-5678" />
</Route>
</Switch>
<Footer />
</Router>
Expand Down
10 changes: 9 additions & 1 deletion src/frameworks/web/components/atoms/Button/Button.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,15 @@ export default {
export const DefaultButton = () => {
const label = text('Text', '바로가기');
const isPrimary = boolean('IsPrimary', true);
return <Button label={label} isPrimary={isPrimary} onClick={action('button-clicked')} />;
const isEnabled = boolean('isEnabled', true);
return (
<Button
label={label}
isPrimary={isPrimary}
isEnabled={isEnabled}
onClick={action('button-clicked')}
/>
);
};

export const FieldButton = () => {
Expand Down
34 changes: 24 additions & 10 deletions src/frameworks/web/components/atoms/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import { IBaseButton, IButton } from 'interfaces/frameworks/web/components/atoms

const BaseButton = styled.button`
font-family: 'Muli', 'Noto Sans KR', sans-serif;
background-color: ${(props: IBaseButton) =>
props.isPrimary ? theme.color.primary.Scarlet : theme.color.primary.Black};
color: ${theme.color.primary.White} !important;
opacity: ${(props: IBaseButton) => (props.isEnabled ? '1' : '0.3')};
border: none;
background-color: ${(props: IBaseButton) => props.bgColor};
color: ${(props: IBaseButton) =>
props.isEnabled ? theme.color.primary.White : theme.color.secondary.Moon} !important;
border: 1px solid
${(props: IBaseButton) => (props.isEnabled ? props.bgColor : theme.color.secondary.Ash)};
outline: none;
cursor: ${(props: IBaseButton) => (props.isEnabled ? 'pointer' : 'inherit')};
border-radius: 10px;
Expand All @@ -19,8 +19,9 @@ const BaseButton = styled.button`
@media (hover: hover) {
&:hover {
background-color: ${(props: IBaseButton) =>
props.isPrimary ? theme.color.primary.Salmon : theme.color.secondary.Nickel};
background-color: ${(props: IBaseButton) => props.hoverColor};
border-color: ${(props: IBaseButton) =>
props.isEnabled ? props.hoverColor : theme.color.secondary.Ash};
}
}
`;
Expand Down Expand Up @@ -71,16 +72,29 @@ export default function Button({
type = 'default',
label,
isPrimary = false,
onClick = null,
onClick = () => undefined,
isEnabled = true,
style,
}: IButton): React.ReactElement {
const ButtonComponent = BUTTONS[type];
let bgColor: string;
let hoverColor: string;
if (!isEnabled) {
bgColor = theme.color.primary.White;
hoverColor = bgColor;
} else if (isPrimary) {
bgColor = theme.color.primary.Scarlet;
hoverColor = theme.color.primary.Salmon;
} else {
bgColor = theme.color.primary.Black;
hoverColor = theme.color.secondary.Nickel;
}
return (
<ButtonComponent
isPrimary={isPrimary}
onClick={isEnabled ? onClick : undefined}
bgColor={bgColor}
hoverColor={hoverColor}
isEnabled={isEnabled}
onClick={() => (isEnabled ? onClick() : undefined)}
style={style}
>
{label}
Expand Down
6 changes: 3 additions & 3 deletions src/frameworks/web/components/atoms/TextField/TextField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ export default function TextField(props: ITextField): React.ReactElement {
const {
defaultLabel,
style,
type,
readOnly,
type = 'text',
readOnly = false,
value,
isButton,
isButton = false,
isError,
buttonSrc,
onButtonClicked,
Expand Down
171 changes: 171 additions & 0 deletions src/frameworks/web/components/organisms/Profile/ProfileInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
/* eslint-disable react/no-unused-state */
/* eslint-disable no-undef */
/* eslint-disable no-alert */
import React, { useState } from 'react';
import { useHistory } from 'react-router-dom';
import styled from 'styled-components';
import theme from 'theme';
import DividedCard from 'frameworks/web/components/molecules/DividedCard/DividedCard';
import Label from 'frameworks/web/components/atoms/Label/Label';
import TextField from 'frameworks/web/components/atoms/TextField/TextField';
import Button from 'frameworks/web/components/atoms/Button/Button';
import { IProfile } from 'interfaces/frameworks/web/components/pages/Profile/IProfile';
import { IProfileInfoState } from 'interfaces/frameworks/web/components/organisms/Profile/IProfileInfo';
import ProfileIllust from 'assets/illust/speaker-apply-illustration.png';

const TextLabelContainer = styled.div`
width: 93px;
float: left;
text-align: right;
`;

const TextFieldContainer = styled.div`
width: 445px;
float: right;
padding-bottom: 64px;
`;

const WarningTextContainer = styled.div`
float: right;
width: 400px;
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 16px;
`;

const WithdrawContainer = styled.div`
width: 289px;
margin-top: 17px;
float: right;
display: flex;
justify-content: space-between;
`;

export default function ProfileInfo(props: IProfile): React.ReactElement {
const { name, email, phone } = props;
const [state, setState] = useState<IProfileInfoState>({ name, phone, password: '' });
const history = useHistory();
const onPasswordChangeClicked = () => {
// 비밀번호 변경 버튼 클릭시 작동되는 함수
};

const onSaveButtonClicked = () => {
// save 버튼 클릭시 작동되는 함수
};

const onWithdrawClicked = () => {
history.push('/profile/withdraw');
};
return (
<div>
<DividedCard title="PROFILE" leftPadding="70px 0 0 0">
{{
left: (
<div>
<img
src={ProfileIllust}
alt="강연자 지원 이미지"
style={{ width: '380px', height: '450px', margin: '75px 0 0 0' }}
/>
</div>
),
right: (
<div style={{ margin: '16px 95px 0 68px' }}>
<TextLabelContainer>
<Label type="H5" style={{ marginTop: '14px' }} color={theme.color.secondary.Nickel}>
이름
</Label>
<Label type="H5" style={{ margin: '54px 0' }} color={theme.color.secondary.Nickel}>
이메일
</Label>
<Label
type="H5"
style={{ marginBottom: '54px' }}
color={theme.color.secondary.Nickel}
>
휴대폰
</Label>
<Label type="H5" color={theme.color.secondary.Nickel}>
현재 비밀번호
</Label>
</TextLabelContainer>
<TextFieldContainer>
<TextField
defaultLabel="이름을 입력하세요"
onValueChange={(data: string) =>
setState({ name: data, phone: state.phone, password: state.password })
}
style={{ width: 'auto' }}
value={state.name}
/>
<TextField
defaultLabel=""
onValueChange={() => undefined}
style={{ width: 'auto', margin: '24px 0' }}
readOnly
value={email}
/>
<TextField
defaultLabel="전화번호를 입력하세요"
onValueChange={(data: string) =>
setState({ name: state.name, phone: data, password: state.password })
}
style={{ width: 'auto' }}
value={state.phone}
/>
<div>
<Button
label="비밀번호 변경"
onClick={onPasswordChangeClicked}
style={{ float: 'right' }}
/>
<TextField
defaultLabel="현재 비밀번호를 입력하세요"
onValueChange={(data: string) =>
setState({ name: state.name, phone: state.phone, password: data })
}
style={{ width: '228px', marginTop: '24px' }}
value={state.password}
/>
</div>
<WarningTextContainer>
<img
src="warning.svg"
alt="경고 아이콘"
style={{ width: '20px', height: '18px' }}
/>
<div style={{ display: 'flex' }}>
<Label type="P2" color={theme.color.alert.Warning}>
현재 비밀번호
</Label>
<Label type="P2" color={theme.color.secondary.Moon}>
를 입력하셔야 개인정보 수정을 완료할 수 있습니다.
</Label>
</div>
</WarningTextContainer>
</TextFieldContainer>
<Button
type="default"
label="저장하기"
isPrimary
onClick={onSaveButtonClicked}
style={{ float: 'right' }}
/>
</div>
),
}}
</DividedCard>
<div style={{ width: '1100px', margin: '0 auto' }}>
<WithdrawContainer>
<Label type="P1" color={theme.color.secondary.Nickel}>
계정을 삭제하시겠습니까?
</Label>
<Label type="H5" color={theme.color.secondary.Nickel} onClick={onWithdrawClicked}>
계정 삭제하기
</Label>
</WithdrawContainer>
</div>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import React, { useState } from 'react';
import { useHistory } from 'react-router-dom';
import styled from 'styled-components';
import theme from 'theme';
import Label from 'frameworks/web/components/atoms/Label/Label';
import Button from 'frameworks/web/components/atoms/Button/Button';
import ContentsBox from 'frameworks/web/components/atoms/ContentsBox/ContentsBox';
import TextField from 'frameworks/web/components/atoms/TextField/TextField';

const CardContainer = styled(ContentsBox)`
width: 730px;
height: auto;
padding: 64px 0 64px 0;
margin: 0 auto;
background-color: white;
text-align: center;
`;

const ContextContainer = styled.div`
margin: 40px 0;
`;

const ButtonContainer = styled.div`
text-align: center;
margin-top: 48px;
`;

const EachButtonContainer = styled.div`
display: inline-block;
margin: 0 15px 0 15px;
`;

export default function ProfileWithdraw(): React.ReactElement {
const [checkText, setCheckText] = useState('');
const history = useHistory();

const onTextValueChange = (data: string) => {
setCheckText(data);
};

const onCancleButtonClicked = () => {
history.goBack();
};

const onDeleteButtonClicked = () => {
// 계정 삭제 로직 추가
};
return (
<CardContainer isDarkBackground={false}>
<Label type="H4" color={theme.color.primary.Azure}>
계정 삭제
</Label>
<ContextContainer>
<Label type="P1" color={theme.color.secondary.Moon} style={{ marginTop: '24px' }}>
계정을 삭제하시면 해당 홈페이지와 관련된 서비스를 이용할 수 없으며,
</Label>
<Label type="P1" color={theme.color.secondary.Moon}>
작성중인 신청폼이 모두 없어집니다. 계정 삭제를 완료하시려면
</Label>
<Label type="P1" color={theme.color.secondary.Moon}>
아래 빈칸에 <span style={{ color: '#F5503D', fontWeight: 'bold' }}>삭제하겠습니다</span>
입력해주세요.
</Label>
</ContextContainer>
<TextField
defaultLabel="삭제하겠습니다"
onValueChange={onTextValueChange}
style={{ width: '350px', margin: '0 auto' }}
/>
<ButtonContainer>
<EachButtonContainer>
<Button label="취소" onClick={onCancleButtonClicked} />
</EachButtonContainer>
<EachButtonContainer>
<Button
label="삭제하기"
isPrimary
isEnabled={checkText === '삭제하겠습니다'}
onClick={onDeleteButtonClicked}
/>
</EachButtonContainer>
</ButtonContainer>
</CardContainer>
);
}
30 changes: 30 additions & 0 deletions src/frameworks/web/components/pages/Profile/Profile.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import styled from 'styled-components';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import theme from 'theme';
import { IProfile } from 'interfaces/frameworks/web/components/pages/Profile/IProfile';
import ProfileInfo from 'frameworks/web/components/organisms/Profile/ProfileInfo';
import ProfileWithdraw from 'frameworks/web/components/organisms/Profile/ProfileWithdraw';
import * as ROUTES from 'utils/routes';

const ProfileContainer = styled.div`
padding: 200px 0 120px 0;
background-color: ${theme.color.secondary.Ash};
`;

export default function Profile({ name, email, phone }: IProfile): React.ReactElement {
return (
<Router>
<ProfileContainer>
<Switch>
<Route exact path={ROUTES.PROFILE}>
<ProfileInfo name={name} email={email} phone={phone} />
</Route>
<Route path={ROUTES.PROFILE_WITHDRAW}>
<ProfileWithdraw />
</Route>
</Switch>
</ProfileContainer>
</Router>
);
}
Loading

0 comments on commit 9d8a6e4

Please sign in to comment.