Skip to content

Commit fd4a732

Browse files
feat(story): Story view (not finished)
1 parent b0a0275 commit fd4a732

40 files changed

+589
-207
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
.idea
1+
.idea
2+
etc

app/.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ module.exports = {
2121

2222
'@typescript-eslint/default-param-last': 0,
2323
'import/prefer-default-export': 0,
24+
'react/no-danger': 0,
2425
'no-param-reassign': 0,
2526
'no-return-assign': 0,
2627
'no-plusplus': 0,

app/src/App.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import {
66
Navigate,
77
} from 'react-router-dom';
88

9-
import StoriesList from 'pages/stories/List';
9+
import StoriesList from 'pages/stories';
10+
import Story from 'pages/story';
1011

1112
import 'assets/styles/main.scss';
1213

@@ -15,6 +16,7 @@ const App = () => (
1516
<Routes>
1617
<Route path="/" element={<Navigate to="/stories/top" />} />
1718
<Route path="/stories/:type" element={<StoriesList />} />
19+
<Route path="/story/:id" element={<Story />} />
1820
</Routes>
1921
</Router>
2022
);
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import React from 'react';
2+
3+
import { CommentInterface } from 'types/comment';
4+
5+
import { Wrapper, HeaderRow, Author, Content, Replies } from './styles';
6+
7+
type Props = {
8+
comment: CommentInterface;
9+
storyId: number;
10+
};
11+
12+
const CommentItemCard: React.FC<Props> = ({ comment, storyId }) => (
13+
<Wrapper>
14+
<HeaderRow>
15+
<Author>{comment.by}</Author>
16+
<div>5 hours ago</div>
17+
</HeaderRow>
18+
<Content dangerouslySetInnerHTML={{ __html: comment.text ?? '' }} />
19+
{comment.kids.length > 0 && comment.parent === storyId && (
20+
<Replies>{comment.kids.length} replies collapsed</Replies>
21+
)}
22+
</Wrapper>
23+
);
24+
25+
export default CommentItemCard;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import styled from 'styled-components';
2+
3+
export const Wrapper = styled.div`
4+
font-size: 1.3rem;
5+
`;
6+
7+
export const HeaderRow = styled.div`
8+
display: flex;
9+
align-items: center;
10+
11+
color: #828282;
12+
`;
13+
14+
export const Author = styled.div`
15+
margin-right: 0.5rem;
16+
17+
text-decoration: underline;
18+
`;
19+
20+
export const Content = styled.div`
21+
margin: 1rem 0;
22+
`;
23+
24+
export const Replies = styled.div`
25+
width: 100%;
26+
27+
padding: 0.5rem;
28+
29+
font-size: 1.2rem;
30+
31+
background-color: #fffbf2;
32+
color: #828282;
33+
34+
border-radius: 0.4rem;
35+
36+
&:hover {
37+
cursor: pointer;
38+
}
39+
`;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import React from 'react';
2+
3+
import { CommentsTree } from 'types/comment';
4+
5+
import CommentItemCard from 'components/common/card/comment/list-item/CommentItemCard';
6+
7+
import { Wrapper } from './styles';
8+
9+
type Props = {
10+
comments: CommentsTree;
11+
storyId: number;
12+
};
13+
14+
const CommentListCard: React.FC<Props> = ({ comments, storyId }) => (
15+
<Wrapper>
16+
{comments.map((comment) => (
17+
<CommentItemCard key={comment.id} storyId={storyId} comment={comment} />
18+
))}
19+
</Wrapper>
20+
);
21+
22+
export default CommentListCard;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import styled from 'styled-components';
2+
3+
export const Wrapper = styled.div`
4+
padding: 1.5rem 3rem;
5+
6+
background-color: #fff;
7+
`;

app/src/components/common/card/item/CardItem.tsx

Lines changed: 0 additions & 37 deletions
This file was deleted.

app/src/components/common/card/list/CardList.tsx

Lines changed: 0 additions & 26 deletions
This file was deleted.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import React from 'react';
2+
3+
import { StoryInterface } from 'types/story';
4+
5+
import {
6+
Wrapper,
7+
Score,
8+
Title,
9+
Source,
10+
Author,
11+
Line,
12+
CommentsCount,
13+
Row,
14+
SourceLink,
15+
} from './styles';
16+
17+
type Props = {
18+
story: StoryInterface;
19+
};
20+
21+
const StoryItemCard: React.FC<Props> = ({ story }) => (
22+
<Wrapper>
23+
<Score>{story.score}</Score>
24+
<div>
25+
{story.url ? (
26+
<Source href={story.url} target="_blank">
27+
<Row>
28+
<Title>{story.title}</Title>
29+
<Source href={story.url} target="_blank">
30+
({story.url})
31+
</Source>
32+
</Row>
33+
</Source>
34+
) : (
35+
<SourceLink to={`/story/${story.id}`}>
36+
<Row>
37+
<Title>{story.title}</Title>
38+
</Row>
39+
</SourceLink>
40+
)}
41+
<Row>
42+
<Author>By {story.by}</Author>
43+
{story.descendants && (
44+
<>
45+
<Line />
46+
<CommentsCount>{story.descendants} comments</CommentsCount>
47+
</>
48+
)}
49+
</Row>
50+
</div>
51+
</Wrapper>
52+
);
53+
54+
export default StoryItemCard;

app/src/components/common/card/item/styles.ts renamed to app/src/components/common/card/story/list-item/styles.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import styled from 'styled-components';
22

3+
import { Link } from 'react-router-dom';
4+
35
export const Wrapper = styled.div`
46
display: flex;
57
align-items: center;
@@ -39,6 +41,10 @@ export const Source = styled.a`
3941
color: #828282;
4042
`;
4143

44+
export const SourceLink = styled(Link)`
45+
color: #828282;
46+
`;
47+
4248
export const Description = styled.div`
4349
color: #828282;
4450
`;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import React from 'react';
2+
3+
import CardItem from 'components/common/card/story/list-item/StoryItemCard';
4+
5+
import { StoryInterface } from 'types/story';
6+
7+
import { List, ListItem } from './styles';
8+
9+
type Props = {
10+
stories: StoryInterface[];
11+
};
12+
13+
const StoryListCard: React.FC<Props> = ({ stories }) => (
14+
<List>
15+
{stories.map(
16+
(item) =>
17+
item && (
18+
<ListItem key={item.id}>
19+
<CardItem story={item} />
20+
</ListItem>
21+
)
22+
)}
23+
</List>
24+
);
25+
26+
export default StoryListCard;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import React from 'react';
2+
3+
import { ItemInterface } from 'types/item';
4+
5+
import { Wrapper, Title, Row, Score, Author, Time } from './styles';
6+
7+
type Props = {
8+
story: ItemInterface;
9+
};
10+
11+
const StorySingleCard: React.FC<Props> = ({ story }) => (
12+
<Wrapper>
13+
<Title>{story.title}</Title>
14+
<Row>
15+
<Score>{story.score} points</Score>| by
16+
<Author>{story.by}</Author>
17+
<Time>6 hours ago</Time>
18+
</Row>
19+
</Wrapper>
20+
);
21+
22+
export default StorySingleCard;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import styled from 'styled-components';
2+
3+
export const Wrapper = styled.div`
4+
padding: 2rem 3rem;
5+
6+
background-color: #fff;
7+
`;
8+
9+
export const Title = styled.h2`
10+
margin-bottom: 1rem;
11+
12+
font-size: 2.4rem;
13+
font-weight: 700;
14+
`;
15+
16+
export const Row = styled.div`
17+
display: flex;
18+
align-items: center;
19+
20+
font-size: 1.5rem;
21+
22+
color: #828282;
23+
`;
24+
25+
export const Score = styled.div`
26+
margin-right: 0.5rem;
27+
`;
28+
29+
export const Author = styled.div`
30+
margin: 0 0.5rem;
31+
32+
text-decoration: underline;
33+
`;
34+
35+
export const Time = styled.div``;

app/src/components/styled/content.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,10 @@ import styled from 'styled-components';
22

33
export const FullContent = styled.div`
44
grid-column: col-start 1 / col-end 12;
5+
6+
& > * {
7+
&:not(:last-of-type) {
8+
margin-bottom: 1.5rem;
9+
}
10+
}
511
`;

app/src/hooks/useActions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { useMemo } from 'react';
22
import { useDispatch } from 'react-redux';
33
import { bindActionCreators } from 'redux';
44

5-
import { actionCreators } from 'store/action-creators';
5+
import actionCreators from 'store/action-creators';
66

77
export const useActions = () => {
88
const dispatch = useDispatch();

0 commit comments

Comments
 (0)