From 3b39b995884c737fe4c291daeec5f4f33dce33aa Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Wed, 8 Nov 2023 15:59:57 +0330 Subject: [PATCH] bring radial chart and complete search part of province and year --- public/locales/fa/app.json | 13 +++- .../reports/Filter/ProvinceFilter.jsx | 59 ++++++++++++++----- .../dashboard/reports/Filter/YearFilter.jsx | 15 ++++- .../dashboard/reports/Filter/index.jsx | 17 +++--- .../reports/LoanDetails/RadialBarChart.jsx | 47 +++++++++++++++ .../dashboard/reports/LoanDetails/index.jsx | 31 ++++++++++ .../reports/LoanDistribution/PieChart.jsx | 8 +-- .../reports/LoanDistribution/PolarChart.jsx | 4 +- .../reports/LoanDistribution/index.jsx | 2 +- .../reports/LoanProgress/BarChart.jsx | 35 +---------- .../dashboard/reports/LoanProgress/index.jsx | 4 +- src/components/dashboard/reports/index.jsx | 2 + src/core/utils/gradientColorHandler.js | 31 ++++++++++ src/lib/app/contexts/chart.jsx | 0 14 files changed, 197 insertions(+), 71 deletions(-) create mode 100644 src/components/dashboard/reports/LoanDetails/RadialBarChart.jsx create mode 100644 src/components/dashboard/reports/LoanDetails/index.jsx create mode 100644 src/core/utils/gradientColorHandler.js delete mode 100644 src/lib/app/contexts/chart.jsx diff --git a/public/locales/fa/app.json b/public/locales/fa/app.json index 07463ed..ddc3f09 100644 --- a/public/locales/fa/app.json +++ b/public/locales/fa/app.json @@ -472,7 +472,16 @@ }, "reports": { "loan_progress": "درصد پیشرفت تسویه وام", - "loan_distribution": "درصد توضیع وام ها در هر مرحله", - "filter_as": "فیلتر های اعمال شده" + "loan_distribution": "درصد توزیع وام ها در هر مرحله", + "filter_as": "فیلتر های اعمال شده", + "loan_details": "اطلاعات وام ها" + }, + "filters": { + "provinces": "استان های", + "province": "استان", + "year": "سال", + "years": "سال های", + "text_field_loading_provinces_list": "درحال دریافت استان ها", + "text_field_error_fetching_provinces": "خطا در دریافت استان ها" } } diff --git a/src/components/dashboard/reports/Filter/ProvinceFilter.jsx b/src/components/dashboard/reports/Filter/ProvinceFilter.jsx index ead52f2..fc5d79b 100644 --- a/src/components/dashboard/reports/Filter/ProvinceFilter.jsx +++ b/src/components/dashboard/reports/Filter/ProvinceFilter.jsx @@ -1,4 +1,6 @@ -import {Box, Chip, FormControl, InputLabel, MenuItem, OutlinedInput, Select} from "@mui/material"; +import {Box, FormControl, InputLabel, MenuItem, OutlinedInput, Select, Typography} from "@mui/material"; +import {useTranslations} from "next-intl"; +import useProvince from "@/lib/app/hooks/useProvince"; const provinceList = [ {name: "قزوین", id: 1}, @@ -6,11 +8,29 @@ const provinceList = [ {name: "مشهد", id: 3} ] -const ProvinceFilter = ({formik, multiple}) => { +const ProvinceFilter = ({formik, multiple, setFilteredText}) => { + const {errorProvinceList, isLoadingProvinceList, provinceList} = useProvince(); + const t = useTranslations(); const provinceChange = (event) => { const {target: {value}} = event; formik.handleChange(event); formik.setFieldValue('province_id', value); + if (Array.isArray(value)) { + const province_names = [] + value.map((item) => { + province_names.push(provinceList.find(province => province.id === item).name) + }) + setFilteredText(prevState => ({ + ...prevState, + province: province_names.length !== 0 ? `| ${t("filters.provinces")}: ${province_names.join(' , ')}` : "" + })); + } else { + const selectedProvince = provinceList.find(province => province.id === value); + setFilteredText(prevState => ({ + ...prevState, + province: `| ${t("filters.province")}: ${selectedProvince.name}` + })); + } }; return ( @@ -24,29 +44,38 @@ const ProvinceFilter = ({formik, multiple}) => { onChange={provinceChange} onBlur={formik.handleBlur("province_id")} input={} + disabled={isLoadingProvinceList || errorProvinceList} renderValue={multiple ? (selected) => ( - + {selected.map((value) => { const selectedProvince = provinceList.find(province => province.id === value); return ( - + + {selectedProvince ? selectedProvince.name : ''} + ); })} ) : undefined} > - {provinceList.map((province) => ( - - {province.name} + {isLoadingProvinceList ? ( + + {t("filters.text_field_loading_provinces_list")} - ))} + ) : errorProvinceList ? ( + + {t("filters.text_field_error_fetching_provinces")} + + ) : ( + provinceList.map((item) => ( + + {item.name} + + )) + )} ) diff --git a/src/components/dashboard/reports/Filter/YearFilter.jsx b/src/components/dashboard/reports/Filter/YearFilter.jsx index c96d704..022e8be 100644 --- a/src/components/dashboard/reports/Filter/YearFilter.jsx +++ b/src/components/dashboard/reports/Filter/YearFilter.jsx @@ -1,14 +1,27 @@ import {Box, Chip, FormControl, InputLabel, MenuItem, OutlinedInput, Select} from "@mui/material"; import moment from "jalali-moment"; +import {useTranslations} from "next-intl"; const currentShamsiYear = moment().format('jYYYY'); const shamsiYearList = Array.from({length: currentShamsiYear - 1399}, (_, index) => (currentShamsiYear - index).toString()); -const YearFilter = ({formik, multiple}) => { +const YearFilter = ({formik, multiple, setFilteredText}) => { + const t = useTranslations(); const yearChange = (event) => { const {target: {value}} = event; formik.handleChange(event); formik.setFieldValue('date', value); + if (Array.isArray(value)) { + setFilteredText(prevState => ({ + ...prevState, + year: `| ${t("filters.years")}: ${value.join(' , ')}` + })); + } else { + setFilteredText(prevState => ({ + ...prevState, + year: `| ${t("filters.year")}: ${value}` + })); + } }; return ( diff --git a/src/components/dashboard/reports/Filter/index.jsx b/src/components/dashboard/reports/Filter/index.jsx index 43b63bd..2ae310e 100644 --- a/src/components/dashboard/reports/Filter/index.jsx +++ b/src/components/dashboard/reports/Filter/index.jsx @@ -6,6 +6,7 @@ import FilterAltIcon from '@mui/icons-material/FilterAlt'; import {useTranslations} from "next-intl"; import TroubleshootIcon from '@mui/icons-material/Troubleshoot'; import moment from "jalali-moment"; +import {useState} from "react"; const periodOfYear = (year) => { const isLeapYear = moment.jIsLeapYear(year); @@ -19,10 +20,11 @@ const periodOfYear = (year) => { const Filter = ({title, filterItem, expanded}) => { const t = useTranslations(); - const filter_by_province = filterItem.find((item) => item.type === "province"); const filter_by_year = filterItem.find((item) => item.type === "year"); + const [filteredText, setFilteredText] = useState({province: "", year: ""}); + const formik = useFormik({ initialValues: { ...(filter_by_year && { @@ -32,11 +34,6 @@ const Filter = ({title, filterItem, expanded}) => { province_id: filter_by_province.multiple ? [] : "" }) }, onSubmit: (values, {setSubmitting}) => { - const dates = values.date - dates.map((date) => { - periodOfYear(date); - }) - console.log("val", values); }, }); return ( @@ -51,7 +48,7 @@ const Filter = ({title, filterItem, expanded}) => { {title} - | {t("reports.filter_as")} : + {filteredText.province} {filteredText.year} @@ -60,10 +57,12 @@ const Filter = ({title, filterItem, expanded}) => { {filter_by_province ? - : "" + : "" } {filter_by_year ? - : "" + : "" } diff --git a/src/components/dashboard/reports/LoanDetails/RadialBarChart.jsx b/src/components/dashboard/reports/LoanDetails/RadialBarChart.jsx new file mode 100644 index 0000000..69e0bc0 --- /dev/null +++ b/src/components/dashboard/reports/LoanDetails/RadialBarChart.jsx @@ -0,0 +1,47 @@ +import Chart from "@/core/components/Chart"; +import {calculateGradientColor} from "@/core/utils/gradientColorHandler"; + +const RadialBarChart = ({data}) => { + const specialOption = { + title: { + text: undefined, + }, + plotOptions: { + radialBar: { + startAngle: -90, + endAngle: 90, + track: { + background: "#e7e7e7", + strokeWidth: '90%', + margin: 5, // margin is in pixels + dropShadow: { + enabled: true, + top: 2, + left: 0, + color: '#999', + opacity: 1, + blur: 2 + } + }, + dataLabels: { + name: { + show: false + }, + value: { + offsetY: -2, + fontSize: '22px' + } + } + } + }, + fill: { + colors: calculateGradientColor(data) + }, + }; + const series = [data] + return ( + + ) +}; + +export default RadialBarChart; \ No newline at end of file diff --git a/src/components/dashboard/reports/LoanDetails/index.jsx b/src/components/dashboard/reports/LoanDetails/index.jsx new file mode 100644 index 0000000..7ecf452 --- /dev/null +++ b/src/components/dashboard/reports/LoanDetails/index.jsx @@ -0,0 +1,31 @@ +import {Grid, Paper} from "@mui/material"; +import {useTranslations} from "next-intl"; +import Filter from "@/components/dashboard/reports/Filter"; +import RadialBarChart from "@/components/dashboard/reports/LoanDetails/RadialBarChart"; + +const LoanDetails = () => { + const t = useTranslations(); + return ( + + + + + + + + + + + + + + + ) +}; + +export default LoanDetails; \ No newline at end of file diff --git a/src/components/dashboard/reports/LoanDistribution/PieChart.jsx b/src/components/dashboard/reports/LoanDistribution/PieChart.jsx index 4dcc225..42fdec2 100644 --- a/src/components/dashboard/reports/LoanDistribution/PieChart.jsx +++ b/src/components/dashboard/reports/LoanDistribution/PieChart.jsx @@ -7,19 +7,15 @@ const Pie = ({data}) => { }, plotOptions: { pie: { - rings: { - strokeWidth: 3, - strokeColor: '#fff', - }, fill: { - colors: ['red', 'blue', 'green', 'yellow', 'pink'] + colors: ['#F99417', '#363062', '#005B41', '#C70039', '#EE9322'] } }, }, fill: { opacity: 0.9, }, - labels: ['Team A', 'Team B', 'Team C', 'Team D', 'Team E'], + labels: [' آیتم 1', ' آیتم 2', ' آیتم 3', ' آیتم 4', ' آیتم 5'], dataLabels: { enabled: true, style: { diff --git a/src/components/dashboard/reports/LoanDistribution/PolarChart.jsx b/src/components/dashboard/reports/LoanDistribution/PolarChart.jsx index 97599c3..c334a01 100644 --- a/src/components/dashboard/reports/LoanDistribution/PolarChart.jsx +++ b/src/components/dashboard/reports/LoanDistribution/PolarChart.jsx @@ -12,14 +12,14 @@ const PolarChart = ({data}) => { strokeColor: '#e3e3e3', }, fill: { - colors: ['red', 'blue', 'green', 'yellow', 'pink'] + colors: ['#F99417', '#363062', '#005B41', '#C70039', '#EE9322'] } }, }, fill: { opacity: 0.9, }, - labels: ['Team A', 'Team B', 'Team C', 'Team D', 'Team E'], + labels: [' آیتم 1', ' آیتم 2', ' آیتم 3', ' آیتم 4', ' آیتم 5'], dataLabels: { enabled: true, style: { diff --git a/src/components/dashboard/reports/LoanDistribution/index.jsx b/src/components/dashboard/reports/LoanDistribution/index.jsx index 2e67323..f9a14bd 100644 --- a/src/components/dashboard/reports/LoanDistribution/index.jsx +++ b/src/components/dashboard/reports/LoanDistribution/index.jsx @@ -45,7 +45,7 @@ const LoanDistribution = () => { diff --git a/src/components/dashboard/reports/LoanProgress/BarChart.jsx b/src/components/dashboard/reports/LoanProgress/BarChart.jsx index 37e85a8..bf0b686 100644 --- a/src/components/dashboard/reports/LoanProgress/BarChart.jsx +++ b/src/components/dashboard/reports/LoanProgress/BarChart.jsx @@ -1,36 +1,5 @@ import Chart from "@/core/components/Chart"; - -function calculateGradientColor(percentage) { - let colorStops = [ - {percent: 0, color: [199, 18, 5]}, // 0%: #3D0C11 - {percent: 33, color: [240, 59, 47]}, // 33%: #D80032 - {percent: 34, color: [237, 204, 101]}, // 34%: #F2F7A1 - {percent: 66, color: [240, 184, 7]}, // 66%: #E9B824 - {percent: 67, color: [167, 211, 151]}, // 67%: #B0D9B1 - {percent: 100, color: [0, 91, 65]} // 100%: #005B41 - ]; - - let segment; - for (let i = 0; i < colorStops.length - 1; i++) { - if (percentage >= colorStops[i].percent && percentage <= colorStops[i + 1].percent) { - segment = i; - break; - } - } - - let color1 = colorStops[segment].color; - let color2 = colorStops[segment + 1].color; - let ratio = (percentage - colorStops[segment].percent) / (colorStops[segment + 1].percent - colorStops[segment].percent); - - let color = [ - Math.round(color1[0] + ratio * (color2[0] - color1[0])), - Math.round(color1[1] + ratio * (color2[1] - color1[1])), - Math.round(color1[2] + ratio * (color2[2] - color1[2])) - ]; - - return `rgb(${color[0]}, ${color[1]}, ${color[2]})`; - -} +import {calculateGradientColor} from "@/core/utils/gradientColorHandler"; const BarChart = ({data}) => { const usableArray = data.map(({name, data, ...rest}) => ({ @@ -83,7 +52,7 @@ const BarChart = ({data}) => { }, }; const series = [{ - name: 'اطلاعی ندارم', + name: 'درصد پیشرفت', data: usableArray }] return ( diff --git a/src/components/dashboard/reports/LoanProgress/index.jsx b/src/components/dashboard/reports/LoanProgress/index.jsx index 4f24949..62bf8aa 100644 --- a/src/components/dashboard/reports/LoanProgress/index.jsx +++ b/src/components/dashboard/reports/LoanProgress/index.jsx @@ -43,8 +43,8 @@ const LoanProgress = () => { diff --git a/src/components/dashboard/reports/index.jsx b/src/components/dashboard/reports/index.jsx index 1626104..5965e08 100644 --- a/src/components/dashboard/reports/index.jsx +++ b/src/components/dashboard/reports/index.jsx @@ -1,11 +1,13 @@ import LoanProgress from "@/components/dashboard/reports/LoanProgress"; import LoanDistribution from "@/components/dashboard/reports/LoanDistribution"; +import LoanDetails from "@/components/dashboard/reports/LoanDetails"; const DashboardReportsComponent = (props) => { return ( <> + ) }; diff --git a/src/core/utils/gradientColorHandler.js b/src/core/utils/gradientColorHandler.js new file mode 100644 index 0000000..780f856 --- /dev/null +++ b/src/core/utils/gradientColorHandler.js @@ -0,0 +1,31 @@ +export const calculateGradientColor = (percentage) => { + let colorStops = [ + {percent: 0, color: [199, 18, 5]}, // 0%: #3D0C11 + {percent: 33, color: [240, 59, 47]}, // 33%: #D80032 + {percent: 34, color: [237, 204, 101]}, // 34%: #F2F7A1 + {percent: 66, color: [240, 184, 7]}, // 66%: #E9B824 + {percent: 67, color: [167, 211, 151]}, // 67%: #B0D9B1 + {percent: 100, color: [0, 91, 65]} // 100%: #005B41 + ]; + + let segment; + for (let i = 0; i < colorStops.length - 1; i++) { + if (percentage >= colorStops[i].percent && percentage <= colorStops[i + 1].percent) { + segment = i; + break; + } + } + + let color1 = colorStops[segment].color; + let color2 = colorStops[segment + 1].color; + let ratio = (percentage - colorStops[segment].percent) / (colorStops[segment + 1].percent - colorStops[segment].percent); + + let color = [ + Math.round(color1[0] + ratio * (color2[0] - color1[0])), + Math.round(color1[1] + ratio * (color2[1] - color1[1])), + Math.round(color1[2] + ratio * (color2[2] - color1[2])) + ]; + + return `rgb(${color[0]}, ${color[1]}, ${color[2]})`; + +} \ No newline at end of file diff --git a/src/lib/app/contexts/chart.jsx b/src/lib/app/contexts/chart.jsx deleted file mode 100644 index e69de29..0000000