Skip to content

Commit

Permalink
feat: 강연 목록 페이지 뷰 추가 (#109)
Browse files Browse the repository at this point in the history
  • Loading branch information
cos18 authored May 29, 2020
1 parent e2e1da7 commit 3292791
Show file tree
Hide file tree
Showing 13 changed files with 407 additions and 5 deletions.
4 changes: 4 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import LandingPage from 'frameworks/web/components/pages/Landing/Landing';
import SignInPage from 'frameworks/web/components/pages/SignIn/SignIn';
import SignUpPage from 'frameworks/web/components/pages/SignUp/SignUp';
import StatusPage from 'frameworks/web/components/pages/StatusPage/StatusPage';
import Lecture from 'frameworks/web/components/pages/Lecture/Lecture';

import apolloClient, { initStorage } from 'frameworks/web/apollo';
import * as ROUTES from 'utils/routes';
Expand Down Expand Up @@ -52,6 +53,9 @@ function App() {
<Route path={ROUTES.PROFILE}>
<ProfilePage />
</Route>
<Route path={ROUTES.LECTURE}>
<Lecture />
</Route>
</Switch>
<Footer />
</Router>
Expand Down
4 changes: 4 additions & 0 deletions src/assets/icon/search.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
138 changes: 138 additions & 0 deletions src/assets/illust/list-illlustration.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 28 additions & 0 deletions src/assets/logo/logo-white.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 2 additions & 4 deletions src/frameworks/web/components/atoms/TextField/TextField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const ImgButton = styled.img`
height: 24px;
float: right;
cursor: pointer;
margin-right: ${(props: ITextFieldElement) => (props.isFocus ? '22px' : '24px')};
margin-right: 24px;
`;

const OptionalLabel = styled.p<IOptionalLabelElement>`
Expand Down Expand Up @@ -135,9 +135,7 @@ export default function TextField(props: ITextField): React.ReactElement {
onChange={(event) => onLabelChange(event.target.value)}
value={value}
/>
{isButton && (
<ImgButton src={buttonSrc} onClick={() => onButtonClicked!()} isFocus={state.isFocus} />
)}
{isButton && <ImgButton src={buttonSrc} onClick={() => onButtonClicked!()} />}
</TextFieldContainerActivate>
{optionalString && <OptionalLabel isError={isError ?? false}>{optionalString}</OptionalLabel>}
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';
import { withKnobs, text } from '@storybook/addon-knobs';
import { action } from '@storybook/addon-actions';
import theme from 'theme';
import LectureCard from 'frameworks/web/components/molecules/LectureCard/LectureCard';

export default {
title: 'Lecture Card',
decorators: [withKnobs],
};

export const SimpleLectureCard = () => {
const title = text('Card Title', '프로그래머, 인공지능 시대의 꽤 괜찮은 직업이지 아니한가?');
const speaker = text('Card Speaker', '박성우');

return (
<div style={{ width: '350px', margin: '20px' }}>
<LectureCard title={title} speaker={speaker} onCardClick={action('card-clicked')} />
</div>
);
};

SimpleLectureCard.story = {
parameters: {
backgrounds: [{ name: 'Snow', value: theme.color.secondary.Snow, default: true }],
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React from 'react';
import styled from 'styled-components';
import theme from 'theme';

import ContentsBox from 'frameworks/web/components/atoms/ContentsBox/ContentsBox';
import Label from 'frameworks/web/components/atoms/Label/Label';
import { ILectureCard } from 'interfaces/frameworks/web/components/molecules/LectureCard/ILectureCard';

const CardContainer = styled(ContentsBox)`
width: auto;
height: auto;
padding: 40px 48px;
background-color: white;
text-align: center;
cursor: pointer;
transition: all 0.2s;
@media (hover: hover) {
&:hover {
box-shadow: 0 5px 30px 0 rgba(155, 155, 155, 0.4);
}
}
`;

const SpeakerContainer = styled.div`
display: flex;
margin-top: 24px;
width: 100%;
justify-content: center;
`;

export default function LectureCard({
title,
speaker,
onCardClick,
style,
}: ILectureCard): React.ReactElement {
return (
// eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions
<div onClick={() => onCardClick()}>
<CardContainer isDarkBackground style={style}>
<Label type="H4" color={theme.color.primary.Azure}>
{title}
</Label>
<SpeakerContainer>
<Label type="H5" color={theme.color.secondary.Moon} style={{ marginRight: '16px' }}>
강연자
</Label>
<Label type="P1" color={theme.color.secondary.Moon}>
{speaker}
</Label>
</SpeakerContainer>
</CardContainer>
</div>
);
}
2 changes: 1 addition & 1 deletion src/frameworks/web/components/organisms/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export const PAGES = {
ROUTES.PROFILE_WITHDRAW,
ROUTES.STATUS,
],
ALWAYS: [ROUTES.HOME],
ALWAYS: [ROUTES.HOME, ROUTES.LECTURE],
};

export default function Header(): React.ReactElement {
Expand Down
52 changes: 52 additions & 0 deletions src/frameworks/web/components/organisms/Lecture/LectureList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React, { ReactNode } from 'react';
import styled from 'styled-components';
import { Row, Col } from 'react-grid-system';

import { ILectureInfo } from 'interfaces/frameworks/web/components/organisms/Lecture/ILectureList';
import LectureCard from '../../molecules/LectureCard/LectureCard';

const LectureListContainer = styled.div`
width: 100%;
max-width: 1280px;
padding: 48px 85px 90px 85px;
`;

export default function LectureList(): React.ReactElement {
const lectureArray: ILectureInfo[] = [];

// TODO: 강연 정보를 불러와야 함
for (let i = 1; i <= 10; i += 1) {
lectureArray.push({ title: `제목 ${i}`, speaker: '테스트' });
}

const onLectureClicked = (idx: number) => {
// TODO: 렉쳐카드 클릭 시 모달이 나오는 함수를 구현해야 함
console.log(idx);
};

function LectureColContainer({ col }: any): React.ReactElement {
const listElement: ReactNode[] = [];
lectureArray.forEach((lecture, i) => {
if (i % 3 === col) {
listElement.push(
<LectureCard
title={lecture.title}
speaker={lecture.speaker}
onCardClick={() => onLectureClicked(i)}
style={{ marginBottom: '30px' }}
/>,
);
}
});
return <Col>{listElement}</Col>;
}
return (
<LectureListContainer>
<Row align="start">
<LectureColContainer col={0} />
<LectureColContainer col={1} />
<LectureColContainer col={2} />
</Row>
</LectureListContainer>
);
}
83 changes: 83 additions & 0 deletions src/frameworks/web/components/pages/Lecture/Lecture.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import React, { useState } from 'react';
import styled from 'styled-components';
import { Row, Col } from 'react-grid-system';

import theme from 'theme';
import SomulLogo from 'assets/logo/logo-white.svg';
import SearchButtonAsset from 'assets/icon/search.svg';
import ListIllustAsset from 'assets/illust/list-illlustration.svg';
import Label from 'frameworks/web/components/atoms/Label/Label';
import TextField from 'frameworks/web/components/atoms/TextField/TextField';
import LectureList from 'frameworks/web/components/organisms/Lecture/LectureList';

const LectureHeader = styled.div`
margin-top: 80px;
padding: 23px 0;
display: flex;
justify-content: center;
background-color: ${theme.color.primary.Azure};
`;

const LectureHeaderContainer = styled(Row)`
width: 100%;
max-width: 1280px;
padding: 0 85px;
`;

const LectureHeaderTitle = styled.div`
display: flex;
margin-bottom: 38px;
`;

const ListIllust = styled.img`
width: 240px;
height: 174px;
`;

const LectureListContainer = styled.div`
display: flex;
justify-content: center;
background-color: ${theme.color.secondary.Snow};
`;

export default function Lecture(): React.ReactElement {
const [searchText, setSearchText] = useState('');
const handleSearch = () => {
console.log(searchText);
// TODO : 검색 로직 구현
};
return (
<>
<LectureHeader>
<LectureHeaderContainer align="center" justify="between" gutterWidth={0}>
<Col xs={8}>
<LectureHeaderTitle>
<img
src={SomulLogo}
alt="소물 로고"
style={{ width: '138px', height: '24px', margin: '6px 21px 6px 0' }}
/>
<Label type="H4" color={theme.color.primary.White}>
강연 리스트
</Label>
</LectureHeaderTitle>
<TextField
defaultLabel="검색어를 입력하세요"
onValueChange={(search: string) => setSearchText(search)}
isButton
buttonSrc={SearchButtonAsset}
onButtonClicked={() => handleSearch()}
style={{ width: 'auto' }}
/>
</Col>
<Col xs={3}>
<ListIllust src={ListIllustAsset} alt="일러스트 이미지" />
</Col>
</LectureHeaderContainer>
</LectureHeader>
<LectureListContainer>
<LectureList />
</LectureListContainer>
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface ILectureCard {
title: string;
speaker: string;
onCardClick: Function;
style?: object;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface ILectureInfo {
title: string;
speaker: string;
// 이후 모달 추가시 인터페이스에 내용 추가
}
2 changes: 2 additions & 0 deletions src/utils/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ export const STATUS = `/status`;

export const PROFILE = `/profile`;
export const PROFILE_WITHDRAW = `${PROFILE}/withdraw`;

export const LECTURE = `/lecture`;

0 comments on commit 3292791

Please sign in to comment.