diff --git a/package-lock.json b/package-lock.json index be9b2a9319fff023449decc12502b05947c1fa50..8452e76beb69650d74607f66b0955a2ad70e8418 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@testing-library/user-event": "^13.5.0", "bootstrap": "^5.3.3", "chart.js": "^4.4.2", + "date-fns": "^3.6.0", "react": "^18.2.0", "react-bootstrap": "^2.10.2", "react-chartjs-2": "^5.2.0", @@ -7005,6 +7006,15 @@ "node": ">=10" } }, + "node_modules/date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -23531,6 +23541,11 @@ "whatwg-url": "^8.0.0" } }, + "date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==" + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", diff --git a/package.json b/package.json index ffcebe65aecee6763da1182542e60c5275d562a4..be784e3adf3ff3545a44dd992b1ae6c7b55a5edd 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "@testing-library/user-event": "^13.5.0", "bootstrap": "^5.3.3", "chart.js": "^4.4.2", + "date-fns": "^3.6.0", "react": "^18.2.0", "react-bootstrap": "^2.10.2", "react-chartjs-2": "^5.2.0", diff --git a/src/App.js b/src/App.js index c6e65641b298a3c0a4b12d09d13745967308918b..7bd67cbe7c8b2fea79e87a0c3ed817ffacb6aa50 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,6 @@ import './App.css'; import Dashboard from './component/Dashboard.js' +import 'bootstrap/dist/css/bootstrap.min.css'; function App() { return ( diff --git a/src/component/DAOLineChart.js b/src/component/DAOLineChart.js index cc5677aadf163c18ea380d1edeecc8c32c3016b4..f47cc2d2c57c9f77d5207203bb3df40dbcb72d10 100644 --- a/src/component/DAOLineChart.js +++ b/src/component/DAOLineChart.js @@ -1,12 +1,10 @@ // eslint-disable-next-line no-unused-vars import { Chart as ChartJS } from "chart.js/auto"; // A ne pas commenter sinon les graphs ne fonctionne plu☼ import { Line } from "react-chartjs-2"; +import { addDays, format, parse } from 'date-fns'; +import { generateData } from "./FalseDataGenerator"; -function DAOLineChart(title, apiData, scale) { - const monthsOrder = ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre']; - - const sortedMonths = Object.keys(apiData).sort((a, b) => monthsOrder.indexOf(a) - monthsOrder.indexOf(b)); - +function DAOLineChart(title, apiData, day) { const options = { responsive: true, plugins: { @@ -20,28 +18,30 @@ function DAOLineChart(title, apiData, scale) { }, }; - let labels = Object.keys(apiData); - let data = Object.values(apiData); - console.log(scale) - if (scale === 'month') { - labels = sortedMonths; - data = sortedMonths.map(month => apiData[month]); - } + + const parsedDay = parse(day, 'dd/MM/yy', new Date()); + + const labels = Array.from({ length: 30 }, (_, index) => { + const date = addDays(parsedDay, index); // Ajouter les jours pour obtenir les jours suivants + return format(date, 'dd/MM/yy'); // Formatage de la date pour l'affichage + }); + + const data = labels.map(label => apiData[label] || 0); const datas = { labels, datasets: [ { - label: 'Nombre de DAO token achetés sur un mois glissant', + label: 'Nombre de DAO token achetés', data, - borderColor: 'rgb(255, 99, 132)', - backgroundColor: 'rgba(255, 99, 132, 0.5)', + borderColor: 'rgb(60, 99, 255)', + backgroundColor: 'rgba(60, 99, 255, 0.5)', } ] }; return ( - <div style={{ width: '80%', margin: 'auto' }}> + <div style={{ width: '50%', margin: 'auto' }}> <Line datasetIdKey="DAO" options={options} data={datas} /> </div> ) diff --git a/src/component/Dashboard.js b/src/component/Dashboard.js index 294c3f1206752c559010cb172cabf08b7dc87cd0..5082a2f2c351877c71d6034b2a3ccb958d0b654c 100644 --- a/src/component/Dashboard.js +++ b/src/component/Dashboard.js @@ -2,30 +2,116 @@ import { useEffect, useState } from "react" import DAOLineChart from "./DAOLineChart" import PieChart from "./PieChart" import VoteBarChart from "./VoteBarGraph" -import { testData, testDataPie } from "./GraphData" -import { Button, ButtonGroup, Dropdown, DropdownButton } from 'react-bootstrap'; +import { ButtonGroup, Dropdown, DropdownButton } from 'react-bootstrap'; +import { generateData, generatePieData} from "./FalseDataGenerator"; const DashBoard = () => { - const [line, setLine] = useState() - const [bar, setBar] = useState() - const [pie, setPie] = useState() + const [line, setLine] = useState('') + const [bar, setBar] = useState('') + const [pie, setPie] = useState('') + const [association, setAssociation] = useState([]) + const [currentAsso, setCurrentAsso] = useState('') + + const url = [ 'https://api.ghostnet.tzkt.io/v1/contracts/KT1QTwmF2eptKss2FWbT1rHP5wCERL16kihQ/storage', + 'https://api.ghostnet.tzkt.io/v1/contracts/KT1ACcRhzuDzVKpwzjZTudcQchEijvj7b7cp/views/listAllAssociations', + 'https://api.ghostnet.tzkt.io/v1/contracts/KT1LnPY3excYVUTLBuCfBbf1hLeGJTLhXNSz/storage', + 'https://api.ghostnet.tzkt.io/v1/contracts/KT1Jrg6G9ziKbpSvzPLhjM4pXWYJqxoZdhMZ/views' + ] + + const getData = async () => { + const data = await fetch( url[0], { + method: 'GET', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json', + }, + }); + const response = await data.json() + console.log(response) + const objectsArray = Object.values(response); + let listeAsso= [] + objectsArray.forEach(asso => { + const assoData= { + nom: asso.name, + lineData: generateData("01/01/24", 1000), + barData: generateData("01/01/24", 20), + propositions: [ + {nom: 'Proposition 1', pieData: generatePieData() }, + {nom: 'Proposition 2', pieData: generatePieData() }, + {nom: 'Proposition 3', pieData: generatePieData() } + ] + } + listeAsso.push(assoData) + }); + setAssociation(listeAsso) + } + + const setDataAsso = (assoName) => { + const asso = association.find(asso => asso.nom === assoName) + setLine(DAOLineChart('Nombre de DAO token achetés sur un mois glissant', asso.lineData, "01/01/24")) + setBar(VoteBarChart('Nombre de propositions soumises au vote sur un mois glissant', asso.barData, "01/01/24")) + setPie('') + setCurrentAsso(asso) + + } + + const setPieData = (propositions, propoName) => { + const proposition = propositions.find(propo => propo.nom === propoName) + setPie(PieChart('Taux de yay, nay ou pass pour chaque proposition', proposition.pieData)) + } useEffect(() => { - setLine(DAOLineChart("Test 1", testData, "month")) - setBar(VoteBarChart("Test 2", testData, "month")) - setPie(PieChart("Test 3", testDataPie)) + if (line === '' && bar === '' && pie === '') { + getData() + } }, [line, bar, pie]) + + const showAssociation = () => { + const result = [] + for (let asso in association){ + const eventKey = `${association[asso].nom}` + const label = `${association[asso].nom}` + result.push( + <Dropdown.Item key={eventKey} eventKey={eventKey} onClick={() => setDataAsso(association[asso].nom)}> + {label} + </Dropdown.Item> + ) + } + return result + } + + const showProposition = (propositions) => { + const result = [] + for (let index in propositions){ + console.log(propositions[index]) + const eventKey = `${propositions[index].nom}` + const label = `${propositions[index].nom}` + result.push( + <Dropdown.Item key={eventKey} eventKey={eventKey} onClick={() => setPieData(propositions, propositions[index].nom)}> + {label} + </Dropdown.Item> + ) + } + return result + } + return (<> - <p>Associations</p> + <p>Liste des Associations</p> <DropdownButton as={ButtonGroup} title="Pour l'association" id='association'> - {//TODO: faire une fonction pour avoir la liste des assos afin de changer les graphs selon l'asso - } + {showAssociation()} </DropdownButton> - <p>First</p> - {line} - <p>Second</p> - {bar} - <p>Third</p> + <div className="d-flex justify-content-center align-items-center"> + {line} + {bar} + </div> + {(line !== '' & bar !== '') && + <> + <p>Liste des propositions</p> + <DropdownButton as={ButtonGroup} title="Pour la proposition" id='proposition'> + {showProposition(currentAsso.propositions)} + </DropdownButton> + </> + } {pie} </>) } diff --git a/src/component/FalseDataGenerator.js b/src/component/FalseDataGenerator.js new file mode 100644 index 0000000000000000000000000000000000000000..aab7a277178d3ccf689f8dbdc8427414dbfbc1d0 --- /dev/null +++ b/src/component/FalseDataGenerator.js @@ -0,0 +1,23 @@ +import { format, addDays } from 'date-fns'; + +export function generateData(startDate, max) { + let currentDate = startDate; + const data = {}; + for (let i = 0; i < 30; i++) { + const formattedDate = format(currentDate, 'dd/MM/yy'); + const randomValue = Math.floor(Math.random() * max); + data[formattedDate] = randomValue; + currentDate = addDays(currentDate, 1); + } + return data; +} + +export function generatePieData() { + const testDataPie = { + "Yay": Math.floor(Math.random() * 30), + "Nay": Math.floor(Math.random() * 30), + "Pass": Math.floor(Math.random() * 10) + } + return testDataPie +} + diff --git a/src/component/GraphData.js b/src/component/GraphData.js deleted file mode 100644 index baf3101f34c6e7d201665d37fdf288855c659f5c..0000000000000000000000000000000000000000 --- a/src/component/GraphData.js +++ /dev/null @@ -1,20 +0,0 @@ -export const testData = { - "Janvier": 10, - "Fevrier": 25, - "Mars": 45, - "Avril": 2, - "Mai": 4, - "Juin": 80, - "Juillet": 74, - "Août": 50, - "Septembre": 6, - "Octobre": 13, - "Novembre": 15, - "Décembre": 24 -} - -export const testDataPie = { - "Yay": 10, - "Nay": 8, - "Pass": 5 -} \ No newline at end of file diff --git a/src/component/PieChart.js b/src/component/PieChart.js index d5c5aee088328ab91534d43a0ed5e70b28c6556b..aa75792f441f7e541df3319d1cc1215ec5226e82 100644 --- a/src/component/PieChart.js +++ b/src/component/PieChart.js @@ -1,6 +1,6 @@ // eslint-disable-next-line no-unused-vars import { Chart as ChartJS } from "chart.js/auto"; // A ne pas commenter sinon les graphs ne fonctionne plu☼ -import { Pie} from "react-chartjs-2"; +import { Pie } from "react-chartjs-2"; function PieChart(title, apiData) { @@ -24,16 +24,16 @@ function PieChart(title, apiData) { labels, datasets: [ { - label: 'Taux de yay, nay ou pass pour chaque proposition', + label: ['Taux de yay','Taux de nay','Taux de pass'], data, borderColor: [ - 'rgb(255, 99, 132)', 'rgb(132, 255, 99)', + 'rgb(255, 99, 132)', 'rgb(132, 99, 255)' ], backgroundColor: [ - 'rgb(255, 99, 132, 0.5)', 'rgb(132, 255, 99, 0.5)', + 'rgb(255, 99, 132, 0.5)', 'rgb(132, 99, 255, 0.5)' ], } @@ -41,7 +41,7 @@ function PieChart(title, apiData) { }; return ( - <div style={{ width: '80%', margin: 'auto' }}> + <div style={{ width: '30%', margin: 'auto' }}> <Pie datasetIdKey="Pie" options={options} data={datas} /> </div> ) diff --git a/src/component/VoteBarGraph.js b/src/component/VoteBarGraph.js index 488ccb132cdf747ac152fbc1eeea5d52b8fe9e41..6879ad5432cc86fbe2a526c3b668de614e2268bb 100644 --- a/src/component/VoteBarGraph.js +++ b/src/component/VoteBarGraph.js @@ -1,47 +1,45 @@ // eslint-disable-next-line no-unused-vars import { Chart as ChartJS } from "chart.js/auto"; // A ne pas commenter sinon les graphs ne fonctionne plu☼ import { Bar } from "react-chartjs-2"; +import { addDays, format, parse } from 'date-fns'; -function VoteBarChart(title, apiData, scale) { - const monthsOrder = ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre']; +function VoteBarChart(title, apiData, day) { + const options = { + responsive: true, + plugins: { + legend: { + position: 'top', + }, + title: { + display: true, + text: title, + }, + }, + }; - const sortedMonths = Object.keys(apiData).sort((a, b) => monthsOrder.indexOf(a) - monthsOrder.indexOf(b)); + const parsedDay = parse(day, 'dd/MM/yy', new Date()); - const options = { - responsive: true, - plugins: { - legend: { - position: 'top', - }, - title: { - display: true, - text: title, - }, - }, - }; + const labels = Array.from({ length: 30 }, (_, index) => { + const date = addDays(parsedDay, index); // Ajouter les jours pour obtenir les jours suivants + return format(date, 'dd/MM/yy'); // Formatage de la date pour l'affichage + }); - let labels = Object.keys(apiData); - let data = Object.values(apiData); - console.log(scale) - if (scale === 'month') { - labels = sortedMonths; - data = sortedMonths.map(month => apiData[month]); - } + const data = labels.map(label => apiData[label] || 0); const datas = { labels, datasets: [ { - label: 'Nombre de propositions soumises au vote sur un mois glissant', + label: 'Nombre de propositions soumises au vote', data, - borderColor: 'rgb(255, 99, 132)', - backgroundColor: 'rgba(255, 99, 132, 0.5)', + borderColor: 'rgb(60, 255, 60)', + backgroundColor: 'rgba(60, 255, 60, 0.5)', } ] }; return ( - <div style={{ width: '80%', margin: 'auto' }}> + <div style={{ width: '50%', margin: 'auto' }}> <Bar datasetIdKey="Vote" options={options} data={datas} /> </div> )