Skip to content

Commit 55ff197

Browse files
added comments
1 parent 39c6d46 commit 55ff197

14 files changed

+298
-11
lines changed

package-lock.json

Lines changed: 37 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@
1111
"@testing-library/react": "^12.1.2",
1212
"@testing-library/user-event": "^13.5.0",
1313
"@types/jest": "^27.4.0",
14+
"@types/luxon": "^2.0.9",
1415
"@types/node": "^16.11.17",
1516
"@types/react": "^17.0.38",
1617
"@types/react-dom": "^17.0.11",
18+
"@types/uuid": "^8.3.4",
19+
"luxon": "^2.3.0",
1720
"mobx": "^6.3.10",
1821
"mobx-react": "^7.2.1",
1922
"react": "^17.0.2",
@@ -23,6 +26,7 @@
2326
"react-scripts": "5.0.0",
2427
"remark-gfm": "^3.0.1",
2528
"typescript": "^4.5.4",
29+
"uuid": "^8.3.2",
2630
"web-vitals": "^2.1.2"
2731
},
2832
"scripts": {

src/App.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@ import { Main } from "./components/main";
1414
import { SideNavStore } from "./store/side-nav-store";
1515
import { SubRedditStore } from "./store/sub-reddit-store";
1616
import { PostStore } from "./store/post-store";
17+
import { CommentStore } from "./store/comment-store";
1718
function App() {
1819
return (
1920
<Box sx={{ display: "flex", flexGrow: 1, height: "100vh" }}>
2021
<Main
2122
sideNavStore={SideNavStore}
2223
subRedditStore={SubRedditStore}
2324
postStore={PostStore}
25+
commentStore={CommentStore}
2426
></Main>
2527
</Box>
2628
);

src/components/about.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export const About = observer(() => {
2929
sort, nested comments, or anything but the most minimal features.
3030
</Typography>
3131
<Typography fontWeight="bold">Technologies Used</Typography>
32-
<Typography variant="body2">
32+
<Typography variant="body2" component="span">
3333
<ul>
3434
<li>React</li>
3535
<li>Typescript</li>

src/components/main.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,13 @@ import { About } from "./about";
1414
import { ISubRedditStore } from "../store/sub-reddit-store";
1515
import { SubReddit } from "./subreddit";
1616
import { IPostStore } from "../store/post-store";
17+
import { PostDetail } from "./post-details";
18+
import { ICommentStore } from "../store/comment-store";
1719
export interface MainParameters {
1820
sideNavStore: ISideNavStore;
1921
subRedditStore: ISubRedditStore;
20-
postStore: IPostStore
22+
postStore: IPostStore;
23+
commentStore: ICommentStore;
2124
}
2225
const Main = observer((parameters: MainParameters) => {
2326
return (
@@ -58,6 +61,15 @@ const Main = observer((parameters: MainParameters) => {
5861
></SubReddit>
5962
}
6063
></Route>
64+
<Route
65+
path="post/:id"
66+
element={
67+
<PostDetail
68+
commentStore={parameters.commentStore}
69+
postsStore={parameters.postStore}
70+
></PostDetail>
71+
}
72+
></Route>
6173
<Route path="about" element={<About></About>} />
6274
<Route index element={<Navigate to="r/all"></Navigate>}></Route>
6375
</Route>
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import {
2+
Box,
3+
Card,
4+
CardContent,
5+
Chip,
6+
Collapse,
7+
IconButton,
8+
Typography,
9+
} from "@mui/material";
10+
import { observer } from "mobx-react";
11+
import { ICommentStore } from "../store/comment-store";
12+
import ArrowUpwardIcon from "@mui/icons-material/ArrowUpward";
13+
import ArrowDownwardIcon from "@mui/icons-material/ArrowDownward";
14+
import React from "react";
15+
import { ExpandLess, ExpandMore } from "@mui/icons-material";
16+
export interface PostCommentDetailsParams {
17+
commentStore: ICommentStore;
18+
commentId: string;
19+
}
20+
21+
export const PostCommentDetails = observer(
22+
(params: PostCommentDetailsParams) => {
23+
const comment = params.commentStore.getById(params.commentId);
24+
const [textOpen, setTextOpen] = React.useState(true);
25+
return (
26+
<Box
27+
sx={{
28+
display: "flex",
29+
flexGrow: 1,
30+
flexDirection: "column",
31+
}}
32+
>
33+
<Card variant="outlined">
34+
<CardContent>
35+
<Box
36+
sx={{
37+
display: "flex",
38+
}}
39+
>
40+
<Chip label={comment.votes} color="secondary"></Chip>
41+
<IconButton
42+
component="span"
43+
color="primary"
44+
onClick={() => params.commentStore.upvote(params.commentId)}
45+
sx={{
46+
paddingLeft: "0",
47+
paddingRight: "0",
48+
}}
49+
>
50+
<ArrowUpwardIcon></ArrowUpwardIcon>
51+
</IconButton>
52+
<IconButton
53+
onClick={() => params.commentStore.downvote(params.commentId)}
54+
component="span"
55+
color="error"
56+
sx={{
57+
paddingLeft: 0,
58+
paddingRight: 0,
59+
}}
60+
>
61+
<ArrowDownwardIcon></ArrowDownwardIcon>
62+
</IconButton>
63+
<IconButton onClick={() => setTextOpen(!textOpen)}>
64+
{textOpen ? <ExpandLess /> : <ExpandMore />}
65+
</IconButton>
66+
</Box>
67+
<Collapse
68+
in={textOpen}
69+
timeout="auto"
70+
unmountOnExit
71+
sx={{ width: "100%" }}
72+
>
73+
<Typography variant="body1">{comment.content}</Typography>
74+
</Collapse>
75+
</CardContent>
76+
</Card>
77+
</Box>
78+
);
79+
}
80+
);

src/components/post-details.tsx

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import {
2+
Box,
3+
Button,
4+
List,
5+
ListItem,
6+
TextField,
7+
Typography,
8+
} from "@mui/material";
9+
import { observer } from "mobx-react";
10+
import React from "react";
11+
import { useParams } from "react-router-dom";
12+
import { IPostStore } from "../store/post-store";
13+
import { PostItem } from "./post-item";
14+
import { DateTime } from "luxon";
15+
import { v4 as uuidV4 } from "uuid";
16+
import { PostComment } from "../model/comment";
17+
import { ICommentStore } from "../store/comment-store";
18+
import { PostCommentDetails } from "./post-comment-details";
19+
export interface PostDetailParams {
20+
postsStore: IPostStore;
21+
commentStore: ICommentStore;
22+
}
23+
24+
export const PostDetail = observer((params: PostDetailParams) => {
25+
const { id } = useParams();
26+
const [commentDetais, setCommentDetails] = React.useState("");
27+
const addComment = () => {
28+
const newComment: PostComment = {
29+
postId: id as string,
30+
votes: 0,
31+
createdAt: DateTime.now().toISO(),
32+
id: uuidV4(),
33+
content: commentDetais,
34+
};
35+
params.commentStore.addComment(newComment);
36+
setCommentDetails("");
37+
};
38+
const postComments = params.commentStore
39+
.getByPostId(id as string)
40+
.map((comment) => (
41+
<ListItem key={`${comment.id}`}>
42+
<PostCommentDetails
43+
commentId={comment.id}
44+
commentStore={params.commentStore}
45+
></PostCommentDetails>
46+
</ListItem>
47+
));
48+
return (
49+
<Box
50+
sx={{
51+
display: "flex",
52+
flexGrow: 1,
53+
flexDirection: "column",
54+
justifyContent: "start",
55+
}}
56+
>
57+
<Box>
58+
<PostItem
59+
postId={id as string}
60+
postStore={params.postsStore}
61+
></PostItem>
62+
</Box>
63+
64+
<Box
65+
sx={{
66+
display: "flex",
67+
flexDirection: "column",
68+
paddingLeft: 1,
69+
paddingRight: 1,
70+
}}
71+
>
72+
<Typography variant="body1">Add Comment</Typography>
73+
<TextField
74+
placeholder="Add Comment"
75+
maxRows={10}
76+
minRows={3}
77+
multiline
78+
value={commentDetais}
79+
onChange={(event) => setCommentDetails(event.target.value)}
80+
></TextField>
81+
<Button disabled={!commentDetais} onClick={() => addComment()}>
82+
Submit
83+
</Button>
84+
</Box>
85+
<Box
86+
sx={{
87+
display: "flex",
88+
flexDirection: "column",
89+
}}
90+
>
91+
<List>{postComments}</List>
92+
</Box>
93+
</Box>
94+
);
95+
});

src/components/post-item.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import ReactMarkdown from "react-markdown";
2020
import remarkGfm from "remark-gfm";
2121
import { IPostStore } from "../store/post-store";
2222
import { observer } from "mobx-react";
23+
import { Link } from "react-router-dom";
2324
export interface PostItemParams {
2425
postId: string;
2526
postStore: IPostStore;
@@ -114,7 +115,9 @@ export const PostItem = observer((params: PostItemParams) => {
114115
}}
115116
>
116117
{post.type === "link" ? linkItemContent() : textItemContent()}
117-
<Typography variant="caption">Comments</Typography>
118+
<Typography variant="caption">
119+
<Link to={`/post/${post.id}`}>Comments</Link>
120+
</Typography>
118121
</CardContent>
119122
</Card>
120123
</Box>

src/components/side-nav.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,12 @@ export const SideNav = observer((params: SideNavParams) => {
6060
flexDirection: "column",
6161
}}
6262
>
63-
<ListItemButton component={Link} to="/r/all">
63+
<ListItemButton key="all" component={Link} to="/r/all">
6464
<ListItemText>All</ListItemText>
6565
<LinkIcon></LinkIcon>
6666
</ListItemButton>
6767
{params.subRedditStore.allSubreddits.map((sub) => (
68-
<SubRedditLink subreddit={sub}></SubRedditLink>
68+
<SubRedditLink key={sub.name} subreddit={sub}></SubRedditLink>
6969
))}
7070
</Box>
7171
</List>

0 commit comments

Comments
 (0)