Skip to content

Commit

Permalink
fixed solution
Browse files Browse the repository at this point in the history
  • Loading branch information
Krykunov committed Dec 5, 2024
1 parent 9fe09d5 commit c0c441e
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 54 deletions.
14 changes: 7 additions & 7 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ import { usePosts } from './hooks/usePosts';
import { useState } from 'react';

export const App: React.FC = () => {
const [isShowForm, setIsShowForm] = useState(false);
const [isFormShown, setIsFormShown] = useState(false);

const { users, currentUser, setCurrentUser } = useUsers();

const { posts, currentPost, setCurrentPost, isPostsLoading, isPostsError } =
usePosts(currentUser?.id || null);

const isShowPostsBlock = currentUser && !isPostsError && !isPostsLoading;
const isPostsBlockShown = currentUser && !isPostsError && !isPostsLoading;

return (
<main className="section">
Expand Down Expand Up @@ -53,8 +53,8 @@ export const App: React.FC = () => {
</div>
)}

{isShowPostsBlock &&
(posts.length === 0 ? (
{isPostsBlockShown &&
(!posts.length ? (
<div
className="notification is-warning"
data-cy="NoPostsYet"
Expand All @@ -66,7 +66,7 @@ export const App: React.FC = () => {
posts={posts}
currentPost={currentPost}
setCurrentPost={setCurrentPost}
setIsShowForm={setIsShowForm}
setIsShowForm={setIsFormShown}
/>
))}
</div>
Expand All @@ -83,8 +83,8 @@ export const App: React.FC = () => {
<div className="tile is-child box is-success ">
<PostDetails
currentPost={currentPost}
isShowForm={isShowForm}
setIsShowForm={setIsShowForm}
isShowForm={isFormShown}
setIsShowForm={setIsFormShown}
/>
</div>
)}
Expand Down
15 changes: 13 additions & 2 deletions src/components/Comment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,22 @@ import type { Comment } from '../types/Comment';
type Props = {
comment: Comment;
deleteComment: (commentId: number) => void;
isCommentDeleteError: boolean;
};

const CommentItem: React.FC<Props> = ({ comment, deleteComment }) => {
const CommentItem: React.FC<Props> = ({
comment,
deleteComment,
isCommentDeleteError,
}) => {
const handleDelete = () => {
deleteComment(comment.id);
};

return (
<article className="message is-small" data-cy="Comment">
<div className="message-header">
<a href={comment.email} data-cy="CommentAuthor">
<a href={`mailto:${comment.email}`} data-cy="CommentAuthor">
{comment.name}
</a>
<button
Expand All @@ -31,6 +36,12 @@ const CommentItem: React.FC<Props> = ({ comment, deleteComment }) => {
<div className="message-body" data-cy="CommentBody">
{comment.body}
</div>

{isCommentDeleteError && (
<div className="notification is-danger" data-cy="CommentDeleteError">
Something went wrong
</div>
)}
</article>
);
};
Expand Down
16 changes: 12 additions & 4 deletions src/components/PostDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,22 @@ export const PostDetails: React.FC<Props> = ({
isCommentsError,
deleteComment,
isCommentCreating,
isCommentDeleteError,
} = useComments(currentPost.id);

const isShowCommentsBlock = !isCommentsError && !isCommentsLoading;

const isNoCommentsMessageShown = isShowCommentsBlock && !comments.length;

const isCommentsBlockShown = isShowCommentsBlock && comments.length !== 0;

const isCommentButtonShown = isShowCommentsBlock && !isShowForm;

return (
<div className="content" data-cy="PostDetails">
<div className="content" data-cy="PostDetails">
<div className="block">
<h2 data-cy="PostTitle">{`#${currentPost.id} ${currentPost.title}`}</h2>
<h2 data-cy="PostTitle">{`#${currentPost.id}: ${currentPost.title}`}</h2>

<p data-cy="PostBody">{currentPost.body}</p>
</div>
Expand All @@ -45,26 +52,27 @@ export const PostDetails: React.FC<Props> = ({
</div>
)}

{isShowCommentsBlock && comments.length === 0 && (
{isNoCommentsMessageShown && (
<p className="title is-4" data-cy="NoCommentsMessage">
No comments yet
</p>
)}

{isShowCommentsBlock && comments.length !== 0 && (
{isCommentsBlockShown && (
<>
<p className="title is-4">Comments:{comments.length}</p>
{comments.map(comment => (
<CommentItem
key={comment.id}
comment={comment}
deleteComment={deleteComment}
isCommentDeleteError={isCommentDeleteError}
/>
))}
</>
)}

{isShowCommentsBlock && !isShowForm && (
{isCommentButtonShown && (
<button
data-cy="WriteCommentButton"
type="button"
Expand Down
4 changes: 2 additions & 2 deletions src/components/PostItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ const PostItem: React.FC<Props> = ({
const handleSelectPost = () => {
if (isSelected) {
setCurrentPost(null);
setIsShowForm(false);
} else {
setCurrentPost(post);
setIsShowForm(false);
}

setIsShowForm(false);
};

return (
Expand Down
27 changes: 25 additions & 2 deletions src/components/UserSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React from 'react';
import React, { useEffect, useRef } from 'react';
import cn from 'classnames';

import { User } from '../types/User';
import { Post } from '../types/Post';
import classNames from 'classnames';

type Props = {
users: User[];
Expand All @@ -25,8 +26,28 @@ export const UserSelector: React.FC<Props> = ({
setIsOpen(false);
};

const componentRef = useRef<HTMLDivElement>(null);

const handleClickOutside = (event: MouseEvent) => {
if (
componentRef.current &&
!componentRef.current.contains(event.target as Node)
) {
setIsOpen(false);
}
};

useEffect(() => {
document.addEventListener('mousedown', handleClickOutside);

return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, []);

return (
<div
ref={componentRef}
data-cy="UserSelector"
className={cn('dropdown', { 'is-active': isOpen })}
>
Expand All @@ -53,7 +74,9 @@ export const UserSelector: React.FC<Props> = ({
<a
key={user.id}
href={`#user-${user.id}`}
className="dropdown-item"
className={classNames('dropdown-item', {
'is-active': currentUser?.id === user.id,
})}
onClick={() => handleSelectUser(user)}
>
{user.name}
Expand Down
34 changes: 15 additions & 19 deletions src/hooks/useComments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const useComments = (postId?: number | null) => {
const [isCommentsLoading, setIsCommentsLoading] = useState(false);
const [isCommentCreating, setIsCommentCreating] = useState(false);
const [isCommentsError, setIsCommentsError] = useState(false);
const [isCommentDeleteError, setIsCommentDeleteError] = useState(false);
const [comments, setComments] = useState<Comment[]>([]);

const loadComments = useCallback(async () => {
Expand All @@ -16,13 +17,11 @@ export const useComments = (postId?: number | null) => {
setIsCommentsLoading(true);
setIsCommentsError(false);
try {
try {
const usersFromServer = await postService.getComments(postId);
const usersFromServer = await postService.getComments(postId);

setComments(usersFromServer);
} catch {
setIsCommentsError(true);
}
setComments(usersFromServer);
} catch {
setIsCommentsError(true);
} finally {
setIsCommentsLoading(false);
}
Expand All @@ -31,13 +30,11 @@ export const useComments = (postId?: number | null) => {
const addComment = useCallback(async (comment: Omit<Comment, 'id'>) => {
setIsCommentCreating(true);
try {
try {
const newComment = await postService.createComment(comment);
const newComment = await postService.createComment(comment);

setComments(prev => [...prev, newComment]);
} catch {
setIsCommentsError(true);
}
setComments(prev => [...prev, newComment]);
} catch {
setIsCommentsError(true);
} finally {
setIsCommentCreating(false);
}
Expand All @@ -47,14 +44,12 @@ export const useComments = (postId?: number | null) => {
async (commentId: number) => {
setComments(prev => prev.filter(comment => comment.id !== commentId));
try {
try {
await postService.deleteComment(commentId);
} catch {
setIsCommentsError(true);
}
} finally {
await postService.deleteComment(commentId);
} catch {
setIsCommentDeleteError(true);
setComments(comments);
setIsCommentsError(false);
} finally {
setIsCommentDeleteError(false);
}
},
[comments],
Expand All @@ -78,5 +73,6 @@ export const useComments = (postId?: number | null) => {
deleteComment,
loadComments,
isCommentCreating,
isCommentDeleteError,
};
};
20 changes: 7 additions & 13 deletions src/hooks/usePosts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,21 @@ export const usePosts = (id: number | null) => {
setIsPostsError(false);

try {
try {
const postsFromServer = await getPosts(userId);
const postsFromServer = await getPosts(userId);

setPosts(postsFromServer);
} catch {
setIsPostsError(true);
}
setPosts(postsFromServer);
} catch {
setIsPostsError(true);
} finally {
setIsPostsLoading(false);
}
}, []);

useEffect(() => {
if (!id) {
setPosts([]);

return;
if (id) {
loadPosts(id);
}

loadPosts(id);
}, [id]);
}, [id, loadPosts]);

return {
posts,
Expand Down
7 changes: 2 additions & 5 deletions src/hooks/useUsers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,12 @@ export const useUsers = () => {
const usersFromServer = await getUsers();

setUsers(usersFromServer);
} catch {
throw new Error('Unable to load users');
} finally {
}
} catch {}
}, []);

useEffect(() => {
loadUsers();
}, []);
}, [loadUsers]);

return {
users,
Expand Down

0 comments on commit c0c441e

Please sign in to comment.