Skip to content

Commit

Permalink
my solution
Browse files Browse the repository at this point in the history
  • Loading branch information
minimal005 committed Dec 18, 2024
1 parent 611a1dc commit bd60246
Show file tree
Hide file tree
Showing 12 changed files with 768 additions and 350 deletions.
290 changes: 196 additions & 94 deletions cypress/integration/page.spec.js

Large diffs are not rendered by default.

134 changes: 97 additions & 37 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import classNames from 'classnames';
import * as postsService from './api/posts';

import 'bulma/css/bulma.css';
import '@fortawesome/fontawesome-free/css/all.css';
Expand All @@ -8,53 +9,112 @@ import { PostsList } from './components/PostsList';
import { PostDetails } from './components/PostDetails';
import { UserSelector } from './components/UserSelector';
import { Loader } from './components/Loader';
import { useEffect, useState } from 'react';
import { Post } from './types/Post';

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 [userSelectedId, setUserSelectedId] = useState<number | null>(null);

<div className="block" data-cy="MainContent">
<p data-cy="NoSelectedUser">No user selected</p>
const [postsByUser, setPostsByUser] = useState<Post[]>([]);
const [postSelected, setPostSelected] = useState<Post | null>(null);

<Loader />
const [isError, setIsError] = useState(false);
const [isLoading, setIsLoadind] = useState(false);
const [isActiveListUsers, setIsActiveListUsers] = useState(false);

<div
className="notification is-danger"
data-cy="PostsLoadingError"
>
Something went wrong!
</div>
useEffect(() => {
if (!userSelectedId) {
return;
}

setPostSelected(null);
setIsLoadind(true);
const getPostsByUser = async () => {
try {
const postsUser = await postsService.getPosts(userSelectedId);

setPostSelected(null);
setPostsByUser(postsUser);
} catch (error) {
setIsError(true);
setPostsByUser([]);
} finally {
setIsLoadind(false);
}
};

<div className="notification is-warning" data-cy="NoPostsYet">
No posts yet
getPostsByUser();
}, [userSelectedId]);

const showMessageAboutNotPosts =
!postsByUser.length && userSelectedId && !isLoading && !isError;

return (
<main className="section" onClick={() => setIsActiveListUsers(false)}>
<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
setIsError={setIsError}
setUserSelectedId={setUserSelectedId}
isActive={isActiveListUsers}
setIsActive={setIsActiveListUsers}
setPostsByUser={setPostsByUser}
/>
</div>

<PostsList />
<div className="block" data-cy="MainContent">
{!userSelectedId && !isLoading && (
<p data-cy="NoSelectedUser">No user selected</p>
)}

{isLoading && <Loader />}

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

{showMessageAboutNotPosts && (
<div className="notification is-warning" data-cy="NoPostsYet">
No posts yet
</div>
)}

{!!postsByUser.length && (
<PostsList
postsByUser={postsByUser}
setPostSelected={setPostSelected}
/>
)}
</div>
</div>
</div>
</div>

<div
data-cy="Sidebar"
className={classNames(
'tile',
'is-parent',
'is-8-desktop',
'Sidebar',
'Sidebar--open',
)}
>
<div className="tile is-child box is-success ">
<PostDetails />
<div
data-cy="Sidebar"
className={classNames(
'tile',
'is-parent',
'is-8-desktop',
'Sidebar',
{ 'Sidebar--open': !!postSelected },
)}
>
{postSelected && (
<div className="tile is-child box is-success ">
<PostDetails postSelected={postSelected} />
</div>
)}
</div>
</div>
</div>
</div>
</main>
);
</main>
);
};
20 changes: 20 additions & 0 deletions src/api/comments.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { client } from '../utils/fetchClient';
import { Comment } from '../types/Comment';

const url = `/comments`;

export const getComments = (postId: number) => {
return client.get<Comment[]>(`${url}?postId=${postId}`);
};

export const createComment = (comment: Omit<Comment, 'id'>) => {
return client.post<Comment>(`${url}`, comment);
};

export const editComment = (comment: Comment) => {
return client.patch<Comment>(`${url}/${comment.id}`, comment);
};

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

const url = `/posts`;

export const getPosts = (userId: number) => {
return client.get<Post[]>(`${url}?userId=${userId}`);
};

export const createPost = (post: Omit<Post, 'id'>) => {
return client.post<Post>(`${url}`, post);
};

export const editPost = (post: Post) => {
return client.patch<Post>(`${url}/${post.id}`, post);
};

export const deletePost = (postId: number) => {
return client.delete(`${url}/${postId}`);
};
20 changes: 20 additions & 0 deletions src/api/users.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { client } from '../utils/fetchClient';
import { User } from '../types/User';

const url = `/users`;

export const getUsers = () => {
return client.get<User[]>(`${url}`);
};

export const createUser = (user: Omit<User, 'id'>) => {
return client.post<User>(`${url}`, user);
};

export const editUser = (user: User) => {
return client.patch<User>(`${url}/${user.id}`, user);
};

export const deleteUser = (userId: number) => {
return client.delete(`${url}/${userId}`);
};
36 changes: 36 additions & 0 deletions src/components/Comment.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react';
import { Comment as CommentItem } from '../types/Comment';

type Props = {
comment: CommentItem;
handleDeleteComment: (commentId: number) => void;
};

const Comment: React.FC<Props> = props => {
const { comment, handleDeleteComment } = props;

return (
<article className="message is-small" data-cy="Comment">
<div className="message-header">
<a href={`mailto:${comment.email}`} data-cy="CommentAuthor">
{comment.name}
</a>
<button
onClick={() => handleDeleteComment(comment.id)}
data-cy="CommentDelete"
type="button"
className="delete is-small"
aria-label="delete"
>
delete button
</button>
</div>

<div className="message-body" data-cy="CommentBody">
{comment.body}
</div>
</article>
);
};

export default React.memo(Comment);
Loading

0 comments on commit bd60246

Please sign in to comment.