|
@@ -0,0 +1,151 @@
|
|
|
+import logoDefault from './logo.svg';
|
|
|
+import {useEffect, useState, useRef} from "react";
|
|
|
+import React from 'react';
|
|
|
+import './App.scss';
|
|
|
+
|
|
|
+ //добавить key
|
|
|
+ //onChange - по изменению
|
|
|
+ //onMoveUp - сдвинуть вверх
|
|
|
+ //onMoveDown - сдвинуть вниз
|
|
|
+ //onDelete - удалить
|
|
|
+ //onAdd - добавить
|
|
|
+
|
|
|
+const PhoneBookEntry = ({data: {name, phone} = {name:'', phone:''}, key='',
|
|
|
+ onChange, onMoveUp, onMoveDown, onDelete, onAdd }) =>{
|
|
|
+ //тут отдавать в наружный onChange такой же обьект как и data
|
|
|
+ return(
|
|
|
+ <>
|
|
|
+ <input value={name} onChange={(e) => onChange({name:e.target.value, phone})} />
|
|
|
+ <input type="number" value={phone} onChange={(e) => onChange({name, phone:e.target.value})} />
|
|
|
+ <button onClick={() => onMoveUp()}>↑</button>
|
|
|
+ <button onClick={()=>onMoveDown()}>↓</button>
|
|
|
+ <button onClick={() => onAdd()}>+</button>
|
|
|
+ <button onClick={() => onDelete({name, phone, key})}>x</button>
|
|
|
+ <br/>
|
|
|
+ </>
|
|
|
+ )
|
|
|
+}
|
|
|
+
|
|
|
+const defaultPeople = [{name:"John",phone:"102"},{name:"Paul",phone:'103'}]
|
|
|
+
|
|
|
+
|
|
|
+ const PhoneBook=({people=defaultPeople, onSave}) =>{
|
|
|
+ const [ppl, setPpl] = useState(people)
|
|
|
+ const [keys, setKeys] = useState(people.map(()=>Math.random()))
|
|
|
+ const [name, setName] = useState('')
|
|
|
+ const [phone, setPhone] = useState('')
|
|
|
+
|
|
|
+ //должно меняться соответственно элемент списка - сдвигаться, удаляться и т.п.
|
|
|
+
|
|
|
+ useEffect(()=>{
|
|
|
+ setPpl(people)
|
|
|
+ //тут keys обновить
|
|
|
+ setKeys(keys)
|
|
|
+ },[people, keys])
|
|
|
+ useEffect(()=>{
|
|
|
+ setTimeout(()=> setPpl(ppl=>[{name:'', phone:''}, ...ppl]),5000)
|
|
|
+ },[])
|
|
|
+
|
|
|
+ //обеспечить для PhoneBookEntry
|
|
|
+ // onChange, onMoveUp, onMoveDown, onDelete
|
|
|
+ const onChange=(newData, i)=>{
|
|
|
+ //создаем новый массив ppl на базе старого,
|
|
|
+ //заменяем один элемент и делаем setPpl
|
|
|
+ //ничего не делаем с keys
|
|
|
+ let arr = [];
|
|
|
+ ppl.forEach((i, num) => {
|
|
|
+ if(num===i){
|
|
|
+ arr.push(newData)
|
|
|
+ }else{
|
|
|
+ arr.push(num)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ setPpl(arr);
|
|
|
+ }
|
|
|
+
|
|
|
+ const onDelete = (i) =>{
|
|
|
+ setPpl(ppl.filter(n=>n.name!==i.name && n.phone!==i.phone))
|
|
|
+ keys.splice(i.key,1)
|
|
|
+ }
|
|
|
+
|
|
|
+ const onMoveDown = (i) =>{
|
|
|
+ let arr = [];
|
|
|
+ ppl.forEach(n=>arr.push(n))
|
|
|
+ let temp=arr[i]
|
|
|
+ let tempKey=keys[i]
|
|
|
+ if(i===arr.length-1){
|
|
|
+ arr[i]=arr[0]
|
|
|
+ arr[0]=temp
|
|
|
+ keys[i]=keys[0]
|
|
|
+ keys[0]=tempKey
|
|
|
+ }else{
|
|
|
+ arr[i]=arr[i+1]
|
|
|
+ arr[i+1]=temp
|
|
|
+ keys[i]=keys[i+1]
|
|
|
+ keys[i+1]=tempKey
|
|
|
+ }
|
|
|
+ setPpl(arr)
|
|
|
+ }
|
|
|
+
|
|
|
+ const onAdd = (newData, i) => {
|
|
|
+ let arr = [];
|
|
|
+ ppl.forEach(n=>arr.push(n))
|
|
|
+ i==='start'?arr.unshift(newData):arr.splice(i+1,0,newData)
|
|
|
+ setPpl(arr)
|
|
|
+ keys.splice(i,0,Math.random())
|
|
|
+ }
|
|
|
+
|
|
|
+ const onMoveUp = (i) => {
|
|
|
+ let arr = [];
|
|
|
+ ppl.forEach(n => arr.push(n))
|
|
|
+ let temp=arr[i]
|
|
|
+ let tempKey=keys[i]
|
|
|
+ if(i===0){
|
|
|
+ arr[i]=arr[arr.length-1]
|
|
|
+ arr[arr.length-1] = temp
|
|
|
+ keys[i]=keys[0]
|
|
|
+ keys[0]=tempKey
|
|
|
+ }else{
|
|
|
+ arr[i]=arr[i-1]
|
|
|
+ arr[i-1]=temp
|
|
|
+ keys[i]=keys[i-1]
|
|
|
+ keys[i-1]=tempKey
|
|
|
+ }
|
|
|
+ setPpl(arr)
|
|
|
+ }
|
|
|
+
|
|
|
+ onSave = (ppl) => console.log(ppl);
|
|
|
+
|
|
|
+ console.log(keys, ppl)
|
|
|
+ //по любым изменениям обновляем массив целиком на базе старого
|
|
|
+ //меняем один или несклько элементов
|
|
|
+ return(
|
|
|
+ <>
|
|
|
+ <input type='text' placeholder='name' value={name} onChange={e => setName(e.target.value)}/>
|
|
|
+ <input type="number" placeholder='phone' value={phone} onChange={e => setPhone(e.target.value)}/>
|
|
|
+ <button onClick={() => onAdd({name, phone}, 'start')}>+</button>
|
|
|
+ <div className="PhoneBook">
|
|
|
+ {ppl.map((data,i)=>
|
|
|
+ <PhoneBookEntry data={data} key={i}
|
|
|
+ onChange={data=>onChange(data,i)}
|
|
|
+ onDelete={()=>onDelete(data)}
|
|
|
+ onAdd={() => onAdd({name, phone}, i)}
|
|
|
+ onMoveDown={() => onMoveDown(i)}
|
|
|
+ onMoveUp={() => onMoveUp(i)}
|
|
|
+ />)
|
|
|
+ }
|
|
|
+ </div>
|
|
|
+ <button onClick={()=>onSave(ppl)}>Save</button>
|
|
|
+ </>
|
|
|
+ )
|
|
|
+ }
|
|
|
+
|
|
|
+ function App() {
|
|
|
+ return (
|
|
|
+ <div className="App">
|
|
|
+ <PhoneBook />
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+export default App;
|