@rsc-labs/medusa-store-analytics-v2
Version:
Get analytics data about your store
929 lines • 136 kB
JavaScript
"use strict";
const jsxRuntime = require("react/jsx-runtime");
const react = require("react");
const adminSdk = require("@medusajs/admin-sdk");
const ui = require("@medusajs/ui");
const icons = require("@medusajs/icons");
const material = require("@mui/material");
const recharts = require("recharts");
const reactRouterDom = require("react-router-dom");
var OrderStatus = /* @__PURE__ */ ((OrderStatus2) => {
OrderStatus2["PENDING"] = "pending";
OrderStatus2["COMPLETED"] = "completed";
OrderStatus2["ARCHIVED"] = "archived";
OrderStatus2["CANCELED"] = "canceled";
OrderStatus2["REQUIRES_ACTION"] = "requires_action";
return OrderStatus2;
})(OrderStatus || {});
var DateLasts = /* @__PURE__ */ ((DateLasts2) => {
DateLasts2["All"] = "All time";
DateLasts2["LastMonth"] = "Last 30 days";
DateLasts2["LastWeek"] = "Last 7 days";
DateLasts2["LastYear"] = "Last 365 days";
return DateLasts2;
})(DateLasts || {});
const GenerateReportButton = ({ orderStatuses, dateRange, dateRangeCompareTo, compareEnabled }) => {
const [loadingButton, setLoadingStatus] = react.useState(false);
const generate = async () => {
ui.toast.loading("Report", {
description: "Generating report...",
duration: Infinity
});
setLoadingStatus(true);
fetch(`/admin/reports-analytics/general`, {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
orderStatuses: Object.values(orderStatuses),
dateRangeFrom: dateRange ? dateRange.from.getTime() : void 0,
dateRangeTo: dateRange ? dateRange.to.getTime() : void 0,
dateRangeFromCompareTo: dateRangeCompareTo ? dateRangeCompareTo.from.getTime() : void 0,
dateRangeToCompareTo: dateRangeCompareTo ? dateRangeCompareTo.to.getTime() : void 0
})
}).then((res) => res.json()).then((responseJson) => {
if (responseJson.buffer) {
const anyBuffer = responseJson.buffer;
const blob = new Blob([new Uint8Array(anyBuffer.data)], { type: "application/pdf" });
ui.toast.dismiss();
setLoadingStatus(false);
const pdfURL = URL.createObjectURL(blob);
window.open(pdfURL, "_blank");
} else {
ui.toast.dismiss();
setLoadingStatus(false);
ui.toast.error("Report", {
description: "Problem happened when generating report"
});
}
setLoadingStatus(false);
}).catch((error) => {
var _a, _b;
ui.toast.dismiss();
setLoadingStatus(false);
const trueError = error;
ui.toast.error("Report", {
description: (_b = (_a = trueError == null ? void 0 : trueError.response) == null ? void 0 : _a.data) == null ? void 0 : _b.message
});
});
};
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
loadingButton && /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", disabled: true, style: { width: 180 }, children: "Generating" }),
!loadingButton && /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { variant: "secondary", onClick: generate, style: { width: 180 }, children: [
"Generate report",
/* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { rounded: "full", size: "2xsmall", color: "green", children: "Beta" })
] })
] });
};
const ComparedDate = ({ compare, comparedToDateRange }) => {
if (comparedToDateRange && compare) {
return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: `Compared to ${comparedToDateRange.from.toLocaleDateString()} - ${comparedToDateRange.to.toLocaleDateString()}` });
}
return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: `No comparison` });
};
const SwitchComparison = ({ compareEnabled, onCheckChange, allTime }) => {
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2", children: [
/* @__PURE__ */ jsxRuntime.jsx(ui.Switch, { id: "manage-inventory", onCheckedChange: onCheckChange, disabled: allTime, checked: compareEnabled && !allTime }),
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { htmlFor: "manage-inventory", children: "Compare" })
] });
};
const DropdownOrderStatus = ({ onOrderStatusChange, appliedStatuses }) => {
const [isDropdownOpen, setIsDropdownOpen] = react.useState(false);
const [selectedStatuses, setSelectedStatuses] = react.useState([]);
const handleStatusToggle = (status) => {
setSelectedStatuses(
(prevSelectedStatuses) => prevSelectedStatuses.includes(status) ? prevSelectedStatuses.filter((selected) => selected !== status) : [...prevSelectedStatuses, status]
);
};
const handleApplyClick = () => {
setIsDropdownOpen(false);
onOrderStatusChange(selectedStatuses.map((selectedStatus) => OrderStatus[selectedStatus.toUpperCase()]));
};
return /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { open: isDropdownOpen, onOpenChange: (isOpen) => {
if (isOpen) {
setSelectedStatuses(Object.values(appliedStatuses));
}
setIsDropdownOpen(isOpen);
}, children: [
/* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { children: /* @__PURE__ */ jsxRuntime.jsx(icons.Adjustments, {}) }) }),
/* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
/* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Label, { className: "gap-x-2", style: { paddingLeft: 8, paddingBottom: 8 }, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", children: "Choose orders" }) }),
Object.values(OrderStatus).map((orderStatus) => /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Item, { className: "gap-x-2", onSelect: (event) => event.preventDefault(), children: [
/* @__PURE__ */ jsxRuntime.jsx(
ui.Checkbox,
{
id: `order-status-${orderStatus}`,
checked: selectedStatuses.includes(orderStatus),
onCheckedChange: () => handleStatusToggle(orderStatus)
}
),
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { htmlFor: `order-status-${orderStatus}`, children: orderStatus })
] }, orderStatus.toString())),
/* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Label, { className: "gap-x-2", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { onClick: handleApplyClick, children: "Apply" }) })
] })
] });
};
const SelectDateLasts = ({ dateLast, onSelectChange }) => {
const dateLastsToSelect = [
DateLasts.LastWeek,
DateLasts.LastMonth,
DateLasts.LastYear,
DateLasts.All
];
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-[170px]", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Select, { size: "small", onValueChange: onSelectChange, value: dateLast, children: [
/* @__PURE__ */ jsxRuntime.jsx(ui.Select.Trigger, { style: { height: "2rem" }, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Value, { placeholder: "Select a date range" }) }),
/* @__PURE__ */ jsxRuntime.jsx(ui.Select.Content, { children: dateLastsToSelect.map((dateToSelect) => /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: dateToSelect, children: dateToSelect == DateLasts.All ? /* @__PURE__ */ jsxRuntime.jsxs(material.Grid, { container: true, spacing: 1, children: [
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: dateToSelect }),
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: "If you have many orders, it might take a while to load statistics.", children: /* @__PURE__ */ jsxRuntime.jsx(icons.ExclamationCircle, {}) }) }) })
] }) : dateToSelect }, dateToSelect)) })
] }) });
};
var ChartResolutionType = /* @__PURE__ */ ((ChartResolutionType2) => {
ChartResolutionType2[ChartResolutionType2["DayMonth"] = 0] = "DayMonth";
ChartResolutionType2[ChartResolutionType2["Month"] = 1] = "Month";
return ChartResolutionType2;
})(ChartResolutionType || {});
function calculateResolution(fromDate, toDate) {
if (!fromDate) return 1;
const calculateToDate = toDate ? new Date(toDate) : new Date(Date.now());
const diffTime = calculateToDate.getTime() - fromDate.getTime();
const weekTime = 6048e5;
const monthTime = weekTime * 4;
const twoMonthsTime = monthTime * 2;
if (diffTime <= twoMonthsTime) {
return 0;
}
const yearTime = monthTime * 12;
if (diffTime < yearTime) {
return 1;
}
return 1;
}
const compareDatesBasedOnResolutionType = (date1, date2, resolutionType) => {
switch (resolutionType) {
case 0:
return new Date(new Date(date1).setHours(0, 0, 0, 0)).getTime() == new Date(new Date(date2).setHours(0, 0, 0, 0)).getTime();
case 1:
return new Date(new Date(new Date(date1).setDate(0)).setHours(0, 0, 0, 0)).getTime() == new Date(new Date(new Date(date2).setDate(0)).setHours(0, 0, 0, 0)).getTime();
default:
return new Date(new Date(date1).setHours(0, 0, 0, 0)).getTime() == new Date(new Date(date2).setHours(0, 0, 0, 0)).getTime();
}
};
const getChartDateName = (date, resolutionType, startDate, endDate) => {
switch (resolutionType) {
case 0:
if (compareDatesBasedOnResolutionType(date, startDate, resolutionType) || compareDatesBasedOnResolutionType(date, endDate, resolutionType)) {
return `${date.getDate().toString()} ${getShortMonthName(date)}`;
}
return date.getDate().toString();
case 1:
if (compareDatesBasedOnResolutionType(date, startDate, resolutionType) || compareDatesBasedOnResolutionType(date, endDate, resolutionType)) {
return `${getShortMonthName(date)} ${date.getFullYear().toString()}`;
}
return getShortMonthName(date);
default:
return date.getFullYear().toString();
}
};
const getChartTooltipDate = (date, resolutionType) => {
switch (resolutionType) {
case 0:
return `${date.getDate().toString()}-${getShortMonthName(date)}`;
case 1:
return `${getShortMonthName(date)}-${date.getFullYear()}`;
default:
return date.getFullYear().toString();
}
};
const getLegendName = (current) => {
return current ? `Current` : `Preceding`;
};
const getShortMonthName = (date) => {
let days = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
return days[date.getMonth()];
};
const incrementDate = (date, resolutionType) => {
switch (resolutionType) {
case ChartResolutionType.DayMonth:
date.setDate(date.getDate() + 1);
break;
case ChartResolutionType.Month:
date.setMonth(date.getMonth() + 1);
break;
default:
date.setDate(date.getDate() + 1);
}
};
const generateChartData = (data, fromDate, toDate, chartResolutionType, toCompareDate, connectEmptyPointsUsingPreviousValue) => {
const currentData = data.current;
const previousData = data.previous;
const startFromDate = new Date(fromDate);
const offsetTime = toDate.getTime() - (toCompareDate ? toCompareDate.getTime() : fromDate.getTime());
const dataPoints = [];
let currentDataValue;
let previousDataValue;
while (startFromDate.getTime() < toDate.getTime() || compareDatesBasedOnResolutionType(startFromDate, toDate, chartResolutionType)) {
const currentOrder = currentData.find((order) => compareDatesBasedOnResolutionType(new Date(order.date), startFromDate, chartResolutionType));
const offsetDate = new Date(startFromDate);
offsetDate.setTime(offsetDate.getTime() - offsetTime);
const previousOrder = previousData.find((previous) => compareDatesBasedOnResolutionType(new Date(previous.date), offsetDate, chartResolutionType));
if (connectEmptyPointsUsingPreviousValue) {
if (currentOrder) {
currentDataValue = parseInt(currentOrder.value);
}
if (previousOrder) {
previousDataValue = parseInt(previousOrder.value);
}
dataPoints.push({
current: {
date: new Date(startFromDate),
value: currentOrder ? parseInt(currentOrder.value) : currentDataValue ? currentDataValue : void 0
},
previous: {
date: new Date(offsetDate),
value: previousOrder ? parseInt(previousOrder.value) : previousDataValue ? previousDataValue : void 0
}
});
} else {
dataPoints.push({
current: {
date: new Date(startFromDate),
value: currentOrder ? parseInt(currentOrder.value) : 0
},
previous: {
date: new Date(offsetDate),
value: previousOrder ? parseInt(previousOrder.value) : 0
}
});
}
incrementDate(startFromDate, chartResolutionType);
}
if (connectEmptyPointsUsingPreviousValue) {
for (let i = dataPoints.length - 1; i >= 0; i--) {
if (dataPoints[i].current.value === void 0) {
if (dataPoints[dataPoints.length - 1].previous.value) {
dataPoints[i].current.value = dataPoints[dataPoints.length - 1].previous.value;
} else {
dataPoints[i].current.value = 0;
}
}
if (dataPoints[i].previous.value) {
previousDataValue = dataPoints[i].previous.value;
} else {
dataPoints[i].previous.value = previousDataValue;
}
}
}
return dataPoints;
};
const ChartCustomTooltip$1 = ({ active, payload, label, resolutionType }) => {
if (active && payload && payload.length) {
switch (resolutionType) {
case ChartResolutionType.DayMonth:
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { children: [
/* @__PURE__ */ jsxRuntime.jsxs(ui.Heading, { level: "h3", style: { color: payload[0].color }, children: [
`${getChartTooltipDate(payload[0].payload.current.date, resolutionType)}`,
" : ",
payload[0].payload.current.value
] }),
payload[1] !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs(ui.Heading, { level: "h3", style: { color: payload[1].color }, children: [
`${getChartTooltipDate(payload[1].payload.previous.date, resolutionType)}`,
" : ",
payload[1].payload.previous.value
] })
] });
case ChartResolutionType.Month:
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { children: [
/* @__PURE__ */ jsxRuntime.jsxs(ui.Heading, { level: "h3", style: { color: payload[0].color }, children: [
`${getChartTooltipDate(payload[0].payload.current.date, resolutionType)}`,
" : ",
payload[0].payload.current.value
] }),
payload[1] !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs(ui.Heading, { level: "h3", style: { color: payload[1].color }, children: [
`${getChartTooltipDate(payload[1].payload.previous.date, resolutionType)}`,
" : ",
payload[1].payload.previous.value
] })
] });
}
}
return null;
};
const areRangesTheSame = (fromDate, toDate, fromCompareDate, toCompareDate) => {
function isToday(date) {
const today = /* @__PURE__ */ new Date();
today.setHours(0, 0, 0, 0);
const givenDate = new Date(date);
givenDate.setHours(0, 0, 0, 0);
return today.getTime() === givenDate.getTime();
}
if (fromCompareDate) {
const oneDay = 24 * 60 * 60 * 1e3;
if (toCompareDate) {
if (isToday(toDate)) {
const diffBase3 = Math.ceil(Math.abs((toDate.getTime() - fromDate.getTime()) / oneDay));
const diffCompare3 = Math.round(Math.abs((toCompareDate.getTime() - fromCompareDate.getTime()) / oneDay));
return diffBase3 == diffCompare3;
}
const diffBase2 = Math.round(Math.abs((toDate.getTime() - fromDate.getTime()) / oneDay));
const diffCompare2 = Math.round(Math.abs((toCompareDate.getTime() - fromCompareDate.getTime()) / oneDay));
return diffBase2 == diffCompare2;
}
const diffBase = Math.ceil(Math.abs((toDate.getTime() - fromDate.getTime()) / oneDay));
const diffCompare = Math.ceil(Math.abs((Date.now() - fromCompareDate.getTime()) / oneDay));
return diffBase == diffCompare;
}
return true;
};
const ChartCurrentPrevious = ({ rawChartData, fromDate, toDate, fromCompareDate, toCompareDate, compareEnabled, connectEmptyPointsUsingPreviousValue }) => {
const [chartDataPoints, setChartData] = react.useState([]);
const resolutionType = calculateResolution(fromDate, toDate);
react.useEffect(() => {
const chartDataPoints2 = generateChartData(
rawChartData,
fromDate,
toDate,
resolutionType,
toCompareDate,
connectEmptyPointsUsingPreviousValue
);
setChartData(chartDataPoints2);
}, [rawChartData, fromDate, toDate]);
if (!areRangesTheSame(fromDate, toDate, fromCompareDate, toCompareDate)) {
const currentPeriodInDays = Math.ceil((toDate.getTime() - fromDate.getTime()) / (24 * 60 * 60 * 1e3));
let precedingPeriodInDays = 0;
if (fromCompareDate) {
if (toCompareDate) {
precedingPeriodInDays = Math.ceil((toCompareDate.getTime() - fromCompareDate.getTime()) / (24 * 60 * 60 * 1e3));
} else {
precedingPeriodInDays = Math.ceil((new Date(Date.now()).getTime() - fromCompareDate.getTime()) / (24 * 60 * 60 * 1e3));
}
}
return /* @__PURE__ */ jsxRuntime.jsx(
material.Box,
{
width: 500,
height: 400,
display: "flex",
alignItems: "center",
justifyContent: "center",
children: /* @__PURE__ */ jsxRuntime.jsxs(material.Grid, { container: true, direction: "column", justifyContent: "center", alignItems: "center", children: [
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Chart can be shown only for the same length of ranges." }) }),
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: `You are comparing ${currentPeriodInDays} days to ${precedingPeriodInDays} days` }) })
] })
}
);
}
return /* @__PURE__ */ jsxRuntime.jsxs(
recharts.AreaChart,
{
width: 500,
height: 400,
data: chartDataPoints,
margin: {
top: 20,
right: 0,
left: 0,
bottom: 0
},
children: [
/* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { strokeDasharray: "3 3" }),
/* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
/* @__PURE__ */ jsxRuntime.jsxs("linearGradient", { id: "colorPrevious", x1: "0", y1: "0", x2: "0", y2: "1", children: [
/* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "5%", stopColor: "#8884d8", stopOpacity: 0.8 }),
/* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "95%", stopColor: "#8884d8", stopOpacity: 0 })
] }),
/* @__PURE__ */ jsxRuntime.jsxs("linearGradient", { id: "colorCurrent", x1: "0", y1: "0", x2: "0", y2: "1", children: [
/* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "5%", stopColor: "#82ca9d", stopOpacity: 0.8 }),
/* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "95%", stopColor: "#82ca9d", stopOpacity: 0 })
] })
] }),
/* @__PURE__ */ jsxRuntime.jsx(recharts.XAxis, { dataKey: (value) => getChartDateName(value.current.date, resolutionType, fromDate, toDate), minTickGap: 15, interval: "preserveStartEnd" }),
/* @__PURE__ */ jsxRuntime.jsx(recharts.YAxis, {}),
/* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartCustomTooltip$1, { active: false, payload: [], label: "", resolutionType }) }),
/* @__PURE__ */ jsxRuntime.jsx(recharts.Area, { name: compareEnabled && fromCompareDate ? getLegendName(true) : void 0, type: "monotone", dataKey: "current.value", stroke: "#82ca9d", fillOpacity: 1, fill: "url(#colorCurrent)" }),
compareEnabled && fromCompareDate && /* @__PURE__ */ jsxRuntime.jsx(recharts.Area, { name: getLegendName(false), type: "monotone", dataKey: "previous.value", stroke: "#8884d8", fillOpacity: 1, fill: "url(#colorPrevious)" }),
compareEnabled && fromCompareDate && /* @__PURE__ */ jsxRuntime.jsx(recharts.Legend, { verticalAlign: "bottom", height: 36, iconType: "circle" })
]
}
);
};
function amountToDisplay(amount, decimalDigits) {
return (amount / Math.pow(10, decimalDigits)).toFixed(decimalDigits);
}
function calculatePercentage(current, previous) {
if (current == previous) {
return 0;
}
if (current == 0) {
return 100;
}
if (previous == 0) {
return void 0;
}
const percentage = Number(((current - previous) / previous).toFixed(2)) * 100;
if (percentage > 0) {
return Math.round(percentage * 100) / 100;
}
return Math.round((percentage - percentage - percentage) * 100) / 100;
}
function convertDateLastsToDateRange(dateLasts) {
let result;
switch (dateLasts) {
case DateLasts.LastMonth:
result = {
// 86400000 - alignment for taking last 29 days, as the current day is 30
from: new Date(new Date((/* @__PURE__ */ new Date()).setDate((/* @__PURE__ */ new Date()).getDate() - 29)).setHours(0, 0, 0, 0)),
to: new Date(Date.now())
};
break;
case DateLasts.LastWeek:
result = {
// 86400000 - alignment for taking last 6 days, as the current day is 7th
from: new Date(new Date(new Date(Date.now() - 6048e5 + 864e5)).setHours(0, 0, 0, 0)),
to: new Date(Date.now())
};
break;
case DateLasts.LastYear:
new Date((/* @__PURE__ */ new Date()).setFullYear((/* @__PURE__ */ new Date()).getFullYear() - 1));
result = {
// + 1 - alignment for taking last 11 months, as the current month is 12th
from: new Date(new Date((/* @__PURE__ */ new Date()).setDate((/* @__PURE__ */ new Date()).getDate() - 364)).setHours(0, 0, 0, 0)),
to: new Date(Date.now())
};
break;
}
return result;
}
function convertDateLastsToComparedDateRange(dateLasts) {
let result;
switch (dateLasts) {
case DateLasts.LastMonth:
result = {
from: new Date(new Date((/* @__PURE__ */ new Date()).setDate((/* @__PURE__ */ new Date()).getDate() - 59)).setHours(0, 0, 0, 0)),
to: new Date(new Date((/* @__PURE__ */ new Date()).setDate((/* @__PURE__ */ new Date()).getDate() - 29)).setHours(0, 0, 0, 0))
};
break;
case DateLasts.LastWeek:
result = {
from: new Date(new Date(Date.now() - 6048e5 * 2 + 864e5).setHours(0, 0, 0, 0)),
to: new Date(new Date(Date.now() - 6048e5 + 864e5).setHours(0, 0, 0, 0))
};
break;
case DateLasts.LastYear:
result = {
from: new Date(new Date((/* @__PURE__ */ new Date()).setDate((/* @__PURE__ */ new Date()).getDate() - 729)).setHours(0, 0, 0, 0)),
to: new Date(new Date((/* @__PURE__ */ new Date()).setDate((/* @__PURE__ */ new Date()).getDate() - 364)).setHours(0, 0, 0, 0))
};
break;
}
return result;
}
function deduceDateUrlParams(dateRange, dateRangeCompareTo, orderStatuses) {
let dateRangeParams = {};
let dateRangeCompareToParams = {};
if (dateRange) {
dateRangeParams = {
dateRangeFrom: dateRange.from.getTime().toString(),
dateRangeTo: dateRange.to.getTime().toString()
};
}
if (dateRangeCompareTo) {
dateRangeCompareToParams = {
dateRangeFromCompareTo: dateRangeCompareTo.from.getTime().toString(),
dateRangeToCompareTo: dateRangeCompareTo.to.getTime().toString()
};
}
const result = new URLSearchParams({
...dateRangeParams,
...dateRangeCompareToParams
});
if (orderStatuses) {
for (const orderStatus of orderStatuses) {
result.append("orderStatuses", orderStatus.toString());
}
}
return result;
}
const OrdersByNewChart = ({ orderStatuses, dateRange, dateRangeCompareTo, compareEnabled }) => {
var _a, _b;
const [data, setData] = react.useState(void 0);
const [error, setError] = react.useState(void 0);
const [isLoading, setLoading] = react.useState(true);
react.useEffect(() => {
setLoading(true);
}, [dateRange, dateRangeCompareTo, orderStatuses]);
react.useEffect(() => {
if (!isLoading) {
return;
}
fetch(`/admin/orders-analytics/history?${deduceDateUrlParams(dateRange, dateRangeCompareTo, orderStatuses).toString()}`, {
credentials: "include"
}).then((res) => res.json()).then((result) => {
setData(result);
setLoading(false);
}).catch((error2) => {
setError(error2);
console.error(error2);
});
}, [isLoading]);
if (isLoading) {
return /* @__PURE__ */ jsxRuntime.jsx(material.CircularProgress, { size: 12 });
}
if (error) {
const trueError = error;
const errorText = `Error when loading data. It shouldn't have happened - please raise an issue. For developer: ${(_b = (_a = trueError == null ? void 0 : trueError.response) == null ? void 0 : _a.data) == null ? void 0 : _b.message}`;
return /* @__PURE__ */ jsxRuntime.jsx(ui.Alert, { variant: "error", children: errorText });
}
if (data == void 0 || data.analytics == void 0) {
return /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", children: "Cannot get orders" });
}
if (data.analytics.dateRangeFrom && data.analytics.dateRangeTo) {
const rawChartData = {
current: data.analytics.current.map((currentData) => {
return {
date: new Date(currentData.date),
value: currentData.orderCount
};
}),
previous: data.analytics.previous.map((previousData) => {
return {
date: new Date(previousData.date),
value: previousData.orderCount
};
})
};
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", children: "New orders by time" }),
/* @__PURE__ */ jsxRuntime.jsx(
ChartCurrentPrevious,
{
rawChartData,
fromDate: new Date(data.analytics.dateRangeFrom),
toDate: new Date(data.analytics.dateRangeTo),
fromCompareDate: data.analytics.dateRangeFromCompareTo ? new Date(data.analytics.dateRangeFromCompareTo) : void 0,
toCompareDate: data.analytics.dateRangeToCompareTo ? new Date(data.analytics.dateRangeToCompareTo) : void 0,
compareEnabled
}
)
] });
} else {
return /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", children: "No orders" });
}
};
const IconComparison = ({ current, previous, switchArrow }) => {
if (current == previous) {
return /* @__PURE__ */ jsxRuntime.jsx(icons.MinusMini, { color: "black" });
}
if (previous && current > previous) {
return /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { color: switchArrow ? "red" : "green" });
}
if (previous && current < previous) {
return /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { color: switchArrow ? "green" : "red" });
}
};
const PercentageComparison = ({ current, label, previous, headingLevel = "h2" }) => {
const percentage = calculatePercentage(parseInt(current), parseInt(previous));
return /* @__PURE__ */ jsxRuntime.jsx(ui.TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: `Previously: ${previous} ${label}`, children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: headingLevel, style: { textDecorationStyle: "dotted", textDecorationLine: "underline", textUnderlineOffset: "3px" }, children: percentage !== void 0 ? `${percentage}%` : `N/A` }) }) }) });
};
const OrdersNumber = ({ orderStatuses, dateRange, dateRangeCompareTo, compareEnabled }) => {
var _a, _b;
const [data, setData] = react.useState(void 0);
const [error, setError] = react.useState(void 0);
const [isLoading, setLoading] = react.useState(true);
react.useEffect(() => {
setLoading(true);
}, [dateRange, dateRangeCompareTo, orderStatuses]);
react.useEffect(() => {
if (!isLoading) {
return;
}
fetch(`/admin/orders-analytics/count?${deduceDateUrlParams(dateRange, dateRangeCompareTo, orderStatuses).toString()}`, {
credentials: "include"
}).then((res) => res.json()).then((result) => {
setData(result);
setLoading(false);
}).catch((error2) => {
setError(error2);
console.error(error2);
});
}, [isLoading]);
if (isLoading) {
return /* @__PURE__ */ jsxRuntime.jsx(material.CircularProgress, { size: 12 });
}
if (error) {
const trueError = error;
const errorText = `Error when loading data. It shouldn't have happened - please raise an issue. For developer: ${(_b = (_a = trueError == null ? void 0 : trueError.response) == null ? void 0 : _a.data) == null ? void 0 : _b.message}`;
return /* @__PURE__ */ jsxRuntime.jsx(ui.Alert, { variant: "error", children: errorText });
}
if (data == void 0 || data.analytics == void 0) {
return /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", children: "Cannot get orders" });
}
return /* @__PURE__ */ jsxRuntime.jsxs(material.Grid, { container: true, alignItems: "center", spacing: 2, children: [
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: data.analytics.current }) }),
compareEnabled && dateRangeCompareTo && /* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsxs(material.Grid, { container: true, alignItems: "center", children: [
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsx(IconComparison, { current: parseInt(data.analytics.current), previous: data.analytics.previous ? parseInt(data.analytics.previous) : void 0 }) }),
data.analytics.previous !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsx(PercentageComparison, { current: data.analytics.current, label: "", previous: data.analytics.previous }) })
] }) })
] });
};
const OrdersOverviewCard = ({ orderStatuses, dateRange, dateRangeCompareTo, compareEnabled }) => {
return /* @__PURE__ */ jsxRuntime.jsxs(material.Grid, { container: true, paddingBottom: 2, spacing: 3, children: [
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, xs: 12, md: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(material.Grid, { container: true, spacing: 2, children: [
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsx(icons.ShoppingCart, {}) }),
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Orders" }) })
] }) }),
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, xs: 12, md: 12, children: /* @__PURE__ */ jsxRuntime.jsx(OrdersNumber, { orderStatuses, dateRange, dateRangeCompareTo, compareEnabled }) }),
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, xs: 12, md: 12, children: /* @__PURE__ */ jsxRuntime.jsx(OrdersByNewChart, { orderStatuses, dateRange, dateRangeCompareTo, compareEnabled }) })
] });
};
function convertToChartData$1(ordersPaymentProviders) {
if (ordersPaymentProviders.length) {
return ordersPaymentProviders.map((ordersPaymentProvider) => {
return {
name: ordersPaymentProvider.paymentProviderId,
value: parseFloat(ordersPaymentProvider.percentage),
displayValue: ordersPaymentProvider.paymentProviderId,
orderCount: ordersPaymentProvider.orderCount
};
});
}
return void 0;
}
const ChartCustomTooltip = ({ active, payload, label }) => {
if (active && payload && payload.length) {
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { children: [
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: `${payload[0].payload.value}%` }),
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: `Provider: ${payload[0].payload.name}` }),
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: `Order count: ${payload[0].payload.orderCount}` })
] });
}
return null;
};
const OrdersPaymentProviderPieChart = ({ ordersPaymentProviderResponse, compareEnabled }) => {
const currentData = convertToChartData$1(ordersPaymentProviderResponse.analytics.current);
const previousData = convertToChartData$1(ordersPaymentProviderResponse.analytics.previous);
const renderLabel = function(entry) {
return entry.displayValue;
};
return /* @__PURE__ */ jsxRuntime.jsxs(recharts.PieChart, { width: 500, height: 300, children: [
/* @__PURE__ */ jsxRuntime.jsx(recharts.Pie, { data: currentData, dataKey: "value", cx: "50%", cy: "50%", innerRadius: 40, outerRadius: 90, fill: "#82ca9d", label: renderLabel }),
compareEnabled && ordersPaymentProviderResponse.analytics.dateRangeFromCompareTo && /* @__PURE__ */ jsxRuntime.jsx(recharts.Pie, { data: previousData, dataKey: "value", cx: "50%", cy: "50%", outerRadius: 30, fill: "#8884d8" }),
compareEnabled && ordersPaymentProviderResponse.analytics.dateRangeFromCompareTo && /* @__PURE__ */ jsxRuntime.jsx(recharts.Legend, { payload: [
{
value: getLegendName(true),
color: "#82ca9d"
},
{
value: getLegendName(false),
color: "#8884d8"
}
], iconType: "circle" }),
/* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartCustomTooltip, { active: false, payload: [], label: "" }) })
] });
};
const OrdersPaymentProviderDetails = ({ dateRange, dateRangeCompareTo, compareEnabled }) => {
var _a, _b;
const [data, setData] = react.useState(void 0);
const [error, setError] = react.useState(void 0);
const [isLoading, setLoading] = react.useState(true);
react.useEffect(() => {
setLoading(true);
}, [dateRange, dateRangeCompareTo]);
react.useEffect(() => {
if (!isLoading) {
return;
}
fetch(`/admin/orders-analytics/payment-provider?${deduceDateUrlParams(dateRange, dateRangeCompareTo).toString()}`, {
credentials: "include"
}).then((res) => res.json()).then((result) => {
setData(result);
setLoading(false);
}).catch((error2) => {
setError(error2);
console.error(error2);
});
}, [isLoading]);
if (isLoading) {
return /* @__PURE__ */ jsxRuntime.jsx(material.CircularProgress, { size: 12 });
}
if (error) {
const trueError = error;
const errorText = `Error when loading data. It shouldn't have happened - please raise an issue. For developer: ${(_b = (_a = trueError == null ? void 0 : trueError.response) == null ? void 0 : _a.data) == null ? void 0 : _b.message}`;
return /* @__PURE__ */ jsxRuntime.jsx(ui.Alert, { variant: "error", children: errorText });
}
if (data && data.analytics == void 0) {
return /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", children: "Cannot get orders" });
}
if (data && data.analytics.dateRangeFrom) {
return /* @__PURE__ */ jsxRuntime.jsx(OrdersPaymentProviderPieChart, { ordersPaymentProviderResponse: data, compareEnabled });
} else {
return /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", children: "No orders" });
}
};
const OrdersPaymentProviderCard = ({ dateRange, dateRangeCompareTo, compareEnabled }) => {
return /* @__PURE__ */ jsxRuntime.jsxs(material.Grid, { container: true, paddingBottom: 2, spacing: 3, children: [
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, xs: 12, md: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(material.Grid, { container: true, spacing: 2, children: [
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsx(icons.Cash, {}) }),
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Payment provider popularity" }) })
] }) }),
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, xs: 12, md: 12, children: /* @__PURE__ */ jsxRuntime.jsx(material.Grid, { container: true, direction: "column", alignItems: "center", paddingTop: 3, children: /* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsx(OrdersPaymentProviderDetails, { dateRange, dateRangeCompareTo, compareEnabled }) }) }) })
] });
};
const SalesNumber = ({ salesHistoryResponse, compareEnabled }) => {
const overallCurrentSum = salesHistoryResponse.analytics.current.reduce((sum, order) => sum + parseInt(order.total), 0);
const overallPreviousSum = salesHistoryResponse.analytics.previous.length > 0 ? salesHistoryResponse.analytics.previous.reduce((sum, order) => sum + parseInt(order.total), 0) : void 0;
return /* @__PURE__ */ jsxRuntime.jsxs(material.Grid, { container: true, alignItems: "center", spacing: 2, children: [
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Heading, { level: "h1", children: [
amountToDisplay(overallCurrentSum, salesHistoryResponse.analytics.currencyDecimalDigits),
" ",
salesHistoryResponse.analytics.currencyCode.toUpperCase()
] }) }),
compareEnabled && salesHistoryResponse.analytics.dateRangeFromCompareTo && /* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsxs(material.Grid, { container: true, alignItems: "center", children: [
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsx(IconComparison, { current: overallCurrentSum, previous: overallPreviousSum ? overallPreviousSum : void 0 }) }),
overallPreviousSum !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsx(PercentageComparison, { current: amountToDisplay(overallCurrentSum, salesHistoryResponse.analytics.currencyDecimalDigits), label: salesHistoryResponse.analytics.currencyCode.toUpperCase(), previous: amountToDisplay(overallPreviousSum, salesHistoryResponse.analytics.currencyDecimalDigits) }) })
] }) })
] });
};
const SalesByNewChart = ({ dateRangeFrom, dateRangeTo, salesHistoryResponse, compareEnabled }) => {
const rawChartData = {
current: salesHistoryResponse.analytics.current.map((currentData) => {
return {
date: new Date(currentData.date),
value: amountToDisplay(parseInt(currentData.total), salesHistoryResponse.analytics.currencyDecimalDigits)
};
}),
previous: salesHistoryResponse.analytics.previous.map((previousData) => {
return {
date: new Date(previousData.date),
value: amountToDisplay(parseInt(previousData.total), salesHistoryResponse.analytics.currencyDecimalDigits)
};
})
};
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", children: "Sales by time" }),
/* @__PURE__ */ jsxRuntime.jsx(
ChartCurrentPrevious,
{
rawChartData,
fromDate: dateRangeFrom,
toDate: dateRangeTo,
fromCompareDate: salesHistoryResponse.analytics.dateRangeFromCompareTo ? new Date(salesHistoryResponse.analytics.dateRangeFromCompareTo) : void 0,
toCompareDate: salesHistoryResponse.analytics.dateRangeToCompareTo ? new Date(salesHistoryResponse.analytics.dateRangeToCompareTo) : void 0,
compareEnabled
}
)
] });
};
const SalesDetails = ({ orderStatuses, currencyCode, dateRange, dateRangeCompareTo, compareEnabled }) => {
var _a, _b;
const [data, setData] = react.useState(void 0);
const [error, setError] = react.useState(void 0);
const [isLoading, setLoading] = react.useState(true);
react.useEffect(() => {
setLoading(true);
}, [dateRange, dateRangeCompareTo, orderStatuses, currencyCode]);
react.useEffect(() => {
if (!isLoading) {
return;
}
const searchParams = deduceDateUrlParams(dateRange, dateRangeCompareTo, orderStatuses);
searchParams.append("currencyCode", currencyCode);
fetch(`/admin/sales-analytics/history?${searchParams.toString()}`, {
credentials: "include"
}).then((res) => res.json()).then((result) => {
setData(result);
setLoading(false);
}).catch((error2) => {
setError(error2);
console.error(error2);
});
}, [isLoading]);
if (isLoading) {
return /* @__PURE__ */ jsxRuntime.jsx(material.CircularProgress, { size: 12 });
}
if (error) {
const trueError = error;
const errorText = `Error when loading data. It shouldn't have happened - please raise an issue. For developer: ${(_b = (_a = trueError == null ? void 0 : trueError.response) == null ? void 0 : _a.data) == null ? void 0 : _b.message}`;
return /* @__PURE__ */ jsxRuntime.jsx(ui.Alert, { variant: "error", children: errorText });
}
if (data && data.analytics == void 0) {
return /* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, xs: 12, md: 12, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", children: "Cannot get orders" }) });
}
if (data && data.analytics.dateRangeFrom && data.analytics.dateRangeTo) {
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, xs: 12, md: 12, children: /* @__PURE__ */ jsxRuntime.jsx(SalesNumber, { salesHistoryResponse: data, compareEnabled }) }),
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, xs: 12, md: 12, children: /* @__PURE__ */ jsxRuntime.jsx(SalesByNewChart, { dateRangeFrom: new Date(data.analytics.dateRangeFrom), dateRangeTo: new Date(data.analytics.dateRangeTo), salesHistoryResponse: data, compareEnabled }) })
] });
} else {
return /* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, xs: 12, md: 12, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", children: "No orders" }) });
}
};
const SalesOverviewCard = ({ orderStatuses, dateRange, dateRangeCompareTo, compareEnabled }) => {
const [value, setValue] = react.useState();
const [regions, setRegions] = react.useState(void 0);
const [error, setError] = react.useState(void 0);
const [isLoading, setLoading] = react.useState(true);
react.useEffect(() => {
if (!isLoading) {
return;
}
fetch(`/admin/regions/`, {
credentials: "include"
}).then((res) => res.json()).then((result) => {
setRegions(result.regions);
setLoading(false);
}).catch((error2) => {
setError(error2);
console.error(error2);
});
}, [isLoading]);
return /* @__PURE__ */ jsxRuntime.jsxs(material.Grid, { container: true, paddingBottom: 2, spacing: 3, children: [
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, xs: 12, md: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(material.Grid, { container: true, spacing: 2, alignItems: "center", children: [
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsx(icons.CurrencyDollar, {}) }),
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Total sales" }) }),
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-[256px]", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Select, { size: "small", onValueChange: setValue, value, children: [
/* @__PURE__ */ jsxRuntime.jsx(ui.Select.Trigger, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Value, { placeholder: "Select a currency" }) }),
/* @__PURE__ */ jsxRuntime.jsxs(ui.Select.Content, { children: [
isLoading && /* @__PURE__ */ jsxRuntime.jsx(material.CircularProgress, {}),
regions && !regions.length && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "No regions" }),
regions && regions.length > 0 && [...new Set(regions.map((region) => region.currency_code))].map((currencyCode) => /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: currencyCode, children: currencyCode.toUpperCase() }, currencyCode))
] })
] }) }) })
] }) }),
value ? /* @__PURE__ */ jsxRuntime.jsx(SalesDetails, { orderStatuses, currencyCode: value, dateRange, dateRangeCompareTo, compareEnabled }) : /* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Please select a currency" }) })
] });
};
const ValueColumn = ({ current, previous, enableComparing }) => {
return /* @__PURE__ */ jsxRuntime.jsxs(material.Grid, { container: true, alignItems: "center", children: [
enableComparing ? /* @__PURE__ */ jsxRuntime.jsx(ui.TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: `Previously: ${previous}`, children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { style: { textDecorationStyle: "dotted", textDecorationLine: "underline", textUnderlineOffset: "3px" }, children: current !== void 0 ? `${current}` : `N/A` }) }) }) }) : /* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: current }) }),
enableComparing && /* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsx(material.Grid, { container: true, alignItems: "center", children: parseInt(current) != (previous ? parseInt(previous) : void 0) && /* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsx(IconComparison, { current: parseInt(current), previous: previous ? parseInt(previous) : void 0 }) }) }) })
] });
};
const PopularityTable = ({ valueColumnName, tableRows, enableComparing }) => {
return /* @__PURE__ */ jsxRuntime.jsxs(material.Grid, { container: true, spacing: 2, children: [
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, xs: 12, children: /* @__PURE__ */ jsxRuntime.jsx(material.Divider, {}) }),
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, xs: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(material.Grid, { container: true, justifyContent: "space-between", children: [
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", children: "Name" }) }),
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", children: valueColumnName }) })
] }) }),
tableRows.length > 0 ? tableRows.map((tableRow) => /* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, xs: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(material.Grid, { container: true, justifyContent: "space-between", children: [
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: tableRow.name }) }),
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsx(ValueColumn, { current: tableRow.current, previous: tableRow.previous, enableComparing }) })
] }) }, tableRow.name)) : /* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, xs: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(material.Grid, { container: true, justifyContent: "space-between", children: [
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "None" }) }),
/* @__PURE__ */ jsxRuntime.jsx(material.Grid, { item: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "None" }) })
] }) })
] });
};
function transformToPopularityTable$1(result) {
const currentMap = /* @__PURE__ */ new Map();
const previousMap = /* @__PURE__ */ new Map();
result.current.forEach((currentItem) => {
const currentCount = currentMap.get(currentItem.salesChannelName) || 0;
currentMap.set(currentItem.salesChannelName, currentCount + parseInt(currentItem.orderCount));
});
result.previous.forEach((previousItem) => {
const previousCount = previousMap.get(previousItem.salesChannelName) || 0;
previousMap.set(previousItem.salesChannelName, previousCount + parseInt(previousItem.orderCount));
});
return Array.from(currentMap.keys()).map((name) => ({
name,
current: String(currentMap.get(name) || 0),
previous: String(previousMap.get(name) || 0)
}));
}
const SalesChannelsPopularityDetails = ({ orderStatuses, dateRange, dateRangeCompareTo, compareEnabled }) => {
var _a, _b;
const [data, setData] = react.useState(void 0);
const [error, setError] = react.useState(void 0);
const [isLoading, setLoading] = react.useState(true);
react.useEffect(() => {
setLoading(true);
}, [dateRange, dateRangeCompareTo, orderStatuses]);
react.useEffect(() => {
if (!isLoading) {
return;
}
fetch(`/admin/sales-analytics/sales-channels-popularity?${deduceDateUrlParams(dateRange, dateRangeCompareTo, orderStatuses).toString()}`, {
credentials: "include"
}).then((res) => res.json()).then((result) => {
setData(result);
setLoading(false);
}).catch((error2) => {
setError(error2);
console.error(error2);
});
}, [isLoading]);
if (isLoading) {
return /* @__PURE__ */ jsxRuntime.jsx(material.CircularProgress, { size: 12 });
}
if (error) {
const trueError = error;
const errorText = `Error when loading data. It shouldn't have happened - please raise an issue. For developer: ${(_b = (_a = trueError == null ? void 0 : trueError.response) == null ? void 0 : _a.data) == null ? void 0 : _b.message}`;
return /* @__PURE__ */ jsxRuntime.jsx(ui.Alert, { variant: "error", children: errorText });
}
if (data && data.analytics == void 0) {
return /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", children: "Cannot get orders"