Skip to content

Commit

Permalink
add dynamic list of post task
Browse files Browse the repository at this point in the history
  • Loading branch information
moskkat40 committed Dec 16, 2024
1 parent 611a1dc commit 23e6227
Show file tree
Hide file tree
Showing 9 changed files with 558 additions and 252 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ form to add new comments.
Install Prettier Extention and use this [VSCode settings](https://mate-academy.github.io/fe-program/tools/vscode/settings.json) to enable format on save.

> Here is [the working version](https://mate-academy.github.io/react_dynamic-list-of-posts/)
Demo: (https://moskkat40/react_dynamic-list-of-posts/)

1. Learn the `utils/fetchClient.ts` and use it to interact with the API (tests expect that you each API request is sent after 300 ms delay);
1. Initially the `App` shows the `UserSelector` and a paragraph `No user selected` in the main content block.
Expand Down
200 changes: 162 additions & 38 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,53 +8,177 @@ import { PostsList } from './components/PostsList';
import { PostDetails } from './components/PostDetails';
import { UserSelector } from './components/UserSelector';
import { Loader } from './components/Loader';
import { useEffect, useMemo, useState } from 'react';
import * as servicesUsers from './api/users';
import * as servicesPosts from './api/posts';
import * as servicesComments from './api/comments';
import { Post } from './types/Post';
import { Comment } from './types/Comment';

export const App = () => (
<main className="section">
<div className="container">
<div className="tile is-ancestor">
<div className="tile is-parent">
<div className="tile is-child box is-success">
<div className="block">
<UserSelector />
</div>
export const App = () => {
const [users, setUsers] = useState([]);
const [isUser, setIsUser] = useState(false);
const [posts, setPosts] = useState([]);
const [comments, setComments] = useState([]);
const [currentPostId, setCurrentPostId] = useState(0);
const [openPostId, setOpenPostId] = useState<number | null>(null);
const [isWritePostButton, setIsWritePostButton] = useState(false);
const [loading, setLoading] = useState('');
const [isError, setIsError] = useState(false);

<div className="block" data-cy="MainContent">
<p data-cy="NoSelectedUser">No user selected</p>
useEffect(() => {
setLoading('users');
servicesUsers
.getUsers()
.then(res => {
setUsers(res);
setIsError(false);
})
.catch(() => setIsError(true))
.finally(() => setLoading(''));
}, []);

<Loader />
const getPostsByUserId = (id: number) => {
setLoading('posts');
setIsUser(true);

<div
className="notification is-danger"
data-cy="PostsLoadingError"
>
Something went wrong!
</div>
return servicesPosts
.getPosts(id)
.then(res => {
setPosts(res);
setIsError(false);
})
.catch(() => setIsError(true))
.finally(() => setLoading(''));
};

const getCommentsByPostId = (postId: number) => {
setLoading('comments');
setCurrentPostId(postId);

servicesComments
.getComments(postId)
.catch(() => setIsError(true))
.then(res => {
setComments(res);
setIsError(false);
})
.finally(() => setLoading(''));
};

const addComment = ({ name, email, body, postId }: Comment) => {
setLoading('addComment');

servicesComments
.createComment({ name, email, body, postId })
.then(newComment => {
setComments(currentComments => [...currentComments, newComment]);
})
.finally(() => setLoading(''));
};

const deleteComment = (commentId: number) => {
servicesComments
.deleteComment(commentId)
.then(res =>

Check failure on line 83 in src/App.tsx

View workflow job for this annotation

GitHub Actions / run_linter (20.x)

'res' is defined but never used
setComments(currentComments =>
currentComments.filter(comment => comment.id !== commentId),
),
);
};

const currentPost = useMemo(() => {
return posts.find((post: Post) => post.id === currentPostId);
}, [currentPostId, posts]);

console.log(isError);

Check failure on line 94 in src/App.tsx

View workflow job for this annotation

GitHub Actions / run_linter (20.x)

Unexpected console statement

<div className="notification is-warning" data-cy="NoPostsYet">
No posts yet
return (
<main className="section">
<div className="container">
<div className="tile is-ancestor">
<div className="tile is-parent">
<div className="tile is-child box is-success">
<div className="block">
<UserSelector
users={users}
setIsUser={setIsUser}
isUser={isUser}
getPostsByUserId={getPostsByUserId}
setOpenPostId={setOpenPostId}
/>
</div>
{loading === 'users' && <Loader />}
<div className="block" data-cy="MainContent">
<p data-cy="NoSelectedUser">
{!isUser && loading !== 'users' && 'No user selected'}
</p>

<PostsList />
{loading === 'posts' && <Loader />}
{isError && (
<div
className="notification is-danger"
data-cy="PostsLoadingError"
>
Something went wrong!
</div>
)}

{posts.length === 0 &&
isUser &&
loading !== 'posts' &&
!isError && (
<div

Check failure on line 131 in src/App.tsx

View workflow job for this annotation

GitHub Actions / run_linter (20.x)

Expected indentation of 18 spaces but found 20
className="notification is-warning"

Check failure on line 132 in src/App.tsx

View workflow job for this annotation

GitHub Actions / run_linter (20.x)

Expected indentation of 20 spaces but found 22
data-cy="NoPostsYet"

Check failure on line 133 in src/App.tsx

View workflow job for this annotation

GitHub Actions / run_linter (20.x)

Expected indentation of 20 spaces but found 22
>

Check failure on line 134 in src/App.tsx

View workflow job for this annotation

GitHub Actions / run_linter (20.x)

Expected indentation of 18 spaces but found 20
No posts yet
</div>

Check failure on line 136 in src/App.tsx

View workflow job for this annotation

GitHub Actions / run_linter (20.x)

Expected indentation of 18 spaces but found 20
)}

Check failure on line 137 in src/App.tsx

View workflow job for this annotation

GitHub Actions / run_linter (20.x)

Expected indentation of 16 spaces but found 18

{isUser &&
posts.length > 0 &&
loading !== 'posts' &&
!isError && (
<PostsList

Check failure on line 143 in src/App.tsx

View workflow job for this annotation

GitHub Actions / run_linter (20.x)

Expected indentation of 18 spaces but found 20
posts={posts}

Check failure on line 144 in src/App.tsx

View workflow job for this annotation

GitHub Actions / run_linter (20.x)

Expected indentation of 20 spaces but found 22
getCommentsByPostId={getCommentsByPostId}
openPostId={openPostId}
setOpenPostId={setOpenPostId}
setIsWritePostButton={setIsWritePostButton}
/>
)}
</div>
</div>
</div>
</div>

<div
data-cy="Sidebar"
className={classNames(
'tile',
'is-parent',
'is-8-desktop',
'Sidebar',
'Sidebar--open',
{posts.length > 0 && openPostId && (
<div
data-cy="Sidebar"
className={classNames(
'tile',
'is-parent',
'is-8-desktop',
'Sidebar',
'Sidebar--open',
)}
>
<div className="tile is-child box is-success ">
<PostDetails
comments={comments}
currentPost={currentPost}
addComment={addComment}
isWritePostButton={isWritePostButton}
setIsWritePostButton={setIsWritePostButton}
deleteComment={deleteComment}
loadingComments={loading === 'comments'}
loadingAddNewComment={loading === 'addComment'}
isError={isError}
/>
</div>
</div>
)}
>
<div className="tile is-child box is-success ">
<PostDetails />
</div>
</div>
</div>
</div>
</main>
);
</main>
);
};
19 changes: 19 additions & 0 deletions src/api/comments.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Comment } from '../types/Comment';
import { client } from '../utils/fetchClient';

export const getComments = (postId: number) => {
return client.get(`/comments?postId=${postId}`);
};

export const createComment = ({
name,
email,
body,
postId,
}: Omit<Comment, 'id'>) => {
return client.post<Comment>('/comments', { name, email, body, postId });
};

export const deleteComment = (commentId: number) => {
return client.delete(`/comments/${commentId}`);
};
5 changes: 5 additions & 0 deletions src/api/posts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { client } from '../utils/fetchClient';

export const getPosts = (userId: number) => {
return client.get(`/posts?userId=${userId}`);
};
5 changes: 5 additions & 0 deletions src/api/users.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { client } from '../utils/fetchClient';

export const getUsers = () => {
return client.get('/users');
};
Loading

0 comments on commit 23e6227

Please sign in to comment.