From ed1e5e61102dbd1570e0ac8a3e4ca8d8d9f47877 Mon Sep 17 00:00:00 2001 From: Jean-Christophe <> Date: Thu, 25 Jan 2024 21:49:51 +0100 Subject: [PATCH] =?UTF-8?q?reafctorisation=20:=20remonter=20l'=C3=A9tat?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/style/app.css | 4 ++ src/assets/style/data.css | 7 +++ src/assets/style/displayController.css | 8 +--- src/assets/style/person.css | 18 ++++---- src/assets/style/personControls.css | 9 ++++ src/assets/style/personListing.css | 1 - src/assets/style/personListingData.css | 15 ++++++ src/assets/style/personsController.css | 3 ++ src/assets/style/rating.css | 9 ++++ src/components/app.component.jsx | 46 +++++++++++++++++++ src/components/data.component.jsx | 16 +++++++ src/components/person.component.jsx | 32 ++++++------- src/components/personListing.component.jsx | 15 +----- .../personListingController.component.jsx | 14 ++++-- .../personListingControls.component.jsx | 18 ++++---- .../personListingData.component.jsx | 27 +++++++++++ src/scripts/main.js | 5 +- 17 files changed, 183 insertions(+), 64 deletions(-) create mode 100644 src/assets/style/app.css create mode 100644 src/assets/style/data.css create mode 100644 src/assets/style/personControls.css create mode 100644 src/assets/style/personListingData.css create mode 100644 src/assets/style/personsController.css create mode 100644 src/assets/style/rating.css create mode 100644 src/components/app.component.jsx create mode 100644 src/components/data.component.jsx create mode 100644 src/components/personListingData.component.jsx diff --git a/src/assets/style/app.css b/src/assets/style/app.css new file mode 100644 index 0000000..d9683e1 --- /dev/null +++ b/src/assets/style/app.css @@ -0,0 +1,4 @@ +div#app { + position : relative; + min-height: 200px; + } diff --git a/src/assets/style/data.css b/src/assets/style/data.css new file mode 100644 index 0000000..05dbf5c --- /dev/null +++ b/src/assets/style/data.css @@ -0,0 +1,7 @@ +span.label, span.value { + padding : 8px; +} + +span.value { + font-weight : bold; +} diff --git a/src/assets/style/displayController.css b/src/assets/style/displayController.css index 1a99f18..5958c9c 100644 --- a/src/assets/style/displayController.css +++ b/src/assets/style/displayController.css @@ -1,9 +1,5 @@ div.controller { - margin : 10px; - padding : 10px; - border : solid thin #AAA; + padding-left : 240px; } -div.controller button { - margin : 0px 10px; -} + diff --git a/src/assets/style/person.css b/src/assets/style/person.css index 07e3a9b..0485682 100644 --- a/src/assets/style/person.css +++ b/src/assets/style/person.css @@ -1,15 +1,15 @@ div.person { - padding: 4px 8px; - margin: 10px; - background-color: rgba(128, 128, 255, 0.7); - color: white; - font-size: medium; + padding : 4px 8px; + margin : 10px; + background-color : rgba(128,128,255, 0.7); + color : white; + font-size : medium; } -div.person>div { - margin: 3px 15px; +div.person > div { + margin : 3px 15px; } div.person span { - color: black; -} \ No newline at end of file + color : black; +} diff --git a/src/assets/style/personControls.css b/src/assets/style/personControls.css new file mode 100644 index 0000000..f847f8e --- /dev/null +++ b/src/assets/style/personControls.css @@ -0,0 +1,9 @@ +div.controls { + margin : 10px; + padding : 10px; + border : solid thin #AAA; +} + +div.controls button { + margin : 0px 10px; +} diff --git a/src/assets/style/personListing.css b/src/assets/style/personListing.css index e3bf74a..f25ad87 100644 --- a/src/assets/style/personListing.css +++ b/src/assets/style/personListing.css @@ -1,5 +1,4 @@ div.personListing { border : dashed thin black ; padding : 10px; - margin : 5px; } diff --git a/src/assets/style/personListingData.css b/src/assets/style/personListingData.css new file mode 100644 index 0000000..fb74de1 --- /dev/null +++ b/src/assets/style/personListingData.css @@ -0,0 +1,15 @@ +div.data { + margin : 10px; + border : solid 2px rgb(60,60,255); + background-color : white; + font-size : 16px; + + position : absolute; + left : 0px; + top : 30px; +} + +div.data div { + padding : 4px 0px; + border : solid thin #CCC; +} diff --git a/src/assets/style/personsController.css b/src/assets/style/personsController.css new file mode 100644 index 0000000..502ae8e --- /dev/null +++ b/src/assets/style/personsController.css @@ -0,0 +1,3 @@ +div.controller { + padding-left : 240px; +} diff --git a/src/assets/style/rating.css b/src/assets/style/rating.css new file mode 100644 index 0000000..d80fb33 --- /dev/null +++ b/src/assets/style/rating.css @@ -0,0 +1,9 @@ +.rating { + margin : 10px; + font-size : x-large; +} + +.rating img { + width : 48px; + vertical-align : middle; +} diff --git a/src/components/app.component.jsx b/src/components/app.component.jsx new file mode 100644 index 0000000..8f22e84 --- /dev/null +++ b/src/components/app.component.jsx @@ -0,0 +1,46 @@ + +import { useState, useEffect } from 'react'; + +import '../assets/style/app.css'; + +import PersonListingController from './personListingController.component.jsx'; +import PersonListingData from './personListingData.component.jsx'; + +import { mockFetch } from '../util/mockAPI.js'; + +const App = () => { + + const [persons, setPersons ] = useState([]); + + const fetchData = async () => { + const data = await mockFetch('http://source.of.data/persons',10); + setPersons( data ); + } + + useEffect( () => { + fetchData(); + }, []); + + /* increment age of person with given id, state is updated */ +const incrementAge = (personId) => { + setPersons ( previousPersons => { + const olderPerson = previousPersons.find( person => person.id === personId ); + olderPerson.age = olderPerson.age + 1; + return [...previousPersons]; + }); +} + +return( + <div id="app"> + <PersonListingController + persons = { persons } + incrementAge = { incrementAge } + /> + <PersonListingData + persons = { persons } + /> + </div> +); +} + +export default App; \ No newline at end of file diff --git a/src/components/data.component.jsx b/src/components/data.component.jsx new file mode 100644 index 0000000..eca6fc4 --- /dev/null +++ b/src/components/data.component.jsx @@ -0,0 +1,16 @@ + +import '../assets/style/data.css'; + +const Data = ( { label, value }) => { + + return( + <div> + <span className= "label"> { label } </span> + : + <span className= "value"> { value } </span> + </div> + ); + +} + +export default Data; \ No newline at end of file diff --git a/src/components/person.component.jsx b/src/components/person.component.jsx index f588ba5..aa276c2 100644 --- a/src/components/person.component.jsx +++ b/src/components/person.component.jsx @@ -2,26 +2,22 @@ import { useState, useEffect, useRef } from 'react'; import '../assets/style/person.css'; -const Person = ( { name = 'Anonymous', age, started, delay } ) => { +const Person = ( { name = 'Anonymous', age, id, started, delay, incrementAge } ) => { -const [ currentAge, setCurrentAge ] = useState(age); -const timer = useRef( undefined ); + const timer = useRef( undefined ); -useEffect( () => { - if (started) { - timer.current = setInterval( () => { - setCurrentAge( previousCurrentAge => previousCurrentAge + 1 ); - console.log('timer is running'); - }, delay); - } - return () => clearInterval( timer.current ); - }, [started, delay] ); + useEffect( () => { + if (started) { + timer.current = setInterval( () => incrementAge( id ), delay); + } + return () => clearInterval( timer.current ); + }, [started, delay] ); -return ( - <div className="person">Here is : - <div>name : <span>{ name }</span> </div> - <div>age : <span>{ currentAge } </span> </div> - </div> -); + return ( + <div className="person">Here is : + <div>name : <span>{ name }</span> </div> + <div>age : <span>{ age } </span> </div> + </div> + ); } export default Person; diff --git a/src/components/personListing.component.jsx b/src/components/personListing.component.jsx index 3c238c0..a279d70 100644 --- a/src/components/personListing.component.jsx +++ b/src/components/personListing.component.jsx @@ -1,6 +1,6 @@ import { useState, useEffect } from 'react'; -import { mockFetch } from '../util/mockAPI.js'; + import '../assets/style/personListing.css'; @@ -8,18 +8,7 @@ import Person from './person.component.jsx'; const PersonListing = props => { - const { started, delay } = props; - - const [persons, setPersons ] = useState([]); - - const fetchData = async () => { - const data = await mockFetch('http://source.of.data/persons',10); - setPersons( data ); - } - - useEffect( () => { - fetchData(); - }, []); + const { persons, incrementAge, started, delay } = props; const personComponents = persons.map(person => <Person {...person} diff --git a/src/components/personListingController.component.jsx b/src/components/personListingController.component.jsx index 935a816..2d130e4 100644 --- a/src/components/personListingController.component.jsx +++ b/src/components/personListingController.component.jsx @@ -5,11 +5,14 @@ import '../assets/style/displayController.css'; import PersonListing from './personListing.component.jsx'; import PersonListingControls from './personListingControls.component.jsx'; -const PersonListingController = ({ initialDelay = 250 }) => { +const INITIAL_DELAY= 1000; + +const PersonListingController = ( props ) => { + const { persons, incrementAge } = props; const [ closed, setClosed ] = useState(false); const [ started, setStarted ] = useState(false); - const [ delay, setDelay ] = useState(initialDelay) + const [ delay, setDelay ] = useState(INITIAL_DELAY); const startStop = () => setStarted( previousStarted => ! previousStarted); const closeComponent = () => { @@ -24,6 +27,7 @@ const PersonListingController = ({ initialDelay = 250 }) => { return null; else return (<PersonListing + { ...props } delay={delay} started={started} />); @@ -40,9 +44,9 @@ const PersonListingController = ({ initialDelay = 250 }) => { } return ( - <div> - {buildListingControls()} - {buildPersonListing()} + <div className="controller"> + { buildListingControls() } + { buildPersonListing() } </div> ); diff --git a/src/components/personListingControls.component.jsx b/src/components/personListingControls.component.jsx index ed45586..f233637 100644 --- a/src/components/personListingControls.component.jsx +++ b/src/components/personListingControls.component.jsx @@ -1,4 +1,4 @@ -import '../assets/style/displayController.css'; +import '../assets/style/personControls.css'; import DelayButton from './delayButton.component.jsx'; @@ -13,14 +13,14 @@ const PersonListingControls = ( { started, closed, changeDelay, closeAction, sta return( - <div className = 'controller'> - <button onClick= { startStop }> - { started ? 'Stop' : 'Start' } - </button> - { buildDelayButtons() } - <button onClick= { closeAction }> - { closed ? 'Open' : 'Close' } - </button> + <div className = 'controls'> + <button onClick= { startStop }> + { started ? 'Stop' : 'Start' } + </button> + { buildDelayButtons() } + <button onClick= { closeAction }> + { closed ? 'Open' : 'Close' } + </button> </div> ); } diff --git a/src/components/personListingData.component.jsx b/src/components/personListingData.component.jsx new file mode 100644 index 0000000..597d77d --- /dev/null +++ b/src/components/personListingData.component.jsx @@ -0,0 +1,27 @@ + +import '../assets/style/personListingData.css'; + +import Data from './data.component.jsx'; + +const PersonListingData = ( { persons } ) => { + + const nbPersonsOlderThan = minAge => { + return persons.filter( person => person.age > minAge ).length ; + } + + const ageList = () => { + return persons.map( person => person.age ); + } + + return( + <div className="data"> + <Data label="nb personnes" value={ persons.length } /> + <Data label="âge > 18" value={ nbPersonsOlderThan(18) } /> + <Data label="âge > 50" value={ nbPersonsOlderThan(50) } /> + <Data label="âge du plus jeune " value={ Math.min(...ageList()) } /> + <Data label="âge du plus vieux " value={ Math.max(...ageList()) } /> + </div> + ); +} + +export default PersonListingData; \ No newline at end of file diff --git a/src/scripts/main.js b/src/scripts/main.js index fb8fbd1..8247b06 100644 --- a/src/scripts/main.js +++ b/src/scripts/main.js @@ -1,12 +1,11 @@ import { createRoot } from 'react-dom/client'; -import PersonListingController from '../components/personListingController.component.jsx'; -import { StrictMode } from 'react'; +import App from '../components/app.component.jsx'; const bootstrapReact = () => { const root = createRoot(document.getElementById('insertReactHere')); - const component = <PersonListingController />; + const component = <App />; root.render(component); } -- GitLab