Skip to content

Commit

Permalink
add task solution
Browse files Browse the repository at this point in the history
  • Loading branch information
Dorosh90 committed Mar 3, 2025
1 parent 593e3fc commit a400813
Show file tree
Hide file tree
Showing 5 changed files with 265 additions and 153 deletions.
4 changes: 2 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { PostDetails } from './components/PostDetails';
import { UserSelector } from './components/UserSelector';
import { useEffect, useState } from 'react';
import { User } from './types/User';
import { getUsers } from './api/posts';
import { Post } from './types/Post';
import { getUsers } from './api/fetchPosts';

export const App = () => {
const [usersList, setUsersList] = useState<User[]>([]);
Expand Down Expand Up @@ -59,7 +59,7 @@ export const App = () => {
'is-8-desktop',
'Sidebar',
{
'Sidebar--open': post,
'Sidebar--open': post && post.userId === user?.id,
},
)}
>
Expand Down
24 changes: 23 additions & 1 deletion src/api/posts.ts → src/api/fetchPosts.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { client } from '../../src/utils/fetchClient';
import { client } from '../utils/fetchClient';
import { Post } from '../types/Post';
import { User } from '../types/User';
import { Comment } from '../types/Comment';
Expand All @@ -20,3 +20,25 @@ export const getComments = async (id: number | undefined) => {

return comments;
};

export const deleteComment = async (postId: number | undefined) => {
const deleteSelectedComment = client.delete(`/comments/${postId}`);

return deleteSelectedComment;
};

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

return createNewComment;
};
185 changes: 157 additions & 28 deletions src/components/NewCommentForm.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,140 @@
import React from 'react';
import React, { useState } from 'react';
import { Comment } from '../types/Comment';
import classNames from 'classnames';
import { Post } from '../types/Post';
import { createComment } from '../api/fetchPosts';

interface Props {
post: Post | null;
setCommentsList: (value: (prev: Comment[]) => Comment[]) => void;
setIsError: (value: boolean) => void;
commentsList: Comment[];
}

export const NewCommentForm: React.FC<Props> = ({
post,
setCommentsList,
commentsList,
setIsError,
}) => {
const [nameInput, setNameInput] = useState('');
const [emailInput, setEmailInput] = useState('');
const [bodyInput, setBodyInput] = useState('');
const [isLoading, setIsLoading] = useState(false);
const [nameError, setNameError] = useState(false);
const [emailError, setEmailError] = useState(false);
const [bodyError, setBodyError] = useState(false);

const resetFormAfterSuccesSubmit = () => {
setNameInput(nameInput);
setEmailInput(emailInput);
setBodyInput('');
};

const resetForm = () => {
setNameInput('');
setEmailInput('');
setBodyInput('');
setNameError(false);
setEmailError(false);
setBodyError(false);
};

const submitForm = async () => {
if (!nameInput) {
setNameError(true);
}

if (!emailInput) {
setEmailError(true);
}

if (!bodyInput) {
setBodyError(true);
}

if (!post?.id) {
setIsError(true);

return;
}

if (!nameInput || !emailInput || !bodyInput) {
return;
}

setIsLoading(true);

const newComment = {
postId: post?.id,
name: nameInput,
email: emailInput,
body: bodyInput,
};

try {
await createComment(newComment);
setCommentsList(prev => [
...prev,
{ ...newComment, id: commentsList.length + 1 },
]);
resetFormAfterSuccesSubmit();
} catch {
setIsError(true);
} finally {
setIsLoading(false);
}
};

export const NewCommentForm: React.FC = () => {
return (
<form data-cy="NewCommentForm">
<form
data-cy="NewCommentForm"
onSubmit={e => {
e.preventDefault();
submitForm();
}}
onReset={resetForm}
>
<div className="field" data-cy="NameField">
<label className="label" htmlFor="comment-author-name">
Author Name
</label>

<div className="control has-icons-left has-icons-right">
<input
value={nameInput}
type="text"
name="name"
id="comment-author-name"
placeholder="Name Surname"
className="input is-danger"
className={classNames('input', {
'is-danger': nameError && !nameInput,
})}
onChange={e => {
setNameInput(e.target.value);
setNameError(false);
}}
/>

<span className="icon is-small is-left">
<i className="fas fa-user" />
</span>

<span
className="icon is-small is-right has-text-danger"
data-cy="ErrorIcon"
>
<i className="fas fa-exclamation-triangle" />
</span>
{nameError && !nameInput && (
<span
className="icon is-small is-right has-text-danger"
data-cy="ErrorIcon"
>
<i className="fas fa-exclamation-triangle" />
</span>
)}
</div>

<p className="help is-danger" data-cy="ErrorMessage">
Name is required
</p>
{nameError && !nameInput && (
<p className="help is-danger" data-cy="ErrorMessage">
Name is required
</p>
)}
</div>

<div className="field" data-cy="EmailField">
Expand All @@ -41,28 +144,39 @@ export const NewCommentForm: React.FC = () => {

<div className="control has-icons-left has-icons-right">
<input
value={emailInput}
type="text"
name="email"
id="comment-author-email"
placeholder="[email protected]"
className="input is-danger"
className={classNames('input', {
'is-danger': emailError,
})}
onChange={e => {
setEmailInput(e.target.value);
setEmailError(false);
}}
/>

<span className="icon is-small is-left">
<i className="fas fa-envelope" />
</span>

<span
className="icon is-small is-right has-text-danger"
data-cy="ErrorIcon"
>
<i className="fas fa-exclamation-triangle" />
</span>
{emailError && !emailInput && (
<span
className="icon is-small is-right has-text-danger"
data-cy="ErrorIcon"
>
<i className="fas fa-exclamation-triangle" />
</span>
)}
</div>

<p className="help is-danger" data-cy="ErrorMessage">
Email is required
</p>
{emailError && !emailInput && (
<p className="help is-danger" data-cy="ErrorMessage">
Email is required
</p>
)}
</div>

<div className="field" data-cy="BodyField">
Expand All @@ -72,23 +186,38 @@ export const NewCommentForm: React.FC = () => {

<div className="control">
<textarea
value={bodyInput}
id="comment-body"
name="body"
placeholder="Type comment here"
className="textarea is-danger"
className={classNames('textarea', {
'is-danger': bodyError && !bodyInput,
})}
onChange={e => {
setBodyInput(e.target.value);
setBodyError(false);
}}
/>
</div>

<p className="help is-danger" data-cy="ErrorMessage">
Enter some text
</p>
{bodyError && !bodyInput && (
<p className="help is-danger" data-cy="ErrorMessage">
Enter some text
</p>
)}
</div>

<div className="field is-grouped">
<div className="control">
<button type="submit" className="button is-link is-loading">
<button
type="submit"
className={classNames('button is-link', {
'is-loading': isLoading,
})}
>
Add
</button>
{/* */}
</div>

<div className="control">
Expand Down
Loading

0 comments on commit a400813

Please sign in to comment.