From 6a236cac7d5eae50450d602a06788a6f5b6b0e53 Mon Sep 17 00:00:00 2001 From: renata_vl Date: Tue, 15 Oct 2024 23:35:03 +0300 Subject: [PATCH] Block with statistics by students in categories --- package-lock.json | 27 ++++ package.json | 4 +- .../StudentsInCategories.styles.ts | 126 ++++++++++++++++++ .../StudentsInCategories.tsx | 98 ++++++++++++++ .../StudentsInCategoriesChart.tsx | 70 ++++++++++ .../translations/en/tutor-home-page.json | 10 ++ .../translations/uk/tutor-home-page.json | 10 ++ src/pages/tutor-home/TutorHome.tsx | 2 + 8 files changed, 346 insertions(+), 1 deletion(-) create mode 100644 src/components/students-in-categories/StudentsInCategories.styles.ts create mode 100644 src/components/students-in-categories/StudentsInCategories.tsx create mode 100644 src/components/students-in-categories/StudentsInCategoriesChart.tsx diff --git a/package-lock.json b/package-lock.json index 44323b9b56..edccc70095 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,7 @@ "@tinymce/tinymce-react": "^5.1.1", "allotment": "^1.19.3", "axios": "^1.6.0", + "chart.js": "^4.4.4", "date-fns": "^2.30.0", "dompurify": "^3.1.1", "emoji-mart": "^5.5.2", @@ -29,6 +30,7 @@ "normalize.css": "^8.0.1", "nuka-carousel": "^8.0.1", "react": "^18.2.0", + "react-chartjs-2": "^5.2.0", "react-dom": "^18.2.0", "react-i18next": "^15.0.0", "react-player": "^2.16.0", @@ -3733,6 +3735,11 @@ "resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz", "integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==" }, + "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==" + }, "node_modules/@mdx-js/mdx": { "version": "1.6.22", "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-1.6.22.tgz", @@ -15449,6 +15456,17 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/chart.js": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.4.tgz", + "integrity": "sha512-emICKGBABnxhMjUjlYRR12PmOXhJ2eJjEHL2/dZlWjxRAZT1D8xplLFq5M0tMQK8ja+wBS/tuVEJB5C6r7VxJA==", + "dependencies": { + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": ">=8" + } + }, "node_modules/check-error": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", @@ -25976,6 +25994,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-docgen": { "version": "5.4.3", "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-5.4.3.tgz", diff --git a/package.json b/package.json index 29853df26f..16fb8cb489 100644 --- a/package.json +++ b/package.json @@ -12,11 +12,12 @@ "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.14.16", "@mui/material": "^5.14.16", - "@reduxjs/toolkit": "^2.2.7", "@mui/x-date-pickers": "^5.0.20", + "@reduxjs/toolkit": "^2.2.7", "@tinymce/tinymce-react": "^5.1.1", "allotment": "^1.19.3", "axios": "^1.6.0", + "chart.js": "^4.4.4", "date-fns": "^2.30.0", "dompurify": "^3.1.1", "emoji-mart": "^5.5.2", @@ -24,6 +25,7 @@ "normalize.css": "^8.0.1", "nuka-carousel": "^8.0.1", "react": "^18.2.0", + "react-chartjs-2": "^5.2.0", "react-dom": "^18.2.0", "react-i18next": "^15.0.0", "react-player": "^2.16.0", diff --git a/src/components/students-in-categories/StudentsInCategories.styles.ts b/src/components/students-in-categories/StudentsInCategories.styles.ts new file mode 100644 index 0000000000..7cb57b79e7 --- /dev/null +++ b/src/components/students-in-categories/StudentsInCategories.styles.ts @@ -0,0 +1,126 @@ +import { TypographyVariantEnum } from '~/types' + +export const styles = { + cardContainer: { + width: '100%', + maxWidth: '460px', + minHeight: '400px', + borderRadius: '8px', + border: '1px', + borderColor: 'basic.lightGrey', + backgroundColor: 'basic.white', + p: { xs: '20px 41px 40px', sm: '20px 41px 68px' }, + boxSizing: 'border-box', + mt: '75px' + }, + + cardTitle: { + typography: TypographyVariantEnum.H5, + color: 'basic.darkGray', + mb: '5px' + }, + + cardSubTitle: { + typography: TypographyVariantEnum.Body2, + color: 'basic.blueGray', + mb: '15px' + }, + + select: { + height: '40px', + border: '1px solid', + borderColor: 'basic.gray', + '& .MuiSelect-select': { + p: '8px 10px' + } + }, + + selectedValue: { + display: 'flex', + gap: 1 + }, + + selectAndButtonContainer: { + display: 'flex', + flexDirection: 'row', + alignItems: 'center', + mb: 'auto', + flexWrap: 'wrap', + gap: '8px' + }, + + clearAllButton: { + height: '40px', + ml: 'auto', + typography: TypographyVariantEnum.Body1, + color: 'basic.darkGray' + }, + + chartAndLegendContainer: { + display: 'flex', + flexDirection: { xs: 'column', sm: 'row' }, + alignItems: 'center', + justifyContent: 'space-between', + mt: '30px', + gap: '15px' + }, + + legendContainer: { + width: '146px', + display: 'flex', + flexDirection: 'column', + gap: '20px' + }, + + legendRow: { + display: 'flex', + alignItems: 'center' + }, + + legendBoxIcon: (color: string) => ({ + width: '12px', + height: '12px', + backgroundColor: color, + mr: 1, + borderRadius: '50%' + }), + + percentage: { + ml: 'auto', + typography: TypographyVariantEnum.Overline, + color: 'basic.black' + }, + + totalStudents: { + typography: TypographyVariantEnum.H5, + color: 'basic.darkGray' + }, + + allStudents: { + typography: TypographyVariantEnum.Subtitle2, + color: 'basic.darkGray', + textAlign: 'center' + }, + + category: { + typography: TypographyVariantEnum.Overline, + color: 'basic.black', + textTransform: 'uppercase' + }, + + diagramContainer: { + width: '170px', + height: '170px', + position: 'relative' + }, + + diagramInnerText: { + position: 'absolute', + top: '50%', + left: '50%', + transform: 'translate(-50%, -50%)', + display: 'flex', + flexDirection: 'column', + alignItems: 'center' + } +} diff --git a/src/components/students-in-categories/StudentsInCategories.tsx b/src/components/students-in-categories/StudentsInCategories.tsx new file mode 100644 index 0000000000..dacc1a0a69 --- /dev/null +++ b/src/components/students-in-categories/StudentsInCategories.tsx @@ -0,0 +1,98 @@ +import { Box, Button, MenuItem, Select, Typography } from '@mui/material' +import { styles } from './StudentsInCategories.styles' +import SchoolIcon from '@mui/icons-material/School' +import EventIcon from '@mui/icons-material/Event' +import StudentsInCatgoriesChart from './StudentsInCategoriesChart' +import { useTranslation } from 'react-i18next' + +const currencies = [ + { + value: 'USD', + label: '$' + }, + { + value: 'EUR', + label: '€' + }, + { + value: 'BTC', + label: '฿' + }, + { + value: 'JPY', + label: '¥' + } +] + +const years = [ + { + value: '2021' + }, + + { + value: '2022' + }, + + { + value: '2023' + }, + + { + value: '2024' + } +] + +function StudentsInCatgories() { + const { t } = useTranslation() + return ( + + + {t('tutorHomePage.studentsInCategories.title')} + + + {t('tutorHomePage.studentsInCategories.subTitle')} + + + + + + + + + + ) +} + +export default StudentsInCatgories diff --git a/src/components/students-in-categories/StudentsInCategoriesChart.tsx b/src/components/students-in-categories/StudentsInCategoriesChart.tsx new file mode 100644 index 0000000000..6d196cc24a --- /dev/null +++ b/src/components/students-in-categories/StudentsInCategoriesChart.tsx @@ -0,0 +1,70 @@ +import { Doughnut } from 'react-chartjs-2' +import { Chart as ChartJS, ArcElement, Tooltip, Legend } from 'chart.js' +import { Box, Typography } from '@mui/material' +import { styles } from './StudentsInCategories.styles' +import { useTranslation } from 'react-i18next' + +ChartJS.register(ArcElement, Tooltip, Legend) + +const categories = [ + { label: 'Languages', value: 75, color: '#79B260' }, + { label: 'Mathematics', value: 12, color: '#FFD166' }, + { label: 'History', value: 8, color: '#EF476F' }, + { label: 'Other (+3)', value: 5, color: '#6C757D' } +] + +const data = { + labels: categories.map((category) => category.label), + datasets: [ + { + data: categories.map((category) => category.value), + backgroundColor: categories.map((category) => category.color), + hoverBackgroundColor: categories.map((category) => category.color), + borderWidth: 1, + cutout: '70%', + rotation: 180 + } + ] +} + +const options = { + responsive: true, + maintainAspectRatio: false, + plugins: { + legend: { + display: false + }, + tooltip: { + enabled: true + } + } +} + +const StudentsInCategoriesChart = () => { + const { t } = useTranslation() + return ( + + + + + 24 + + {t('tutorHomePage.studentsInCategories.allStudents')} + + + + + + {categories.map((category, index) => ( + + + {category.label} + {category.value}% + + ))} + + + ) +} + +export default StudentsInCategoriesChart diff --git a/src/constants/translations/en/tutor-home-page.json b/src/constants/translations/en/tutor-home-page.json index 73e6d586e0..eaad238d64 100644 --- a/src/constants/translations/en/tutor-home-page.json +++ b/src/constants/translations/en/tutor-home-page.json @@ -13,5 +13,15 @@ "title": "Popular Categories", "description": "Explore tutoring categories you're passionate about.", "viewMore": "View more" + }, + "studentsInCategories": { + "title": "Students in Your Categories", + "subTitle": "Statistics of your students quantity during the last time.", + "resetButton": "Clear all", + "select": { + "category": "Category", + "year": "Year" + }, + "allStudents": "All students" } } diff --git a/src/constants/translations/uk/tutor-home-page.json b/src/constants/translations/uk/tutor-home-page.json index 315a09e973..c43f9c1ea3 100644 --- a/src/constants/translations/uk/tutor-home-page.json +++ b/src/constants/translations/uk/tutor-home-page.json @@ -13,5 +13,15 @@ "title": "Популярні категорії", "description": "Досліджуйте категорії репетиторства, які вас цікавлять.", "viewMore": "Дивитися більше" + }, + "studentsInCategories": { + "title": "Студенти по Ваших категоріях", + "subTitle": "Статистика кількості Ваших студентів протягом останнього часу", + "resetButton": "Очистити", + "select": { + "category": "Категорія", + "year": "Рік" + }, + "allStudents": "Всі студенти" } } diff --git a/src/pages/tutor-home/TutorHome.tsx b/src/pages/tutor-home/TutorHome.tsx index e9bbc4e331..0e1e1db314 100644 --- a/src/pages/tutor-home/TutorHome.tsx +++ b/src/pages/tutor-home/TutorHome.tsx @@ -15,6 +15,7 @@ import { translationKey } from '~/components/find-block/find-student-constants' import Calendar from '~/components/calendar/Calendar' import TutorSchedule from '~/components/tutor-schedule/TutorSchedule' import { Box } from '@mui/material' +import StudentsInCatgories from '~/components/students-in-categories/StudentsInCategories' const TutorHome = () => { const { t } = useTranslation() @@ -39,6 +40,7 @@ const TutorHome = () => { +