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

feat: 강연 목록 페이지 뷰 추가 #109

Merged
merged 3 commits into from
May 29, 2020
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
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`;