diff --git a/src/App.tsx b/src/App.tsx index 017957182..85f02c52b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,57 +4,137 @@ import 'bulma/css/bulma.css'; import '@fortawesome/fontawesome-free/css/all.css'; import './App.scss'; -import { PostsList } from './components/PostsList'; -import { PostDetails } from './components/PostDetails'; import { UserSelector } from './components/UserSelector'; +import React, { useEffect } from 'react'; +import { User } from './types/User'; +import { getPostsOfUser, getUsers } from './utils/api'; +import { Post } from './types/Post'; +import { PostsList } from './components/PostsList'; import { Loader } from './components/Loader'; +import { PostDetails } from './components/PostDetails'; -export const App = () => ( -
-
-
-
-
-
- -
+export const App = () => { + const [usersFromServer, setUsersFromServer] = React.useState(); + const [postsFromServer, setPostsFromServer] = React.useState(); -
-

No user selected

+ const [chosenUser, setChosenUser] = React.useState(null); + const [postError, setPostError] = React.useState(false); + const [isPostsLoading, setIsPostsLoading] = React.useState(false); + const [activePost, setActivePost] = React.useState(null); - + // Стан для помилок під час завантаження користувачів + const [userErrors, setUserErrors] = React.useState(false); -
- Something went wrong! -
+ // Завантажуємо користувачів + useEffect(() => { + const fetchUsers = async () => { + try { + const currentUsers = await getUsers(); + + setUsersFromServer(currentUsers); + } catch (err) { + setUserErrors(true); + } + }; + + fetchUsers(); + }, []); -
- No posts yet + // Завантажуємо пости обраного користувача + useEffect(() => { + const fetchPosts = async () => { + setIsPostsLoading(true); + try { + const currentPosts = await getPostsOfUser(chosenUser?.id ?? 0); + + setPostsFromServer(currentPosts); + } catch (err) { + setPostError(true); + } finally { + setIsPostsLoading(false); + } + }; + + if (chosenUser) { + setActivePost(null); + fetchPosts(); + } + }, [chosenUser]); + + return ( +
+
+
+
+
+
+ {/* + Передаємо у UserSelector порожній масив + замість null, щоб уникнути помилок .map() + */} +
- +
+ {/* Якщо помилка при завантаженні користувачів */} + {userErrors && ( +
+ Failed to load users. Please try again later. +
+ )} + + {/* Якщо нема обраного користувача */} + {!userErrors && !chosenUser ? ( +

No user selected

+ ) : isPostsLoading ? ( + + ) : postError ? ( +
+ Something went wrong! +
+ ) : postsFromServer?.length === 0 ? ( +
+ No posts yet +
+ ) : ( + + )} +
-
-
-
- +
+ {activePost && ( +
+ +
+ )}
-
-
-); +
+ ); +}; diff --git a/src/components/NewCommentForm.tsx b/src/components/NewCommentForm.tsx index 73a8a0b45..b9c8debd7 100644 --- a/src/components/NewCommentForm.tsx +++ b/src/components/NewCommentForm.tsx @@ -1,8 +1,89 @@ -import React from 'react'; +import React, { useState } from 'react'; +import { addComment } from '../utils/api'; +import { Comment } from '../types/Comment'; + +type Props = { + postId: number; + onCommentAdded: (newComment: Comment) => void; +}; + +export const NewCommentForm: React.FC = ({ postId, onCommentAdded }) => { + const [name, setName] = useState(''); + const [email, setEmail] = useState(''); + const [body, setBody] = useState(''); + const [errors, setErrors] = useState<{ + name?: string; + email?: string; + body?: string; + }>({}); + const [isSubmitting, setIsSubmitting] = useState(false); + const [formError, setFormError] = useState(null); + + const validate = () => { + const newErrors: typeof errors = {}; + + if (!name.trim()) { + newErrors.name = 'Name is required'; + } + + if (!email.trim() || !/^[\w.%+-]+@[\w.-]+\.[a-zA-Z]{2,}$/.test(email)) { + newErrors.email = 'Email is required'; + } + + if (!body.trim()) { + newErrors.body = 'Enter some text'; + } + + setErrors(newErrors); + + return Object.keys(newErrors).length === 0; + }; + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + setFormError(null); + + if (!validate()) { + return; + } + + setIsSubmitting(true); + + try { + const newComment: Comment = await addComment({ + postId, + name, + email, + body, + }); + + onCommentAdded(newComment); + + setBody(''); + setErrors({}); + } catch (err) { + setFormError('Failed to add comment. Please try again later.'); + } finally { + setIsSubmitting(false); + } + }; + + const handleClear = () => { + setName(''); + setEmail(''); + setBody(''); + setErrors({}); + setFormError(null); + }; -export const NewCommentForm: React.FC = () => { return ( -
+ + {formError && ( +
+ {formError} +
+ )} +
-
@@ -73,27 +169,41 @@ export const NewCommentForm: React.FC = () => {