From 08bea5333a71438b2ede89a30eff2ecbc7e6be2a Mon Sep 17 00:00:00 2001 From: Wioleta Lip Date: Fri, 30 Jan 2026 23:56:36 +0100 Subject: [PATCH 1/3] develop --- README.md | 2 +- src/App.scss | 29 ----- src/App.tsx | 120 ++++---------------- src/components/CommentInfo/CommentInfo.tsx | 24 +++- src/components/CommentList/CommentList.scss | 8 +- src/components/CommentList/CommentList.tsx | 17 ++- src/components/PostInfo/PostInfo.scss | 21 +++- src/components/PostInfo/PostInfo.tsx | 34 +++++- src/components/PostList/PostList.tsx | 17 ++- src/components/UserInfo/UserInfo.scss | 5 +- src/components/UserInfo/UserInfo.tsx | 14 ++- src/types/Comment.ts | 7 ++ src/types/Post.ts | 11 ++ src/types/User.ts | 5 + 14 files changed, 181 insertions(+), 133 deletions(-) create mode 100644 src/types/Comment.ts create mode 100644 src/types/Post.ts create mode 100644 src/types/User.ts diff --git a/README.md b/README.md index b1a2b34341..bab47ac02e 100644 --- a/README.md +++ b/README.md @@ -17,4 +17,4 @@ This task is similar to [Static List of TODOs](https://github.com/mate-academy/r - Implement a solution following the [React task guideline](https://github.com/mate-academy/react_task-guideline#react-tasks-guideline). - Use the [React TypeScript cheat sheet](https://mate-academy.github.io/fe-program/js/extra/react-typescript). - Open one more terminal and run tests with `npm test` to ensure your solution is correct. -- Replace `` with your Github username in the [DEMO LINK](https://.github.io/react_static-list-of-posts/) and add it to the PR description. +- Replace `` with your Github username in the [DEMO LINK](https://wiolip.github.io/react_static-list-of-posts/) and add it to the PR description. diff --git a/src/App.scss b/src/App.scss index 98bb3956c3..6436509521 100644 --- a/src/App.scss +++ b/src/App.scss @@ -5,32 +5,3 @@ iframe { .App__title { text-align: center; } - -.PostInfo { - margin: 10px auto; - width: 90%; - border: 1px solid #000; - border-radius: 8px; - background-color: lightgray; - padding: 1em; - - &__title { - margin: 0; - } - - &__header { - margin-bottom: 1em; - } -} - -.UserInfo { - font-weight: bold; -} - -.CommentList { - display: flex; - flex-direction: column; - gap: 0.7em; - background-color: #eee; - padding: 1em; -} diff --git a/src/App.tsx b/src/App.tsx index 6ccd7807c2..8bf7a58b4b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,106 +1,36 @@ import React from 'react'; - import './App.scss'; +import { type Comment } from './types/Comment'; +import { type User } from './types/User'; +import { PostList } from './components/PostList'; -// import postsFromServer from './api/posts'; -// import commentsFromServer from './api/comments'; -// import usersFromServer from './api/users'; - -export const App: React.FC = () => ( -
-

Static list of posts

- -
-
-
-

qui est esse

- -

- {' Posted by '} - - - Leanne Graham - -

-
- -

- est rerum tempore vitae sequi sint nihil reprehenderit dolor beatae ea - dolores neque fugiat blanditiis voluptate porro vel nihil molestiae ut - reiciendis qui aperiam non debitis possimus qui neque nisi nulla -

- -
+import postsFromServer from './api/posts'; +import commentsFromServer from './api/comments'; +import usersFromServer from './api/users'; - No comments yet -
+function getUserById(userId: number): User | undefined { + return usersFromServer.find(user => user.id === userId); +} -
-
-

doloremque illum aliquid sunt

+function getCommentsByPostId(postId: number): Comment[] { + return commentsFromServer.filter(comment => comment.postId === postId); +} -

- {' Posted by '} +export const posts = postsFromServer.map(post => { + const user = getUserById(post.userId); + const comments = getCommentsByPostId(post.id); - - Patricia Lebsack - -

-
+ return { + ...post, + user, + comments, + }; +}); -

- deserunt eos nobis asperiores et hic est debitis repellat molestiae - optio nihil ratione ut eos beatae quibusdam distinctio maiores earum - voluptates et aut adipisci ea maiores voluptas maxime -

- -
-
-
- pariatur omnis in - - {' by '} - - - Telly_Lynch@karl.co.uk - -
- -
- dolorum voluptas laboriosam quisquam ab totam beatae et aut - aliquid optio assumenda voluptas velit itaque quidem voluptatem - tempore cupiditate in itaque sit molestiae minus dolores magni -
-
- -
-
- - odio adipisci rerum aut animi - - - {' by '} - - - Nikita@garfield.biz - -
+export const App: React.FC = () => ( +
+

Static list of posts

-
- quia molestiae reprehenderit quasi aspernatur aut expedita - occaecati aliquam eveniet laudantium omnis quibusdam delectus - saepe quia accusamus maiores nam est cum et ducimus et vero - voluptates excepturi deleniti ratione -
-
-
-
-
+
); diff --git a/src/components/CommentInfo/CommentInfo.tsx b/src/components/CommentInfo/CommentInfo.tsx index 4471a7b9a3..8ce7688f87 100644 --- a/src/components/CommentInfo/CommentInfo.tsx +++ b/src/components/CommentInfo/CommentInfo.tsx @@ -1,3 +1,25 @@ import React from 'react'; +import { type Comment } from '../../types/Comment'; +import './CommentInfo.css'; -export const CommentInfo: React.FC = () => <>Put the comment here; +type Props = { + comment: Comment; +}; + +export const CommentInfo: React.FC = ({ comment }) => { + return ( +
+
+ {comment.name} + + {' by '} + + + {comment.email} + +
+ +
{comment.body}
+
+ ); +}; diff --git a/src/components/CommentList/CommentList.scss b/src/components/CommentList/CommentList.scss index f1b40ee00e..91c2ed5fbb 100644 --- a/src/components/CommentList/CommentList.scss +++ b/src/components/CommentList/CommentList.scss @@ -1 +1,7 @@ -// add styles here +.CommentList { + display: flex; + flex-direction: column; + gap: 0.7em; + background-color: #eee; + padding: 1em; +} diff --git a/src/components/CommentList/CommentList.tsx b/src/components/CommentList/CommentList.tsx index 8cc7d72e14..ff34d4b197 100644 --- a/src/components/CommentList/CommentList.tsx +++ b/src/components/CommentList/CommentList.tsx @@ -1,3 +1,18 @@ import React from 'react'; +import { type Comment } from '../../types/Comment'; +import { CommentInfo } from '../CommentInfo'; +import './CommentList.css'; -export const CommentList: React.FC = () => <>Put the list here; +type Props = { + comments: Comment[]; +}; + +export const CommentList: React.FC = ({ comments }) => { + return ( +
+ {comments.map(comment => ( + + ))} +
+ ); +}; diff --git a/src/components/PostInfo/PostInfo.scss b/src/components/PostInfo/PostInfo.scss index f1b40ee00e..d04c5a424a 100644 --- a/src/components/PostInfo/PostInfo.scss +++ b/src/components/PostInfo/PostInfo.scss @@ -1 +1,20 @@ -// add styles here +.PostInfo { + margin: 10px auto; + width: 90%; + border: 1px solid #000; + border-radius: 8px; + background-color: lightgray; + padding: 1em; + + &__title { + margin: 0; + } + + &__header { + margin-bottom: 1em; + } +} + + + + diff --git a/src/components/PostInfo/PostInfo.tsx b/src/components/PostInfo/PostInfo.tsx index 90220ae5e1..8968504ca2 100644 --- a/src/components/PostInfo/PostInfo.tsx +++ b/src/components/PostInfo/PostInfo.tsx @@ -1,3 +1,35 @@ import React from 'react'; +import { type Post } from '../../types/Post'; +import { UserInfo } from '../UserInfo'; +import { CommentList } from '../CommentList'; +import './PostInfo.css'; -export const PostInfo: React.FC = () => <>Put the post here; +type Props = { + post: Post; +}; + +export const PostInfo: React.FC = ({ post }) => { + return ( +
+
+

{post.title}

+ +

+ {' Posted by '} + + {post.user ? : null} +

+
+ +

{post.body}

+ +
+ + {post.comments.length === 0 ? ( + No comments yet + ) : ( + + )} +
+ ); +}; diff --git a/src/components/PostList/PostList.tsx b/src/components/PostList/PostList.tsx index d7bc7aa5fa..6e3a1bf0bf 100644 --- a/src/components/PostList/PostList.tsx +++ b/src/components/PostList/PostList.tsx @@ -1,3 +1,18 @@ import React from 'react'; +import { PostInfo } from '../PostInfo'; +import { type Post } from '../../types/Post'; +import './PostList.css'; -export const PostList: React.FC = () => <>Put the list here; +type Props = { + posts: Post[]; +}; + +export const PostList: React.FC = ({ posts }) => { + return ( +
+ {posts.map(post => ( + + ))} +
+ ); +}; diff --git a/src/components/UserInfo/UserInfo.scss b/src/components/UserInfo/UserInfo.scss index f1b40ee00e..309060069d 100644 --- a/src/components/UserInfo/UserInfo.scss +++ b/src/components/UserInfo/UserInfo.scss @@ -1 +1,4 @@ -// add styles here +.UserInfo { + font-weight: bold; +} + diff --git a/src/components/UserInfo/UserInfo.tsx b/src/components/UserInfo/UserInfo.tsx index 0435cbfa67..9768effa7c 100644 --- a/src/components/UserInfo/UserInfo.tsx +++ b/src/components/UserInfo/UserInfo.tsx @@ -1,3 +1,15 @@ import React from 'react'; +import { type User } from '../../types/User'; +import './UserInfo.css'; -export const UserInfo: React.FC = () => <>Put the user here; +type Props = { + user: User; +}; + +export const UserInfo: React.FC = ({ user }) => { + return ( + + {user.name} + + ); +}; diff --git a/src/types/Comment.ts b/src/types/Comment.ts new file mode 100644 index 0000000000..14df6303f3 --- /dev/null +++ b/src/types/Comment.ts @@ -0,0 +1,7 @@ +export interface Comment { + postId: number; + id: number; + name: string; + email: string; + body: string; +} diff --git a/src/types/Post.ts b/src/types/Post.ts new file mode 100644 index 0000000000..d574bb7803 --- /dev/null +++ b/src/types/Post.ts @@ -0,0 +1,11 @@ +import { type User } from './User'; +import { type Comment } from './Comment'; + +export interface Post { + userId: number; + id: number; + title: string; + body: string; + user?: User; + comments?: Comment[]; +} diff --git a/src/types/User.ts b/src/types/User.ts new file mode 100644 index 0000000000..6eafe74c1a --- /dev/null +++ b/src/types/User.ts @@ -0,0 +1,5 @@ +export interface User { + id: number; + name: string; + email: string; +} From 7aa49daebbc6a616fded0049507882e05fe0f9ab Mon Sep 17 00:00:00 2001 From: Wioleta Lip Date: Sat, 31 Jan 2026 00:07:49 +0100 Subject: [PATCH 2/3] solution --- src/components/PostInfo/PostInfo.tsx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/components/PostInfo/PostInfo.tsx b/src/components/PostInfo/PostInfo.tsx index 8968504ca2..222222a751 100644 --- a/src/components/PostInfo/PostInfo.tsx +++ b/src/components/PostInfo/PostInfo.tsx @@ -9,26 +9,28 @@ type Props = { }; export const PostInfo: React.FC = ({ post }) => { + const hasComments = post.comments && post.comments.length > 0; + return (

{post.title}

-

- {' Posted by '} - - {post.user ? : null} -

+ {post.user && ( +

+ Posted by +

+ )}

{post.body}


- {post.comments.length === 0 ? ( + {!hasComments ? ( No comments yet ) : ( - + )}
); From bb4540264edb3e47a12ddf3b6c5a66937c9def12 Mon Sep 17 00:00:00 2001 From: Wioleta Lip Date: Sat, 31 Jan 2026 11:19:34 +0100 Subject: [PATCH 3/3] solution v1 --- src/components/CommentInfo/CommentInfo.tsx | 27 +++++++++------------- src/components/CommentList/CommentList.tsx | 20 ++++++++-------- src/components/PostList/PostList.tsx | 20 ++++++++-------- src/types/imdex.ts | 3 +++ 4 files changed, 34 insertions(+), 36 deletions(-) create mode 100644 src/types/imdex.ts diff --git a/src/components/CommentInfo/CommentInfo.tsx b/src/components/CommentInfo/CommentInfo.tsx index 8ce7688f87..e807b8e627 100644 --- a/src/components/CommentInfo/CommentInfo.tsx +++ b/src/components/CommentInfo/CommentInfo.tsx @@ -6,20 +6,15 @@ type Props = { comment: Comment; }; -export const CommentInfo: React.FC = ({ comment }) => { - return ( -
-
- {comment.name} - - {' by '} - - - {comment.email} - -
- -
{comment.body}
+export const CommentInfo: React.FC = ({ comment }) => ( +
+
+ {comment.name} by + + {comment.email} +
- ); -}; + +
{comment.body}
+
+); diff --git a/src/components/CommentList/CommentList.tsx b/src/components/CommentList/CommentList.tsx index ff34d4b197..d89ff58ff2 100644 --- a/src/components/CommentList/CommentList.tsx +++ b/src/components/CommentList/CommentList.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { Fragment } from 'react'; import { type Comment } from '../../types/Comment'; import { CommentInfo } from '../CommentInfo'; import './CommentList.css'; @@ -7,12 +7,12 @@ type Props = { comments: Comment[]; }; -export const CommentList: React.FC = ({ comments }) => { - return ( -
- {comments.map(comment => ( - - ))} -
- ); -}; +export const CommentList: React.FC = ({ comments }) => ( +
+ {comments.map(comment => ( + + + + ))} +
+); diff --git a/src/components/PostList/PostList.tsx b/src/components/PostList/PostList.tsx index 6e3a1bf0bf..42c2e0334b 100644 --- a/src/components/PostList/PostList.tsx +++ b/src/components/PostList/PostList.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { Fragment } from 'react'; import { PostInfo } from '../PostInfo'; import { type Post } from '../../types/Post'; import './PostList.css'; @@ -7,12 +7,12 @@ type Props = { posts: Post[]; }; -export const PostList: React.FC = ({ posts }) => { - return ( -
- {posts.map(post => ( - - ))} -
- ); -}; +export const PostList: React.FC = ({ posts }) => ( +
+ {posts.map(post => ( + + + + ))} +
+); diff --git a/src/types/imdex.ts b/src/types/imdex.ts new file mode 100644 index 0000000000..dd7e0b3cf9 --- /dev/null +++ b/src/types/imdex.ts @@ -0,0 +1,3 @@ +export * from './User'; +export * from './Comment'; +export * from './Post';