@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.css +21 -0
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +11 -2
- package/dist/index.d.ts +11 -2
- package/dist/index.js +490 -311
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +491 -313
- 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
|
}
|
|
@@ -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
|
|
6048
|
-
|
|
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
|
-
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 =
|
|
6109
|
-
const effectiveLoading =
|
|
6172
|
+
const effectiveData = useApi ? rawData : props.data || [];
|
|
6173
|
+
const effectiveLoading = useApi ? localLoading : externalLoading;
|
|
6110
6174
|
(0, import_react36.useEffect)(() => {
|
|
6111
|
-
if (
|
|
6175
|
+
if (useApi) {
|
|
6112
6176
|
setCurrentPage(1);
|
|
6113
6177
|
}
|
|
6114
|
-
}, [
|
|
6178
|
+
}, [useApi]);
|
|
6115
6179
|
const fetchData = (0, import_react36.useCallback)(async (page) => {
|
|
6116
6180
|
if (!apiUrl) return;
|
|
6117
|
-
|
|
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 (!
|
|
6217
|
+
if (!useApi) return;
|
|
6154
6218
|
fetchData(currentPage);
|
|
6155
|
-
}, [
|
|
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:
|
|
6231
|
+
fill: item.fill || palette[index % palette.length]
|
|
6168
6232
|
}));
|
|
6169
6233
|
}, [effectiveData, dataKey, dataLabel]);
|
|
6170
6234
|
const chartType = props.chartType || "bar";
|
|
6171
|
-
const
|
|
6172
|
-
|
|
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
|
-
|
|
6204
|
-
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
|
|
6208
|
-
|
|
6209
|
-
|
|
6210
|
-
|
|
6211
|
-
|
|
6212
|
-
|
|
6213
|
-
|
|
6214
|
-
|
|
6215
|
-
|
|
6216
|
-
|
|
6217
|
-
|
|
6218
|
-
|
|
6219
|
-
|
|
6220
|
-
|
|
6221
|
-
|
|
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
|
-
|
|
6231
|
-
|
|
6232
|
-
|
|
6233
|
-
|
|
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)("
|
|
6237
|
-
|
|
6238
|
-
|
|
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
|
|
6347
|
-
const
|
|
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
|
|
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 =
|
|
6425
|
-
const effectiveLoading =
|
|
6562
|
+
const effectiveData = useApi ? rawData : props.data || [];
|
|
6563
|
+
const effectiveLoading = useApi ? localLoading : externalLoading;
|
|
6426
6564
|
(0, import_react37.useEffect)(() => {
|
|
6427
|
-
if (!
|
|
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 ||
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
6583
|
-
|
|
6584
|
-
|
|
6585
|
-
|
|
6586
|
-
|
|
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
|
-
|
|
6589
|
-
|
|
6590
|
-
|
|
6591
|
-
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
|
|
6595
|
-
|
|
6596
|
-
|
|
6597
|
-
|
|
6598
|
-
|
|
6599
|
-
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
|
|
6603
|
-
|
|
6604
|
-
|
|
6605
|
-
|
|
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
|
-
|
|
6611
|
-
|
|
6612
|
-
|
|
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
|
|