diff --git a/src/App.scss b/src/App.scss index 93f0af3a..70d8e384 100644 --- a/src/App.scss +++ b/src/App.scss @@ -2,3 +2,7 @@ iframe { display: none; } + +.selected { + background-color: red; +} diff --git a/src/App.tsx b/src/App.tsx index f6361547..ed0aecfb 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -3,36 +3,88 @@ import React from 'react'; import '@fortawesome/fontawesome-free/css/all.css'; import 'bulma/css/bulma.css'; import './App.scss'; +import { getPeopleFromServer } from './api'; +import { Person } from './types/Person'; +import { PeoplesTable } from './PeoplesTable'; +import { Loader } from './Loader'; -import peopleFromServer from './people.json'; +const MOCK_LOADING_TIME = 1000; -export class App extends React.Component { - state = {}; +type State = { + peopleFromServer: Person[]; + isError: boolean; + isLoading: boolean; +}; + +export class App extends React.Component<{}, State> { + state: State = { + peopleFromServer: [], + isError: false, + isLoading: false, + }; + + componentDidMount() { + this.setState({ + isLoading: true, + }); + + const people = getPeopleFromServer(); + + if (!people) { + setTimeout( + () => { + this.setState({ + isError: true, + isLoading: false, + }); + }, + MOCK_LOADING_TIME, + ); + + return; + } + + setTimeout( + () => { + this.setState({ + peopleFromServer: people, + isLoading: false, + }); + }, + MOCK_LOADING_TIME, + ); + } render() { + const { + peopleFromServer, + isLoading, + isError, + } = this.state; + + const isNoUsers = peopleFromServer.length === 0 + && !isLoading + && !isError; + return (

People table

- - - - - - - - - - - {peopleFromServer.map(person => ( - - - - - - ))} - -
namesexborn
{person.name}{person.sex}{person.born}
+ {isError && ( +

Sorry, an error occurred

+ )} + + {isLoading && ( + + )} + + {isNoUsers && ( +

No users.

+ )} + + {peopleFromServer.length > 0 && ( + + )}
); } diff --git a/src/Loader.tsx b/src/Loader.tsx new file mode 100644 index 00000000..65fcd6aa --- /dev/null +++ b/src/Loader.tsx @@ -0,0 +1,3 @@ +export const Loader: React.FC = () => ( +

Loading...

+); diff --git a/src/PeoplesTable.tsx b/src/PeoplesTable.tsx new file mode 100644 index 00000000..5615fd7f --- /dev/null +++ b/src/PeoplesTable.tsx @@ -0,0 +1,61 @@ +import React from 'react'; +import { PersonFromTable } from './PersonFromTable'; +import { Person } from './types/Person'; + +type Props = { + peopleToDisplay: Person[]; +}; + +type State = { + selectedPersonSlug: string; +}; + +export class PeoplesTable extends React.Component { + state: State = { + selectedPersonSlug: '', + }; + + handleSelectPerson = (personSlug: string) => { + this.setState({ + selectedPersonSlug: personSlug, + }); + }; + + render() { + const { + peopleToDisplay, + } = this.props; + + const { + selectedPersonSlug, + } = this.state; + + return ( + + + + + + + + + + + + {peopleToDisplay.map(person => ( + + ))} + +
namesexbornselect
+ ); + } +} diff --git a/src/PersonFromTable.tsx b/src/PersonFromTable.tsx new file mode 100644 index 00000000..cd467fc1 --- /dev/null +++ b/src/PersonFromTable.tsx @@ -0,0 +1,29 @@ +import { Person } from './types/Person'; + +type Props = { + person: Person; + selectPerson: (personSlug: string) => void; + className?: string; +}; + +export const PersonFromTable: React.FC = ({ + person, + selectPerson, + className, +}) => ( + + {person.name} + {person.sex} + {person.born} + + + + +); diff --git a/src/api.ts b/src/api.ts new file mode 100644 index 00000000..e6d4bfa1 --- /dev/null +++ b/src/api.ts @@ -0,0 +1,5 @@ +import peopleFromServer from './people.json'; + +export const getPeopleFromServer = () => { + return peopleFromServer; +};