counter and chart package added

This commit was merged in pull request #12.
This commit is contained in:
victorAnumudu
2025-04-13 11:19:19 +01:00
parent 55e5b9606a
commit f98299d39b
8 changed files with 382 additions and 31 deletions
+35 -25
View File
@@ -1,29 +1,39 @@
import React, { useEffect, useState } from 'react';
// import React, { useEffect, useState } from 'react';
// const CustomCounter = ({ targetNumber, timeInSeconds }) => {
// const [count, setCount] = useState(0);
// useEffect(() => {
// if (targetNumber <= 0 || timeInSeconds <= 0) return; // Handle edge cases
// const interval = Math.floor(timeInSeconds * 1000 / targetNumber); // Time interval for each count in milliseconds
// const totalTime = timeInSeconds * 1000; // Total time for the entire count in milliseconds
// let currentCount = 0;
// const intervalId = setInterval(() => {
// currentCount++;
// setCount((prevCount) => prevCount + 1); // Update state using the previous state
// if (currentCount >= targetNumber) {
// clearInterval(intervalId); // Stop the counting when the target number is reached
// }
// }, interval);
// // Cleanup the interval on component unmount
// return () => clearInterval(intervalId);
// }, [targetNumber, timeInSeconds]);
// return <>{count}</>;
// };
// export default CustomCounter;
import React from 'react';
import CountUp from 'react-countup';
const CustomCounter = ({ targetNumber, timeInSeconds }) => {
const [count, setCount] = useState(0);
useEffect(() => {
if (targetNumber <= 0 || timeInSeconds <= 0) return; // Handle edge cases
const interval = Math.floor(timeInSeconds * 1000 / targetNumber); // Time interval for each count in milliseconds
const totalTime = timeInSeconds * 1000; // Total time for the entire count in milliseconds
let currentCount = 0;
const intervalId = setInterval(() => {
currentCount++;
setCount((prevCount) => prevCount + 1); // Update state using the previous state
if (currentCount >= targetNumber) {
clearInterval(intervalId); // Stop the counting when the target number is reached
}
}, interval);
// Cleanup the interval on component unmount
return () => clearInterval(intervalId);
}, [targetNumber, timeInSeconds]);
return <>{count}</>;
return <CountUp end={targetNumber} duration={timeInSeconds} />;
};
export default CustomCounter;
export default CustomCounter;
+1 -1
View File
@@ -25,7 +25,7 @@ export default function BreadcrumbCom({title, span, paths}) {
return (
// ${stickNav ? 'sticky top-0 transition-[top] duration-1000 shadow-md shadow-black' : '-top-[100px] static'}
<div className={`sticky z-[999] -top-10 bg-white-body dark:bg-black-body dark:border-b dark:border-black-box dark:shadow-sm dark:shadow-black-box`}>
<div className={`sticky z-[970] top-[78px] lg:-top-10 bg-white-body dark:bg-black-body dark:border-b dark:border-black-box dark:shadow-sm dark:shadow-black-box`}>
<div className= {`w-full py-2 flex justify-between items-center`}>
<div className='flex flex-col gap-2'>
<div className='flex flex-col md:flex-row gap-1 md:items-center'>
+187
View File
@@ -0,0 +1,187 @@
import {useEffect, useRef} from 'react'
import ApexCharts from 'apexcharts'
const Widget1 = ({chartHeight='50px'}) => {
const chartRef = useRef(null)
const {mode} = '' // to be replaced by theme mode value later
useEffect(() => {
const chart = refreshChart()
return () => {
if (chart) {
chart.destroy()
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [chartRef, mode])
const refreshChart = () => {
if (!chartRef.current) {
return
}
const chart = new ApexCharts(chartRef.current, chartOptions(chartHeight))
if (chart) {
chart.render()
}
return chart
}
return (
<div className='w-full'>
{/* end::Title */}
<div
ref={chartRef}
className='mixed-widget-13-chart'
style={{height: chartHeight, minHeight: chartHeight}}
></div>
</div>
)
}
const chartOptions = (chartHeight) => {
// const labelColor = getCSSVariableValue('--bs-gray-800')
// const strokeColor = getCSSVariableValue('--bs-gray-300')
const labelColor = '#e9e9e9'
const strokeColor = '#e3e3e3'
// const strokeColor = getCSSVariableValue('--bs-gray-300') as string
return {
series: [
{
name: 'Net Profit',
data: [15, 25, 15, 40, 20, 50],
},
],
grid: {
show: false,
padding: {
top: 0,
bottom: 0,
left: 0,
right: 0,
},
},
chart: {
fontFamily: 'inherit',
type: 'area',
height: chartHeight,
toolbar: {
show: false,
},
zoom: {
enabled: false,
},
sparkline: {
enabled: true,
},
},
plotOptions: {},
legend: {
show: false,
},
dataLabels: {
enabled: false,
},
fill: {
type: 'gradient',
gradient: {
opacityFrom: 0.4,
opacityTo: 0,
stops: [20, 120, 120, 120],
},
},
stroke: {
curve: 'smooth',
show: true,
width: 3,
colors: ['#FFFFFF'],
},
xaxis: {
categories: ['Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul'],
axisBorder: {
show: false,
},
axisTicks: {
show: false,
},
labels: {
show: false,
style: {
colors: labelColor,
fontSize: '12px',
},
},
crosshairs: {
show: false,
position: 'front',
stroke: {
color: strokeColor,
width: 1,
dashArray: 3,
},
},
tooltip: {
enabled: true,
formatter: undefined,
offsetY: 0,
style: {
fontSize: '12px',
},
},
},
yaxis: {
min: 0,
max: 60,
labels: {
show: false,
style: {
colors: labelColor,
fontSize: '12px',
},
},
},
states: {
normal: {
filter: {
type: 'none',
value: 0,
},
},
hover: {
filter: {
type: 'none',
value: 0,
},
},
active: {
allowMultipleDataPointsSelection: false,
filter: {
type: 'none',
value: 0,
},
},
},
tooltip: {
style: {
fontSize: '12px',
},
y: {
formatter: function (val) {
return '$' + val + ' thousands'
},
},
},
colors: ['#ffffff'],
markers: {
colors: [labelColor],
strokeColors: [strokeColor],
strokeWidth: 3,
},
}
}
export {Widget1}
+147
View File
@@ -0,0 +1,147 @@
import {useEffect, useRef} from 'react'
import ApexCharts from 'apexcharts'
const Widget2 = ({chartHeight='100px'}) => {
const chartRef = useRef(null)
const {mode} = '' // to be replaced by theme mode value later
useEffect(() => {
const chart = refreshChart()
return () => {
if (chart) {
chart.destroy()
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [chartRef, mode])
const refreshChart = () => {
if (!chartRef.current) {
return
}
const chart = new ApexCharts(chartRef.current, chartOptions(chartHeight))
if (chart) {
chart.render()
}
return chart
}
return (
<div className='w-full'>
{/* end::Title */}
<div
ref={chartRef}
className='mixed-widget-13-chart'
style={{height: chartHeight, minHeight: chartHeight}}
></div>
</div>
)
}
const chartOptions = (chartHeight) => {
// const labelColor = getCSSVariableValue('--bs-gray-800')
return {
series: [
{
name: 'Inflation',
data: [1, 2.1, 1, 2.1, 4.1, 6.1, 4.1, 4.1, 2.1, 4.1, 2.1, 3.1, 1, 1, 2.1],
},
],
chart: {
fontFamily: 'inherit',
height: chartHeight,
type: 'bar',
toolbar: {
show: false,
},
},
grid: {
show: false,
padding: {
top: 0,
bottom: 0,
left: 0,
right: 0,
},
},
colors: ['#ffffff'],
plotOptions: {
bar: {
borderRadius: 2.5,
dataLabels: {
position: 'top', // top, center, bottom
},
columnWidth: '20%',
},
},
dataLabels: {
enabled: false,
formatter: function (val) {
return val + '%'
},
offsetY: -20,
style: {
fontSize: '12px',
colors: ['#304758'],
},
},
xaxis: {
labels: {
show: false,
},
categories: [
'Jan',
'Feb',
'Mar',
'Apr',
'May',
'Jun',
'Jul',
'Aug',
'Sep',
'Oct',
'Nov',
'Dec',
'Jan',
'Feb',
'Mar',
],
position: 'top',
axisBorder: {
show: false,
},
axisTicks: {
show: false,
},
crosshairs: {
show: false,
},
tooltip: {
enabled: false,
},
},
yaxis: {
show: false,
axisBorder: {
show: false,
},
axisTicks: {
show: false,
// background: labelColor,
},
labels: {
show: false,
formatter: function (val) {
return val + '%'
},
},
},
}
}
export {Widget2}
+1 -1
View File
@@ -29,7 +29,7 @@ export default function DashboardLayout() {
</div>
<div className={`main w-full bg-inherit ${pathname == '/' && 'large:mr-[400px]'}`}>
<div className='fixed top-0 left-0 z-[777] w-full px-8 bg-inherit lg:hidden'>
<div className='fixed top-0 left-0 z-[980] w-full px-8 bg-inherit lg:hidden'>
<DashboardHeader />
</div>