Skip to content

Commit

Permalink
Solution
Browse files Browse the repository at this point in the history
  • Loading branch information
Valeraom committed Oct 26, 2024
1 parent 8b7ce12 commit 87c5264
Show file tree
Hide file tree
Showing 17 changed files with 598 additions and 177 deletions.
31 changes: 31 additions & 0 deletions src/App.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,37 @@
}
}

@media print, screen and (min-width: 769px) {
.tile:not(.is-child) {
display: flex;
}
}

.tile.is-ancestor:last-child {
margin-bottom: -.75rem;
}

.tile.is-ancestor {
margin-left: -.75rem;
margin-right: -.75rem;
margin-top: -.75rem;
}

.tile {
align-items: stretch;
min-height: min-content;
flex-basis: 0;
flex-grow: 1;
flex-shrink: 1;
}

.message-body {
white-space: pre-line;
}

.container {
flex-grow: 1;
margin: 0 auto;
position: relative;
width: auto;
}
136 changes: 92 additions & 44 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,60 +1,108 @@
import classNames from 'classnames';

import 'bulma/css/bulma.css';
import '@fortawesome/fontawesome-free/css/all.css';
import cn from 'classnames';
import './App.scss';

import { PostsList } from './components/PostsList';
import { PostDetails } from './components/PostDetails';
import { UserSelector } from './components/UserSelector';
import { Loader } from './components/Loader';

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>
import { PostsList, PostDetails, UserSelector, Loader } from './components';
import { User } from './types';
import { usePosts, useUsers } from './hooks';

<div className="block" data-cy="MainContent">
<p data-cy="NoSelectedUser">No user selected</p>
export const App = () => {
const {
users,
errorMessage: usersErrorMessage,
selectedUser,
setSelectedUser,
} = useUsers();
const {
posts,
selectedPost,
setSelectedPost,
isLoading,
setIsLoading,
errorMessage: postsErrorMessage,
} = usePosts(selectedUser?.id);

<Loader />
const errorMessage = usersErrorMessage || postsErrorMessage;

<div
className="notification is-danger"
data-cy="PostsLoadingError"
>
Something went wrong!
</div>
const handleSelectUserId = (user: User) => {
setIsLoading(true);
setSelectedPost(null);
setSelectedUser(user);

<div className="notification is-warning" data-cy="NoPostsYet">
No posts yet
if (selectedUser === user) {
setIsLoading(false);
}
};

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}
selectedUser={selectedUser}
onSelectUser={handleSelectUserId}
/>
</div>

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

{selectedUser && isLoading && <Loader />}

{selectedUser && !isLoading && errorMessage && (
<div
className="notification is-danger"
data-cy="PostsLoadingError"
>
{errorMessage}
</div>
)}

{selectedUser &&
!isLoading &&
!errorMessage &&
posts.length === 0 && (
<div
className="notification is-warning"
data-cy="NoPostsYet"
>
No posts yet
</div>
)}

{selectedUser &&
!isLoading &&
!errorMessage &&
posts.length !== 0 && (
<PostsList
posts={posts}
selectedPost={selectedPost}
onSelectPost={setSelectedPost}
/>
)}
</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={cn('tile is-parent is-8-desktop Sidebar', {
'Sidebar--open': selectedPost,
})}
>
<div className="tile is-child box is-success ">
{selectedPost && <PostDetails selectedPost={selectedPost} />}
</div>
</div>
</div>
</div>
</div>
</main>
);
</main>
);
};
14 changes: 14 additions & 0 deletions src/api/comments.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Comment } from '../types/Comment';
import { client } from '../utils/fetchClient';

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

export const deleteComment = (commentId: number) => {
return client.delete(`/comments/${commentId}`);
};

export const addComment = (newComment: Omit<Comment, 'id'>) => {
return client.post<Comment>('/comments', newComment);
};
6 changes: 6 additions & 0 deletions src/api/posts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Post } from '../types/Post';
import { client } from '../utils/fetchClient';

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

export const getUsers = () => {
return client.get<User[]>('/users');
};
33 changes: 33 additions & 0 deletions src/components/CommentItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { FC } from 'react';

import { Comment } from '../types';

type Props = {
comment: Comment;
onDelete: (commentId: number) => Promise<void>;
};

export const CommentItem: FC<Props> = ({ comment, onDelete }) => {
const { id, name, email, body } = comment;

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

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

0 comments on commit 87c5264

Please sign in to comment.