From 43f0349ed84f2e3f88ed7a2a1b33aee34bebc86e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=20=D0=9B=D0=B0=D0=B9=D0=B5=D1=80?= Date: Tue, 10 Sep 2024 23:34:42 +0300 Subject: [PATCH 1/2] =?UTF-8?q?=D0=A0=D0=B5=D1=84=D0=B0=D0=BA=D1=82=D0=BE?= =?UTF-8?q?=D1=80=D0=B8=D0=BD=D0=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- my-app/src/App.scss | 9 +++ my-app/src/App.tsx | 61 ++++++++++------- my-app/src/components/button/Button.tsx | 8 +++ my-app/src/components/button/index.ts | 1 + my-app/src/components/form/Form.tsx | 68 +++++++++++++++++++ my-app/src/components/form/index.ts | 1 + .../src/components/memberCard/MemberCard.tsx | 14 ++++ my-app/src/components/memberCard/index.ts | 1 + .../components/memberCard/parts/cardInfo.tsx | 2 +- my-app/src/components/tabs/Tabs.tsx | 16 +++++ my-app/src/components/tabs/const.ts | 4 ++ my-app/src/components/tabs/index.ts | 1 + 12 files changed, 161 insertions(+), 25 deletions(-) create mode 100644 my-app/src/components/button/Button.tsx create mode 100644 my-app/src/components/button/index.ts create mode 100644 my-app/src/components/form/Form.tsx create mode 100644 my-app/src/components/form/index.ts create mode 100644 my-app/src/components/memberCard/MemberCard.tsx create mode 100644 my-app/src/components/memberCard/index.ts create mode 100644 my-app/src/components/tabs/Tabs.tsx create mode 100644 my-app/src/components/tabs/const.ts create mode 100644 my-app/src/components/tabs/index.ts diff --git a/my-app/src/App.scss b/my-app/src/App.scss index 1c35be7..b142d03 100644 --- a/my-app/src/App.scss +++ b/my-app/src/App.scss @@ -14,4 +14,13 @@ margin: 0px; padding: 0px; box-sizing: border-box; +} + +.button-with-label { + display: flex; + flex-direction: column; + gap: 5px; + justify-content: center; + align-items: center; + padding-top: 12px; } \ No newline at end of file diff --git a/my-app/src/App.tsx b/my-app/src/App.tsx index 5a4830a..784643a 100644 --- a/my-app/src/App.tsx +++ b/my-app/src/App.tsx @@ -2,15 +2,19 @@ import "./App.scss"; import { MemberCard } from "../src/components/memberCard"; import { useEffect, useState } from "react"; import { UserProps } from "./components/memberCard/types"; -import { ButtonWithLabel } from "./components/buttonWithLabel"; -import Form from "./components/form"; +import { Form } from "./components/form"; import { Tabs } from "./components/tabs"; +import { TABS_NAME } from "./components/tabs/const"; +import { Button } from "./components/button"; + +const START_COUNT_USER = 1; +const INCREASE_COUNT_USER = 5; export default function App() { const [users, setUsers] = useState([]); - const [moreUsers, setMoreUsers] = useState([]); - const [addedUser, setAddedUser] = useState(null); - const [tabForm, setTabForm] = useState(true); + const [lastAddedUser, setLastAddedUser] = useState(null); + const [tabForm, setTabForm] = useState(TABS_NAME.FORM); + const [countShowUser, setCountShowUser] = useState(START_COUNT_USER); useEffect(() => { fetch('https://jsonplaceholder.typicode.com/users') @@ -18,31 +22,40 @@ export default function App() { .then((res) => setUsers(res)); }, []); - const onButtonClick = () => { - fetch('https://jsonplaceholder.typicode.com/users') - .then((response) => response.json()) - .then((res) => setMoreUsers(res)); + const handleMoreUsersClick = () => { + setCountShowUser((value) => value + INCREASE_COUNT_USER); }; const handleUserAddition = (user: UserProps) => { - setAddedUser(user); -}; + setLastAddedUser(user); + }; return (
- - {!tabForm && users.map((user) => )} - {!tabForm && moreUsers.map((user) => )} - {!tabForm && more users} - {tabForm &&
} - {addedUser && ( - - )} + + + {tabForm == TABS_NAME.USERS && +
+ {users.slice(0, countShowUser) + .map((user: UserProps) => )} + +
+

нажми меня!

+ +
+
+ } + + {tabForm == TABS_NAME.FORM && + + } + + {lastAddedUser && +
+ Последний добавленный пользователь: + +
+ }
); } diff --git a/my-app/src/components/button/Button.tsx b/my-app/src/components/button/Button.tsx new file mode 100644 index 0000000..c986301 --- /dev/null +++ b/my-app/src/components/button/Button.tsx @@ -0,0 +1,8 @@ +import "./style.scss"; + +export const Button = ({ onClick, children }: {onClick: () => void, children?: string}) => { + + return ( + + ); +}; \ No newline at end of file diff --git a/my-app/src/components/button/index.ts b/my-app/src/components/button/index.ts new file mode 100644 index 0000000..3d1f3cc --- /dev/null +++ b/my-app/src/components/button/index.ts @@ -0,0 +1 @@ +export * from './Button'; \ No newline at end of file diff --git a/my-app/src/components/form/Form.tsx b/my-app/src/components/form/Form.tsx new file mode 100644 index 0000000..418b61f --- /dev/null +++ b/my-app/src/components/form/Form.tsx @@ -0,0 +1,68 @@ +import React, { useState, FormEvent, ChangeEvent } from 'react'; +import './style.scss'; + +interface FormProps { + onUserAddition: (user: any) => void; // Принимаем функцию для обновления состояния верхнего компонента +} + +export const Form: React.FC = ({ onUserAddition }) => { + const [username, setUsername] = useState(''); + const [phone, setPhone] = useState(''); + const [website, setWebsite] = useState(''); + + const handleFieldUpdate = (event: ChangeEvent) => { + switch (event.target.name) { + case "username": + setUsername(event.target.value); + break; + case "phone": + setPhone(event.target.value); + break; + case "website": + setWebsite(event.target.value); + break; + } + }; + + const handleSubmit = (event: FormEvent) => { + event.preventDefault(); + + fetch('https://jsonplaceholder.typicode.com/users', { + method: 'POST', + body: JSON.stringify({ + username, + phone, + website, + }), + headers: { + 'Content-type': 'application/json; charset=UTF-8', + }, + }) + .then((response) => response.json()) + .then((user) => onUserAddition(user)); + }; + + return ( + +
+ +
+
+ +
+
+ +
+ + + ); +}; \ No newline at end of file diff --git a/my-app/src/components/form/index.ts b/my-app/src/components/form/index.ts new file mode 100644 index 0000000..511d53b --- /dev/null +++ b/my-app/src/components/form/index.ts @@ -0,0 +1 @@ +export * from './Form'; \ No newline at end of file diff --git a/my-app/src/components/memberCard/MemberCard.tsx b/my-app/src/components/memberCard/MemberCard.tsx new file mode 100644 index 0000000..8037e7d --- /dev/null +++ b/my-app/src/components/memberCard/MemberCard.tsx @@ -0,0 +1,14 @@ +import { FC } from "react"; +import "./style.scss"; + +import { UserProps } from "./types"; +import { CardInfo } from "./parts/cardInfo"; + +export const MemberCard: FC = ({ name, ...childProps }) => { + return ( +
+

{name}

+ +
+ ); +}; \ No newline at end of file diff --git a/my-app/src/components/memberCard/index.ts b/my-app/src/components/memberCard/index.ts new file mode 100644 index 0000000..82ae487 --- /dev/null +++ b/my-app/src/components/memberCard/index.ts @@ -0,0 +1 @@ +export * from './MemberCard'; \ No newline at end of file diff --git a/my-app/src/components/memberCard/parts/cardInfo.tsx b/my-app/src/components/memberCard/parts/cardInfo.tsx index 77b279a..f8468bb 100644 --- a/my-app/src/components/memberCard/parts/cardInfo.tsx +++ b/my-app/src/components/memberCard/parts/cardInfo.tsx @@ -1,4 +1,4 @@ -import { FC, useEffect } from "react"; +import { FC } from "react"; import "../style.scss"; import { UserProps } from "../types"; diff --git a/my-app/src/components/tabs/Tabs.tsx b/my-app/src/components/tabs/Tabs.tsx new file mode 100644 index 0000000..fdfc405 --- /dev/null +++ b/my-app/src/components/tabs/Tabs.tsx @@ -0,0 +1,16 @@ +import { Button } from "../button"; +import { TABS_NAME } from "./const"; + +export interface ITabsProps { + onChange: (tab: TABS_NAME) => void; +} + +export const Tabs = ({ onChange }: ITabsProps) => { + + return ( +
+ + +
+ ); +}; \ No newline at end of file diff --git a/my-app/src/components/tabs/const.ts b/my-app/src/components/tabs/const.ts new file mode 100644 index 0000000..5256146 --- /dev/null +++ b/my-app/src/components/tabs/const.ts @@ -0,0 +1,4 @@ +export enum TABS_NAME { + FORM = 'form', + USERS = 'users', +} \ No newline at end of file diff --git a/my-app/src/components/tabs/index.ts b/my-app/src/components/tabs/index.ts new file mode 100644 index 0000000..601c477 --- /dev/null +++ b/my-app/src/components/tabs/index.ts @@ -0,0 +1 @@ +export * from './Tabs'; \ No newline at end of file From e8fdf06ae032557938c0708524be1b58a2922548 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=20=D0=9B=D0=B0=D0=B9=D0=B5=D1=80?= Date: Fri, 13 Sep 2024 23:39:37 +0300 Subject: [PATCH 2/2] =?UTF-8?q?=D0=A3=D0=B1=D1=80=D0=B0=D0=BD=D1=8B=20any,?= =?UTF-8?q?=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=20=D1=82?= =?UTF-8?q?=D0=B8=D0=BF,=20=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D0=BD=D0=B0=20=D1=84=D1=83=D0=BD=D0=BA=D1=86?= =?UTF-8?q?=D0=B8=D1=8F=20memo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- my-app/src/components/button/Button.tsx | 7 +- my-app/src/components/button/index.tsx | 8 --- .../src/components/buttonWithLabel/index.tsx | 12 ---- .../src/components/buttonWithLabel/style.scss | 7 -- my-app/src/components/form/Form.tsx | 9 +-- my-app/src/components/form/index.tsx | 68 ------------------- .../src/components/memberCard/MemberCard.tsx | 6 +- 7 files changed, 14 insertions(+), 103 deletions(-) delete mode 100644 my-app/src/components/button/index.tsx delete mode 100644 my-app/src/components/buttonWithLabel/index.tsx delete mode 100644 my-app/src/components/buttonWithLabel/style.scss delete mode 100644 my-app/src/components/form/index.tsx diff --git a/my-app/src/components/button/Button.tsx b/my-app/src/components/button/Button.tsx index c986301..1709781 100644 --- a/my-app/src/components/button/Button.tsx +++ b/my-app/src/components/button/Button.tsx @@ -1,6 +1,11 @@ import "./style.scss"; -export const Button = ({ onClick, children }: {onClick: () => void, children?: string}) => { +export interface IButtonProps { + onClick: () => void; + children?: string; +} + +export const Button = ({ onClick, children }: IButtonProps) => { return ( diff --git a/my-app/src/components/button/index.tsx b/my-app/src/components/button/index.tsx deleted file mode 100644 index c986301..0000000 --- a/my-app/src/components/button/index.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import "./style.scss"; - -export const Button = ({ onClick, children }: {onClick: () => void, children?: string}) => { - - return ( - - ); -}; \ No newline at end of file diff --git a/my-app/src/components/buttonWithLabel/index.tsx b/my-app/src/components/buttonWithLabel/index.tsx deleted file mode 100644 index 4401bc4..0000000 --- a/my-app/src/components/buttonWithLabel/index.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { Button } from "../button"; -import "./style.scss"; - -export const ButtonWithLabel = ({ onClick, children }: { onClick: () => void, children: string }) => { - const text =

нажми меня!

; - return ( -
- {text} - -
- ); -}; \ No newline at end of file diff --git a/my-app/src/components/buttonWithLabel/style.scss b/my-app/src/components/buttonWithLabel/style.scss deleted file mode 100644 index 614b4db..0000000 --- a/my-app/src/components/buttonWithLabel/style.scss +++ /dev/null @@ -1,7 +0,0 @@ -.button-with-label { - display: flex; - flex-direction: column; - gap: 5px; - justify-content: center; - align-items: center; -} \ No newline at end of file diff --git a/my-app/src/components/form/Form.tsx b/my-app/src/components/form/Form.tsx index 418b61f..8d4c460 100644 --- a/my-app/src/components/form/Form.tsx +++ b/my-app/src/components/form/Form.tsx @@ -1,11 +1,12 @@ -import React, { useState, FormEvent, ChangeEvent } from 'react'; +import React, { useState, FormEvent, ChangeEvent, memo } from 'react'; import './style.scss'; +import { UserProps } from '../memberCard/types'; interface FormProps { - onUserAddition: (user: any) => void; // Принимаем функцию для обновления состояния верхнего компонента + onUserAddition: (user: UserProps) => void; // Принимаем функцию для обновления состояния верхнего компонента } -export const Form: React.FC = ({ onUserAddition }) => { +export const Form: React.FC = memo(({ onUserAddition }) => { const [username, setUsername] = useState(''); const [phone, setPhone] = useState(''); const [website, setWebsite] = useState(''); @@ -65,4 +66,4 @@ export const Form: React.FC = ({ onUserAddition }) => { ); -}; \ No newline at end of file +}); \ No newline at end of file diff --git a/my-app/src/components/form/index.tsx b/my-app/src/components/form/index.tsx deleted file mode 100644 index 08e5b8b..0000000 --- a/my-app/src/components/form/index.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import React, { useState, FormEvent, ChangeEvent } from 'react'; -import './style.scss'; - -interface FormProps { - onUserAddition: (user: any) => void; // Принимаем функцию для обновления состояния верхнего компонента -} - -const Form: React.FC = ({ onUserAddition }) => { - const [username, setUsername] = useState(''); - const [phone, setPhone] = useState(''); - const [website, setWebsite] = useState(''); - - const handleUsernameChange = (event: ChangeEvent) => { - setUsername(event.target.value); - }; - - const handlePhoneChange = (event: ChangeEvent) => { - setPhone(event.target.value); - }; - - const handlewebsiteChange = (event: ChangeEvent) => { - setWebsite(event.target.value); - }; - - const handleSubmit = (event: FormEvent) => { - event.preventDefault(); - - fetch('https://jsonplaceholder.typicode.com/users', { - method: 'POST', - body: JSON.stringify({ - username, - phone, - website, - }), - headers: { - 'Content-type': 'application/json; charset=UTF-8', - }, - }) - .then((response) => response.json()) - .then((user) => onUserAddition(user)); - }; - - return ( -
-
- -
-
- -
-
- -
- -
- ); -}; - -export default Form; diff --git a/my-app/src/components/memberCard/MemberCard.tsx b/my-app/src/components/memberCard/MemberCard.tsx index 8037e7d..95b0d0b 100644 --- a/my-app/src/components/memberCard/MemberCard.tsx +++ b/my-app/src/components/memberCard/MemberCard.tsx @@ -1,14 +1,14 @@ -import { FC } from "react"; +import { FC, memo } from "react"; import "./style.scss"; import { UserProps } from "./types"; import { CardInfo } from "./parts/cardInfo"; -export const MemberCard: FC = ({ name, ...childProps }) => { +export const MemberCard: FC = memo(({ name, ...childProps }) => { return (

{name}

); -}; \ No newline at end of file +}); \ No newline at end of file