@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.css +21 -0
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +12 -3
- package/dist/index.d.ts +12 -3
- package/dist/index.js +495 -317
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +496 -319
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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
|
-
|
|
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 (
|
|
3047
|
-
|
|
3048
|
-
|
|
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
|
}
|
|
@@ -3468,7 +3530,6 @@ function LazyMultiSelectDropdown({
|
|
|
3468
3530
|
onChange,
|
|
3469
3531
|
placeholder,
|
|
3470
3532
|
className,
|
|
3471
|
-
id,
|
|
3472
3533
|
disabled,
|
|
3473
3534
|
readOnly,
|
|
3474
3535
|
source,
|
|
@@ -3534,10 +3595,10 @@ function LazyMultiSelectDropdown({
|
|
|
3534
3595
|
}
|
|
3535
3596
|
};
|
|
3536
3597
|
const selectedOptions = (0, import_react30.useMemo)(() => {
|
|
3537
|
-
return normalizedValue.map((
|
|
3538
|
-
const fromLazy = lazyOptions.find((opt) => opt.value ===
|
|
3598
|
+
return normalizedValue.map((id) => {
|
|
3599
|
+
const fromLazy = lazyOptions.find((opt) => opt.value === id);
|
|
3539
3600
|
if (fromLazy) return fromLazy;
|
|
3540
|
-
return { value:
|
|
3601
|
+
return { value: id, label: id };
|
|
3541
3602
|
});
|
|
3542
3603
|
}, [normalizedValue, lazyOptions]);
|
|
3543
3604
|
(0, import_react30.useEffect)(() => {
|
|
@@ -3572,11 +3633,11 @@ function LazyMultiSelectDropdown({
|
|
|
3572
3633
|
} else {
|
|
3573
3634
|
updated = ensureUnique([...normalizedValue, val]);
|
|
3574
3635
|
}
|
|
3575
|
-
onChange?.(convertOutput(updated),
|
|
3636
|
+
onChange?.(convertOutput(updated), props.name ?? "");
|
|
3576
3637
|
};
|
|
3577
3638
|
const removeTag = (val) => {
|
|
3578
3639
|
const updated = normalizedValue.filter((v) => v !== val);
|
|
3579
|
-
onChange?.(convertOutput(updated),
|
|
3640
|
+
onChange?.(convertOutput(updated), props.name ?? "");
|
|
3580
3641
|
};
|
|
3581
3642
|
const handleFocus = () => {
|
|
3582
3643
|
if (!disabled) {
|
|
@@ -6045,51 +6106,48 @@ var import_react36 = __toESM(require("react"));
|
|
|
6045
6106
|
var import_axios4 = __toESM(require("axios"));
|
|
6046
6107
|
var import_recharts = require("recharts");
|
|
6047
6108
|
var import_jsx_runtime68 = require("react/jsx-runtime");
|
|
6048
|
-
var
|
|
6049
|
-
|
|
6050
|
-
|
|
6051
|
-
|
|
6052
|
-
|
|
6053
|
-
|
|
6054
|
-
|
|
6055
|
-
|
|
6056
|
-
|
|
6057
|
-
|
|
6058
|
-
|
|
6059
|
-
|
|
6060
|
-
|
|
6061
|
-
|
|
6062
|
-
|
|
6063
|
-
|
|
6064
|
-
|
|
6065
|
-
|
|
6066
|
-
|
|
6067
|
-
|
|
6068
|
-
|
|
6069
|
-
|
|
6070
|
-
|
|
6071
|
-
|
|
6072
|
-
|
|
6073
|
-
|
|
6074
|
-
|
|
6075
|
-
|
|
6076
|
-
|
|
6077
|
-
|
|
6078
|
-
|
|
6079
|
-
|
|
6080
|
-
|
|
6081
|
-
|
|
6082
|
-
|
|
6083
|
-
|
|
6084
|
-
|
|
6085
|
-
|
|
6086
|
-
|
|
6087
|
-
|
|
6088
|
-
|
|
6089
|
-
|
|
6090
|
-
];
|
|
6091
|
-
return palette[Math.floor(Math.random() * palette.length)];
|
|
6092
|
-
};
|
|
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
|
+
];
|
|
6093
6151
|
var ChartComponent = ({
|
|
6094
6152
|
className,
|
|
6095
6153
|
style,
|
|
@@ -6097,25 +6155,30 @@ var ChartComponent = ({
|
|
|
6097
6155
|
dataKey,
|
|
6098
6156
|
dataLabel,
|
|
6099
6157
|
apiUrl,
|
|
6158
|
+
source,
|
|
6100
6159
|
isPaginationEnabled,
|
|
6101
6160
|
limit = 10,
|
|
6102
6161
|
canvasMode,
|
|
6162
|
+
showLegends = true,
|
|
6163
|
+
legendPosition = "bottom",
|
|
6164
|
+
onLegendClick,
|
|
6103
6165
|
...props
|
|
6104
6166
|
}) => {
|
|
6167
|
+
const useApi = source === "api" && !!apiUrl;
|
|
6105
6168
|
const [rawData, setRawData] = (0, import_react36.useState)([]);
|
|
6106
6169
|
const [rawMeta, setRawMeta] = (0, import_react36.useState)(null);
|
|
6107
6170
|
const [localLoading, setLocalLoading] = (0, import_react36.useState)(false);
|
|
6108
6171
|
const [currentPage, setCurrentPage] = (0, import_react36.useState)(1);
|
|
6109
|
-
const effectiveData =
|
|
6110
|
-
const effectiveLoading =
|
|
6172
|
+
const effectiveData = useApi ? rawData : props.data || [];
|
|
6173
|
+
const effectiveLoading = useApi ? localLoading : externalLoading;
|
|
6111
6174
|
(0, import_react36.useEffect)(() => {
|
|
6112
|
-
if (
|
|
6175
|
+
if (useApi) {
|
|
6113
6176
|
setCurrentPage(1);
|
|
6114
6177
|
}
|
|
6115
|
-
}, [
|
|
6178
|
+
}, [useApi]);
|
|
6116
6179
|
const fetchData = (0, import_react36.useCallback)(async (page) => {
|
|
6117
6180
|
if (!apiUrl) return;
|
|
6118
|
-
|
|
6181
|
+
let cancelled = false;
|
|
6119
6182
|
try {
|
|
6120
6183
|
setLocalLoading(true);
|
|
6121
6184
|
const params = new URLSearchParams({
|
|
@@ -6151,9 +6214,9 @@ var ChartComponent = ({
|
|
|
6151
6214
|
}
|
|
6152
6215
|
}, [apiUrl, limit]);
|
|
6153
6216
|
(0, import_react36.useEffect)(() => {
|
|
6154
|
-
if (!
|
|
6217
|
+
if (!useApi) return;
|
|
6155
6218
|
fetchData(currentPage);
|
|
6156
|
-
}, [
|
|
6219
|
+
}, [useApi, currentPage, fetchData]);
|
|
6157
6220
|
const handlePageChange = (newPage) => {
|
|
6158
6221
|
if (rawMeta && (newPage < 1 || newPage > rawMeta.pages)) return;
|
|
6159
6222
|
setCurrentPage(newPage);
|
|
@@ -6162,15 +6225,59 @@ var ChartComponent = ({
|
|
|
6162
6225
|
if (!Array.isArray(effectiveData) || effectiveData.length === 0 || !dataKey || !dataLabel) {
|
|
6163
6226
|
return [];
|
|
6164
6227
|
}
|
|
6165
|
-
return effectiveData.map((item) => ({
|
|
6228
|
+
return effectiveData.map((item, index) => ({
|
|
6166
6229
|
...item,
|
|
6167
6230
|
[dataKey]: Number(item[dataKey] || 0),
|
|
6168
|
-
fill:
|
|
6231
|
+
fill: item.fill || palette[index % palette.length]
|
|
6169
6232
|
}));
|
|
6170
6233
|
}, [effectiveData, dataKey, dataLabel]);
|
|
6171
6234
|
const chartType = props.chartType || "bar";
|
|
6172
|
-
const
|
|
6173
|
-
|
|
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) {
|
|
6174
6281
|
return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
|
|
6175
6282
|
"div",
|
|
6176
6283
|
{
|
|
@@ -6201,141 +6308,167 @@ var ChartComponent = ({
|
|
|
6201
6308
|
}
|
|
6202
6309
|
);
|
|
6203
6310
|
}
|
|
6204
|
-
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
|
|
6208
|
-
|
|
6209
|
-
|
|
6210
|
-
|
|
6211
|
-
|
|
6212
|
-
|
|
6213
|
-
|
|
6214
|
-
|
|
6215
|
-
|
|
6216
|
-
|
|
6217
|
-
|
|
6218
|
-
|
|
6219
|
-
|
|
6220
|
-
|
|
6221
|
-
|
|
6222
|
-
|
|
6223
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { children: "Next \u2192" })
|
|
6224
|
-
}
|
|
6225
|
-
)
|
|
6226
|
-
] }),
|
|
6227
|
-
/* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "flex items-center space-x-2 hidden sm:flex", children: [
|
|
6228
|
-
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
6229
|
-
"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",
|
|
6230
6330
|
{
|
|
6231
|
-
|
|
6232
|
-
|
|
6233
|
-
|
|
6234
|
-
|
|
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
|
+
]
|
|
6235
6466
|
}
|
|
6236
6467
|
),
|
|
6237
|
-
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)("
|
|
6238
|
-
|
|
6239
|
-
|
|
6240
|
-
|
|
6241
|
-
onClick: () => handlePageChange(currentPage + 1),
|
|
6242
|
-
disabled: currentPage >= rawMeta.pages || localLoading,
|
|
6243
|
-
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",
|
|
6244
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { children: "Next \u2192" })
|
|
6245
|
-
}
|
|
6246
|
-
)
|
|
6247
|
-
] })
|
|
6248
|
-
] }),
|
|
6249
|
-
/* @__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: [
|
|
6250
|
-
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_recharts.CartesianGrid, { strokeDasharray: "3 3" }),
|
|
6251
|
-
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
6252
|
-
import_recharts.XAxis,
|
|
6253
|
-
{
|
|
6254
|
-
dataKey: dataLabel,
|
|
6255
|
-
angle: -45,
|
|
6256
|
-
textAnchor: "end",
|
|
6257
|
-
interval: 0,
|
|
6258
|
-
tickFormatter: (value) => value?.toString().length > 10 ? `${value.toString().substring(0, 10)}...` : value,
|
|
6259
|
-
tick: {
|
|
6260
|
-
fontSize: 13,
|
|
6261
|
-
fontWeight: 500,
|
|
6262
|
-
fill: "#666",
|
|
6263
|
-
fontFamily: "inherit"
|
|
6264
|
-
},
|
|
6265
|
-
height: 80,
|
|
6266
|
-
className: "hidden sm:block"
|
|
6267
|
-
}
|
|
6268
|
-
),
|
|
6269
|
-
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
6270
|
-
import_recharts.YAxis,
|
|
6271
|
-
{
|
|
6272
|
-
tickFormatter: (value) => `${(value / 1e3).toFixed(0)}k`,
|
|
6273
|
-
tick: {
|
|
6274
|
-
fontSize: 12,
|
|
6275
|
-
fill: "#94a3b8",
|
|
6276
|
-
fontWeight: 500
|
|
6277
|
-
},
|
|
6278
|
-
domain: ["dataMin", "dataMax"],
|
|
6279
|
-
width: 60
|
|
6280
|
-
}
|
|
6281
|
-
),
|
|
6282
|
-
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_recharts.Tooltip, { formatter: (value) => [`${value}`, "Count"] }),
|
|
6283
|
-
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_recharts.Legend, { verticalAlign: legendsPosition, align: "center" }),
|
|
6284
|
-
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
6285
|
-
import_recharts.Bar,
|
|
6286
|
-
{
|
|
6287
|
-
dataKey,
|
|
6288
|
-
radius: [6, 6, 0, 0],
|
|
6289
|
-
isAnimationActive: false
|
|
6290
|
-
}
|
|
6291
|
-
)
|
|
6292
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_recharts.AreaChart, { data, children: [
|
|
6293
|
-
/* @__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: [
|
|
6294
|
-
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)("stop", { offset: "5%", stopColor: "#00695C", stopOpacity: 0.8 }),
|
|
6295
|
-
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)("stop", { offset: "95%", stopColor: "#00695C", stopOpacity: 0 })
|
|
6296
|
-
] }) }),
|
|
6297
|
-
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_recharts.CartesianGrid, { strokeDasharray: "3 3" }),
|
|
6298
|
-
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
6299
|
-
import_recharts.XAxis,
|
|
6300
|
-
{
|
|
6301
|
-
dataKey: dataLabel,
|
|
6302
|
-
angle: 0,
|
|
6303
|
-
interval: 0,
|
|
6304
|
-
tick: {
|
|
6305
|
-
fontSize: 13,
|
|
6306
|
-
fontWeight: 500,
|
|
6307
|
-
fill: "#666",
|
|
6308
|
-
fontFamily: "inherit"
|
|
6309
|
-
}
|
|
6310
|
-
}
|
|
6311
|
-
),
|
|
6312
|
-
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
6313
|
-
import_recharts.YAxis,
|
|
6314
|
-
{
|
|
6315
|
-
tickFormatter: (value) => `${(value / 1e3).toFixed(0)}k`,
|
|
6316
|
-
tick: {
|
|
6317
|
-
fontSize: 12,
|
|
6318
|
-
fill: "#94a3b8",
|
|
6319
|
-
fontWeight: 500
|
|
6320
|
-
},
|
|
6321
|
-
domain: ["dataMin", "dataMax"],
|
|
6322
|
-
width: 60
|
|
6323
|
-
}
|
|
6324
|
-
),
|
|
6325
|
-
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_recharts.Tooltip, { formatter: (value) => `${value}k` }),
|
|
6326
|
-
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
6327
|
-
import_recharts.Area,
|
|
6328
|
-
{
|
|
6329
|
-
type: "monotone",
|
|
6330
|
-
dataKey,
|
|
6331
|
-
stroke: "#00695C",
|
|
6332
|
-
fillOpacity: 1,
|
|
6333
|
-
fill: "url(#colorCount)",
|
|
6334
|
-
isAnimationActive: false
|
|
6335
|
-
}
|
|
6336
|
-
)
|
|
6337
|
-
] }) })
|
|
6338
|
-
] });
|
|
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
|
+
);
|
|
6339
6472
|
};
|
|
6340
6473
|
var BarChart_default = import_react36.default.memo(ChartComponent);
|
|
6341
6474
|
|
|
@@ -6344,8 +6477,8 @@ var import_react37 = __toESM(require("react"));
|
|
|
6344
6477
|
var import_axios5 = __toESM(require("axios"));
|
|
6345
6478
|
var import_recharts2 = require("recharts");
|
|
6346
6479
|
var import_jsx_runtime69 = require("react/jsx-runtime");
|
|
6347
|
-
var
|
|
6348
|
-
const
|
|
6480
|
+
var getRandomColor = () => {
|
|
6481
|
+
const palette2 = [
|
|
6349
6482
|
"#2563eb",
|
|
6350
6483
|
"#1d4ed8",
|
|
6351
6484
|
"#1e40af",
|
|
@@ -6407,7 +6540,7 @@ var getRandomColor2 = () => {
|
|
|
6407
6540
|
"#155e75",
|
|
6408
6541
|
"#164e63"
|
|
6409
6542
|
];
|
|
6410
|
-
return
|
|
6543
|
+
return palette2[Math.floor(Math.random() * palette2.length)];
|
|
6411
6544
|
};
|
|
6412
6545
|
var DonutChart = ({
|
|
6413
6546
|
className,
|
|
@@ -6416,16 +6549,20 @@ var DonutChart = ({
|
|
|
6416
6549
|
dataKey = "value",
|
|
6417
6550
|
dataLabel = "name",
|
|
6418
6551
|
apiUrl,
|
|
6552
|
+
source,
|
|
6553
|
+
legendPosition = "bottom",
|
|
6554
|
+
onLegendClick,
|
|
6419
6555
|
...props
|
|
6420
6556
|
}) => {
|
|
6421
6557
|
const showLegends = props.showLegends ?? true;
|
|
6422
6558
|
const canvasMode = props.canvasMode;
|
|
6559
|
+
const useApi = source === "api" && !!apiUrl;
|
|
6423
6560
|
const [rawData, setRawData] = (0, import_react37.useState)([]);
|
|
6424
6561
|
const [localLoading, setLocalLoading] = (0, import_react37.useState)(false);
|
|
6425
|
-
const effectiveData =
|
|
6426
|
-
const effectiveLoading =
|
|
6562
|
+
const effectiveData = useApi ? rawData : props.data || [];
|
|
6563
|
+
const effectiveLoading = useApi ? localLoading : externalLoading;
|
|
6427
6564
|
(0, import_react37.useEffect)(() => {
|
|
6428
|
-
if (!
|
|
6565
|
+
if (!useApi) return;
|
|
6429
6566
|
let cancelled = false;
|
|
6430
6567
|
const fetchData = async () => {
|
|
6431
6568
|
try {
|
|
@@ -6459,12 +6596,12 @@ var DonutChart = ({
|
|
|
6459
6596
|
return () => {
|
|
6460
6597
|
cancelled = true;
|
|
6461
6598
|
};
|
|
6462
|
-
}, [apiUrl]);
|
|
6599
|
+
}, [useApi, apiUrl]);
|
|
6463
6600
|
const data = (0, import_react37.useMemo)(() => {
|
|
6464
6601
|
if (!Array.isArray(effectiveData) || effectiveData.length === 0) return [];
|
|
6465
6602
|
return effectiveData.map((item) => ({
|
|
6466
6603
|
...item,
|
|
6467
|
-
color: item.color ||
|
|
6604
|
+
color: item.color || getRandomColor(),
|
|
6468
6605
|
[dataKey]: Number(item[dataKey] ?? 0),
|
|
6469
6606
|
[dataLabel]: item[dataLabel] ?? "Unknown"
|
|
6470
6607
|
}));
|
|
@@ -6512,42 +6649,59 @@ var DonutChart = ({
|
|
|
6512
6649
|
}, []);
|
|
6513
6650
|
const renderLegends = (0, import_react37.useMemo)(() => {
|
|
6514
6651
|
if (!showLegends) return null;
|
|
6515
|
-
|
|
6516
|
-
|
|
6517
|
-
|
|
6518
|
-
|
|
6519
|
-
|
|
6520
|
-
|
|
6521
|
-
|
|
6522
|
-
|
|
6523
|
-
|
|
6524
|
-
|
|
6525
|
-
|
|
6526
|
-
|
|
6527
|
-
|
|
6528
|
-
|
|
6529
|
-
|
|
6530
|
-
|
|
6531
|
-
|
|
6532
|
-
|
|
6533
|
-
|
|
6534
|
-
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
|
|
6541
|
-
|
|
6542
|
-
|
|
6543
|
-
|
|
6544
|
-
|
|
6545
|
-
|
|
6546
|
-
|
|
6547
|
-
|
|
6548
|
-
|
|
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]);
|
|
6549
6703
|
if (!mounted) return null;
|
|
6550
|
-
if (effectiveLoading
|
|
6704
|
+
if (effectiveLoading) {
|
|
6551
6705
|
return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
|
|
6552
6706
|
"div",
|
|
6553
6707
|
{
|
|
@@ -6577,66 +6731,90 @@ var DonutChart = ({
|
|
|
6577
6731
|
}
|
|
6578
6732
|
);
|
|
6579
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
|
+
}
|
|
6580
6744
|
const { inner, outer } = getDynamicRadius();
|
|
6581
6745
|
const innerRadius = inner;
|
|
6582
6746
|
const outerRadius = outer;
|
|
6583
|
-
|
|
6584
|
-
|
|
6585
|
-
|
|
6586
|
-
|
|
6587
|
-
|
|
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",
|
|
6588
6756
|
{
|
|
6589
|
-
|
|
6590
|
-
|
|
6591
|
-
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
|
|
6595
|
-
|
|
6596
|
-
|
|
6597
|
-
|
|
6598
|
-
|
|
6599
|
-
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
|
|
6603
|
-
|
|
6604
|
-
|
|
6605
|
-
|
|
6606
|
-
|
|
6607
|
-
|
|
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
|
+
]
|
|
6608
6812
|
}
|
|
6609
6813
|
),
|
|
6610
|
-
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
6611
|
-
|
|
6612
|
-
|
|
6613
|
-
|
|
6614
|
-
const label = payload && payload.payload ? payload.payload[dataLabel] : name;
|
|
6615
|
-
const actualItem = data.find((item) => item[dataLabel] === label);
|
|
6616
|
-
const actualValue = actualItem ? actualItem[dataKey] : value;
|
|
6617
|
-
const valueFormatted = actualValue >= 1e3 ? `${(actualValue / 1e3).toFixed(0)}k` : actualValue.toLocaleString();
|
|
6618
|
-
const percentage = (actualValue / total * 100).toFixed(1);
|
|
6619
|
-
return [
|
|
6620
|
-
`${label}: ${valueFormatted} (${percentage}%)`
|
|
6621
|
-
];
|
|
6622
|
-
},
|
|
6623
|
-
contentStyle: {
|
|
6624
|
-
backgroundColor: "white",
|
|
6625
|
-
border: "1px solid #e5e7eb",
|
|
6626
|
-
borderRadius: "8px",
|
|
6627
|
-
fontSize: "13px",
|
|
6628
|
-
padding: "8px 12px"
|
|
6629
|
-
}
|
|
6630
|
-
}
|
|
6631
|
-
)
|
|
6632
|
-
] }) }),
|
|
6633
|
-
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: [
|
|
6634
|
-
formattedTotal,
|
|
6635
|
-
/* @__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" })
|
|
6636
|
-
] }) })
|
|
6637
|
-
] }),
|
|
6638
|
-
renderLegends
|
|
6639
|
-
] });
|
|
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
|
+
);
|
|
6640
6818
|
};
|
|
6641
6819
|
var PieChart_default = import_react37.default.memo(DonutChart);
|
|
6642
6820
|
|