From e07fa0f4573f24a17b041fecfd82977f9f80ae50 Mon Sep 17 00:00:00 2001 From: Sasha Yatsykovych Date: Mon, 28 Nov 2022 07:39:38 +0200 Subject: [PATCH 1/7] version 1 --- src/App.tsx | 43 +++++------ src/components/PeopleTable/PeopleTable.scss | 3 + src/components/PeopleTable/PeopleTable.tsx | 81 +++++++++++++++++++++ 3 files changed, 106 insertions(+), 21 deletions(-) create mode 100644 src/components/PeopleTable/PeopleTable.scss create mode 100644 src/components/PeopleTable/PeopleTable.tsx diff --git a/src/App.tsx b/src/App.tsx index f6361547..1c3ce1fa 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,34 +5,35 @@ import 'bulma/css/bulma.css'; import './App.scss'; import peopleFromServer from './people.json'; +import { Person } from './types/Person'; +import { PeopleTable } from './components/PeopleTable/PeopleTable'; +import { Loader } from './components/Loader'; -export class App extends React.Component { - state = {}; +interface State { + people: Person[], +} + +export class App extends React.Component<{}, State> { + state: Readonly = { + people: [], + }; + + componentDidMount() { + setTimeout(() => { + this.setState({ people: peopleFromServer }); + }, 1000); + } render() { + const { people } = this.state; + return (

People table

- - - - - - - - - - - {peopleFromServer.map(person => ( - - - - - - ))} - -
namesexborn
{person.name}{person.sex}{person.born}
+ {people.length > 0 + ? + : }
); } diff --git a/src/components/PeopleTable/PeopleTable.scss b/src/components/PeopleTable/PeopleTable.scss new file mode 100644 index 00000000..6cb93e78 --- /dev/null +++ b/src/components/PeopleTable/PeopleTable.scss @@ -0,0 +1,3 @@ +.isSelected { + background-color: yellowgreen; +} diff --git a/src/components/PeopleTable/PeopleTable.tsx b/src/components/PeopleTable/PeopleTable.tsx new file mode 100644 index 00000000..4f8bd7d7 --- /dev/null +++ b/src/components/PeopleTable/PeopleTable.tsx @@ -0,0 +1,81 @@ +import { Component } from 'react'; +import classNames from 'classnames'; + +import { Person } from '../../types/Person'; +import './PeopleTable.scss'; + +interface Props { + people: Person[] +} + +interface State { + selectedPerson: Person | null; +} + +export class PeopleTable extends Component { + state: Readonly = { + selectedPerson: null, + }; + + handlePersonSelection = (person: Person | null) => { + this.setState({ selectedPerson: person }); + } + + isSelected = (person: Person) => { + return person.slug === this.state.selectedPerson?.slug; + } + + render() { + const { isSelected } = this; + const { people } = this.props; + const { selectedPerson } = this.state; + + return ( + + + + + + + + + + + + + {people.map(person => ( + + + + + + + ))} + +
{selectedPerson?.name || 'Nobody selected'}
-namesexborn
+ {isSelected(person) + ? ( + + ) + : ( + + )} + {person.name}{person.sex}{person.born}
+ ); + } +} From b01b9d7d127108b1acf167c586c8b732449540dc Mon Sep 17 00:00:00 2001 From: Sasha Yatsykovych Date: Wed, 30 Nov 2022 08:40:59 +0200 Subject: [PATCH 2/7] versino 2 --- src/App.tsx | 40 ++-- src/components/PeopleTable/PeopleTable.tsx | 218 ++++++++++++++------- 2 files changed, 162 insertions(+), 96 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 1c3ce1fa..33474132 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,40 +1,28 @@ -import React from 'react'; +import { FC, useEffect, useState } from 'react'; import '@fortawesome/fontawesome-free/css/all.css'; import 'bulma/css/bulma.css'; import './App.scss'; -import peopleFromServer from './people.json'; -import { Person } from './types/Person'; import { PeopleTable } from './components/PeopleTable/PeopleTable'; import { Loader } from './components/Loader'; -interface State { - people: Person[], -} +export const App: FC = () => { + const [isLoaded, setIsLoaded] = useState(false); -export class App extends React.Component<{}, State> { - state: Readonly = { - people: [], - }; - - componentDidMount() { + useEffect(() => { setTimeout(() => { - this.setState({ people: peopleFromServer }); + setIsLoaded(true); }, 1000); - } + }, []); - render() { - const { people } = this.state; + return ( +
+

People table

- return ( -
-

People table

+ {!isLoaded && } - {people.length > 0 - ? - : } -
- ); - } -} + {isLoaded && } +
+ ); +}; diff --git a/src/components/PeopleTable/PeopleTable.tsx b/src/components/PeopleTable/PeopleTable.tsx index 4f8bd7d7..4b3300c2 100644 --- a/src/components/PeopleTable/PeopleTable.tsx +++ b/src/components/PeopleTable/PeopleTable.tsx @@ -1,81 +1,159 @@ -import { Component } from 'react'; +import { useState } from 'react'; import classNames from 'classnames'; +import peopleFromServer from '../../people.json'; import { Person } from '../../types/Person'; import './PeopleTable.scss'; -interface Props { - people: Person[] -} +export const PeopleTable = () => { + const [people, setPeople] = useState(peopleFromServer); + const [selectedPeople, setSelectedPeople] = useState([]); -interface State { - selectedPerson: Person | null; -} + const handlePersonSelection = (personToAdd: Person) => { + setSelectedPeople((prevSelectedPeople) => ([ + ...prevSelectedPeople, + personToAdd, + ])); + }; -export class PeopleTable extends Component { - state: Readonly = { - selectedPerson: null, + const handlePersonUnselection = (personToRemove: Person) => { + setSelectedPeople((prevSelectedPeople) => prevSelectedPeople + .filter( + person => person.slug !== personToRemove.slug, + )); }; - handlePersonSelection = (person: Person | null) => { - this.setState({ selectedPerson: person }); - } - - isSelected = (person: Person) => { - return person.slug === this.state.selectedPerson?.slug; - } - - render() { - const { isSelected } = this; - const { people } = this.props; - const { selectedPerson } = this.state; - - return ( - - - - - - - - - - - - - {people.map(person => ( - - - - - - - ))} - -
{selectedPerson?.name || 'Nobody selected'}
-namesexborn
- {isSelected(person) - ? ( - - ) - : ( - - )} - {person.name}{person.sex}{person.born}
+ const handleMoveDown = (personToMoveDown: Person) => { + const peopleCopy = [...people]; + + const personIndex = peopleCopy.findIndex( + person => person.slug === personToMoveDown.slug, + ); + + if (personIndex === peopleCopy.length - 1) { + return; + } + + setPeople((prevPeople) => ([ + ...prevPeople.slice(0, personIndex), + prevPeople[personIndex + 1], + prevPeople[personIndex], + ...prevPeople.slice(personIndex + 2), + ])); + }; + + const handleMoveUp = (personToMoveDown: Person) => { + const peopleCopy = [...people]; + + const personIndex = peopleCopy.findIndex( + person => person.slug === personToMoveDown.slug, + ); + + if (personIndex === 0) { + return; + } + + const swap = peopleCopy[personIndex]; + + peopleCopy[personIndex] = peopleCopy[personIndex - 1]; + peopleCopy[personIndex - 1] = swap; + + setPeople(peopleCopy); + }; + + const isSelected = (personToCheck: Person) => { + return selectedPeople.some( + person => person.slug === personToCheck.slug, ); - } + }; + + const clearSelectedPeople = () => { + setSelectedPeople([]); + }; + + return ( + + + + + + + + + + + + + + {people.map(person => ( + + + + + + + + + ))} + +
+ + {selectedPeople.map(person => person.name).join(', ')} +
-namesexbornreorder
+ {isSelected(person) + ? ( + + ) + : ( + + )} + + {person.name} + {person.sex}{person.born} + + + +
+ ); } From f555d4f21e50101cbfd08d00fb66f02aed3dccb0 Mon Sep 17 00:00:00 2001 From: Sasha Yatsykovych Date: Wed, 30 Nov 2022 08:42:19 +0200 Subject: [PATCH 3/7] small improvements --- src/components/PeopleTable/PeopleTable.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/PeopleTable/PeopleTable.tsx b/src/components/PeopleTable/PeopleTable.tsx index 4b3300c2..756f180f 100644 --- a/src/components/PeopleTable/PeopleTable.tsx +++ b/src/components/PeopleTable/PeopleTable.tsx @@ -156,4 +156,4 @@ export const PeopleTable = () => { ); -} +}; From e4f4a41b78c22d75b2ddf674232baf732270f151 Mon Sep 17 00:00:00 2001 From: Sasha Yatsykovych Date: Wed, 30 Nov 2022 09:04:51 +0200 Subject: [PATCH 4/7] improvements --- src/components/PeopleTable/PeopleTable.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/PeopleTable/PeopleTable.tsx b/src/components/PeopleTable/PeopleTable.tsx index 756f180f..667224b2 100644 --- a/src/components/PeopleTable/PeopleTable.tsx +++ b/src/components/PeopleTable/PeopleTable.tsx @@ -109,6 +109,7 @@ export const PeopleTable = () => { From 9c69ecabfb7aaa21c1cd94ee9a22f1c5884e5b04 Mon Sep 17 00:00:00 2001 From: Sasha Yatsykovych Date: Wed, 30 Nov 2022 09:09:13 +0200 Subject: [PATCH 5/7] add buttons --- src/components/PeopleTable/PeopleTable.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/PeopleTable/PeopleTable.tsx b/src/components/PeopleTable/PeopleTable.tsx index 667224b2..ebfcb2e3 100644 --- a/src/components/PeopleTable/PeopleTable.tsx +++ b/src/components/PeopleTable/PeopleTable.tsx @@ -109,7 +109,7 @@ export const PeopleTable = () => {