diff --git a/assets/js/apexcharts-helper.js b/assets/js/apexcharts-helper.js
new file mode 100644
index 0000000..6b7cc49
--- /dev/null
+++ b/assets/js/apexcharts-helper.js
@@ -0,0 +1,335 @@
+/**
+ * Builds a custom tooltip for a chart.
+ *
+ * @param {Object} props - Properties of the data point.
+ * @param {Object} options - Customization options for the tooltip.
+ * @returns {string} - The HTML string for the custom tooltip.
+ */
+function buildTooltip(props, options) {
+ // Destructuring options with default values
+ const {
+ title,
+ valuePrefix = "$",
+ isValueDivided = true,
+ valuePostfix = "",
+ hasTextLabel = false,
+ invertGroup = false,
+ labelDivider = "",
+ wrapperClasses = "bg-base-100 min-w-28 text-base-content/80 rounded-lg !border-none",
+ wrapperExtClasses = "",
+ seriesClasses = "text-xs items-center",
+ seriesExtClasses = "",
+ titleClasses = "!text-sm !font-semibold !bg-base-100 !border-base-content/40 text-base-content/90 rounded-t-lg !px-2.5",
+ titleExtClasses = "",
+ markerClasses = "!w-2.5 !h-2.5 !me-1.5 rtl:!mr-0",
+ markerExtClasses = "",
+ valueClasses = "!font-medium text-base-content/80 !ms-auto",
+ valueExtClasses = "",
+ labelClasses = "text-base-content/90",
+ labelExtClasses = "",
+ } = options;
+
+ const { dataPointIndex } = props;
+ const { colors } = props.ctx.opts;
+ const series = props.ctx.opts.series;
+ let seriesGroups = "";
+
+ // Loop through each series to build the series groups
+ series.forEach((single, i) => {
+ const val =
+ props.series[i][dataPointIndex] ||
+ (typeof series[i].data[dataPointIndex] !== "object"
+ ? series[i].data[dataPointIndex]
+ : props.series[i][dataPointIndex]);
+
+ const label = series[i].name;
+ const groupData = invertGroup
+ ? {
+ left: `${hasTextLabel ? label : ""}${labelDivider}`,
+ right: `${valuePrefix}${
+ val >= 1000 && isValueDivided
+ ? (val / 1000).toFixed(2) + "k"
+ : val.toFixed(2)
+ }${valuePostfix}`,
+ }
+ : {
+ left: `${valuePrefix}${
+ val >= 1000 && isValueDivided
+ ? (val / 1000).toFixed(2) + "k"
+ : val.toFixed(2)
+ }${valuePostfix}`,
+ right: `${hasTextLabel ? label : ""}${labelDivider}`,
+ };
+
+ const labelMarkup = `${groupData.left}`;
+
+ seriesGroups += `
+
+
+
+
+ ${
+ groupData.right
+ }
+
+
+
+ ${labelMarkup}
+
`;
+ });
+
+ // Return the final HTML for the tooltip
+ return `
+
${title}
+ ${seriesGroups}
+
`;
+}
+
+/**
+ * Builds a custom tooltip for comparing two series.
+ *
+ * @param {Object} props - Properties of the data point.
+ * @param {Object} options - Customization options for the tooltip.
+ * @returns {string} - The HTML string for the custom tooltip.
+ */
+function buildTooltipCompareTwo(props, options) {
+ const { dataPointIndex } = props;
+ const { categories } = props.ctx.opts.xaxis;
+ const { colors } = props.ctx.opts;
+ const series = props.ctx.opts.series;
+
+ const {
+ title,
+ valuePrefix = "$",
+ isValueDivided = true,
+ valuePostfix = "",
+ hasCategory = true,
+ hasTextLabel = false,
+ labelDivider = "",
+ wrapperClasses = "bg-base-100 min-w-48 text-base-content/80 rounded-lg !border-none",
+ wrapperExtClasses = "",
+ seriesClasses = "text-xs items-center !justify-between",
+ seriesExtClasses = "",
+ titleClasses = "!text-sm !font-semibold !bg-base-100 !border-base-content/40 text-base-content/90 rounded-t-lg !px-2.5",
+ titleExtClasses = "flex justify-between",
+ markerClasses = "!w-2.5 !h-2.5 !me-1.5",
+ markerExtClasses = "",
+ valueClasses = "!font-medium text-base-content/80 !ms-auto",
+ valueExtClasses = "",
+ labelClasses = "text-base-content/90 !fw-medium",
+ labelExtClasses = "",
+ } = options;
+
+ let seriesGroups = "";
+ const s0 = series[0].data[dataPointIndex];
+ const s1 = series[1].data[dataPointIndex];
+ const category = categories[dataPointIndex].split(" ");
+ const newCategory = hasCategory
+ ? `${category[0]}${category[1] ? " " : ""}${
+ category[1] ? category[1].slice(0, 3) : ""
+ }`
+ : "";
+ const isGrowing = s0 > s1;
+ const isDifferenceIsNull = s0 / s1 === 1;
+ const difference = isDifferenceIsNull ? 0 : (s0 / s1) * 100;
+ const icon = isGrowing
+ ? ``
+ : ``;
+
+ // Loop through each series to build the series groups
+ series.forEach((_, i) => {
+ const val =
+ props.series[i][dataPointIndex] ||
+ (typeof series[i].data[dataPointIndex] !== "object"
+ ? series[i].data[dataPointIndex]
+ : props.series[i][dataPointIndex]);
+
+ const label = series[i].name;
+ const altValue = series[i].altValue || null;
+ const labelMarkup = `${newCategory} ${
+ label || ""
+ }`;
+ const valueMarkup =
+ altValue ||
+ `${valuePrefix}${
+ val >= 1000 && isValueDivided ? `${val / 1000}k` : val
+ }${valuePostfix}${labelDivider}`;
+
+ seriesGroups += ``;
+ });
+
+ // Return the final HTML for the tooltip
+ return `
+
+ ${title}
+
+ ${!isDifferenceIsNull ? icon : ""}
+ ${difference.toFixed(1)}%
+
+
+ ${seriesGroups}
+
`;
+}
+
+/**
+ * Builds an alternative custom tooltip for comparing two series.
+ *
+ * @param {Object} props - Properties of the data point.
+ * @param {Object} options - Customization options for the tooltip.
+ * @returns {string} - The HTML string for the custom tooltip.
+ */
+function buildTooltipCompareTwoAlt(props, options) {
+ const { dataPointIndex } = props;
+ const { categories } = props.ctx.opts.xaxis;
+ const { colors } = props.ctx.opts;
+ const series = props.ctx.opts.series;
+
+ const {
+ title,
+ valuePrefix = "$",
+ isValueDivided = true,
+ valuePostfix = "",
+ hasCategory = true,
+ hasTextLabel = false,
+ labelDivider = "",
+ wrapperClasses = "bg-base-100 min-w-48 text-base-content/80 rounded-lg !border-none",
+ wrapperExtClasses = "",
+ seriesClasses = "text-xs items-center !justify-between",
+ seriesExtClasses = "",
+ titleClasses = "!text-sm !font-semibold !bg-base-100 !border-base-content/40 text-base-content/90 rounded-t-lg flex !justify-between !px-2.5",
+ titleExtClasses = "",
+ markerClasses = "!w-2.5 !h-2.5 !me-1.5",
+ markerExtClasses = "",
+ valueClasses = "!font-medium text-base-content/80 !ms-auto",
+ valueExtClasses = "",
+ labelClasses = "text-base-content/90 !fw-medium",
+ labelExtClasses = "",
+ } = options;
+
+ let seriesGroups = "";
+ const s0 = series[0].data[dataPointIndex];
+ const s1 = series[1].data[dataPointIndex];
+ const category = categories[dataPointIndex].split(" ");
+ const newCategory = hasCategory
+ ? `${category[0]}${category[1] ? " " : ""}${
+ category[1] ? category[1].slice(0, 3) : ""
+ }`
+ : "";
+ const isGrowing = s0 > s1;
+ const isDifferenceIsNull = s0 / s1 === 1;
+ const difference = isDifferenceIsNull ? 0 : (s0 / s1) * 100;
+ const icon = isGrowing
+ ? ``
+ : ``;
+
+ // Loop through each series to build the series groups
+ series.forEach((single, i) => {
+ const val =
+ props.series[i][dataPointIndex] ||
+ (typeof series[i].data[dataPointIndex] !== "object"
+ ? series[i].data[dataPointIndex]
+ : props.series[i][dataPointIndex]);
+
+ const label = series[i].name;
+ const labelMarkup = `${valuePrefix}${
+ val >= 1000 && isValueDivided ? `${val / 1000}k` : val
+ }${valuePostfix}`;
+
+ seriesGroups += ``;
+ });
+
+ // Return the final HTML for the tooltip
+ return `
+
+ ${title}
+
+ ${!isDifferenceIsNull ? icon : ""}
+ ${difference.toFixed(1)}%
+
+
+ ${seriesGroups}
+
`;
+}
+
+/**
+ * Builds a custom tooltip for a donut chart.
+ *
+ * @param {Object} context - Context of the data point.
+ * @param {Array} textColor - Array of text colors for each series.
+ * @returns {string} - The HTML string for the custom tooltip.
+ */
+function buildTooltipForDonut({ series, seriesIndex, w }, textColor) {
+ const { globals } = w;
+ const { colors } = globals;
+
+ // Return the final HTML for the donut tooltip
+ return ``;
+}
+
+/**
+ * Initializes and builds an ApexChart with the given configurations.
+ *
+ * @param {string} id - The DOM element ID where the chart will be rendered.
+ * @param {function} shared - Shared configuration function.
+ * @returns {Object|null} - The initialized chart instance or null.
+ */
+function buildChart(id, shared) {
+ const $chart = document.querySelector(id);
+ let chart = null;
+
+ if (!$chart) return false;
+
+ const optionsFn = () => shared();
+ // Initialize and render the chart
+ if ($chart) {
+ chart = new ApexCharts($chart, optionsFn());
+ chart.render();
+ }
+
+ return chart;
+}