From 7e2be1e4ec969287e7fa733efb79f9ead1373abe Mon Sep 17 00:00:00 2001 From: Fanevarak <89824148+Fanevarak@users.noreply.github.com> Date: Sun, 5 Feb 2023 05:05:00 -0500 Subject: [PATCH] LOL --- assets/APIService.ts | 3 +- assets/controllers.json | 6 + assets/react/controllers/BarChart.tsx | 40 +++ assets/react/controllers/PieChart.tsx | 76 ++++++ assets/styles/resume.css | 8 + composer.json | 1 + composer.lock | 82 +++++- config/bundles.php | 1 + package-lock.json | 362 ++++++++++++++++++++++++-- package.json | 6 + src/Controller/EconomicController.php | 30 +++ src/Controller/SummaryController.php | 26 ++ src/Entity/User.php | 1 + src/Service/SummaryService.php | 19 ++ symfony.lock | 3 + templates/economic/index.html.twig | 20 ++ templates/summary/index.html.twig | 20 ++ 17 files changed, 680 insertions(+), 24 deletions(-) create mode 100644 assets/react/controllers/BarChart.tsx create mode 100644 assets/react/controllers/PieChart.tsx create mode 100644 assets/styles/resume.css create mode 100644 src/Controller/EconomicController.php create mode 100644 src/Controller/SummaryController.php create mode 100644 src/Service/SummaryService.php create mode 100644 templates/economic/index.html.twig create mode 100644 templates/summary/index.html.twig diff --git a/assets/APIService.ts b/assets/APIService.ts index 1e63004..1d81b58 100644 --- a/assets/APIService.ts +++ b/assets/APIService.ts @@ -1,6 +1,5 @@ import TransactionComponant from "./react/controllers/TransactionComponant"; - -interface Transaction { +export interface Transaction { id?: number; amount: number; description:string; diff --git a/assets/controllers.json b/assets/controllers.json index 7e8416f..9fe245a 100644 --- a/assets/controllers.json +++ b/assets/controllers.json @@ -1,5 +1,11 @@ { "controllers": { + "@symfony/ux-chartjs": { + "chart": { + "enabled": true, + "fetch": "eager" + } + }, "@symfony/ux-react": { "react": { "enabled": true, diff --git a/assets/react/controllers/BarChart.tsx b/assets/react/controllers/BarChart.tsx new file mode 100644 index 0000000..01d2854 --- /dev/null +++ b/assets/react/controllers/BarChart.tsx @@ -0,0 +1,40 @@ +import * as React from "react"; +import { Bar } from "react-chartjs-2"; +import APIService, { Transaction } from "../../APIService"; +import dayjs from 'dayjs'; + +export default async function BarChart() { + const defaultDate = new dayjs(); + defaultDate.setDate(1); + const [date, setDate] = React.useState(defaultDate); + + + let apiService = new APIService(); + let myLabels: string[] = [ + "restaurant", + "bar", + "store", + "groceries", + "sport", + "restaurant", + "transport", + "other", + "subscription" + ]; + + // Get Transactions + const transactions = await apiService.read(); + transactions.sort((x, y) => { + let d1 = new Date(x.date).getTime(); + let d2 = new Date(y.date).getTime(); + + return (d1 + d2); + }) + + transactions.filter((tr:Transaction) => { + // do thing + // use props.date + }) +} + + diff --git a/assets/react/controllers/PieChart.tsx b/assets/react/controllers/PieChart.tsx new file mode 100644 index 0000000..ce4fa68 --- /dev/null +++ b/assets/react/controllers/PieChart.tsx @@ -0,0 +1,76 @@ +import * as React from "react"; +import { Pie } from "react-chartjs-2"; +import { Chart, ArcElement, Title } from 'chart.js'; +import APIService from '../../APIService'; + +import '../../styles/resume.css'; + +Chart.register(ArcElement); +Chart.register(Title); + + +export default async function PieChart() { + let apiService = new APIService(); + let myLabels: string[] = [ + "restaurant", + "bar", + "store", + "groceries", + "sport", + "restaurant", + "transport", + "other", + "subscription" + ]; + + let values: number[] = []; + myLabels.forEach((x) => { + values.push(0); + }); + + const transactions = await apiService.read(); + console.log(transactions); + transactions.forEach((x, i) => { + console.log(x); + const category: string = x.category; + const id: number = myLabels.indexOf(category); + values[id] += x.amount; + }) + + const data = { + labels: myLabels, + datasets: [{ + label: 'values', + data: values, + backgroundColor: [ + 'rgb(255, 99, 132)', + 'rgb(54, 162, 235)', + 'rgb(199, 58, 58)', + 'rgb(51, 255, 255)', + 'rgb(81, 255, 128)', + 'rgb(242, 211, 8)', + 'rgb(242, 133, 8)', + ], + hoverOffset: 4 + }], + options: { + responsive: true, + plugins: { + legend: { + position: 'right', + rtl: true, + labels: { + usePointStyle: true, + pointStyle: 'circle', + padding: 20, + } + } + }, + } + } + + return <div className="pie-chart"> + <p className="text">This is text</p> + <Pie data={data}/> + </div>; +} \ No newline at end of file diff --git a/assets/styles/resume.css b/assets/styles/resume.css new file mode 100644 index 0000000..33da8df --- /dev/null +++ b/assets/styles/resume.css @@ -0,0 +1,8 @@ +.pie-chart { + height: 400px; + aspect-ratio: 1/1; +} + +.text { + color: cyan; +} \ No newline at end of file diff --git a/composer.json b/composer.json index 2c786a7..eecdb15 100644 --- a/composer.json +++ b/composer.json @@ -38,6 +38,7 @@ "symfony/string": "6.2.*", "symfony/translation": "6.2.*", "symfony/twig-bundle": "6.2.*", + "symfony/ux-chartjs": "^2.7", "symfony/ux-react": "^2.7", "symfony/validator": "6.2.*", "symfony/web-link": "6.2.*", diff --git a/composer.lock b/composer.lock index 470ec5f..ecdbd9c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,6 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a659557a21bfc78b323050b349489fa1", "packages": [ { "name": "doctrine/annotations", @@ -6802,6 +6801,87 @@ ], "time": "2023-01-01T08:38:09+00:00" }, + { + "name": "symfony/ux-chartjs", + "version": "v2.7.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/ux-chartjs.git", + "reference": "1dc192838f6bfbc30236cc971652ee049263274a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/ux-chartjs/zipball/1dc192838f6bfbc30236cc971652ee049263274a", + "reference": "1dc192838f6bfbc30236cc971652ee049263274a", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/config": "^4.4.17|^5.0|^6.0", + "symfony/dependency-injection": "^4.4.17|^5.0|^6.0", + "symfony/http-kernel": "^4.4.17|^5.0|^6.0" + }, + "conflict": { + "symfony/flex": "<1.13", + "symfony/webpack-encore-bundle": "<1.11" + }, + "require-dev": { + "symfony/framework-bundle": "^4.4.17|^5.0|^6.0", + "symfony/phpunit-bridge": "^5.2|^6.0", + "symfony/twig-bundle": "^4.4.17|^5.0|^6.0", + "symfony/var-dumper": "^4.4.17|^5.0|^6.0", + "symfony/webpack-encore-bundle": "^1.11" + }, + "type": "symfony-bundle", + "extra": { + "thanks": { + "name": "symfony/ux", + "url": "https://github.com/symfony/ux" + } + }, + "autoload": { + "psr-4": { + "Symfony\\UX\\Chartjs\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Titouan Galopin", + "email": "galopintitouan@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Chart.js integration for Symfony", + "homepage": "https://symfony.com", + "keywords": [ + "symfony-ux" + ], + "support": { + "source": "https://github.com/symfony/ux-chartjs/tree/v2.7.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-01-24T15:40:19+00:00" + }, { "name": "symfony/ux-react", "version": "v2.7.1", diff --git a/config/bundles.php b/config/bundles.php index cf0ea26..47928e7 100644 --- a/config/bundles.php +++ b/config/bundles.php @@ -15,4 +15,5 @@ return [ Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true], Symfony\UX\React\ReactBundle::class => ['all' => true], Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true], + Symfony\UX\Chartjs\ChartjsBundle::class => ['all' => true], ]; diff --git a/package-lock.json b/package-lock.json index 3b7ac26..7953cdd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,22 @@ { - "name": "app", + "name": "smart-money", "lockfileVersion": 2, "requires": true, "packages": { "": { "license": "UNLICENSED", + "dependencies": { + "chartjs-plugin-datalabels": "^2.2.0", + "dayjs": "^1.11.7", + "react-chartjs-2": "^5.2.0" + }, "devDependencies": { "@babel/core": "^7.17.0", "@babel/preset-env": "^7.16.0", "@babel/preset-react": "^7.0.0", "@hotwired/stimulus": "^3.0.0", "@symfony/stimulus-bridge": "^3.2.0", + "@symfony/ux-chartjs": "file:vendor/symfony/ux-chartjs/assets", "@symfony/ux-react": "file:vendor/symfony/ux-react/assets", "@symfony/webpack-encore": "^4.0.0", "core-js": "^3.23.0", @@ -1918,6 +1924,12 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, + "node_modules/@kurkle/color": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz", + "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==", + "peer": true + }, "node_modules/@leichtgewicht/ip-codec": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", @@ -1968,16 +1980,13 @@ "@hotwired/stimulus": "^3.0" } }, + "node_modules/@symfony/ux-chartjs": { + "resolved": "vendor/symfony/ux-chartjs/assets", + "link": true + }, "node_modules/@symfony/ux-react": { - "version": "1.0.0", - "resolved": "file:vendor/symfony/ux-react/assets", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@hotwired/stimulus": "^3.0.0", - "react": "^18.0", - "react-dom": "^18.0" - } + "resolved": "vendor/symfony/ux-react/assets", + "link": true }, "node_modules/@symfony/webpack-encore": { "version": "4.2.0", @@ -2272,6 +2281,15 @@ "@types/node": "*" } }, + "node_modules/@types/chart.js": { + "version": "2.9.37", + "resolved": "https://registry.npmjs.org/@types/chart.js/-/chart.js-2.9.37.tgz", + "integrity": "sha512-9bosRfHhkXxKYfrw94EmyDQcdjMaQPkU1fH2tDxu8DWXxf1mjzWQAV4laJF51ZbC2ycYwNDvIm1rGez8Bug0vg==", + "dev": true, + "dependencies": { + "moment": "^2.10.2" + } + }, "node_modules/@types/connect": { "version": "3.4.35", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", @@ -2407,6 +2425,12 @@ "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==", "dev": true }, + "node_modules/@types/prop-types": { + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", + "dev": true + }, "node_modules/@types/qs": { "version": "6.9.7", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", @@ -2419,12 +2443,38 @@ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", "dev": true }, + "node_modules/@types/react": { + "version": "18.0.27", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.27.tgz", + "integrity": "sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA==", + "dev": true, + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.0.10", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.10.tgz", + "integrity": "sha512-E42GW/JA4Qv15wQdqJq8DL4JhNpB3prJgjgapN3qJT9K2zO5IIAQh4VXvCEDupoqAwnz0cY4RlXeC/ajX5SFHg==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", "dev": true }, + "node_modules/@types/scheduler": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", + "dev": true + }, "node_modules/@types/serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", @@ -3191,6 +3241,26 @@ "node": ">=0.8.0" } }, + "node_modules/chart.js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.2.0.tgz", + "integrity": "sha512-wbtcV+QKeH0F7gQZaCJEIpsNriFheacouJQTVIjITi3eQA8bTlIBoknz0+dgV79aeKLNMAX+nDslIVE/nJ3rzA==", + "peer": true, + "dependencies": { + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": "^7.0.0" + } + }, + "node_modules/chartjs-plugin-datalabels": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/chartjs-plugin-datalabels/-/chartjs-plugin-datalabels-2.2.0.tgz", + "integrity": "sha512-14ZU30lH7n89oq+A4bWaJPnAG8a7ZTk7dKf48YAzMvJjQtjrgg5Dpk9f+LbjCF6bpx3RAGTeL13IXpKQYyRvlw==", + "peerDependencies": { + "chart.js": ">=3.0.0" + } + }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -3692,6 +3762,12 @@ "node": ">=4" } }, + "node_modules/cssfontparser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/cssfontparser/-/cssfontparser-1.2.1.tgz", + "integrity": "sha512-6tun4LoZnj7VN6YeegOVb67KBX/7JJsqvj+pv3ZA7F878/eN33AbGa5b/S/wXxS/tcp8nc40xRUrsPlxIyNUPg==", + "dev": true + }, "node_modules/cssnano": { "version": "5.1.14", "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.14.tgz", @@ -3780,6 +3856,17 @@ "node": ">=8.0.0" } }, + "node_modules/csstype": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", + "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==", + "dev": true + }, + "node_modules/dayjs": { + "version": "1.11.7", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz", + "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==" + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -4970,6 +5057,16 @@ "node": ">=0.10.0" } }, + "node_modules/jest-canvas-mock": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jest-canvas-mock/-/jest-canvas-mock-2.4.0.tgz", + "integrity": "sha512-mmMpZzpmLzn5vepIaHk5HoH3Ka4WykbSoLuG/EKoJd0x0ID/t+INo1l8ByfcUJuDM+RIsL4QDg/gDnBbrj2/IQ==", + "dev": true, + "dependencies": { + "cssfontparser": "^1.2.1", + "moo-color": "^1.0.2" + } + }, "node_modules/jest-util": { "version": "29.4.1", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.1.tgz", @@ -5099,8 +5196,7 @@ "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/jsesc": { "version": "2.5.2", @@ -5219,7 +5315,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, @@ -5444,6 +5539,30 @@ "node": "*" } }, + "node_modules/moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/moo-color": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/moo-color/-/moo-color-1.0.3.tgz", + "integrity": "sha512-i/+ZKXMDf6aqYtBhuOcej71YSlbjT3wCO/4H1j8rPvxDJEifdwgg5MaFyu6iYAT8GBZJg2z0dkgK4YMzvURALQ==", + "dev": true, + "dependencies": { + "color-name": "^1.1.4" + } + }, + "node_modules/moo-color/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -6528,7 +6647,6 @@ "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", - "dev": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -6536,6 +6654,15 @@ "node": ">=0.10.0" } }, + "node_modules/react-chartjs-2": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-5.2.0.tgz", + "integrity": "sha512-98iN5aguJyVSxp5U3CblRLH67J8gkfyGNbiK3c+l1QI/G4irHMPQw44aEPmjVag+YKTyQ260NcF82GTQ3bdscA==", + "peerDependencies": { + "chart.js": "^4.1.1", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -6698,6 +6825,12 @@ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", "dev": true }, + "node_modules/resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==", + "dev": true + }, "node_modules/resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -8174,6 +8307,48 @@ "engines": { "node": ">=12" } + }, + "vendor/symfony/ux-chartjs/assets": { + "name": "@symfony/ux-chartjs", + "version": "1.1.0", + "dev": true, + "license": "MIT", + "devDependencies": { + "@hotwired/stimulus": "^3.0.0", + "@types/chart.js": "^2.9.34", + "chart.js": "^3.4.1 <3.9", + "jest-canvas-mock": "^2.3.0", + "resize-observer-polyfill": "^1.5.1" + }, + "peerDependencies": { + "@hotwired/stimulus": "^3.0.0", + "chart.js": "^3.4.1" + } + }, + "vendor/symfony/ux-chartjs/assets/node_modules/chart.js": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.8.2.tgz", + "integrity": "sha512-7rqSlHWMUKFyBDOJvmFGW2lxULtcwaPLegDjX/Nu5j6QybY+GCiQkEY+6cqHw62S5tcwXMD8Y+H5OBGoR7d+ZQ==", + "dev": true + }, + "vendor/symfony/ux-react/assets": { + "name": "@symfony/ux-react", + "version": "1.0.0", + "dev": true, + "license": "MIT", + "devDependencies": { + "@hotwired/stimulus": "^3.0.0", + "@types/react": "^18.0", + "@types/react-dom": "^18.0", + "@types/webpack-env": "^1.16", + "react": "^18.0", + "react-dom": "^18.0" + }, + "peerDependencies": { + "@hotwired/stimulus": "^3.0.0", + "react": "^18.0", + "react-dom": "^18.0" + } } }, "dependencies": { @@ -9507,6 +9682,12 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, + "@kurkle/color": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz", + "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==", + "peer": true + }, "@leichtgewicht/ip-codec": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", @@ -9544,10 +9725,34 @@ "schema-utils": "^3.0.0" } }, + "@symfony/ux-chartjs": { + "version": "file:vendor/symfony/ux-chartjs/assets", + "requires": { + "@hotwired/stimulus": "^3.0.0", + "@types/chart.js": "^2.9.34", + "chart.js": "^3.4.1 <3.9", + "jest-canvas-mock": "^2.3.0", + "resize-observer-polyfill": "^1.5.1" + }, + "dependencies": { + "chart.js": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.8.2.tgz", + "integrity": "sha512-7rqSlHWMUKFyBDOJvmFGW2lxULtcwaPLegDjX/Nu5j6QybY+GCiQkEY+6cqHw62S5tcwXMD8Y+H5OBGoR7d+ZQ==", + "dev": true + } + } + }, "@symfony/ux-react": { - "version": "1.0.0", - "dev": true, - "requires": {} + "version": "file:vendor/symfony/ux-react/assets", + "requires": { + "@hotwired/stimulus": "^3.0.0", + "@types/react": "^18.0", + "@types/react-dom": "^18.0", + "@types/webpack-env": "^1.16", + "react": "^18.0", + "react-dom": "^18.0" + } }, "@symfony/webpack-encore": { "version": "4.2.0", @@ -9677,6 +9882,15 @@ "@types/node": "*" } }, + "@types/chart.js": { + "version": "2.9.37", + "resolved": "https://registry.npmjs.org/@types/chart.js/-/chart.js-2.9.37.tgz", + "integrity": "sha512-9bosRfHhkXxKYfrw94EmyDQcdjMaQPkU1fH2tDxu8DWXxf1mjzWQAV4laJF51ZbC2ycYwNDvIm1rGez8Bug0vg==", + "dev": true, + "requires": { + "moment": "^2.10.2" + } + }, "@types/connect": { "version": "3.4.35", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", @@ -9812,6 +10026,12 @@ "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==", "dev": true }, + "@types/prop-types": { + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", + "dev": true + }, "@types/qs": { "version": "6.9.7", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", @@ -9824,12 +10044,38 @@ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", "dev": true }, + "@types/react": { + "version": "18.0.27", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.27.tgz", + "integrity": "sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA==", + "dev": true, + "requires": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "@types/react-dom": { + "version": "18.0.10", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.10.tgz", + "integrity": "sha512-E42GW/JA4Qv15wQdqJq8DL4JhNpB3prJgjgapN3qJT9K2zO5IIAQh4VXvCEDupoqAwnz0cY4RlXeC/ajX5SFHg==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, "@types/retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", "dev": true }, + "@types/scheduler": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", + "dev": true + }, "@types/serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", @@ -10449,6 +10695,21 @@ } } }, + "chart.js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.2.0.tgz", + "integrity": "sha512-wbtcV+QKeH0F7gQZaCJEIpsNriFheacouJQTVIjITi3eQA8bTlIBoknz0+dgV79aeKLNMAX+nDslIVE/nJ3rzA==", + "peer": true, + "requires": { + "@kurkle/color": "^0.3.0" + } + }, + "chartjs-plugin-datalabels": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/chartjs-plugin-datalabels/-/chartjs-plugin-datalabels-2.2.0.tgz", + "integrity": "sha512-14ZU30lH7n89oq+A4bWaJPnAG8a7ZTk7dKf48YAzMvJjQtjrgg5Dpk9f+LbjCF6bpx3RAGTeL13IXpKQYyRvlw==", + "requires": {} + }, "chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -10805,6 +11066,12 @@ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true }, + "cssfontparser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/cssfontparser/-/cssfontparser-1.2.1.tgz", + "integrity": "sha512-6tun4LoZnj7VN6YeegOVb67KBX/7JJsqvj+pv3ZA7F878/eN33AbGa5b/S/wXxS/tcp8nc40xRUrsPlxIyNUPg==", + "dev": true + }, "cssnano": { "version": "5.1.14", "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.14.tgz", @@ -10869,6 +11136,17 @@ "css-tree": "^1.1.2" } }, + "csstype": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", + "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==", + "dev": true + }, + "dayjs": { + "version": "1.11.7", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz", + "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==" + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -11767,6 +12045,16 @@ "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true }, + "jest-canvas-mock": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jest-canvas-mock/-/jest-canvas-mock-2.4.0.tgz", + "integrity": "sha512-mmMpZzpmLzn5vepIaHk5HoH3Ka4WykbSoLuG/EKoJd0x0ID/t+INo1l8ByfcUJuDM+RIsL4QDg/gDnBbrj2/IQ==", + "dev": true, + "requires": { + "cssfontparser": "^1.2.1", + "moo-color": "^1.0.2" + } + }, "jest-util": { "version": "29.4.1", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.1.tgz", @@ -11864,8 +12152,7 @@ "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "jsesc": { "version": "2.5.2", @@ -11957,7 +12244,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, "requires": { "js-tokens": "^3.0.0 || ^4.0.0" } @@ -12121,6 +12407,29 @@ "brace-expansion": "^1.1.7" } }, + "moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "dev": true + }, + "moo-color": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/moo-color/-/moo-color-1.0.3.tgz", + "integrity": "sha512-i/+ZKXMDf6aqYtBhuOcej71YSlbjT3wCO/4H1j8rPvxDJEifdwgg5MaFyu6iYAT8GBZJg2z0dkgK4YMzvURALQ==", + "dev": true, + "requires": { + "color-name": "^1.1.4" + }, + "dependencies": { + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -12870,11 +13179,16 @@ "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", - "dev": true, "requires": { "loose-envify": "^1.1.0" } }, + "react-chartjs-2": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-5.2.0.tgz", + "integrity": "sha512-98iN5aguJyVSxp5U3CblRLH67J8gkfyGNbiK3c+l1QI/G4irHMPQw44aEPmjVag+YKTyQ260NcF82GTQ3bdscA==", + "requires": {} + }, "react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -13012,6 +13326,12 @@ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", "dev": true }, + "resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==", + "dev": true + }, "resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", diff --git a/package.json b/package.json index 87c63a4..a4dc734 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "@babel/preset-react": "^7.0.0", "@hotwired/stimulus": "^3.0.0", "@symfony/stimulus-bridge": "^3.2.0", + "@symfony/ux-chartjs": "file:vendor/symfony/ux-chartjs/assets", "@symfony/ux-react": "file:vendor/symfony/ux-react/assets", "@symfony/webpack-encore": "^4.0.0", "core-js": "^3.23.0", @@ -24,5 +25,10 @@ "dev": "encore dev", "watch": "encore dev --watch", "build": "encore production --progress" + }, + "dependencies": { + "chartjs-plugin-datalabels": "^2.2.0", + "dayjs": "^1.11.7", + "react-chartjs-2": "^5.2.0" } } diff --git a/src/Controller/EconomicController.php b/src/Controller/EconomicController.php new file mode 100644 index 0000000..fe444b0 --- /dev/null +++ b/src/Controller/EconomicController.php @@ -0,0 +1,30 @@ +<?php + +namespace App\Controller; + +use App\Entity\User; +use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Routing\Annotation\Route; +use Symfony\Bundle\SecurityBundle\Security; + +class EconomicController extends AbstractController +{ + #[Route('/economic', name: 'app_economic')] + public function index(): Response + { + $user = $this->calculate(); + return $this->render('economic/index.html.twig', [ + 'controller_name' => 'EconomicController', + 'user' => $user + ]); + } + + // #[Route('/economic', name: 'calculate', methods: ['GET'])] + public function calculate(): User { + // $user = $this->getUser(); + $user = new User(); + $user->setName("Bob"); + return $user; + } +} diff --git a/src/Controller/SummaryController.php b/src/Controller/SummaryController.php new file mode 100644 index 0000000..122e66e --- /dev/null +++ b/src/Controller/SummaryController.php @@ -0,0 +1,26 @@ +<?php + +namespace App\Controller; + +use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Routing\Annotation\Route; +use App\Service\SummaryService; +use Symfony\UX\Chartjs\Model\Chart; +use Symfony\UX\Chartjs\Builder\ChartBuilderInterface; + +class SummaryController extends AbstractController +{ + #[Route('/summary', name: 'app_summary')] + public function index( + SummaryService $summaryService, + ChartBuilderInterface $chartBuilder + ): Response + { + $transactions = $summaryService->getAllTransactions(); + return $this->render('summary/index.html.twig', [ + 'controller_name' => 'SummaryController', + 'transactions' => $transactions + ]); + } +} \ No newline at end of file diff --git a/src/Entity/User.php b/src/Entity/User.php index c87fb62..b7cf4b8 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -26,6 +26,7 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface #[ORM\Column(length: 255)] private ?string $password = null; + private ?string $email = null; public function __construct() { diff --git a/src/Service/SummaryService.php b/src/Service/SummaryService.php new file mode 100644 index 0000000..565b029 --- /dev/null +++ b/src/Service/SummaryService.php @@ -0,0 +1,19 @@ +<?php +namespace App\Service; +use App\Entity\Transaction; +use App\Entity\User; + +class SummaryService { + private User $user; + private $transactions; + + public function __construct() { + // $this->user = $user; + // Get transactions + + } + + public function getAllTransactions() { + return $this->transactions; + } +} \ No newline at end of file diff --git a/symfony.lock b/symfony.lock index 194af4a..62c2b3e 100644 --- a/symfony.lock +++ b/symfony.lock @@ -263,6 +263,9 @@ "templates/base.html.twig" ] }, + "symfony/ux-chartjs": { + "version": "v2.7.1" + }, "symfony/ux-react": { "version": "v2.7.1" }, diff --git a/templates/economic/index.html.twig b/templates/economic/index.html.twig new file mode 100644 index 0000000..0927d8d --- /dev/null +++ b/templates/economic/index.html.twig @@ -0,0 +1,20 @@ +{% extends 'base.html.twig' %} + +{% block title %}Hello EconomicController!{% endblock %} + +{% block body %} +<style> + .example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; } + .example-wrapper code { background: #F5F5F5; padding: 2px 6px; } +</style> + +<div class="example-wrapper"> + <h1>Hello {{ user.name }}! ✅</h1> + + This friendly message is coming from: + <ul> + <li>Your controller at <code><a href="{{ '/home/faneva/Programmation/Hackatown/smart-money/src/Controller/EconomicController.php'|file_link(0) }}">src/Controller/EconomicController.php</a></code></li> + <li>Your template at <code><a href="{{ '/home/faneva/Programmation/Hackatown/smart-money/templates/economic/index.html.twig'|file_link(0) }}">templates/economic/index.html.twig</a></code></li> + </ul> +</div> +{% endblock %} diff --git a/templates/summary/index.html.twig b/templates/summary/index.html.twig new file mode 100644 index 0000000..d6e3c5c --- /dev/null +++ b/templates/summary/index.html.twig @@ -0,0 +1,20 @@ +{% extends "base.html.twig" %} +{% block title %}Resume +{% endblock %} +{% block javascripts %} + {{ parent() }} + +{% endblock %} + +{% block body %} +<style> + .example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; } + .example-wrapper code { background: #F5F5F5; padding: 2px 6px; } +</style> + +<div class="example-wrapper"> + <h1>Hello {{ controller_name }}! ✅</h1> + + <div {{ react_component('PieChart')}}></div> +</div> +{% endblock %} -- GitLab