diff --git a/src/s1-main/App.tsx b/src/s1-main/App.tsx index 67d92cf..233f912 100644 --- a/src/s1-main/App.tsx +++ b/src/s1-main/App.tsx @@ -2,6 +2,7 @@ import React from 'react' import s from './App.module.css' import HW1 from '../s2-homeworks/hw01/HW1' import HW2 from '../s2-homeworks/hw02/HW2' +import HW3 from '../s2-homeworks/hw03/HW3' function App() { // для дз 12 @@ -17,7 +18,7 @@ function App() { > - {/**/} + {/**/} {/**/} diff --git a/src/s2-homeworks/hw03/Greeting.module.css b/src/s2-homeworks/hw03/Greeting.module.css index c599170..5ca61a5 100644 --- a/src/s2-homeworks/hw03/Greeting.module.css +++ b/src/s2-homeworks/hw03/Greeting.module.css @@ -10,7 +10,9 @@ } .error { + position: absolute; margin-top: 7px; + color: #cc0000; font-family: 'Montserrat', sans-serif; font-weight: 400; @@ -19,21 +21,23 @@ } .input { + width: 370px; + padding: 8px 0 8px 12px; + border: 1px solid #d1d1d1; border-radius: 5px; - width: 370px; + + color: #000; font-family: 'Montserrat', sans-serif; font-style: normal; font-weight: 500; font-size: 16px; line-height: 20px; - padding: 8px 0 8px 12px; - color: #000; } .input:focus { - outline: none; border: 1px solid #06c; + outline: none; } .errorInput { @@ -41,19 +45,21 @@ } .button { + height: 36px; margin-left: 12px; + padding: 8px 24px; + background: #06c; color: white; border: none; border-radius: 3px; outline: none; - padding: 8px 24px; + font-family: 'Montserrat', sans-serif; font-weight: 600; font-size: 14px; line-height: 20px; cursor: pointer; - height: 36px; } .button:focus { @@ -67,12 +73,14 @@ cursor: default; } -.count { +.text { + margin-bottom: 9px; + + opacity: .5; font-family: 'Montserrat', sans-serif; font-weight: 400; font-size: 14px; line-height: 17px; - margin-bottom: 9px; } .greeting { diff --git a/src/s2-homeworks/hw03/Greeting.tsx b/src/s2-homeworks/hw03/Greeting.tsx index e5ae70f..d17977b 100644 --- a/src/s2-homeworks/hw03/Greeting.tsx +++ b/src/s2-homeworks/hw03/Greeting.tsx @@ -1,15 +1,15 @@ -import React, { ChangeEvent, KeyboardEvent } from 'react' +import React, {ChangeEvent, KeyboardEvent} from 'react' import s from './Greeting.module.css' type GreetingPropsType = { - name: string // need to fix any - setNameCallback: (e: ChangeEvent) => void // need to fix any - addUser: () => void // need to fix any - onBlur: () => void // need to fix any - onEnter: (e: KeyboardEvent) => void - error: string // need to fix any - totalUsers: number // need to fix any - lastUser?: string // need to fix any + name: any // need to fix any + setNameCallback: any // need to fix any + addUser: any // need to fix any + onBlur: any // need to fix any + onEnter: any // need to fix any + error: any // need to fix any + totalUsers: any // need to fix any + lastUserName?: any // need to fix any } // презентационная компонента (для верстальщика) @@ -19,19 +19,23 @@ const Greeting: React.FC = ( setNameCallback, addUser, onEnter, + onBlur, error, totalUsers, - lastUser, - onBlur, + lastUserName, } // деструктуризация пропсов ) => { const inputClass = error ? `${s.input} ${s.errorInput}` : s.input // need to fix with (?:) return (
-
- {totalUsers} +
+ {'Людей добавили: '} + + {totalUsers} +
+
= ( id={'hw3-button'} onClick={addUser} className={s.button} - disabled={!name} + disabled={!name.trim()} > add
- {lastUser && ( + {lastUserName && (
- hello {lastUser}! + hello {lastUserName}!
)}
diff --git a/src/s2-homeworks/hw03/GreetingContainer.tsx b/src/s2-homeworks/hw03/GreetingContainer.tsx index a3e3e46..306b28d 100644 --- a/src/s2-homeworks/hw03/GreetingContainer.tsx +++ b/src/s2-homeworks/hw03/GreetingContainer.tsx @@ -3,8 +3,30 @@ import Greeting from './Greeting' import { UserType } from './HW3' type GreetingContainerPropsType = { - users: UserType[] // need to fix any - addUserCallback: (name: string) => void // need to fix any + users: any // need to fix any + addUserCallback: any // need to fix any +} + +export const pureAddUser = (name: any, setError: any, setName: any, addUserCallback: any) => { + // если имя пустое - показать ошибку, иначе - добавить юзера и очистить инпут + if (!name.trim()) { + setError('name is required!') + } else { + addUserCallback(name) + setName('') + } +} + +export const pureOnBlur = (name: any, setError: any) => { // если имя пустое - показать ошибку + if (!name.trim()) { + setError('name is required!') + } +} + +export const pureOnEnter = (e: any, addUser: any) => { // если нажата кнопка Enter - добавить + if (e.key === 'Enter') { + addUser() + } } // более простой и понятный для новичков @@ -16,54 +38,39 @@ const GreetingContainer: React.FC = ({ addUserCallback, }) => { // деструктуризация пропсов - const [name, setName] = useState('') // need to fix any - const [error, setError] = useState('') // need to fix any + const [name, setName] = useState('') // need to fix any + const [error, setError] = useState('') // need to fix any - const setNameCallback = (e: ChangeEvent) => { - // need to fix any // нельзя пробелы перед и после имени, можно в середине + const setNameCallback = (e: any) => { // need to fix any setName(e.currentTarget.value) // need to fix + error && setError('') } const addUser = () => { - addUserCallback(name) - setName('') + pureAddUser(name, setError, setName, addUserCallback) } const onBlur = () => { - const trimmedName = name.trim() - - if (!trimmedName) { - setError('name is required!') - } - setName(trimmedName) // need to fix + pureOnBlur(name, setError) } - const onEnter = (e: KeyboardEvent) => { - if (e.key === 'Enter') { - const trimmedName = name.trim() - - if (!trimmedName) { - setName('') - setError('name is required!') - } else { - addUserCallback(trimmedName) - setName('') - } - } + const onEnter = (e: any) => { + pureOnEnter(e, addUser) } const totalUsers = users.length // need to fix + const lastUserName = users[users.length - 1]?.name // need to fix return ( ) } diff --git a/src/s2-homeworks/hw03/HW3.tsx b/src/s2-homeworks/hw03/HW3.tsx index 2d675d0..2fb2f8a 100644 --- a/src/s2-homeworks/hw03/HW3.tsx +++ b/src/s2-homeworks/hw03/HW3.tsx @@ -1,25 +1,41 @@ import React, { useState } from 'react' import { v1 } from 'uuid' -import s from './Greeting.module.css' import s2 from '../../s1-main/App.module.css' import GreetingContainer from './GreetingContainer' +/* +* 1 - описать тип UserType +* 2 - указать нужный тип в useState с users +* 3 - дописать типы и логику функции pureAddUserCallback и проверить её тестами +* 4 - в файле GreetingContainer.tsx дописать типизацию пропсов +* 5 - в файле GreetingContainer.tsx указать нужные типы в useState с name и error +* 6 - в файле GreetingContainer.tsx дописать тип и логику функции setNameCallback +* 7 - в файле GreetingContainer.tsx дописать логику функций pureAddUser, pureOnBlur, pureOnEnter и проверить их тестами +* 8 - в файле GreetingContainer.tsx вычислить количество добавленных и имя последнего (totalUsers, lastUserName) +* 9 - в файле Greeting.tsx дописать типизацию пропсов +* 10 - в файле Greeting.tsx вычислить inputClass в зависимости от наличия ошибки +* 11 - сделать стили в соответствии с дизайном +* */ + // types export type UserType = { - _id: string // need to fix any - name: string // need to fix any + _id: any // need to fix any + name: any // need to fix any +} + +export const pureAddUserCallback = (name: any, setUsers: any, users: any) => { // need to fix any + const user = { // need to fix + _id: v1(), + name, + } + setUsers([...users, user]) } const HW3 = () => { - const [users, setUsers] = useState([]) // need to fix any + const [users, setUsers] = useState([]) // need to fix any - const addUserCallback = (name: string) => { - // need to fix any - const user = { - _id: v1(), - name, - } - setUsers([...users, user]) // need to fix + const addUserCallback = (name: any) => { // need to fix any + pureAddUserCallback(name, setUsers, users) } return ( diff --git a/src/s2-homeworks/hw03/tests/pureAddUser.test.tsx b/src/s2-homeworks/hw03/tests/pureAddUser.test.tsx new file mode 100644 index 0000000..e49d5c2 --- /dev/null +++ b/src/s2-homeworks/hw03/tests/pureAddUser.test.tsx @@ -0,0 +1,43 @@ +import React from 'react' +import {pureAddUser} from '../GreetingContainer' + +let name: any +const setName = (a: any) => { + name = a +} +let error: any +const setError = (a: any) => { + error = a +} +let added: any +const addUserCallback = () => { + added = true +} + +beforeEach(() => { + name = '' + error = '' + added = false +}) + +test('name 1', () => { + name = '1' + pureAddUser(name, setError, setName, addUserCallback) + expect(name).toBe('') + expect(error).toBe('') + expect(added).toBe(true) +}) +test('name 2', () => { + name = '' + pureAddUser(name, setError, setName, addUserCallback) + expect(name).toBe('') + expect(error).toBe('name is required!') + expect(added).toBe(false) +}) +test('name 3', () => { + name = ' ' + pureAddUser(name, setError, setName, addUserCallback) + expect(name).toBe(' ') + expect(error).toBe('name is required!') + expect(added).toBe(false) +}) diff --git a/src/s2-homeworks/hw03/tests/pureAddUserCallback.test.tsx b/src/s2-homeworks/hw03/tests/pureAddUserCallback.test.tsx new file mode 100644 index 0000000..a8251ce --- /dev/null +++ b/src/s2-homeworks/hw03/tests/pureAddUserCallback.test.tsx @@ -0,0 +1,18 @@ +import React from 'react' +import {pureAddUserCallback} from '../HW3' + +let initialState: any[] +const setName = (a: any[]) => { + initialState = a +} + +beforeEach(() => { + initialState = [] +}) + +test('name 1', () => { + pureAddUserCallback('name', setName, initialState) + expect(initialState.length).toBe(1) + expect(initialState[0].name).toBe('name') + expect(!!initialState[0]._id).toBe(true) +}) diff --git a/src/s2-homeworks/hw03/tests/pureOnBlur.test.tsx b/src/s2-homeworks/hw03/tests/pureOnBlur.test.tsx new file mode 100644 index 0000000..6007fb1 --- /dev/null +++ b/src/s2-homeworks/hw03/tests/pureOnBlur.test.tsx @@ -0,0 +1,29 @@ +import React from 'react' +import {pureOnBlur} from '../GreetingContainer' + +let name: any +let error: any +const setError = (a: any) => { + error = a +} + +beforeEach(() => { + name = '' + error = '' +}) + +test('name 1', () => { + name = '1' + pureOnBlur(name, setError) + expect(error).toBe('') +}) +test('name 2', () => { + name = '' + pureOnBlur(name, setError) + expect(error).toBe('name is required!') +}) +test('name 3', () => { + name = ' ' + pureOnBlur(name, setError) + expect(error).toBe('name is required!') +}) diff --git a/src/s2-homeworks/hw03/tests/pureOnEnter.test.tsx b/src/s2-homeworks/hw03/tests/pureOnEnter.test.tsx new file mode 100644 index 0000000..7635db8 --- /dev/null +++ b/src/s2-homeworks/hw03/tests/pureOnEnter.test.tsx @@ -0,0 +1,20 @@ +import React from 'react' +import {pureOnEnter} from '../GreetingContainer' + +let added: any +const addUser = () => { + added = true +} + +beforeEach(() => { + added = false +}) + +test('name 1', () => { + pureOnEnter({key: 'Enter'} as any, addUser) + expect(added).toBe(true) +}) +test('name 2', () => { + pureOnEnter({key: ''} as any, addUser) + expect(added).toBe(false) +})