@algorithm-shift/design-system 1.3.120 → 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.js CHANGED
@@ -3012,13 +3012,61 @@ function resolveDate(option, customOption) {
3012
3012
  switch (option) {
3013
3013
  case "today":
3014
3014
  return /* @__PURE__ */ new Date();
3015
- case "custom":
3016
- return customOption ? new Date(customOption) : void 0;
3015
+ case "custom": {
3016
+ if (!customOption) return void 0;
3017
+ const d = new Date(customOption);
3018
+ return !isNaN(d.getTime()) ? d : void 0;
3019
+ }
3017
3020
  case "none":
3018
3021
  default:
3019
3022
  return void 0;
3020
3023
  }
3021
3024
  }
3025
+ function resolveDefaultDate(option, customOption) {
3026
+ if (!option || option === "none") return void 0;
3027
+ const now = /* @__PURE__ */ new Date();
3028
+ switch (option) {
3029
+ case "today":
3030
+ return new Date(now);
3031
+ case "currentPlus1Week": {
3032
+ const d = new Date(now);
3033
+ d.setDate(d.getDate() + 7);
3034
+ return d;
3035
+ }
3036
+ case "currentPlus1Year": {
3037
+ const d = new Date(now);
3038
+ d.setFullYear(d.getFullYear() + 1);
3039
+ return d;
3040
+ }
3041
+ case "previousDay": {
3042
+ const d = new Date(now);
3043
+ d.setDate(d.getDate() - 1);
3044
+ return d;
3045
+ }
3046
+ case "previous1Week": {
3047
+ const d = new Date(now);
3048
+ d.setDate(d.getDate() - 7);
3049
+ return d;
3050
+ }
3051
+ case "previous1Month": {
3052
+ const d = new Date(now);
3053
+ d.setMonth(d.getMonth() - 1);
3054
+ return d;
3055
+ }
3056
+ case "previous1Year": {
3057
+ const d = new Date(now);
3058
+ d.setFullYear(d.getFullYear() - 1);
3059
+ return d;
3060
+ }
3061
+ case "custom": {
3062
+ if (!customOption) return void 0;
3063
+ const d = new Date(customOption);
3064
+ return !isNaN(d.getTime()) ? d : void 0;
3065
+ }
3066
+ default:
3067
+ return void 0;
3068
+ }
3069
+ }
3022
3070
  function DateTimePicker({
3023
3071
  className,
3024
3072
  style,
@@ -3036,6 +3084,8 @@ function DateTimePicker({
3036
3084
  const customMinimumDate = props.customMinimumDate ?? "";
3037
3085
  const maximumDate = props.maximumDate ?? "none";
3038
3086
  const customMaximumDate = props.customMaximumDate ?? "";
3087
+ const defaultDateValue = props.defaultDateValue ?? "none";
3088
+ const customDefaultDate = props.customDefaultDate ?? "";
3039
3089
  const isEditable = props.isEditable ?? true;
3040
3090
  const isDisabled = props.isDisabled ?? false;
3041
3091
  const isReadonly = props.isReadonly ?? false;
@@ -3043,9 +3093,11 @@ function DateTimePicker({
3043
3093
  const minDate = resolveDate(minimumDate, customMinimumDate);
3044
3094
  const maxDate = resolveDate(maximumDate, customMaximumDate);
3045
3095
  const [date, setDate] = React8.useState(() => {
3046
- if (!props.value) return void 0;
3047
- const d = new Date(props.value);
3048
- return isNaN(d.getTime()) ? void 0 : d;
3096
+ if (props.value) {
3097
+ const d = new Date(props.value);
3098
+ if (!isNaN(d.getTime())) return d;
3099
+ }
3100
+ return resolveDefaultDate(defaultDateValue, customDefaultDate);
3049
3101
  });
3050
3102
  const initialHours = date ? date.getHours() : 0;
3051
3103
  const initialMinutes = date ? date.getMinutes() : 0;
@@ -3060,26 +3112,6 @@ function DateTimePicker({
3060
3112
  React8.useEffect(() => {
3061
3113
  setAmPm(hours >= 12 ? "PM" : "AM");
3062
3114
  }, [hours]);
3063
- React8.useEffect(() => {
3064
- if (!props.value) {
3065
- setDate(void 0);
3066
- return;
3067
- }
3068
- const d = new Date(props.value);
3069
- if (!isNaN(d.getTime())) {
3070
- setDate(d);
3071
- setHours(d.getHours());
3072
- setMinutes(d.getMinutes());
3073
- }
3074
- }, [props.value]);
3075
- const [year, setYear] = React8.useState(date ? date.getFullYear() : (/* @__PURE__ */ new Date()).getFullYear());
3076
- React8.useEffect(() => {
3077
- if (!date) return;
3078
- const newDate = new Date(date);
3079
- newDate.setFullYear(year);
3080
- setDate(newDate);
3081
- emitChange(newDate);
3082
- }, [year]);
3083
3115
  const emitChange = (nextDate) => {
3084
3116
  if (!props.onChange) return;
3085
3117
  let valueString = "";
@@ -3101,6 +3133,36 @@ function DateTimePicker({
3101
3133
  };
3102
3134
  props.onChange(event, props.name || "");
3103
3135
  };
3136
+ React8.useEffect(() => {
3137
+ if (!props.value) {
3138
+ const defaultDate = resolveDefaultDate(defaultDateValue, customDefaultDate);
3139
+ setDate(defaultDate);
3140
+ if (defaultDate) {
3141
+ setYear(defaultDate.getFullYear());
3142
+ setHours(defaultDate.getHours());
3143
+ setMinutes(defaultDate.getMinutes());
3144
+ emitChange(defaultDate);
3145
+ } else {
3146
+ setHours(0);
3147
+ setMinutes(0);
3148
+ }
3149
+ return;
3150
+ }
3151
+ const d = new Date(props.value);
3152
+ if (!isNaN(d.getTime())) {
3153
+ setDate(d);
3154
+ setHours(d.getHours());
3155
+ setMinutes(d.getMinutes());
3156
+ }
3157
+ }, [props.value, defaultDateValue, customDefaultDate]);
3158
+ const [year, setYear] = React8.useState(date ? date.getFullYear() : (/* @__PURE__ */ new Date()).getFullYear());
3159
+ React8.useEffect(() => {
3160
+ if (!date) return;
3161
+ const newDate = new Date(date);
3162
+ newDate.setFullYear(year);
3163
+ setDate(newDate);
3164
+ emitChange(newDate);
3165
+ }, [year]);
3104
3166
  const updateDateTime = (nextBaseDate, h = hours, m = minutes) => {
3105
3167
  if (!nextBaseDate) {
3106
3168
  setDate(void 0);
@@ -3331,7 +3393,7 @@ function DateTimePicker({
3331
3393
  name: props.name,
3332
3394
  autoComplete: isAutocomplete ? "on" : "off",
3333
3395
  readOnly: isReadonly,
3334
- value: !date ? "" : mode === "date" ? (0, import_date_fns.format)(date, "yyyy-MM-dd") : mode === "time" ? (0, import_date_fns.format)(date, "HH:mm:ss") : date.toISOString(),
3396
+ value: !date || isNaN(date.getTime()) ? "" : mode === "date" ? (0, import_date_fns.format)(date, "yyyy-MM-dd") : mode === "time" ? (0, import_date_fns.format)(date, "HH:mm:ss") : date.toISOString(),
3335
3397
  onChange: () => {
3336
3398
  }
3337
3399
  }
@@ -6044,51 +6106,48 @@ var import_react36 = __toESM(require("react"));
6044
6106
  var import_axios4 = __toESM(require("axios"));
6045
6107
  var import_recharts = require("recharts");
6046
6108
  var import_jsx_runtime68 = require("react/jsx-runtime");
6047
- var getRandomColor = () => {
6048
- const palette = [
6049
- "#2563eb",
6050
- "#1d4ed8",
6051
- "#1e40af",
6052
- "#1e3a8a",
6053
- "#1e293b",
6054
- "#10b981",
6055
- "#059669",
6056
- "#047857",
6057
- "#065f46",
6058
- "#022c22",
6059
- "#f59e0b",
6060
- "#d97706",
6061
- "#b45309",
6062
- "#92400e",
6063
- "#422006",
6064
- "#ef4444",
6065
- "#dc2626",
6066
- "#b91c1c",
6067
- "#991b1b",
6068
- "#7f1d1d",
6069
- "#8b5cf6",
6070
- "#7c3aed",
6071
- "#6d28d9",
6072
- "#5b21b6",
6073
- "#4c1d95",
6074
- "#14b8a6",
6075
- "#0d9488",
6076
- "#0f766e",
6077
- "#115e59",
6078
- "#134e4a",
6079
- "#ec4899",
6080
- "#db2777",
6081
- "#be185d",
6082
- "#9d174d",
6083
- "#831843",
6084
- "#22c55e",
6085
- "#16a34a",
6086
- "#15803d",
6087
- "#166534",
6088
- "#14532d"
6089
- ];
6090
- return palette[Math.floor(Math.random() * palette.length)];
6091
- };
6109
+ var palette = [
6110
+ "#2563eb",
6111
+ "#1d4ed8",
6112
+ "#1e40af",
6113
+ "#1e3a8a",
6114
+ "#1e293b",
6115
+ "#10b981",
6116
+ "#059669",
6117
+ "#047857",
6118
+ "#065f46",
6119
+ "#022c22",
6120
+ "#f59e0b",
6121
+ "#d97706",
6122
+ "#b45309",
6123
+ "#92400e",
6124
+ "#422006",
6125
+ "#ef4444",
6126
+ "#dc2626",
6127
+ "#b91c1c",
6128
+ "#991b1b",
6129
+ "#7f1d1d",
6130
+ "#8b5cf6",
6131
+ "#7c3aed",
6132
+ "#6d28d9",
6133
+ "#5b21b6",
6134
+ "#4c1d95",
6135
+ "#14b8a6",
6136
+ "#0d9488",
6137
+ "#0f766e",
6138
+ "#115e59",
6139
+ "#134e4a",
6140
+ "#ec4899",
6141
+ "#db2777",
6142
+ "#be185d",
6143
+ "#9d174d",
6144
+ "#831843",
6145
+ "#22c55e",
6146
+ "#16a34a",
6147
+ "#15803d",
6148
+ "#166534",
6149
+ "#14532d"
6150
+ ];
6092
6151
  var ChartComponent = ({
6093
6152
  className,
6094
6153
  style,
@@ -6096,25 +6155,30 @@ var ChartComponent = ({
6096
6155
  dataKey,
6097
6156
  dataLabel,
6098
6157
  apiUrl,
6158
+ source,
6099
6159
  isPaginationEnabled,
6100
6160
  limit = 10,
6101
6161
  canvasMode,
6162
+ showLegends = true,
6163
+ legendPosition = "bottom",
6164
+ onLegendClick,
6102
6165
  ...props
6103
6166
  }) => {
6167
+ const useApi = source === "api" && !!apiUrl;
6104
6168
  const [rawData, setRawData] = (0, import_react36.useState)([]);
6105
6169
  const [rawMeta, setRawMeta] = (0, import_react36.useState)(null);
6106
6170
  const [localLoading, setLocalLoading] = (0, import_react36.useState)(false);
6107
6171
  const [currentPage, setCurrentPage] = (0, import_react36.useState)(1);
6108
- const effectiveData = apiUrl ? rawData : props.data || [];
6109
- const effectiveLoading = apiUrl ? localLoading : externalLoading;
6172
+ const effectiveData = useApi ? rawData : props.data || [];
6173
+ const effectiveLoading = useApi ? localLoading : externalLoading;
6110
6174
  (0, import_react36.useEffect)(() => {
6111
- if (apiUrl) {
6175
+ if (useApi) {
6112
6176
  setCurrentPage(1);
6113
6177
  }
6114
- }, [apiUrl]);
6178
+ }, [useApi]);
6115
6179
  const fetchData = (0, import_react36.useCallback)(async (page) => {
6116
6180
  if (!apiUrl) return;
6117
- const cancelled = false;
6181
+ let cancelled = false;
6118
6182
  try {
6119
6183
  setLocalLoading(true);
6120
6184
  const params = new URLSearchParams({
@@ -6150,9 +6214,9 @@ var ChartComponent = ({
6150
6214
  }
6151
6215
  }, [apiUrl, limit]);
6152
6216
  (0, import_react36.useEffect)(() => {
6153
- if (!apiUrl) return;
6217
+ if (!useApi) return;
6154
6218
  fetchData(currentPage);
6155
- }, [apiUrl, currentPage, fetchData]);
6219
+ }, [useApi, currentPage, fetchData]);
6156
6220
  const handlePageChange = (newPage) => {
6157
6221
  if (rawMeta && (newPage < 1 || newPage > rawMeta.pages)) return;
6158
6222
  setCurrentPage(newPage);
@@ -6161,15 +6225,59 @@ var ChartComponent = ({
6161
6225
  if (!Array.isArray(effectiveData) || effectiveData.length === 0 || !dataKey || !dataLabel) {
6162
6226
  return [];
6163
6227
  }
6164
- return effectiveData.map((item) => ({
6228
+ return effectiveData.map((item, index) => ({
6165
6229
  ...item,
6166
6230
  [dataKey]: Number(item[dataKey] || 0),
6167
- fill: getRandomColor()
6231
+ fill: item.fill || palette[index % palette.length]
6168
6232
  }));
6169
6233
  }, [effectiveData, dataKey, dataLabel]);
6170
6234
  const chartType = props.chartType || "bar";
6171
- const legendsPosition = ["middle", "bottom"].includes(props.legendsPosition) ? props.legendsPosition : "top";
6172
- if (effectiveLoading || data.length === 0) {
6235
+ const forceMobile = canvasMode === "mobile" || canvasMode === "tablet";
6236
+ const renderLegends = (0, import_react36.useMemo)(() => {
6237
+ if (!showLegends || !dataKey || !dataLabel) return null;
6238
+ const isLegendRight2 = !forceMobile && legendPosition === "right";
6239
+ return /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
6240
+ "div",
6241
+ {
6242
+ 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",
6243
+ children: data.map((d, index) => {
6244
+ const value = d[dataKey] ?? 0;
6245
+ const displayValue = value >= 1e3 ? `${(value / 1e3).toFixed(0)}k` : value.toLocaleString();
6246
+ const payload = {
6247
+ name: d[dataLabel],
6248
+ value,
6249
+ [dataLabel]: d[dataLabel],
6250
+ [dataKey]: value
6251
+ };
6252
+ return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
6253
+ "div",
6254
+ {
6255
+ role: onLegendClick ? "button" : void 0,
6256
+ tabIndex: onLegendClick ? 0 : void 0,
6257
+ onClick: onLegendClick ? () => onLegendClick(payload) : void 0,
6258
+ onKeyDown: onLegendClick ? (e) => e.key === "Enter" && onLegendClick(payload) : void 0,
6259
+ 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" : ""}`,
6260
+ children: [
6261
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
6262
+ "span",
6263
+ {
6264
+ className: "inline-block w-[12px] h-[12px] rounded-full shrink-0 border-2 border-white/50",
6265
+ style: { backgroundColor: d.fill }
6266
+ }
6267
+ ),
6268
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "min-w-0 flex-1", children: [
6269
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "text-gray-900 text-[11px] md:text-[13px] font-semibold block truncate leading-tight capitalize", children: d[dataLabel] }),
6270
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "text-xs text-gray-600 font-medium", children: displayValue })
6271
+ ] })
6272
+ ]
6273
+ },
6274
+ `legend-${index}`
6275
+ );
6276
+ })
6277
+ }
6278
+ );
6279
+ }, [data, dataLabel, dataKey, showLegends, onLegendClick, legendPosition, forceMobile]);
6280
+ if (effectiveLoading) {
6173
6281
  return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
6174
6282
  "div",
6175
6283
  {
@@ -6200,141 +6308,167 @@ var ChartComponent = ({
6200
6308
  }
6201
6309
  );
6202
6310
  }
6203
- return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: `${className} h-[450px]`, style, children: [
6204
- isPaginationEnabled && rawMeta && /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "flex items-center justify-between mb-4 px-2", children: [
6205
- /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "flex items-center space-x-2 sm:hidden w-full justify-center", children: [
6206
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
6207
- "button",
6208
- {
6209
- onClick: () => handlePageChange(currentPage - 1),
6210
- disabled: currentPage === 1 || localLoading,
6211
- 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",
6212
- children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { children: "\u2190 Prev" })
6213
- }
6214
- ),
6215
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "px-2 py-2 text-xs font-semibold text-gray-700 min-w-[36px] text-center flex-shrink-0", children: currentPage }),
6216
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
6217
- "button",
6218
- {
6219
- onClick: () => handlePageChange(currentPage + 1),
6220
- disabled: currentPage >= rawMeta.pages || localLoading,
6221
- 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",
6222
- children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { children: "Next \u2192" })
6223
- }
6224
- )
6225
- ] }),
6226
- /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "flex items-center space-x-2 hidden sm:flex", children: [
6227
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
6228
- "button",
6311
+ if (data.length === 0) {
6312
+ return /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
6313
+ "div",
6314
+ {
6315
+ 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}`,
6316
+ style,
6317
+ children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "text-center", children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("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__ */ (0, import_jsx_runtime68.jsx)("span", { className: "text-sm font-medium text-gray-600", children: "No data" }) }) })
6318
+ }
6319
+ );
6320
+ }
6321
+ const isLegendRight = !forceMobile && legendPosition === "right";
6322
+ return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
6323
+ "div",
6324
+ {
6325
+ className: `relative flex ${isLegendRight ? "flex-row items-stretch gap-4" : "flex-col items-center"} ${className}`,
6326
+ style,
6327
+ children: [
6328
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
6329
+ "div",
6229
6330
  {
6230
- onClick: () => handlePageChange(currentPage - 1),
6231
- disabled: currentPage === 1 || localLoading,
6232
- 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",
6233
- children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { children: "\u2190 Prev" })
6331
+ 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"}`,
6332
+ children: [
6333
+ isPaginationEnabled && rawMeta && /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "flex items-center justify-between mb-4 px-2", children: [
6334
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "flex items-center space-x-2 sm:hidden w-full justify-center", children: [
6335
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
6336
+ "button",
6337
+ {
6338
+ onClick: () => handlePageChange(currentPage - 1),
6339
+ disabled: currentPage === 1 || localLoading,
6340
+ 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",
6341
+ children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { children: "\u2190 Prev" })
6342
+ }
6343
+ ),
6344
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "px-2 py-2 text-xs font-semibold text-gray-700 min-w-[36px] text-center flex-shrink-0", children: currentPage }),
6345
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
6346
+ "button",
6347
+ {
6348
+ onClick: () => handlePageChange(currentPage + 1),
6349
+ disabled: currentPage >= rawMeta.pages || localLoading,
6350
+ 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",
6351
+ children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { children: "Next \u2192" })
6352
+ }
6353
+ )
6354
+ ] }),
6355
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "hidden sm:flex items-center space-x-2", children: [
6356
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
6357
+ "button",
6358
+ {
6359
+ onClick: () => handlePageChange(currentPage - 1),
6360
+ disabled: currentPage === 1 || localLoading,
6361
+ 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",
6362
+ children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { children: "\u2190 Prev" })
6363
+ }
6364
+ ),
6365
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "px-3 py-1 text-sm font-medium text-gray-700", children: currentPage }),
6366
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
6367
+ "button",
6368
+ {
6369
+ onClick: () => handlePageChange(currentPage + 1),
6370
+ disabled: currentPage >= rawMeta.pages || localLoading,
6371
+ 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",
6372
+ children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { children: "Next \u2192" })
6373
+ }
6374
+ )
6375
+ ] })
6376
+ ] }),
6377
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_recharts.ResponsiveContainer, { width: "100%", height: "100%", children: chartType === "bar" ? /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_recharts.BarChart, { data, children: [
6378
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_recharts.CartesianGrid, { strokeDasharray: "3 3" }),
6379
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
6380
+ import_recharts.XAxis,
6381
+ {
6382
+ dataKey: dataLabel,
6383
+ angle: -45,
6384
+ textAnchor: "end",
6385
+ interval: 0,
6386
+ tickFormatter: (value) => value?.toString().length > 10 ? `${value.toString().substring(0, 10)}...` : value,
6387
+ tick: {
6388
+ fontSize: 13,
6389
+ fontWeight: 500,
6390
+ fill: "#666",
6391
+ fontFamily: "inherit"
6392
+ },
6393
+ height: 80,
6394
+ className: "hidden sm:block"
6395
+ }
6396
+ ),
6397
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
6398
+ import_recharts.YAxis,
6399
+ {
6400
+ tickFormatter: (value) => `${(value / 1e3).toFixed(0)}k`,
6401
+ tick: {
6402
+ fontSize: 12,
6403
+ fill: "#94a3b8",
6404
+ fontWeight: 500
6405
+ },
6406
+ domain: ["dataMin", "dataMax"],
6407
+ width: 60
6408
+ }
6409
+ ),
6410
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_recharts.Tooltip, { formatter: (value) => [`${value}`, "Count"] }),
6411
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
6412
+ import_recharts.Bar,
6413
+ {
6414
+ dataKey,
6415
+ radius: [6, 6, 0, 0],
6416
+ isAnimationActive: false
6417
+ }
6418
+ )
6419
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_recharts.AreaChart, { data, children: [
6420
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("linearGradient", { id: "colorCount", x1: "0", y1: "0", x2: "0", y2: "1", children: [
6421
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("stop", { offset: "5%", stopColor: "#00695C", stopOpacity: 0.8 }),
6422
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("stop", { offset: "95%", stopColor: "#00695C", stopOpacity: 0 })
6423
+ ] }) }),
6424
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_recharts.CartesianGrid, { strokeDasharray: "3 3" }),
6425
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
6426
+ import_recharts.XAxis,
6427
+ {
6428
+ dataKey: dataLabel,
6429
+ angle: 0,
6430
+ interval: 0,
6431
+ tick: {
6432
+ fontSize: 13,
6433
+ fontWeight: 500,
6434
+ fill: "#666",
6435
+ fontFamily: "inherit"
6436
+ }
6437
+ }
6438
+ ),
6439
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
6440
+ import_recharts.YAxis,
6441
+ {
6442
+ tickFormatter: (value) => `${(value / 1e3).toFixed(0)}k`,
6443
+ tick: {
6444
+ fontSize: 12,
6445
+ fill: "#94a3b8",
6446
+ fontWeight: 500
6447
+ },
6448
+ domain: ["dataMin", "dataMax"],
6449
+ width: 60
6450
+ }
6451
+ ),
6452
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_recharts.Tooltip, { formatter: (value) => `${value}k` }),
6453
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
6454
+ import_recharts.Area,
6455
+ {
6456
+ type: "monotone",
6457
+ dataKey,
6458
+ stroke: "#00695C",
6459
+ fillOpacity: 1,
6460
+ fill: "url(#colorCount)",
6461
+ isAnimationActive: false
6462
+ }
6463
+ )
6464
+ ] }) })
6465
+ ]
6234
6466
  }
6235
6467
  ),
6236
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "px-3 py-1 text-sm font-medium text-gray-700", children: currentPage }),
6237
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
6238
- "button",
6239
- {
6240
- onClick: () => handlePageChange(currentPage + 1),
6241
- disabled: currentPage >= rawMeta.pages || localLoading,
6242
- 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",
6243
- children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { children: "Next \u2192" })
6244
- }
6245
- )
6246
- ] })
6247
- ] }),
6248
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_recharts.ResponsiveContainer, { width: "100%", height: "100%", children: chartType === "bar" ? /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_recharts.BarChart, { data, children: [
6249
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_recharts.CartesianGrid, { strokeDasharray: "3 3" }),
6250
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
6251
- import_recharts.XAxis,
6252
- {
6253
- dataKey: dataLabel,
6254
- angle: -45,
6255
- textAnchor: "end",
6256
- interval: 0,
6257
- tickFormatter: (value) => value?.toString().length > 10 ? `${value.toString().substring(0, 10)}...` : value,
6258
- tick: {
6259
- fontSize: 13,
6260
- fontWeight: 500,
6261
- fill: "#666",
6262
- fontFamily: "inherit"
6263
- },
6264
- height: 80,
6265
- className: "hidden sm:block"
6266
- }
6267
- ),
6268
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
6269
- import_recharts.YAxis,
6270
- {
6271
- tickFormatter: (value) => `${(value / 1e3).toFixed(0)}k`,
6272
- tick: {
6273
- fontSize: 12,
6274
- fill: "#94a3b8",
6275
- fontWeight: 500
6276
- },
6277
- domain: ["dataMin", "dataMax"],
6278
- width: 60
6279
- }
6280
- ),
6281
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_recharts.Tooltip, { formatter: (value) => [`${value}`, "Count"] }),
6282
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_recharts.Legend, { verticalAlign: legendsPosition, align: "center" }),
6283
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
6284
- import_recharts.Bar,
6285
- {
6286
- dataKey,
6287
- radius: [6, 6, 0, 0],
6288
- isAnimationActive: false
6289
- }
6290
- )
6291
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_recharts.AreaChart, { data, children: [
6292
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("linearGradient", { id: "colorCount", x1: "0", y1: "0", x2: "0", y2: "1", children: [
6293
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("stop", { offset: "5%", stopColor: "#00695C", stopOpacity: 0.8 }),
6294
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("stop", { offset: "95%", stopColor: "#00695C", stopOpacity: 0 })
6295
- ] }) }),
6296
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_recharts.CartesianGrid, { strokeDasharray: "3 3" }),
6297
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
6298
- import_recharts.XAxis,
6299
- {
6300
- dataKey: dataLabel,
6301
- angle: 0,
6302
- interval: 0,
6303
- tick: {
6304
- fontSize: 13,
6305
- fontWeight: 500,
6306
- fill: "#666",
6307
- fontFamily: "inherit"
6308
- }
6309
- }
6310
- ),
6311
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
6312
- import_recharts.YAxis,
6313
- {
6314
- tickFormatter: (value) => `${(value / 1e3).toFixed(0)}k`,
6315
- tick: {
6316
- fontSize: 12,
6317
- fill: "#94a3b8",
6318
- fontWeight: 500
6319
- },
6320
- domain: ["dataMin", "dataMax"],
6321
- width: 60
6322
- }
6323
- ),
6324
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_recharts.Tooltip, { formatter: (value) => `${value}k` }),
6325
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
6326
- import_recharts.Area,
6327
- {
6328
- type: "monotone",
6329
- dataKey,
6330
- stroke: "#00695C",
6331
- fillOpacity: 1,
6332
- fill: "url(#colorCount)",
6333
- isAnimationActive: false
6334
- }
6335
- )
6336
- ] }) })
6337
- ] });
6468
+ showLegends && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: isLegendRight ? "flex flex-col w-[30%] min-w-[180px] justify-center" : "w-full", children: renderLegends })
6469
+ ]
6470
+ }
6471
+ );
6338
6472
  };
6339
6473
  var BarChart_default = import_react36.default.memo(ChartComponent);
6340
6474
 
@@ -6343,8 +6477,8 @@ var import_react37 = __toESM(require("react"));
6343
6477
  var import_axios5 = __toESM(require("axios"));
6344
6478
  var import_recharts2 = require("recharts");
6345
6479
  var import_jsx_runtime69 = require("react/jsx-runtime");
6346
- var getRandomColor2 = () => {
6347
- const palette = [
6480
+ var getRandomColor = () => {
6481
+ const palette2 = [
6348
6482
  "#2563eb",
6349
6483
  "#1d4ed8",
6350
6484
  "#1e40af",
@@ -6406,7 +6540,7 @@ var getRandomColor2 = () => {
6406
6540
  "#155e75",
6407
6541
  "#164e63"
6408
6542
  ];
6409
- return palette[Math.floor(Math.random() * palette.length)];
6543
+ return palette2[Math.floor(Math.random() * palette2.length)];
6410
6544
  };
6411
6545
  var DonutChart = ({
6412
6546
  className,
@@ -6415,16 +6549,20 @@ var DonutChart = ({
6415
6549
  dataKey = "value",
6416
6550
  dataLabel = "name",
6417
6551
  apiUrl,
6552
+ source,
6553
+ legendPosition = "bottom",
6554
+ onLegendClick,
6418
6555
  ...props
6419
6556
  }) => {
6420
6557
  const showLegends = props.showLegends ?? true;
6421
6558
  const canvasMode = props.canvasMode;
6559
+ const useApi = source === "api" && !!apiUrl;
6422
6560
  const [rawData, setRawData] = (0, import_react37.useState)([]);
6423
6561
  const [localLoading, setLocalLoading] = (0, import_react37.useState)(false);
6424
- const effectiveData = apiUrl ? rawData : props.data || [];
6425
- const effectiveLoading = apiUrl ? localLoading : externalLoading;
6562
+ const effectiveData = useApi ? rawData : props.data || [];
6563
+ const effectiveLoading = useApi ? localLoading : externalLoading;
6426
6564
  (0, import_react37.useEffect)(() => {
6427
- if (!apiUrl) return;
6565
+ if (!useApi) return;
6428
6566
  let cancelled = false;
6429
6567
  const fetchData = async () => {
6430
6568
  try {
@@ -6458,12 +6596,12 @@ var DonutChart = ({
6458
6596
  return () => {
6459
6597
  cancelled = true;
6460
6598
  };
6461
- }, [apiUrl]);
6599
+ }, [useApi, apiUrl]);
6462
6600
  const data = (0, import_react37.useMemo)(() => {
6463
6601
  if (!Array.isArray(effectiveData) || effectiveData.length === 0) return [];
6464
6602
  return effectiveData.map((item) => ({
6465
6603
  ...item,
6466
- color: item.color || getRandomColor2(),
6604
+ color: item.color || getRandomColor(),
6467
6605
  [dataKey]: Number(item[dataKey] ?? 0),
6468
6606
  [dataLabel]: item[dataLabel] ?? "Unknown"
6469
6607
  }));
@@ -6511,42 +6649,59 @@ var DonutChart = ({
6511
6649
  }, []);
6512
6650
  const renderLegends = (0, import_react37.useMemo)(() => {
6513
6651
  if (!showLegends) return null;
6514
- return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "flex flex-wrap justify-center gap-2 mt-4 w-full max-w-4xl", children: chartData.map((d, index) => {
6515
- const actualValue = data.find(
6516
- (item) => item[dataLabel] === d[dataLabel]
6517
- )?.[dataKey] ?? d[dataKey];
6518
- const displayValue = actualValue >= 1e3 ? `${(actualValue / 1e3).toFixed(0)}k` : actualValue.toLocaleString();
6519
- return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
6520
- "div",
6521
- {
6522
- 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",
6523
- children: [
6524
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
6525
- "span",
6526
- {
6527
- className: "inline-block w-[12px] h-[12px] rounded-full shrink-0 border-2 border-white/50",
6528
- style: { backgroundColor: d.color }
6529
- }
6530
- ),
6531
- /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { className: "min-w-0 flex-1", children: [
6532
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "text-gray-900 text-[11px] md:text-[13px] font-semibold block truncate leading-tight", children: d[dataLabel] }),
6533
- /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { className: "flex items-center gap-1 text-xs text-gray-600 font-medium", children: [
6534
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { children: displayValue }),
6535
- /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("span", { children: [
6536
- (actualValue / total * 100).toFixed(1),
6537
- "%"
6538
- ] }),
6539
- d.isBoosted && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "text-[9px] px-1 py-0.5 bg-blue-100 text-blue-700 rounded-full", children: "min" })
6540
- ] })
6541
- ] })
6542
- ]
6543
- },
6544
- `legend-${index}`
6545
- );
6546
- }) });
6547
- }, [chartData, data, dataLabel, dataKey, total, showLegends]);
6652
+ const isLegendRight2 = !forceMobile && legendPosition === "right";
6653
+ return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
6654
+ "div",
6655
+ {
6656
+ 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",
6657
+ children: chartData.map((d, index) => {
6658
+ const actualValue = data.find(
6659
+ (item) => item[dataLabel] === d[dataLabel]
6660
+ )?.[dataKey] ?? d[dataKey];
6661
+ const displayValue = actualValue >= 1e3 ? `${(actualValue / 1e3).toFixed(0)}k` : actualValue.toLocaleString();
6662
+ const payload = {
6663
+ name: d[dataLabel],
6664
+ value: actualValue,
6665
+ [dataLabel]: d[dataLabel],
6666
+ [dataKey]: actualValue
6667
+ };
6668
+ return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
6669
+ "div",
6670
+ {
6671
+ role: onLegendClick ? "button" : void 0,
6672
+ tabIndex: onLegendClick ? 0 : void 0,
6673
+ onClick: onLegendClick ? () => onLegendClick(payload) : void 0,
6674
+ onKeyDown: onLegendClick ? (e) => e.key === "Enter" && onLegendClick(payload) : void 0,
6675
+ 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" : ""}`,
6676
+ children: [
6677
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
6678
+ "span",
6679
+ {
6680
+ className: "inline-block w-[12px] h-[12px] rounded-full shrink-0 border-2 border-white/50",
6681
+ style: { backgroundColor: d.color }
6682
+ }
6683
+ ),
6684
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { className: "min-w-0 flex-1", children: [
6685
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "text-gray-900 text-[11px] md:text-[13px] font-semibold block truncate leading-tight", children: d[dataLabel] }),
6686
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { className: "flex items-center gap-1 text-xs text-gray-600 font-medium", children: [
6687
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { children: displayValue }),
6688
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("span", { children: [
6689
+ (actualValue / total * 100).toFixed(1),
6690
+ "%"
6691
+ ] }),
6692
+ d.isBoosted && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "text-[9px] px-1 py-0.5 bg-blue-100 text-blue-700 rounded-full", children: "min" })
6693
+ ] })
6694
+ ] })
6695
+ ]
6696
+ },
6697
+ `legend-${index}`
6698
+ );
6699
+ })
6700
+ }
6701
+ );
6702
+ }, [chartData, data, dataLabel, dataKey, total, showLegends, onLegendClick, legendPosition, forceMobile]);
6548
6703
  if (!mounted) return null;
6549
- if (effectiveLoading || data.length === 0) {
6704
+ if (effectiveLoading) {
6550
6705
  return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
6551
6706
  "div",
6552
6707
  {
@@ -6576,66 +6731,90 @@ var DonutChart = ({
6576
6731
  }
6577
6732
  );
6578
6733
  }
6734
+ if (data.length === 0) {
6735
+ return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
6736
+ "div",
6737
+ {
6738
+ 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}`,
6739
+ style,
6740
+ children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "text-center", children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("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__ */ (0, import_jsx_runtime69.jsx)("span", { className: "text-sm font-medium text-gray-600", children: "No data" }) }) })
6741
+ }
6742
+ );
6743
+ }
6579
6744
  const { inner, outer } = getDynamicRadius();
6580
6745
  const innerRadius = inner;
6581
6746
  const outerRadius = outer;
6582
- return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { className: `relative flex flex-col items-center ${className}`, style, children: [
6583
- /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { className: "relative w-full md:w-[75%] h-[280px] md:h-[380px] flex items-center justify-center mb-2", children: [
6584
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_recharts2.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(import_recharts2.PieChart, { children: [
6585
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
6586
- import_recharts2.Pie,
6747
+ const isLegendRight = !forceMobile && legendPosition === "right";
6748
+ return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
6749
+ "div",
6750
+ {
6751
+ className: `relative flex ${isLegendRight ? "flex-row items-stretch gap-4" : "flex-col items-center"} ${className}`,
6752
+ style,
6753
+ children: [
6754
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
6755
+ "div",
6587
6756
  {
6588
- data: chartData,
6589
- cx: "50%",
6590
- cy: "50%",
6591
- innerRadius,
6592
- outerRadius,
6593
- dataKey,
6594
- labelLine: false,
6595
- isAnimationActive: true,
6596
- animationDuration: 800,
6597
- minAngle: 3,
6598
- children: chartData.map((entry, index) => /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
6599
- import_recharts2.Cell,
6600
- {
6601
- fill: entry.color,
6602
- stroke: entry.isBoosted ? "#fff" : "transparent",
6603
- strokeWidth: entry.isBoosted ? 1.5 : 0
6604
- },
6605
- `cell-${index}`
6606
- ))
6757
+ 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"}`,
6758
+ children: [
6759
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_recharts2.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(import_recharts2.PieChart, { children: [
6760
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
6761
+ import_recharts2.Pie,
6762
+ {
6763
+ data: chartData,
6764
+ cx: "50%",
6765
+ cy: "50%",
6766
+ innerRadius,
6767
+ outerRadius,
6768
+ dataKey,
6769
+ labelLine: false,
6770
+ isAnimationActive: true,
6771
+ animationDuration: 800,
6772
+ minAngle: 3,
6773
+ children: chartData.map((entry, index) => /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
6774
+ import_recharts2.Cell,
6775
+ {
6776
+ fill: entry.color,
6777
+ stroke: entry.isBoosted ? "#fff" : "transparent",
6778
+ strokeWidth: entry.isBoosted ? 1.5 : 0
6779
+ },
6780
+ `cell-${index}`
6781
+ ))
6782
+ }
6783
+ ),
6784
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
6785
+ import_recharts2.Tooltip,
6786
+ {
6787
+ formatter: (value, name, payload) => {
6788
+ const label = payload && payload.payload ? payload.payload[dataLabel] : name;
6789
+ const actualItem = data.find((item) => item[dataLabel] === label);
6790
+ const actualValue = actualItem ? actualItem[dataKey] : value;
6791
+ const valueFormatted = actualValue >= 1e3 ? `${(actualValue / 1e3).toFixed(0)}k` : actualValue.toLocaleString();
6792
+ const percentage = (actualValue / total * 100).toFixed(1);
6793
+ return [
6794
+ `${label}: ${valueFormatted} (${percentage}%)`
6795
+ ];
6796
+ },
6797
+ contentStyle: {
6798
+ backgroundColor: "white",
6799
+ border: "1px solid #e5e7eb",
6800
+ borderRadius: "8px",
6801
+ fontSize: "13px",
6802
+ padding: "8px 12px"
6803
+ }
6804
+ }
6805
+ )
6806
+ ] }) }),
6807
+ total > 0 && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("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__ */ (0, import_jsx_runtime69.jsxs)("div", { className: "text-[#1f2937] leading-tight", children: [
6808
+ formattedTotal,
6809
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "text-sm md:text-base font-normal text-gray-600 block md:inline-block md:ml-1", children: "total" })
6810
+ ] }) })
6811
+ ]
6607
6812
  }
6608
6813
  ),
6609
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
6610
- import_recharts2.Tooltip,
6611
- {
6612
- formatter: (value, name, payload) => {
6613
- const label = payload && payload.payload ? payload.payload[dataLabel] : name;
6614
- const actualItem = data.find((item) => item[dataLabel] === label);
6615
- const actualValue = actualItem ? actualItem[dataKey] : value;
6616
- const valueFormatted = actualValue >= 1e3 ? `${(actualValue / 1e3).toFixed(0)}k` : actualValue.toLocaleString();
6617
- const percentage = (actualValue / total * 100).toFixed(1);
6618
- return [
6619
- `${label}: ${valueFormatted} (${percentage}%)`
6620
- ];
6621
- },
6622
- contentStyle: {
6623
- backgroundColor: "white",
6624
- border: "1px solid #e5e7eb",
6625
- borderRadius: "8px",
6626
- fontSize: "13px",
6627
- padding: "8px 12px"
6628
- }
6629
- }
6630
- )
6631
- ] }) }),
6632
- total > 0 && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("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__ */ (0, import_jsx_runtime69.jsxs)("div", { className: "text-[#1f2937] leading-tight", children: [
6633
- formattedTotal,
6634
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "text-sm md:text-base font-normal text-gray-600 block md:inline-block md:ml-1", children: "total" })
6635
- ] }) })
6636
- ] }),
6637
- renderLegends
6638
- ] });
6814
+ showLegends && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: isLegendRight ? "flex flex-col w-[30%] min-w-[180px] justify-center" : "w-full", children: renderLegends })
6815
+ ]
6816
+ }
6817
+ );
6639
6818
  };
6640
6819
  var PieChart_default = import_react37.default.memo(DonutChart);
6641
6820