@algorithm-shift/design-system 1.3.119 → 1.3.121

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -2918,13 +2918,61 @@ function resolveDate(option, customOption) {
2918
2918
  switch (option) {
2919
2919
  case "today":
2920
2920
  return /* @__PURE__ */ new Date();
2921
- case "custom":
2922
- return customOption ? new Date(customOption) : void 0;
2921
+ case "custom": {
2922
+ if (!customOption) return void 0;
2923
+ const d = new Date(customOption);
2924
+ return !isNaN(d.getTime()) ? d : void 0;
2925
+ }
2923
2926
  case "none":
2924
2927
  default:
2925
2928
  return void 0;
2926
2929
  }
2927
2930
  }
2931
+ function resolveDefaultDate(option, customOption) {
2932
+ if (!option || option === "none") return void 0;
2933
+ const now = /* @__PURE__ */ new Date();
2934
+ switch (option) {
2935
+ case "today":
2936
+ return new Date(now);
2937
+ case "currentPlus1Week": {
2938
+ const d = new Date(now);
2939
+ d.setDate(d.getDate() + 7);
2940
+ return d;
2941
+ }
2942
+ case "currentPlus1Year": {
2943
+ const d = new Date(now);
2944
+ d.setFullYear(d.getFullYear() + 1);
2945
+ return d;
2946
+ }
2947
+ case "previousDay": {
2948
+ const d = new Date(now);
2949
+ d.setDate(d.getDate() - 1);
2950
+ return d;
2951
+ }
2952
+ case "previous1Week": {
2953
+ const d = new Date(now);
2954
+ d.setDate(d.getDate() - 7);
2955
+ return d;
2956
+ }
2957
+ case "previous1Month": {
2958
+ const d = new Date(now);
2959
+ d.setMonth(d.getMonth() - 1);
2960
+ return d;
2961
+ }
2962
+ case "previous1Year": {
2963
+ const d = new Date(now);
2964
+ d.setFullYear(d.getFullYear() - 1);
2965
+ return d;
2966
+ }
2967
+ case "custom": {
2968
+ if (!customOption) return void 0;
2969
+ const d = new Date(customOption);
2970
+ return !isNaN(d.getTime()) ? d : void 0;
2971
+ }
2972
+ default:
2973
+ return void 0;
2974
+ }
2975
+ }
2928
2976
  function DateTimePicker({
2929
2977
  className,
2930
2978
  style,
@@ -2942,6 +2990,8 @@ function DateTimePicker({
2942
2990
  const customMinimumDate = props.customMinimumDate ?? "";
2943
2991
  const maximumDate = props.maximumDate ?? "none";
2944
2992
  const customMaximumDate = props.customMaximumDate ?? "";
2993
+ const defaultDateValue = props.defaultDateValue ?? "none";
2994
+ const customDefaultDate = props.customDefaultDate ?? "";
2945
2995
  const isEditable = props.isEditable ?? true;
2946
2996
  const isDisabled = props.isDisabled ?? false;
2947
2997
  const isReadonly = props.isReadonly ?? false;
@@ -2949,9 +2999,11 @@ function DateTimePicker({
2949
2999
  const minDate = resolveDate(minimumDate, customMinimumDate);
2950
3000
  const maxDate = resolveDate(maximumDate, customMaximumDate);
2951
3001
  const [date, setDate] = React8.useState(() => {
2952
- if (!props.value) return void 0;
2953
- const d = new Date(props.value);
2954
- return isNaN(d.getTime()) ? void 0 : d;
3002
+ if (props.value) {
3003
+ const d = new Date(props.value);
3004
+ if (!isNaN(d.getTime())) return d;
3005
+ }
3006
+ return resolveDefaultDate(defaultDateValue, customDefaultDate);
2955
3007
  });
2956
3008
  const initialHours = date ? date.getHours() : 0;
2957
3009
  const initialMinutes = date ? date.getMinutes() : 0;
@@ -2966,26 +3018,6 @@ function DateTimePicker({
2966
3018
  React8.useEffect(() => {
2967
3019
  setAmPm(hours >= 12 ? "PM" : "AM");
2968
3020
  }, [hours]);
2969
- React8.useEffect(() => {
2970
- if (!props.value) {
2971
- setDate(void 0);
2972
- return;
2973
- }
2974
- const d = new Date(props.value);
2975
- if (!isNaN(d.getTime())) {
2976
- setDate(d);
2977
- setHours(d.getHours());
2978
- setMinutes(d.getMinutes());
2979
- }
2980
- }, [props.value]);
2981
- const [year, setYear] = React8.useState(date ? date.getFullYear() : (/* @__PURE__ */ new Date()).getFullYear());
2982
- React8.useEffect(() => {
2983
- if (!date) return;
2984
- const newDate = new Date(date);
2985
- newDate.setFullYear(year);
2986
- setDate(newDate);
2987
- emitChange(newDate);
2988
- }, [year]);
2989
3021
  const emitChange = (nextDate) => {
2990
3022
  if (!props.onChange) return;
2991
3023
  let valueString = "";
@@ -3007,6 +3039,36 @@ function DateTimePicker({
3007
3039
  };
3008
3040
  props.onChange(event, props.name || "");
3009
3041
  };
3042
+ React8.useEffect(() => {
3043
+ if (!props.value) {
3044
+ const defaultDate = resolveDefaultDate(defaultDateValue, customDefaultDate);
3045
+ setDate(defaultDate);
3046
+ if (defaultDate) {
3047
+ setYear(defaultDate.getFullYear());
3048
+ setHours(defaultDate.getHours());
3049
+ setMinutes(defaultDate.getMinutes());
3050
+ emitChange(defaultDate);
3051
+ } else {
3052
+ setHours(0);
3053
+ setMinutes(0);
3054
+ }
3055
+ return;
3056
+ }
3057
+ const d = new Date(props.value);
3058
+ if (!isNaN(d.getTime())) {
3059
+ setDate(d);
3060
+ setHours(d.getHours());
3061
+ setMinutes(d.getMinutes());
3062
+ }
3063
+ }, [props.value, defaultDateValue, customDefaultDate]);
3064
+ const [year, setYear] = React8.useState(date ? date.getFullYear() : (/* @__PURE__ */ new Date()).getFullYear());
3065
+ React8.useEffect(() => {
3066
+ if (!date) return;
3067
+ const newDate = new Date(date);
3068
+ newDate.setFullYear(year);
3069
+ setDate(newDate);
3070
+ emitChange(newDate);
3071
+ }, [year]);
3010
3072
  const updateDateTime = (nextBaseDate, h = hours, m = minutes) => {
3011
3073
  if (!nextBaseDate) {
3012
3074
  setDate(void 0);
@@ -3237,7 +3299,7 @@ function DateTimePicker({
3237
3299
  name: props.name,
3238
3300
  autoComplete: isAutocomplete ? "on" : "off",
3239
3301
  readOnly: isReadonly,
3240
- value: !date ? "" : mode === "date" ? format(date, "yyyy-MM-dd") : mode === "time" ? format(date, "HH:mm:ss") : date.toISOString(),
3302
+ value: !date || isNaN(date.getTime()) ? "" : mode === "date" ? format(date, "yyyy-MM-dd") : mode === "time" ? format(date, "HH:mm:ss") : date.toISOString(),
3241
3303
  onChange: () => {
3242
3304
  }
3243
3305
  }
@@ -3374,7 +3436,6 @@ function LazyMultiSelectDropdown({
3374
3436
  onChange,
3375
3437
  placeholder,
3376
3438
  className,
3377
- id,
3378
3439
  disabled,
3379
3440
  readOnly,
3380
3441
  source,
@@ -3440,10 +3501,10 @@ function LazyMultiSelectDropdown({
3440
3501
  }
3441
3502
  };
3442
3503
  const selectedOptions = useMemo6(() => {
3443
- return normalizedValue.map((id2) => {
3444
- const fromLazy = lazyOptions.find((opt) => opt.value === id2);
3504
+ return normalizedValue.map((id) => {
3505
+ const fromLazy = lazyOptions.find((opt) => opt.value === id);
3445
3506
  if (fromLazy) return fromLazy;
3446
- return { value: id2, label: id2 };
3507
+ return { value: id, label: id };
3447
3508
  });
3448
3509
  }, [normalizedValue, lazyOptions]);
3449
3510
  useEffect25(() => {
@@ -3478,11 +3539,11 @@ function LazyMultiSelectDropdown({
3478
3539
  } else {
3479
3540
  updated = ensureUnique([...normalizedValue, val]);
3480
3541
  }
3481
- onChange?.(convertOutput(updated), id);
3542
+ onChange?.(convertOutput(updated), props.name ?? "");
3482
3543
  };
3483
3544
  const removeTag = (val) => {
3484
3545
  const updated = normalizedValue.filter((v) => v !== val);
3485
- onChange?.(convertOutput(updated), id);
3546
+ onChange?.(convertOutput(updated), props.name ?? "");
3486
3547
  };
3487
3548
  const handleFocus = () => {
3488
3549
  if (!disabled) {
@@ -5968,55 +6029,51 @@ import {
5968
6029
  YAxis,
5969
6030
  CartesianGrid,
5970
6031
  Tooltip as Tooltip2,
5971
- ResponsiveContainer,
5972
- Legend
6032
+ ResponsiveContainer
5973
6033
  } from "recharts";
5974
6034
  import { jsx as jsx68, jsxs as jsxs42 } from "react/jsx-runtime";
5975
- var getRandomColor = () => {
5976
- const palette = [
5977
- "#2563eb",
5978
- "#1d4ed8",
5979
- "#1e40af",
5980
- "#1e3a8a",
5981
- "#1e293b",
5982
- "#10b981",
5983
- "#059669",
5984
- "#047857",
5985
- "#065f46",
5986
- "#022c22",
5987
- "#f59e0b",
5988
- "#d97706",
5989
- "#b45309",
5990
- "#92400e",
5991
- "#422006",
5992
- "#ef4444",
5993
- "#dc2626",
5994
- "#b91c1c",
5995
- "#991b1b",
5996
- "#7f1d1d",
5997
- "#8b5cf6",
5998
- "#7c3aed",
5999
- "#6d28d9",
6000
- "#5b21b6",
6001
- "#4c1d95",
6002
- "#14b8a6",
6003
- "#0d9488",
6004
- "#0f766e",
6005
- "#115e59",
6006
- "#134e4a",
6007
- "#ec4899",
6008
- "#db2777",
6009
- "#be185d",
6010
- "#9d174d",
6011
- "#831843",
6012
- "#22c55e",
6013
- "#16a34a",
6014
- "#15803d",
6015
- "#166534",
6016
- "#14532d"
6017
- ];
6018
- return palette[Math.floor(Math.random() * palette.length)];
6019
- };
6035
+ var palette = [
6036
+ "#2563eb",
6037
+ "#1d4ed8",
6038
+ "#1e40af",
6039
+ "#1e3a8a",
6040
+ "#1e293b",
6041
+ "#10b981",
6042
+ "#059669",
6043
+ "#047857",
6044
+ "#065f46",
6045
+ "#022c22",
6046
+ "#f59e0b",
6047
+ "#d97706",
6048
+ "#b45309",
6049
+ "#92400e",
6050
+ "#422006",
6051
+ "#ef4444",
6052
+ "#dc2626",
6053
+ "#b91c1c",
6054
+ "#991b1b",
6055
+ "#7f1d1d",
6056
+ "#8b5cf6",
6057
+ "#7c3aed",
6058
+ "#6d28d9",
6059
+ "#5b21b6",
6060
+ "#4c1d95",
6061
+ "#14b8a6",
6062
+ "#0d9488",
6063
+ "#0f766e",
6064
+ "#115e59",
6065
+ "#134e4a",
6066
+ "#ec4899",
6067
+ "#db2777",
6068
+ "#be185d",
6069
+ "#9d174d",
6070
+ "#831843",
6071
+ "#22c55e",
6072
+ "#16a34a",
6073
+ "#15803d",
6074
+ "#166534",
6075
+ "#14532d"
6076
+ ];
6020
6077
  var ChartComponent = ({
6021
6078
  className,
6022
6079
  style,
@@ -6024,25 +6081,30 @@ var ChartComponent = ({
6024
6081
  dataKey,
6025
6082
  dataLabel,
6026
6083
  apiUrl,
6084
+ source,
6027
6085
  isPaginationEnabled,
6028
6086
  limit = 10,
6029
6087
  canvasMode,
6088
+ showLegends = true,
6089
+ legendPosition = "bottom",
6090
+ onLegendClick,
6030
6091
  ...props
6031
6092
  }) => {
6093
+ const useApi = source === "api" && !!apiUrl;
6032
6094
  const [rawData, setRawData] = useState15([]);
6033
6095
  const [rawMeta, setRawMeta] = useState15(null);
6034
6096
  const [localLoading, setLocalLoading] = useState15(false);
6035
6097
  const [currentPage, setCurrentPage] = useState15(1);
6036
- const effectiveData = apiUrl ? rawData : props.data || [];
6037
- const effectiveLoading = apiUrl ? localLoading : externalLoading;
6098
+ const effectiveData = useApi ? rawData : props.data || [];
6099
+ const effectiveLoading = useApi ? localLoading : externalLoading;
6038
6100
  useEffect29(() => {
6039
- if (apiUrl) {
6101
+ if (useApi) {
6040
6102
  setCurrentPage(1);
6041
6103
  }
6042
- }, [apiUrl]);
6104
+ }, [useApi]);
6043
6105
  const fetchData = useCallback7(async (page) => {
6044
6106
  if (!apiUrl) return;
6045
- const cancelled = false;
6107
+ let cancelled = false;
6046
6108
  try {
6047
6109
  setLocalLoading(true);
6048
6110
  const params = new URLSearchParams({
@@ -6078,9 +6140,9 @@ var ChartComponent = ({
6078
6140
  }
6079
6141
  }, [apiUrl, limit]);
6080
6142
  useEffect29(() => {
6081
- if (!apiUrl) return;
6143
+ if (!useApi) return;
6082
6144
  fetchData(currentPage);
6083
- }, [apiUrl, currentPage, fetchData]);
6145
+ }, [useApi, currentPage, fetchData]);
6084
6146
  const handlePageChange = (newPage) => {
6085
6147
  if (rawMeta && (newPage < 1 || newPage > rawMeta.pages)) return;
6086
6148
  setCurrentPage(newPage);
@@ -6089,15 +6151,59 @@ var ChartComponent = ({
6089
6151
  if (!Array.isArray(effectiveData) || effectiveData.length === 0 || !dataKey || !dataLabel) {
6090
6152
  return [];
6091
6153
  }
6092
- return effectiveData.map((item) => ({
6154
+ return effectiveData.map((item, index) => ({
6093
6155
  ...item,
6094
6156
  [dataKey]: Number(item[dataKey] || 0),
6095
- fill: getRandomColor()
6157
+ fill: item.fill || palette[index % palette.length]
6096
6158
  }));
6097
6159
  }, [effectiveData, dataKey, dataLabel]);
6098
6160
  const chartType = props.chartType || "bar";
6099
- const legendsPosition = ["middle", "bottom"].includes(props.legendsPosition) ? props.legendsPosition : "top";
6100
- if (effectiveLoading || data.length === 0) {
6161
+ const forceMobile = canvasMode === "mobile" || canvasMode === "tablet";
6162
+ const renderLegends = useMemo11(() => {
6163
+ if (!showLegends || !dataKey || !dataLabel) return null;
6164
+ const isLegendRight2 = !forceMobile && legendPosition === "right";
6165
+ return /* @__PURE__ */ jsx68(
6166
+ "div",
6167
+ {
6168
+ className: isLegendRight2 ? "flex flex-col gap-2 w-full min-w-0 justify-start" : "flex flex-wrap justify-center gap-2 mt-4 w-full max-w-4xl",
6169
+ children: data.map((d, index) => {
6170
+ const value = d[dataKey] ?? 0;
6171
+ const displayValue = value >= 1e3 ? `${(value / 1e3).toFixed(0)}k` : value.toLocaleString();
6172
+ const payload = {
6173
+ name: d[dataLabel],
6174
+ value,
6175
+ [dataLabel]: d[dataLabel],
6176
+ [dataKey]: value
6177
+ };
6178
+ return /* @__PURE__ */ jsxs42(
6179
+ "div",
6180
+ {
6181
+ role: onLegendClick ? "button" : void 0,
6182
+ tabIndex: onLegendClick ? 0 : void 0,
6183
+ onClick: onLegendClick ? () => onLegendClick(payload) : void 0,
6184
+ onKeyDown: onLegendClick ? (e) => e.key === "Enter" && onLegendClick(payload) : void 0,
6185
+ className: `flex items-center space-x-2 rounded-lg border border-gray-200/50 px-3 py-1.5 min-w-[180px] w-[180px] bg-white/80 backdrop-blur-sm shadow-sm hover:shadow-md transition-all ${onLegendClick ? "cursor-pointer" : ""}`,
6186
+ children: [
6187
+ /* @__PURE__ */ jsx68(
6188
+ "span",
6189
+ {
6190
+ className: "inline-block w-[12px] h-[12px] rounded-full shrink-0 border-2 border-white/50",
6191
+ style: { backgroundColor: d.fill }
6192
+ }
6193
+ ),
6194
+ /* @__PURE__ */ jsxs42("div", { className: "min-w-0 flex-1", children: [
6195
+ /* @__PURE__ */ jsx68("span", { className: "text-gray-900 text-[11px] md:text-[13px] font-semibold block truncate leading-tight capitalize", children: d[dataLabel] }),
6196
+ /* @__PURE__ */ jsx68("span", { className: "text-xs text-gray-600 font-medium", children: displayValue })
6197
+ ] })
6198
+ ]
6199
+ },
6200
+ `legend-${index}`
6201
+ );
6202
+ })
6203
+ }
6204
+ );
6205
+ }, [data, dataLabel, dataKey, showLegends, onLegendClick, legendPosition, forceMobile]);
6206
+ if (effectiveLoading) {
6101
6207
  return /* @__PURE__ */ jsxs42(
6102
6208
  "div",
6103
6209
  {
@@ -6128,141 +6234,167 @@ var ChartComponent = ({
6128
6234
  }
6129
6235
  );
6130
6236
  }
6131
- return /* @__PURE__ */ jsxs42("div", { className: `${className} h-[450px]`, style, children: [
6132
- isPaginationEnabled && rawMeta && /* @__PURE__ */ jsxs42("div", { className: "flex items-center justify-between mb-4 px-2", children: [
6133
- /* @__PURE__ */ jsxs42("div", { className: "flex items-center space-x-2 sm:hidden w-full justify-center", children: [
6134
- /* @__PURE__ */ jsx68(
6135
- "button",
6136
- {
6137
- onClick: () => handlePageChange(currentPage - 1),
6138
- disabled: currentPage === 1 || localLoading,
6139
- className: "flex-1 px-3 py-2 text-xs font-medium rounded-lg border bg-white shadow-sm hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-200 flex items-center justify-center space-x-1 min-w-0",
6140
- children: /* @__PURE__ */ jsx68("span", { children: "\u2190 Prev" })
6141
- }
6142
- ),
6143
- /* @__PURE__ */ jsx68("span", { className: "px-2 py-2 text-xs font-semibold text-gray-700 min-w-[36px] text-center flex-shrink-0", children: currentPage }),
6144
- /* @__PURE__ */ jsx68(
6145
- "button",
6146
- {
6147
- onClick: () => handlePageChange(currentPage + 1),
6148
- disabled: currentPage >= rawMeta.pages || localLoading,
6149
- className: "flex-1 px-3 py-2 text-xs font-medium rounded-lg border bg-white shadow-sm hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-200 flex items-center justify-center space-x-1 min-w-0",
6150
- children: /* @__PURE__ */ jsx68("span", { children: "Next \u2192" })
6151
- }
6152
- )
6153
- ] }),
6154
- /* @__PURE__ */ jsxs42("div", { className: "flex items-center space-x-2 hidden sm:flex", children: [
6155
- /* @__PURE__ */ jsx68(
6156
- "button",
6237
+ if (data.length === 0) {
6238
+ return /* @__PURE__ */ jsx68(
6239
+ "div",
6240
+ {
6241
+ className: `relative flex flex-col items-center justify-center w-full h-[300px] md:h-[400px] bg-gradient-to-br from-gray-50 to-gray-100 rounded-xl p-6 ${className}`,
6242
+ style,
6243
+ children: /* @__PURE__ */ jsx68("div", { className: "text-center", children: /* @__PURE__ */ jsx68("div", { className: "inline-flex items-center space-x-2 bg-white/80 px-6 py-3 rounded-xl backdrop-blur-sm border border-gray-200 shadow-lg", children: /* @__PURE__ */ jsx68("span", { className: "text-sm font-medium text-gray-600", children: "No data" }) }) })
6244
+ }
6245
+ );
6246
+ }
6247
+ const isLegendRight = !forceMobile && legendPosition === "right";
6248
+ return /* @__PURE__ */ jsxs42(
6249
+ "div",
6250
+ {
6251
+ className: `relative flex ${isLegendRight ? "flex-row items-stretch gap-4" : "flex-col items-center"} ${className}`,
6252
+ style,
6253
+ children: [
6254
+ /* @__PURE__ */ jsxs42(
6255
+ "div",
6157
6256
  {
6158
- onClick: () => handlePageChange(currentPage - 1),
6159
- disabled: currentPage === 1 || localLoading,
6160
- className: "px-3 py-1.5 text-sm font-medium rounded-lg border bg-white shadow-sm hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-200 flex items-center space-x-1",
6161
- children: /* @__PURE__ */ jsx68("span", { children: "\u2190 Prev" })
6257
+ className: `relative flex items-center justify-center ${isLegendRight ? "flex-[2] min-w-0 max-w-[70%] h-[450px]" : "w-full md:w-[75%] h-[450px] mb-2"}`,
6258
+ children: [
6259
+ isPaginationEnabled && rawMeta && /* @__PURE__ */ jsxs42("div", { className: "flex items-center justify-between mb-4 px-2", children: [
6260
+ /* @__PURE__ */ jsxs42("div", { className: "flex items-center space-x-2 sm:hidden w-full justify-center", children: [
6261
+ /* @__PURE__ */ jsx68(
6262
+ "button",
6263
+ {
6264
+ onClick: () => handlePageChange(currentPage - 1),
6265
+ disabled: currentPage === 1 || localLoading,
6266
+ className: "flex-1 px-3 py-2 text-xs font-medium rounded-lg border bg-white shadow-sm hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-200 flex items-center justify-center space-x-1 min-w-0",
6267
+ children: /* @__PURE__ */ jsx68("span", { children: "\u2190 Prev" })
6268
+ }
6269
+ ),
6270
+ /* @__PURE__ */ jsx68("span", { className: "px-2 py-2 text-xs font-semibold text-gray-700 min-w-[36px] text-center flex-shrink-0", children: currentPage }),
6271
+ /* @__PURE__ */ jsx68(
6272
+ "button",
6273
+ {
6274
+ onClick: () => handlePageChange(currentPage + 1),
6275
+ disabled: currentPage >= rawMeta.pages || localLoading,
6276
+ className: "flex-1 px-3 py-2 text-xs font-medium rounded-lg border bg-white shadow-sm hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-200 flex items-center justify-center space-x-1 min-w-0",
6277
+ children: /* @__PURE__ */ jsx68("span", { children: "Next \u2192" })
6278
+ }
6279
+ )
6280
+ ] }),
6281
+ /* @__PURE__ */ jsxs42("div", { className: "hidden sm:flex items-center space-x-2", children: [
6282
+ /* @__PURE__ */ jsx68(
6283
+ "button",
6284
+ {
6285
+ onClick: () => handlePageChange(currentPage - 1),
6286
+ disabled: currentPage === 1 || localLoading,
6287
+ className: "px-3 py-1.5 text-sm font-medium rounded-lg border bg-white shadow-sm hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-200 flex items-center space-x-1",
6288
+ children: /* @__PURE__ */ jsx68("span", { children: "\u2190 Prev" })
6289
+ }
6290
+ ),
6291
+ /* @__PURE__ */ jsx68("span", { className: "px-3 py-1 text-sm font-medium text-gray-700", children: currentPage }),
6292
+ /* @__PURE__ */ jsx68(
6293
+ "button",
6294
+ {
6295
+ onClick: () => handlePageChange(currentPage + 1),
6296
+ disabled: currentPage >= rawMeta.pages || localLoading,
6297
+ className: "px-3 py-1.5 text-sm font-medium rounded-lg border bg-white shadow-sm hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-200 flex items-center space-x-1",
6298
+ children: /* @__PURE__ */ jsx68("span", { children: "Next \u2192" })
6299
+ }
6300
+ )
6301
+ ] })
6302
+ ] }),
6303
+ /* @__PURE__ */ jsx68(ResponsiveContainer, { width: "100%", height: "100%", children: chartType === "bar" ? /* @__PURE__ */ jsxs42(BarChart, { data, children: [
6304
+ /* @__PURE__ */ jsx68(CartesianGrid, { strokeDasharray: "3 3" }),
6305
+ /* @__PURE__ */ jsx68(
6306
+ XAxis,
6307
+ {
6308
+ dataKey: dataLabel,
6309
+ angle: -45,
6310
+ textAnchor: "end",
6311
+ interval: 0,
6312
+ tickFormatter: (value) => value?.toString().length > 10 ? `${value.toString().substring(0, 10)}...` : value,
6313
+ tick: {
6314
+ fontSize: 13,
6315
+ fontWeight: 500,
6316
+ fill: "#666",
6317
+ fontFamily: "inherit"
6318
+ },
6319
+ height: 80,
6320
+ className: "hidden sm:block"
6321
+ }
6322
+ ),
6323
+ /* @__PURE__ */ jsx68(
6324
+ YAxis,
6325
+ {
6326
+ tickFormatter: (value) => `${(value / 1e3).toFixed(0)}k`,
6327
+ tick: {
6328
+ fontSize: 12,
6329
+ fill: "#94a3b8",
6330
+ fontWeight: 500
6331
+ },
6332
+ domain: ["dataMin", "dataMax"],
6333
+ width: 60
6334
+ }
6335
+ ),
6336
+ /* @__PURE__ */ jsx68(Tooltip2, { formatter: (value) => [`${value}`, "Count"] }),
6337
+ /* @__PURE__ */ jsx68(
6338
+ Bar,
6339
+ {
6340
+ dataKey,
6341
+ radius: [6, 6, 0, 0],
6342
+ isAnimationActive: false
6343
+ }
6344
+ )
6345
+ ] }) : /* @__PURE__ */ jsxs42(AreaChart, { data, children: [
6346
+ /* @__PURE__ */ jsx68("defs", { children: /* @__PURE__ */ jsxs42("linearGradient", { id: "colorCount", x1: "0", y1: "0", x2: "0", y2: "1", children: [
6347
+ /* @__PURE__ */ jsx68("stop", { offset: "5%", stopColor: "#00695C", stopOpacity: 0.8 }),
6348
+ /* @__PURE__ */ jsx68("stop", { offset: "95%", stopColor: "#00695C", stopOpacity: 0 })
6349
+ ] }) }),
6350
+ /* @__PURE__ */ jsx68(CartesianGrid, { strokeDasharray: "3 3" }),
6351
+ /* @__PURE__ */ jsx68(
6352
+ XAxis,
6353
+ {
6354
+ dataKey: dataLabel,
6355
+ angle: 0,
6356
+ interval: 0,
6357
+ tick: {
6358
+ fontSize: 13,
6359
+ fontWeight: 500,
6360
+ fill: "#666",
6361
+ fontFamily: "inherit"
6362
+ }
6363
+ }
6364
+ ),
6365
+ /* @__PURE__ */ jsx68(
6366
+ YAxis,
6367
+ {
6368
+ tickFormatter: (value) => `${(value / 1e3).toFixed(0)}k`,
6369
+ tick: {
6370
+ fontSize: 12,
6371
+ fill: "#94a3b8",
6372
+ fontWeight: 500
6373
+ },
6374
+ domain: ["dataMin", "dataMax"],
6375
+ width: 60
6376
+ }
6377
+ ),
6378
+ /* @__PURE__ */ jsx68(Tooltip2, { formatter: (value) => `${value}k` }),
6379
+ /* @__PURE__ */ jsx68(
6380
+ Area,
6381
+ {
6382
+ type: "monotone",
6383
+ dataKey,
6384
+ stroke: "#00695C",
6385
+ fillOpacity: 1,
6386
+ fill: "url(#colorCount)",
6387
+ isAnimationActive: false
6388
+ }
6389
+ )
6390
+ ] }) })
6391
+ ]
6162
6392
  }
6163
6393
  ),
6164
- /* @__PURE__ */ jsx68("span", { className: "px-3 py-1 text-sm font-medium text-gray-700", children: currentPage }),
6165
- /* @__PURE__ */ jsx68(
6166
- "button",
6167
- {
6168
- onClick: () => handlePageChange(currentPage + 1),
6169
- disabled: currentPage >= rawMeta.pages || localLoading,
6170
- className: "px-3 py-1.5 text-sm font-medium rounded-lg border bg-white shadow-sm hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-200 flex items-center space-x-1",
6171
- children: /* @__PURE__ */ jsx68("span", { children: "Next \u2192" })
6172
- }
6173
- )
6174
- ] })
6175
- ] }),
6176
- /* @__PURE__ */ jsx68(ResponsiveContainer, { width: "100%", height: "100%", children: chartType === "bar" ? /* @__PURE__ */ jsxs42(BarChart, { data, children: [
6177
- /* @__PURE__ */ jsx68(CartesianGrid, { strokeDasharray: "3 3" }),
6178
- /* @__PURE__ */ jsx68(
6179
- XAxis,
6180
- {
6181
- dataKey: dataLabel,
6182
- angle: -45,
6183
- textAnchor: "end",
6184
- interval: 0,
6185
- tickFormatter: (value) => value?.toString().length > 10 ? `${value.toString().substring(0, 10)}...` : value,
6186
- tick: {
6187
- fontSize: 13,
6188
- fontWeight: 500,
6189
- fill: "#666",
6190
- fontFamily: "inherit"
6191
- },
6192
- height: 80,
6193
- className: "hidden sm:block"
6194
- }
6195
- ),
6196
- /* @__PURE__ */ jsx68(
6197
- YAxis,
6198
- {
6199
- tickFormatter: (value) => `${(value / 1e3).toFixed(0)}k`,
6200
- tick: {
6201
- fontSize: 12,
6202
- fill: "#94a3b8",
6203
- fontWeight: 500
6204
- },
6205
- domain: ["dataMin", "dataMax"],
6206
- width: 60
6207
- }
6208
- ),
6209
- /* @__PURE__ */ jsx68(Tooltip2, { formatter: (value) => [`${value}`, "Count"] }),
6210
- /* @__PURE__ */ jsx68(Legend, { verticalAlign: legendsPosition, align: "center" }),
6211
- /* @__PURE__ */ jsx68(
6212
- Bar,
6213
- {
6214
- dataKey,
6215
- radius: [6, 6, 0, 0],
6216
- isAnimationActive: false
6217
- }
6218
- )
6219
- ] }) : /* @__PURE__ */ jsxs42(AreaChart, { data, children: [
6220
- /* @__PURE__ */ jsx68("defs", { children: /* @__PURE__ */ jsxs42("linearGradient", { id: "colorCount", x1: "0", y1: "0", x2: "0", y2: "1", children: [
6221
- /* @__PURE__ */ jsx68("stop", { offset: "5%", stopColor: "#00695C", stopOpacity: 0.8 }),
6222
- /* @__PURE__ */ jsx68("stop", { offset: "95%", stopColor: "#00695C", stopOpacity: 0 })
6223
- ] }) }),
6224
- /* @__PURE__ */ jsx68(CartesianGrid, { strokeDasharray: "3 3" }),
6225
- /* @__PURE__ */ jsx68(
6226
- XAxis,
6227
- {
6228
- dataKey: dataLabel,
6229
- angle: 0,
6230
- interval: 0,
6231
- tick: {
6232
- fontSize: 13,
6233
- fontWeight: 500,
6234
- fill: "#666",
6235
- fontFamily: "inherit"
6236
- }
6237
- }
6238
- ),
6239
- /* @__PURE__ */ jsx68(
6240
- YAxis,
6241
- {
6242
- tickFormatter: (value) => `${(value / 1e3).toFixed(0)}k`,
6243
- tick: {
6244
- fontSize: 12,
6245
- fill: "#94a3b8",
6246
- fontWeight: 500
6247
- },
6248
- domain: ["dataMin", "dataMax"],
6249
- width: 60
6250
- }
6251
- ),
6252
- /* @__PURE__ */ jsx68(Tooltip2, { formatter: (value) => `${value}k` }),
6253
- /* @__PURE__ */ jsx68(
6254
- Area,
6255
- {
6256
- type: "monotone",
6257
- dataKey,
6258
- stroke: "#00695C",
6259
- fillOpacity: 1,
6260
- fill: "url(#colorCount)",
6261
- isAnimationActive: false
6262
- }
6263
- )
6264
- ] }) })
6265
- ] });
6394
+ showLegends && /* @__PURE__ */ jsx68("div", { className: isLegendRight ? "flex flex-col w-[30%] min-w-[180px] justify-center" : "w-full", children: renderLegends })
6395
+ ]
6396
+ }
6397
+ );
6266
6398
  };
6267
6399
  var BarChart_default = React14.memo(ChartComponent);
6268
6400
 
@@ -6277,8 +6409,8 @@ import {
6277
6409
  Tooltip as Tooltip3
6278
6410
  } from "recharts";
6279
6411
  import { jsx as jsx69, jsxs as jsxs43 } from "react/jsx-runtime";
6280
- var getRandomColor2 = () => {
6281
- const palette = [
6412
+ var getRandomColor = () => {
6413
+ const palette2 = [
6282
6414
  "#2563eb",
6283
6415
  "#1d4ed8",
6284
6416
  "#1e40af",
@@ -6340,7 +6472,7 @@ var getRandomColor2 = () => {
6340
6472
  "#155e75",
6341
6473
  "#164e63"
6342
6474
  ];
6343
- return palette[Math.floor(Math.random() * palette.length)];
6475
+ return palette2[Math.floor(Math.random() * palette2.length)];
6344
6476
  };
6345
6477
  var DonutChart = ({
6346
6478
  className,
@@ -6349,16 +6481,20 @@ var DonutChart = ({
6349
6481
  dataKey = "value",
6350
6482
  dataLabel = "name",
6351
6483
  apiUrl,
6484
+ source,
6485
+ legendPosition = "bottom",
6486
+ onLegendClick,
6352
6487
  ...props
6353
6488
  }) => {
6354
6489
  const showLegends = props.showLegends ?? true;
6355
6490
  const canvasMode = props.canvasMode;
6491
+ const useApi = source === "api" && !!apiUrl;
6356
6492
  const [rawData, setRawData] = useState16([]);
6357
6493
  const [localLoading, setLocalLoading] = useState16(false);
6358
- const effectiveData = apiUrl ? rawData : props.data || [];
6359
- const effectiveLoading = apiUrl ? localLoading : externalLoading;
6494
+ const effectiveData = useApi ? rawData : props.data || [];
6495
+ const effectiveLoading = useApi ? localLoading : externalLoading;
6360
6496
  useEffect30(() => {
6361
- if (!apiUrl) return;
6497
+ if (!useApi) return;
6362
6498
  let cancelled = false;
6363
6499
  const fetchData = async () => {
6364
6500
  try {
@@ -6392,12 +6528,12 @@ var DonutChart = ({
6392
6528
  return () => {
6393
6529
  cancelled = true;
6394
6530
  };
6395
- }, [apiUrl]);
6531
+ }, [useApi, apiUrl]);
6396
6532
  const data = useMemo12(() => {
6397
6533
  if (!Array.isArray(effectiveData) || effectiveData.length === 0) return [];
6398
6534
  return effectiveData.map((item) => ({
6399
6535
  ...item,
6400
- color: item.color || getRandomColor2(),
6536
+ color: item.color || getRandomColor(),
6401
6537
  [dataKey]: Number(item[dataKey] ?? 0),
6402
6538
  [dataLabel]: item[dataLabel] ?? "Unknown"
6403
6539
  }));
@@ -6445,42 +6581,59 @@ var DonutChart = ({
6445
6581
  }, []);
6446
6582
  const renderLegends = useMemo12(() => {
6447
6583
  if (!showLegends) return null;
6448
- return /* @__PURE__ */ jsx69("div", { className: "flex flex-wrap justify-center gap-2 mt-4 w-full max-w-4xl", children: chartData.map((d, index) => {
6449
- const actualValue = data.find(
6450
- (item) => item[dataLabel] === d[dataLabel]
6451
- )?.[dataKey] ?? d[dataKey];
6452
- const displayValue = actualValue >= 1e3 ? `${(actualValue / 1e3).toFixed(0)}k` : actualValue.toLocaleString();
6453
- return /* @__PURE__ */ jsxs43(
6454
- "div",
6455
- {
6456
- className: "flex items-center space-x-2 rounded-lg border border-gray-200/50 px-3 py-1.5 w-[48%] sm:w-[32%] md:w-auto bg-white/80 backdrop-blur-sm shadow-sm hover:shadow-md transition-all",
6457
- children: [
6458
- /* @__PURE__ */ jsx69(
6459
- "span",
6460
- {
6461
- className: "inline-block w-[12px] h-[12px] rounded-full shrink-0 border-2 border-white/50",
6462
- style: { backgroundColor: d.color }
6463
- }
6464
- ),
6465
- /* @__PURE__ */ jsxs43("div", { className: "min-w-0 flex-1", children: [
6466
- /* @__PURE__ */ jsx69("span", { className: "text-gray-900 text-[11px] md:text-[13px] font-semibold block truncate leading-tight", children: d[dataLabel] }),
6467
- /* @__PURE__ */ jsxs43("div", { className: "flex items-center gap-1 text-xs text-gray-600 font-medium", children: [
6468
- /* @__PURE__ */ jsx69("span", { children: displayValue }),
6469
- /* @__PURE__ */ jsxs43("span", { children: [
6470
- (actualValue / total * 100).toFixed(1),
6471
- "%"
6472
- ] }),
6473
- d.isBoosted && /* @__PURE__ */ jsx69("span", { className: "text-[9px] px-1 py-0.5 bg-blue-100 text-blue-700 rounded-full", children: "min" })
6474
- ] })
6475
- ] })
6476
- ]
6477
- },
6478
- `legend-${index}`
6479
- );
6480
- }) });
6481
- }, [chartData, data, dataLabel, dataKey, total, showLegends]);
6584
+ const isLegendRight2 = !forceMobile && legendPosition === "right";
6585
+ return /* @__PURE__ */ jsx69(
6586
+ "div",
6587
+ {
6588
+ className: isLegendRight2 ? "flex flex-col gap-2 w-full min-w-0 justify-start" : "flex flex-wrap justify-center gap-2 mt-4 w-full max-w-4xl",
6589
+ children: chartData.map((d, index) => {
6590
+ const actualValue = data.find(
6591
+ (item) => item[dataLabel] === d[dataLabel]
6592
+ )?.[dataKey] ?? d[dataKey];
6593
+ const displayValue = actualValue >= 1e3 ? `${(actualValue / 1e3).toFixed(0)}k` : actualValue.toLocaleString();
6594
+ const payload = {
6595
+ name: d[dataLabel],
6596
+ value: actualValue,
6597
+ [dataLabel]: d[dataLabel],
6598
+ [dataKey]: actualValue
6599
+ };
6600
+ return /* @__PURE__ */ jsxs43(
6601
+ "div",
6602
+ {
6603
+ role: onLegendClick ? "button" : void 0,
6604
+ tabIndex: onLegendClick ? 0 : void 0,
6605
+ onClick: onLegendClick ? () => onLegendClick(payload) : void 0,
6606
+ onKeyDown: onLegendClick ? (e) => e.key === "Enter" && onLegendClick(payload) : void 0,
6607
+ className: `flex items-center space-x-2 rounded-lg border border-gray-200/50 px-3 py-1.5 w-[48%] sm:w-[32%] md:w-auto bg-white/80 backdrop-blur-sm shadow-sm hover:shadow-md transition-all ${onLegendClick ? "cursor-pointer" : ""}`,
6608
+ children: [
6609
+ /* @__PURE__ */ jsx69(
6610
+ "span",
6611
+ {
6612
+ className: "inline-block w-[12px] h-[12px] rounded-full shrink-0 border-2 border-white/50",
6613
+ style: { backgroundColor: d.color }
6614
+ }
6615
+ ),
6616
+ /* @__PURE__ */ jsxs43("div", { className: "min-w-0 flex-1", children: [
6617
+ /* @__PURE__ */ jsx69("span", { className: "text-gray-900 text-[11px] md:text-[13px] font-semibold block truncate leading-tight", children: d[dataLabel] }),
6618
+ /* @__PURE__ */ jsxs43("div", { className: "flex items-center gap-1 text-xs text-gray-600 font-medium", children: [
6619
+ /* @__PURE__ */ jsx69("span", { children: displayValue }),
6620
+ /* @__PURE__ */ jsxs43("span", { children: [
6621
+ (actualValue / total * 100).toFixed(1),
6622
+ "%"
6623
+ ] }),
6624
+ d.isBoosted && /* @__PURE__ */ jsx69("span", { className: "text-[9px] px-1 py-0.5 bg-blue-100 text-blue-700 rounded-full", children: "min" })
6625
+ ] })
6626
+ ] })
6627
+ ]
6628
+ },
6629
+ `legend-${index}`
6630
+ );
6631
+ })
6632
+ }
6633
+ );
6634
+ }, [chartData, data, dataLabel, dataKey, total, showLegends, onLegendClick, legendPosition, forceMobile]);
6482
6635
  if (!mounted) return null;
6483
- if (effectiveLoading || data.length === 0) {
6636
+ if (effectiveLoading) {
6484
6637
  return /* @__PURE__ */ jsxs43(
6485
6638
  "div",
6486
6639
  {
@@ -6510,66 +6663,90 @@ var DonutChart = ({
6510
6663
  }
6511
6664
  );
6512
6665
  }
6666
+ if (data.length === 0) {
6667
+ return /* @__PURE__ */ jsx69(
6668
+ "div",
6669
+ {
6670
+ className: `relative flex flex-col items-center justify-center w-full h-[300px] md:h-[400px] bg-gradient-to-br from-gray-50 to-gray-100 rounded-xl p-6 ${className}`,
6671
+ style,
6672
+ children: /* @__PURE__ */ jsx69("div", { className: "text-center", children: /* @__PURE__ */ jsx69("div", { className: "inline-flex items-center space-x-2 bg-white/80 px-6 py-3 rounded-xl backdrop-blur-sm border border-gray-200 shadow-lg", children: /* @__PURE__ */ jsx69("span", { className: "text-sm font-medium text-gray-600", children: "No data" }) }) })
6673
+ }
6674
+ );
6675
+ }
6513
6676
  const { inner, outer } = getDynamicRadius();
6514
6677
  const innerRadius = inner;
6515
6678
  const outerRadius = outer;
6516
- return /* @__PURE__ */ jsxs43("div", { className: `relative flex flex-col items-center ${className}`, style, children: [
6517
- /* @__PURE__ */ jsxs43("div", { className: "relative w-full md:w-[75%] h-[280px] md:h-[380px] flex items-center justify-center mb-2", children: [
6518
- /* @__PURE__ */ jsx69(ResponsiveContainer2, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs43(PieChart, { children: [
6519
- /* @__PURE__ */ jsx69(
6520
- Pie,
6679
+ const isLegendRight = !forceMobile && legendPosition === "right";
6680
+ return /* @__PURE__ */ jsxs43(
6681
+ "div",
6682
+ {
6683
+ className: `relative flex ${isLegendRight ? "flex-row items-stretch gap-4" : "flex-col items-center"} ${className}`,
6684
+ style,
6685
+ children: [
6686
+ /* @__PURE__ */ jsxs43(
6687
+ "div",
6521
6688
  {
6522
- data: chartData,
6523
- cx: "50%",
6524
- cy: "50%",
6525
- innerRadius,
6526
- outerRadius,
6527
- dataKey,
6528
- labelLine: false,
6529
- isAnimationActive: true,
6530
- animationDuration: 800,
6531
- minAngle: 3,
6532
- children: chartData.map((entry, index) => /* @__PURE__ */ jsx69(
6533
- Cell,
6534
- {
6535
- fill: entry.color,
6536
- stroke: entry.isBoosted ? "#fff" : "transparent",
6537
- strokeWidth: entry.isBoosted ? 1.5 : 0
6538
- },
6539
- `cell-${index}`
6540
- ))
6689
+ className: `relative flex items-center justify-center ${isLegendRight ? "flex-[2] min-w-0 max-w-[70%]" : "w-full md:w-[75%]"} h-[280px] md:h-[380px] ${isLegendRight ? "" : "mb-2"}`,
6690
+ children: [
6691
+ /* @__PURE__ */ jsx69(ResponsiveContainer2, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs43(PieChart, { children: [
6692
+ /* @__PURE__ */ jsx69(
6693
+ Pie,
6694
+ {
6695
+ data: chartData,
6696
+ cx: "50%",
6697
+ cy: "50%",
6698
+ innerRadius,
6699
+ outerRadius,
6700
+ dataKey,
6701
+ labelLine: false,
6702
+ isAnimationActive: true,
6703
+ animationDuration: 800,
6704
+ minAngle: 3,
6705
+ children: chartData.map((entry, index) => /* @__PURE__ */ jsx69(
6706
+ Cell,
6707
+ {
6708
+ fill: entry.color,
6709
+ stroke: entry.isBoosted ? "#fff" : "transparent",
6710
+ strokeWidth: entry.isBoosted ? 1.5 : 0
6711
+ },
6712
+ `cell-${index}`
6713
+ ))
6714
+ }
6715
+ ),
6716
+ /* @__PURE__ */ jsx69(
6717
+ Tooltip3,
6718
+ {
6719
+ formatter: (value, name, payload) => {
6720
+ const label = payload && payload.payload ? payload.payload[dataLabel] : name;
6721
+ const actualItem = data.find((item) => item[dataLabel] === label);
6722
+ const actualValue = actualItem ? actualItem[dataKey] : value;
6723
+ const valueFormatted = actualValue >= 1e3 ? `${(actualValue / 1e3).toFixed(0)}k` : actualValue.toLocaleString();
6724
+ const percentage = (actualValue / total * 100).toFixed(1);
6725
+ return [
6726
+ `${label}: ${valueFormatted} (${percentage}%)`
6727
+ ];
6728
+ },
6729
+ contentStyle: {
6730
+ backgroundColor: "white",
6731
+ border: "1px solid #e5e7eb",
6732
+ borderRadius: "8px",
6733
+ fontSize: "13px",
6734
+ padding: "8px 12px"
6735
+ }
6736
+ }
6737
+ )
6738
+ ] }) }),
6739
+ total > 0 && /* @__PURE__ */ jsx69("div", { className: `absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 text-center pointer-events-none ${forceMobile ? "text-xl px-2" : "text-3xl px-4"} font-bold bg-white/90 backdrop-blur-sm rounded-full py-1 shadow-lg`, children: /* @__PURE__ */ jsxs43("div", { className: "text-[#1f2937] leading-tight", children: [
6740
+ formattedTotal,
6741
+ /* @__PURE__ */ jsx69("span", { className: "text-sm md:text-base font-normal text-gray-600 block md:inline-block md:ml-1", children: "total" })
6742
+ ] }) })
6743
+ ]
6541
6744
  }
6542
6745
  ),
6543
- /* @__PURE__ */ jsx69(
6544
- Tooltip3,
6545
- {
6546
- formatter: (value, name, payload) => {
6547
- const label = payload && payload.payload ? payload.payload[dataLabel] : name;
6548
- const actualItem = data.find((item) => item[dataLabel] === label);
6549
- const actualValue = actualItem ? actualItem[dataKey] : value;
6550
- const valueFormatted = actualValue >= 1e3 ? `${(actualValue / 1e3).toFixed(0)}k` : actualValue.toLocaleString();
6551
- const percentage = (actualValue / total * 100).toFixed(1);
6552
- return [
6553
- `${label}: ${valueFormatted} (${percentage}%)`
6554
- ];
6555
- },
6556
- contentStyle: {
6557
- backgroundColor: "white",
6558
- border: "1px solid #e5e7eb",
6559
- borderRadius: "8px",
6560
- fontSize: "13px",
6561
- padding: "8px 12px"
6562
- }
6563
- }
6564
- )
6565
- ] }) }),
6566
- total > 0 && /* @__PURE__ */ jsx69("div", { className: `absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 text-center pointer-events-none ${forceMobile ? "text-xl px-2" : "text-3xl px-4"} font-bold bg-white/90 backdrop-blur-sm rounded-full py-1 shadow-lg`, children: /* @__PURE__ */ jsxs43("div", { className: "text-[#1f2937] leading-tight", children: [
6567
- formattedTotal,
6568
- /* @__PURE__ */ jsx69("span", { className: "text-sm md:text-base font-normal text-gray-600 block md:inline-block md:ml-1", children: "total" })
6569
- ] }) })
6570
- ] }),
6571
- renderLegends
6572
- ] });
6746
+ showLegends && /* @__PURE__ */ jsx69("div", { className: isLegendRight ? "flex flex-col w-[30%] min-w-[180px] justify-center" : "w-full", children: renderLegends })
6747
+ ]
6748
+ }
6749
+ );
6573
6750
  };
6574
6751
  var PieChart_default = React15.memo(DonutChart);
6575
6752