@levi-gemcommerce/analytics 1.0.0-dev.14 → 1.0.0-dev.16
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/esm/core/gemxql/builder/clauses/time-query.d.ts +2 -1
- package/dist/esm/core/gemxql/builder/helpers/date-query-helpers.d.ts +1 -1
- package/dist/esm/core/gemxql/hooks/useAnalyticData.d.ts +1 -2
- package/dist/esm/core/gemxql/types/date-filter.d.ts +1 -1
- package/dist/esm/core/gemxql/types/index.d.ts +0 -1
- package/dist/esm/gemxql.js +183 -2
- package/dist/esm/gemxql.mjs +183 -2
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +117 -3
- package/dist/esm/index.mjs +117 -3
- package/dist/esm/providers/ConvertMoneyProvider.d.ts +13 -0
- package/dist/esm/providers/currencyRatesStore.d.ts +7 -0
- package/dist/esm/providers/index.d.ts +5 -0
- package/dist/esm/providers/useFetchCurrencyRates.d.ts +1 -0
- package/dist/esm/utils/currency.d.ts +5 -0
- package/dist/umd/esm/core/gemxql/builder/clauses/time-query.d.ts +2 -1
- package/dist/umd/esm/core/gemxql/builder/helpers/date-query-helpers.d.ts +1 -1
- package/dist/umd/esm/core/gemxql/hooks/useAnalyticData.d.ts +1 -2
- package/dist/umd/esm/core/gemxql/types/date-filter.d.ts +1 -1
- package/dist/umd/esm/core/gemxql/types/index.d.ts +0 -1
- package/dist/umd/esm/index.d.ts +1 -0
- package/dist/umd/esm/providers/ConvertMoneyProvider.d.ts +13 -0
- package/dist/umd/esm/providers/currencyRatesStore.d.ts +7 -0
- package/dist/umd/esm/providers/index.d.ts +5 -0
- package/dist/umd/esm/providers/useFetchCurrencyRates.d.ts +1 -0
- package/dist/umd/esm/utils/currency.d.ts +5 -0
- package/dist/umd/gemxql.js +1 -1
- package/dist/umd/index.js +1 -1
- package/package.json +2 -2
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { GemXQlFilters, GemXQlOverrideFilters } from '../../types';
|
|
2
|
+
import type { AnalyticDateFilter } from '@/components';
|
|
2
3
|
export interface IBuildTimeQueryParams {
|
|
3
4
|
dateRange?: AnalyticDateFilter;
|
|
4
5
|
compareDateRange?: AnalyticDateFilter;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { IGetTextPrice } from '../helpers/formatAnalyticData';
|
|
2
1
|
import type { AnalyticValueType } from '../types';
|
|
3
2
|
interface IFormatDataParams {
|
|
4
3
|
value: AnalyticValueType;
|
|
@@ -20,5 +19,5 @@ interface IUseAnalyticDataReturn {
|
|
|
20
19
|
formatData: (params: IFormatDataParams) => AnalyticValueType;
|
|
21
20
|
computeMetric: (params: IComputeMetricParams) => IComputeMetricResult;
|
|
22
21
|
}
|
|
23
|
-
export declare const useAnalyticData: (
|
|
22
|
+
export declare const useAnalyticData: () => IUseAnalyticDataReturn;
|
|
24
23
|
export {};
|
package/dist/esm/gemxql.js
CHANGED
|
@@ -3,7 +3,9 @@ import quarterOfYear from 'dayjs/plugin/quarterOfYear.js';
|
|
|
3
3
|
import timezone from 'dayjs/plugin/timezone.js';
|
|
4
4
|
import utc from 'dayjs/plugin/utc.js';
|
|
5
5
|
import { useQuery } from '@tanstack/react-query';
|
|
6
|
-
import {
|
|
6
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
7
|
+
import { createContext, useContext, useState, useRef, useCallback, useEffect } from 'react';
|
|
8
|
+
import { create } from 'zustand';
|
|
7
9
|
|
|
8
10
|
const NONE_VALUE = 'None';
|
|
9
11
|
const PLACEHOLDER_VALUE = '-';
|
|
@@ -947,7 +949,186 @@ const useGemxQlNamedQuery = ({ name, variables, fetcher }, options) => {
|
|
|
947
949
|
};
|
|
948
950
|
useGemxQlNamedQuery.getKey = (name, variables) => [name, variables];
|
|
949
951
|
|
|
950
|
-
|
|
952
|
+
var EMetricKey;
|
|
953
|
+
(function (EMetricKey) {
|
|
954
|
+
EMetricKey["SESSION"] = "sessions";
|
|
955
|
+
EMetricKey["ORDERS"] = "orders";
|
|
956
|
+
EMetricKey["PAGE_VIEWS"] = "pageviews";
|
|
957
|
+
EMetricKey["VISITORS"] = "visitors";
|
|
958
|
+
EMetricKey["BOUNCE_RATE"] = "bounce_rate";
|
|
959
|
+
EMetricKey["CTR"] = "ctr";
|
|
960
|
+
EMetricKey["CONVERSION_RATE"] = "conversion_rate";
|
|
961
|
+
EMetricKey["AVG_TIME_ON_PAGE"] = "average_time_on_page";
|
|
962
|
+
EMetricKey["ADDED_TO_CART"] = "added_to_cart";
|
|
963
|
+
EMetricKey["ADD_TO_CART_RATE"] = "added_to_cart_rate";
|
|
964
|
+
EMetricKey["REACHED_CHECKOUT"] = "sessions_that_reached_checkout";
|
|
965
|
+
EMetricKey["COMPLETE_CHECKOUT"] = "sessions_that_completed_checkout";
|
|
966
|
+
EMetricKey["CART_ADDITION"] = "sessions_with_cart_additions";
|
|
967
|
+
EMetricKey["AOV"] = "aov";
|
|
968
|
+
EMetricKey["REVENUE"] = "revenue";
|
|
969
|
+
EMetricKey["RPV"] = "revenue_per_visitor";
|
|
970
|
+
EMetricKey["VISITOR_ITEMS"] = "visitor_items";
|
|
971
|
+
EMetricKey["DEVICE_ITEMS"] = "device_items";
|
|
972
|
+
EMetricKey["TRAFFIC_SOURCE_ITEMS"] = "traffic_source_items";
|
|
973
|
+
})(EMetricKey || (EMetricKey = {}));
|
|
974
|
+
|
|
975
|
+
({
|
|
976
|
+
[EMetricKey.SESSION]: {
|
|
977
|
+
title: 'Sessions',
|
|
978
|
+
content: 'A period during which a visitor interacts with your online store',
|
|
979
|
+
},
|
|
980
|
+
[EMetricKey.VISITORS]: {
|
|
981
|
+
title: 'Visitors',
|
|
982
|
+
content: 'Number of unique individuals who visit your online store',
|
|
983
|
+
},
|
|
984
|
+
[EMetricKey.BOUNCE_RATE]: {
|
|
985
|
+
title: 'Bounce rate',
|
|
986
|
+
content: 'Percentage of visitors who leave your store after viewing only one page, without interacting further',
|
|
987
|
+
formula: (jsxs(Fragment, { children: [jsx("span", { className: "formula-variable", children: "Bounce rate" }), jsx("span", { children: " = " }), jsx("span", { className: "formula-input", children: "sessions with a pageview" }), jsx("span", { className: "formula-operator", children: " / " }), jsx("span", { className: "formula-input", children: "total sessions" })] })),
|
|
988
|
+
},
|
|
989
|
+
[EMetricKey.CTR]: {
|
|
990
|
+
title: 'Click-through rate',
|
|
991
|
+
content: 'Percentage of clicks to open new page, compared to the number of times the page was viewed',
|
|
992
|
+
formula: (jsxs(Fragment, { children: [jsx("span", { className: "formula-variable", children: "Click-through rate" }), jsx("span", { children: " = " }), jsx("span", { className: "formula-input", children: "total clicks" }), jsx("span", { className: "formula-operator", children: " / " }), jsx("span", { className: "formula-input", children: "total pageviews" })] })),
|
|
993
|
+
},
|
|
994
|
+
[EMetricKey.AVG_TIME_ON_PAGE]: {
|
|
995
|
+
title: 'Average time on page',
|
|
996
|
+
content: 'Average duration that visitors spend on a page before clicking to open new page',
|
|
997
|
+
formula: (jsxs(Fragment, { children: [jsx("span", { className: "formula-variable", children: "Average time on page" }), jsx("span", { children: " = " }), jsx("span", { className: "formula-input", children: "total time on page" }), jsx("span", { className: "formula-operator", children: " / " }), jsx("span", { className: "formula-input", children: "(total pageviews - total exits)" })] })),
|
|
998
|
+
},
|
|
999
|
+
[EMetricKey.PAGE_VIEWS]: {
|
|
1000
|
+
title: 'Pageviews',
|
|
1001
|
+
content: 'Number of times a page on your online store has been viewed by visitors',
|
|
1002
|
+
},
|
|
1003
|
+
[EMetricKey.RPV]: {
|
|
1004
|
+
title: 'Revenue per visitor',
|
|
1005
|
+
content: 'Average revenue generated from each visitor',
|
|
1006
|
+
formula: (jsxs(Fragment, { children: [jsx("span", { className: "formula-variable", children: "Revenue per visitor" }), jsx("span", { children: " = " }), jsx("span", { className: "formula-input", children: "total revenue" }), jsx("span", { className: "formula-operator", children: " / " }), jsx("span", { className: "formula-input", children: "total visitors" })] })),
|
|
1007
|
+
},
|
|
1008
|
+
[EMetricKey.ADDED_TO_CART]: {
|
|
1009
|
+
title: 'Added to cart',
|
|
1010
|
+
content: 'Total number of the event when a customer adds a product to their cart on your online store',
|
|
1011
|
+
},
|
|
1012
|
+
[EMetricKey.REACHED_CHECKOUT]: {
|
|
1013
|
+
title: 'Sessions that reached checkout',
|
|
1014
|
+
content: 'Sessions in your online store in which the checkout page was reached',
|
|
1015
|
+
},
|
|
1016
|
+
[EMetricKey.COMPLETE_CHECKOUT]: {
|
|
1017
|
+
title: 'Sessions that completed checkout',
|
|
1018
|
+
content: 'Sessions in your online store in which a purchase was completed',
|
|
1019
|
+
},
|
|
1020
|
+
[EMetricKey.ORDERS]: {
|
|
1021
|
+
title: 'Orders',
|
|
1022
|
+
content: 'Number of orders that went through this pages',
|
|
1023
|
+
},
|
|
1024
|
+
[EMetricKey.CONVERSION_RATE]: {
|
|
1025
|
+
title: 'Conversion rate',
|
|
1026
|
+
content: 'Percentage of online store sessions that completed an order',
|
|
1027
|
+
formula: (jsxs(Fragment, { children: [jsx("span", { className: "formula-variable", children: "Conversion rate" }), jsx("span", { children: " = " }), jsx("span", { className: "formula-input", children: "sessions that completed checkout" }), jsx("span", { className: "formula-operator", children: " / " }), jsx("span", { className: "formula-input", children: "total sessions" })] })),
|
|
1028
|
+
},
|
|
1029
|
+
[EMetricKey.AOV]: {
|
|
1030
|
+
title: 'Average order value',
|
|
1031
|
+
content: 'Average value of orders placed in your online store',
|
|
1032
|
+
formula: (jsxs(Fragment, { children: [jsx("span", { className: "formula-variable", children: "Average order value" }), jsx("span", { children: " = " }), jsx("span", { className: "formula-input", children: "total revenue" }), jsx("span", { className: "formula-operator", children: " / " }), jsx("span", { className: "formula-input", children: "total orders" })] })),
|
|
1033
|
+
},
|
|
1034
|
+
[EMetricKey.REVENUE]: {
|
|
1035
|
+
title: 'Revenue',
|
|
1036
|
+
content: 'Total income generated from sales after discounts',
|
|
1037
|
+
formula: (jsxs(Fragment, { children: [jsx("span", { className: "formula-variable", children: "Revenue" }), jsx("span", { children: " = " }), jsx("span", { className: "formula-input", children: "gross sales" }), jsx("span", { className: "formula-operator", children: " - " }), jsx("span", { className: "formula-input", children: "discounts" })] })),
|
|
1038
|
+
},
|
|
1039
|
+
[EMetricKey.ADD_TO_CART_RATE]: {
|
|
1040
|
+
title: 'Add to cart rate',
|
|
1041
|
+
content: 'Percentage of sessions in which the customer added item to the cart',
|
|
1042
|
+
formula: (jsxs(Fragment, { children: [jsx("span", { className: "formula-variable", children: "Added to cart rate" }), jsx("span", { children: " = " }), jsx("span", { className: "formula-input", children: "sessions with cart additions" }), jsx("span", { className: "formula-operator", children: " / " }), jsx("span", { className: "formula-input", children: "total sessions" })] })),
|
|
1043
|
+
},
|
|
1044
|
+
[EMetricKey.CART_ADDITION]: {
|
|
1045
|
+
title: 'Sessions with cart additions',
|
|
1046
|
+
content: 'Sessions in your online store in which a visitor added item to the cart',
|
|
1047
|
+
},
|
|
1048
|
+
[EMetricKey.VISITOR_ITEMS]: {
|
|
1049
|
+
title: 'Sessions by visitor type',
|
|
1050
|
+
content: '<p>Numbers of new and returning visitors</p>',
|
|
1051
|
+
contentList: [
|
|
1052
|
+
'New visitor: who accesses your store for the first time after GemX installation',
|
|
1053
|
+
'Returning visitor: who comes back to your store after GemX installation',
|
|
1054
|
+
],
|
|
1055
|
+
},
|
|
1056
|
+
[EMetricKey.DEVICE_ITEMS]: {
|
|
1057
|
+
title: 'Sessions by device type',
|
|
1058
|
+
content: `Sessions in your online store by the visitor's device type`,
|
|
1059
|
+
},
|
|
1060
|
+
[EMetricKey.TRAFFIC_SOURCE_ITEMS]: {
|
|
1061
|
+
title: 'Sessions by traffic source',
|
|
1062
|
+
content: 'Sessions on your page by where visitors come from',
|
|
1063
|
+
},
|
|
1064
|
+
});
|
|
1065
|
+
|
|
1066
|
+
var EAnalyticMode;
|
|
1067
|
+
(function (EAnalyticMode) {
|
|
1068
|
+
EAnalyticMode["ALL_SESSION"] = "ALL_SESSION";
|
|
1069
|
+
EAnalyticMode["FIRST_SESSION"] = "FIRST_SESSION";
|
|
1070
|
+
EAnalyticMode["PAGE_ONLY"] = "PAGE_ONLY";
|
|
1071
|
+
})(EAnalyticMode || (EAnalyticMode = {}));
|
|
1072
|
+
|
|
1073
|
+
var EVisitorType;
|
|
1074
|
+
(function (EVisitorType) {
|
|
1075
|
+
EVisitorType["NEW"] = "new";
|
|
1076
|
+
EVisitorType["RETURNING"] = "returning";
|
|
1077
|
+
})(EVisitorType || (EVisitorType = {}));
|
|
1078
|
+
var EDeviceType;
|
|
1079
|
+
(function (EDeviceType) {
|
|
1080
|
+
EDeviceType["DESKTOP"] = "desktop";
|
|
1081
|
+
EDeviceType["MOBILE"] = "mobile";
|
|
1082
|
+
EDeviceType["TABLET"] = "tablet";
|
|
1083
|
+
})(EDeviceType || (EDeviceType = {}));
|
|
1084
|
+
var ETrafficSourceType;
|
|
1085
|
+
(function (ETrafficSourceType) {
|
|
1086
|
+
ETrafficSourceType["DIRECT"] = "direct";
|
|
1087
|
+
ETrafficSourceType["EMAIL"] = "email";
|
|
1088
|
+
ETrafficSourceType["REFERRAL"] = "referral";
|
|
1089
|
+
ETrafficSourceType["ORGANIC_SOCIAL"] = "organic-social";
|
|
1090
|
+
ETrafficSourceType["ORGANIC_SEARCH"] = "organic-search";
|
|
1091
|
+
ETrafficSourceType["PAID_SOCIAL"] = "paid-social";
|
|
1092
|
+
ETrafficSourceType["PAID_SEARCH"] = "paid-search";
|
|
1093
|
+
ETrafficSourceType["SMS"] = "sms";
|
|
1094
|
+
})(ETrafficSourceType || (ETrafficSourceType = {}));
|
|
1095
|
+
|
|
1096
|
+
[
|
|
1097
|
+
{ value: EVisitorType.NEW, label: 'New' },
|
|
1098
|
+
{ value: EVisitorType.RETURNING, label: 'Returning' },
|
|
1099
|
+
];
|
|
1100
|
+
[
|
|
1101
|
+
{ value: EDeviceType.DESKTOP, label: 'Desktop' },
|
|
1102
|
+
{ value: EDeviceType.TABLET, label: 'Tablet' },
|
|
1103
|
+
{ value: EDeviceType.MOBILE, label: 'Mobile' },
|
|
1104
|
+
];
|
|
1105
|
+
[
|
|
1106
|
+
{ value: ETrafficSourceType.DIRECT, label: 'Direct' },
|
|
1107
|
+
{ value: ETrafficSourceType.EMAIL, label: 'Email' },
|
|
1108
|
+
{ value: ETrafficSourceType.REFERRAL, label: 'Referral' },
|
|
1109
|
+
{ value: ETrafficSourceType.ORGANIC_SOCIAL, label: 'Organic social' },
|
|
1110
|
+
{ value: ETrafficSourceType.ORGANIC_SEARCH, label: 'Organic search' },
|
|
1111
|
+
{ value: ETrafficSourceType.PAID_SOCIAL, label: 'Paid social' },
|
|
1112
|
+
{ value: ETrafficSourceType.PAID_SEARCH, label: 'Paid search' },
|
|
1113
|
+
{ value: ETrafficSourceType.SMS, label: 'SMS' },
|
|
1114
|
+
];
|
|
1115
|
+
|
|
1116
|
+
create((set) => ({
|
|
1117
|
+
currencyRates: null,
|
|
1118
|
+
setCurrencyRates: (rates) => set({ currencyRates: rates }),
|
|
1119
|
+
}));
|
|
1120
|
+
|
|
1121
|
+
const ConvertMoneyContext = createContext({
|
|
1122
|
+
getTextPrice: (price) => {
|
|
1123
|
+
if (typeof price === 'string')
|
|
1124
|
+
return price;
|
|
1125
|
+
return `${price ?? 0}`;
|
|
1126
|
+
},
|
|
1127
|
+
});
|
|
1128
|
+
const useConvertMoneyContext = () => useContext(ConvertMoneyContext);
|
|
1129
|
+
|
|
1130
|
+
const useAnalyticData = () => {
|
|
1131
|
+
const { getTextPrice } = useConvertMoneyContext();
|
|
951
1132
|
const formatData = ({ value, formatter, name }) => {
|
|
952
1133
|
return formatAnalyticData({ value, formatter, getTextPrice, name });
|
|
953
1134
|
};
|
package/dist/esm/gemxql.mjs
CHANGED
|
@@ -3,7 +3,9 @@ import quarterOfYear from 'dayjs/plugin/quarterOfYear.js';
|
|
|
3
3
|
import timezone from 'dayjs/plugin/timezone.js';
|
|
4
4
|
import utc from 'dayjs/plugin/utc.js';
|
|
5
5
|
import { useQuery } from '@tanstack/react-query';
|
|
6
|
-
import {
|
|
6
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
7
|
+
import { createContext, useContext, useState, useRef, useCallback, useEffect } from 'react';
|
|
8
|
+
import { create } from 'zustand';
|
|
7
9
|
|
|
8
10
|
const NONE_VALUE = 'None';
|
|
9
11
|
const PLACEHOLDER_VALUE = '-';
|
|
@@ -947,7 +949,186 @@ const useGemxQlNamedQuery = ({ name, variables, fetcher }, options) => {
|
|
|
947
949
|
};
|
|
948
950
|
useGemxQlNamedQuery.getKey = (name, variables) => [name, variables];
|
|
949
951
|
|
|
950
|
-
|
|
952
|
+
var EMetricKey;
|
|
953
|
+
(function (EMetricKey) {
|
|
954
|
+
EMetricKey["SESSION"] = "sessions";
|
|
955
|
+
EMetricKey["ORDERS"] = "orders";
|
|
956
|
+
EMetricKey["PAGE_VIEWS"] = "pageviews";
|
|
957
|
+
EMetricKey["VISITORS"] = "visitors";
|
|
958
|
+
EMetricKey["BOUNCE_RATE"] = "bounce_rate";
|
|
959
|
+
EMetricKey["CTR"] = "ctr";
|
|
960
|
+
EMetricKey["CONVERSION_RATE"] = "conversion_rate";
|
|
961
|
+
EMetricKey["AVG_TIME_ON_PAGE"] = "average_time_on_page";
|
|
962
|
+
EMetricKey["ADDED_TO_CART"] = "added_to_cart";
|
|
963
|
+
EMetricKey["ADD_TO_CART_RATE"] = "added_to_cart_rate";
|
|
964
|
+
EMetricKey["REACHED_CHECKOUT"] = "sessions_that_reached_checkout";
|
|
965
|
+
EMetricKey["COMPLETE_CHECKOUT"] = "sessions_that_completed_checkout";
|
|
966
|
+
EMetricKey["CART_ADDITION"] = "sessions_with_cart_additions";
|
|
967
|
+
EMetricKey["AOV"] = "aov";
|
|
968
|
+
EMetricKey["REVENUE"] = "revenue";
|
|
969
|
+
EMetricKey["RPV"] = "revenue_per_visitor";
|
|
970
|
+
EMetricKey["VISITOR_ITEMS"] = "visitor_items";
|
|
971
|
+
EMetricKey["DEVICE_ITEMS"] = "device_items";
|
|
972
|
+
EMetricKey["TRAFFIC_SOURCE_ITEMS"] = "traffic_source_items";
|
|
973
|
+
})(EMetricKey || (EMetricKey = {}));
|
|
974
|
+
|
|
975
|
+
({
|
|
976
|
+
[EMetricKey.SESSION]: {
|
|
977
|
+
title: 'Sessions',
|
|
978
|
+
content: 'A period during which a visitor interacts with your online store',
|
|
979
|
+
},
|
|
980
|
+
[EMetricKey.VISITORS]: {
|
|
981
|
+
title: 'Visitors',
|
|
982
|
+
content: 'Number of unique individuals who visit your online store',
|
|
983
|
+
},
|
|
984
|
+
[EMetricKey.BOUNCE_RATE]: {
|
|
985
|
+
title: 'Bounce rate',
|
|
986
|
+
content: 'Percentage of visitors who leave your store after viewing only one page, without interacting further',
|
|
987
|
+
formula: (jsxs(Fragment, { children: [jsx("span", { className: "formula-variable", children: "Bounce rate" }), jsx("span", { children: " = " }), jsx("span", { className: "formula-input", children: "sessions with a pageview" }), jsx("span", { className: "formula-operator", children: " / " }), jsx("span", { className: "formula-input", children: "total sessions" })] })),
|
|
988
|
+
},
|
|
989
|
+
[EMetricKey.CTR]: {
|
|
990
|
+
title: 'Click-through rate',
|
|
991
|
+
content: 'Percentage of clicks to open new page, compared to the number of times the page was viewed',
|
|
992
|
+
formula: (jsxs(Fragment, { children: [jsx("span", { className: "formula-variable", children: "Click-through rate" }), jsx("span", { children: " = " }), jsx("span", { className: "formula-input", children: "total clicks" }), jsx("span", { className: "formula-operator", children: " / " }), jsx("span", { className: "formula-input", children: "total pageviews" })] })),
|
|
993
|
+
},
|
|
994
|
+
[EMetricKey.AVG_TIME_ON_PAGE]: {
|
|
995
|
+
title: 'Average time on page',
|
|
996
|
+
content: 'Average duration that visitors spend on a page before clicking to open new page',
|
|
997
|
+
formula: (jsxs(Fragment, { children: [jsx("span", { className: "formula-variable", children: "Average time on page" }), jsx("span", { children: " = " }), jsx("span", { className: "formula-input", children: "total time on page" }), jsx("span", { className: "formula-operator", children: " / " }), jsx("span", { className: "formula-input", children: "(total pageviews - total exits)" })] })),
|
|
998
|
+
},
|
|
999
|
+
[EMetricKey.PAGE_VIEWS]: {
|
|
1000
|
+
title: 'Pageviews',
|
|
1001
|
+
content: 'Number of times a page on your online store has been viewed by visitors',
|
|
1002
|
+
},
|
|
1003
|
+
[EMetricKey.RPV]: {
|
|
1004
|
+
title: 'Revenue per visitor',
|
|
1005
|
+
content: 'Average revenue generated from each visitor',
|
|
1006
|
+
formula: (jsxs(Fragment, { children: [jsx("span", { className: "formula-variable", children: "Revenue per visitor" }), jsx("span", { children: " = " }), jsx("span", { className: "formula-input", children: "total revenue" }), jsx("span", { className: "formula-operator", children: " / " }), jsx("span", { className: "formula-input", children: "total visitors" })] })),
|
|
1007
|
+
},
|
|
1008
|
+
[EMetricKey.ADDED_TO_CART]: {
|
|
1009
|
+
title: 'Added to cart',
|
|
1010
|
+
content: 'Total number of the event when a customer adds a product to their cart on your online store',
|
|
1011
|
+
},
|
|
1012
|
+
[EMetricKey.REACHED_CHECKOUT]: {
|
|
1013
|
+
title: 'Sessions that reached checkout',
|
|
1014
|
+
content: 'Sessions in your online store in which the checkout page was reached',
|
|
1015
|
+
},
|
|
1016
|
+
[EMetricKey.COMPLETE_CHECKOUT]: {
|
|
1017
|
+
title: 'Sessions that completed checkout',
|
|
1018
|
+
content: 'Sessions in your online store in which a purchase was completed',
|
|
1019
|
+
},
|
|
1020
|
+
[EMetricKey.ORDERS]: {
|
|
1021
|
+
title: 'Orders',
|
|
1022
|
+
content: 'Number of orders that went through this pages',
|
|
1023
|
+
},
|
|
1024
|
+
[EMetricKey.CONVERSION_RATE]: {
|
|
1025
|
+
title: 'Conversion rate',
|
|
1026
|
+
content: 'Percentage of online store sessions that completed an order',
|
|
1027
|
+
formula: (jsxs(Fragment, { children: [jsx("span", { className: "formula-variable", children: "Conversion rate" }), jsx("span", { children: " = " }), jsx("span", { className: "formula-input", children: "sessions that completed checkout" }), jsx("span", { className: "formula-operator", children: " / " }), jsx("span", { className: "formula-input", children: "total sessions" })] })),
|
|
1028
|
+
},
|
|
1029
|
+
[EMetricKey.AOV]: {
|
|
1030
|
+
title: 'Average order value',
|
|
1031
|
+
content: 'Average value of orders placed in your online store',
|
|
1032
|
+
formula: (jsxs(Fragment, { children: [jsx("span", { className: "formula-variable", children: "Average order value" }), jsx("span", { children: " = " }), jsx("span", { className: "formula-input", children: "total revenue" }), jsx("span", { className: "formula-operator", children: " / " }), jsx("span", { className: "formula-input", children: "total orders" })] })),
|
|
1033
|
+
},
|
|
1034
|
+
[EMetricKey.REVENUE]: {
|
|
1035
|
+
title: 'Revenue',
|
|
1036
|
+
content: 'Total income generated from sales after discounts',
|
|
1037
|
+
formula: (jsxs(Fragment, { children: [jsx("span", { className: "formula-variable", children: "Revenue" }), jsx("span", { children: " = " }), jsx("span", { className: "formula-input", children: "gross sales" }), jsx("span", { className: "formula-operator", children: " - " }), jsx("span", { className: "formula-input", children: "discounts" })] })),
|
|
1038
|
+
},
|
|
1039
|
+
[EMetricKey.ADD_TO_CART_RATE]: {
|
|
1040
|
+
title: 'Add to cart rate',
|
|
1041
|
+
content: 'Percentage of sessions in which the customer added item to the cart',
|
|
1042
|
+
formula: (jsxs(Fragment, { children: [jsx("span", { className: "formula-variable", children: "Added to cart rate" }), jsx("span", { children: " = " }), jsx("span", { className: "formula-input", children: "sessions with cart additions" }), jsx("span", { className: "formula-operator", children: " / " }), jsx("span", { className: "formula-input", children: "total sessions" })] })),
|
|
1043
|
+
},
|
|
1044
|
+
[EMetricKey.CART_ADDITION]: {
|
|
1045
|
+
title: 'Sessions with cart additions',
|
|
1046
|
+
content: 'Sessions in your online store in which a visitor added item to the cart',
|
|
1047
|
+
},
|
|
1048
|
+
[EMetricKey.VISITOR_ITEMS]: {
|
|
1049
|
+
title: 'Sessions by visitor type',
|
|
1050
|
+
content: '<p>Numbers of new and returning visitors</p>',
|
|
1051
|
+
contentList: [
|
|
1052
|
+
'New visitor: who accesses your store for the first time after GemX installation',
|
|
1053
|
+
'Returning visitor: who comes back to your store after GemX installation',
|
|
1054
|
+
],
|
|
1055
|
+
},
|
|
1056
|
+
[EMetricKey.DEVICE_ITEMS]: {
|
|
1057
|
+
title: 'Sessions by device type',
|
|
1058
|
+
content: `Sessions in your online store by the visitor's device type`,
|
|
1059
|
+
},
|
|
1060
|
+
[EMetricKey.TRAFFIC_SOURCE_ITEMS]: {
|
|
1061
|
+
title: 'Sessions by traffic source',
|
|
1062
|
+
content: 'Sessions on your page by where visitors come from',
|
|
1063
|
+
},
|
|
1064
|
+
});
|
|
1065
|
+
|
|
1066
|
+
var EAnalyticMode;
|
|
1067
|
+
(function (EAnalyticMode) {
|
|
1068
|
+
EAnalyticMode["ALL_SESSION"] = "ALL_SESSION";
|
|
1069
|
+
EAnalyticMode["FIRST_SESSION"] = "FIRST_SESSION";
|
|
1070
|
+
EAnalyticMode["PAGE_ONLY"] = "PAGE_ONLY";
|
|
1071
|
+
})(EAnalyticMode || (EAnalyticMode = {}));
|
|
1072
|
+
|
|
1073
|
+
var EVisitorType;
|
|
1074
|
+
(function (EVisitorType) {
|
|
1075
|
+
EVisitorType["NEW"] = "new";
|
|
1076
|
+
EVisitorType["RETURNING"] = "returning";
|
|
1077
|
+
})(EVisitorType || (EVisitorType = {}));
|
|
1078
|
+
var EDeviceType;
|
|
1079
|
+
(function (EDeviceType) {
|
|
1080
|
+
EDeviceType["DESKTOP"] = "desktop";
|
|
1081
|
+
EDeviceType["MOBILE"] = "mobile";
|
|
1082
|
+
EDeviceType["TABLET"] = "tablet";
|
|
1083
|
+
})(EDeviceType || (EDeviceType = {}));
|
|
1084
|
+
var ETrafficSourceType;
|
|
1085
|
+
(function (ETrafficSourceType) {
|
|
1086
|
+
ETrafficSourceType["DIRECT"] = "direct";
|
|
1087
|
+
ETrafficSourceType["EMAIL"] = "email";
|
|
1088
|
+
ETrafficSourceType["REFERRAL"] = "referral";
|
|
1089
|
+
ETrafficSourceType["ORGANIC_SOCIAL"] = "organic-social";
|
|
1090
|
+
ETrafficSourceType["ORGANIC_SEARCH"] = "organic-search";
|
|
1091
|
+
ETrafficSourceType["PAID_SOCIAL"] = "paid-social";
|
|
1092
|
+
ETrafficSourceType["PAID_SEARCH"] = "paid-search";
|
|
1093
|
+
ETrafficSourceType["SMS"] = "sms";
|
|
1094
|
+
})(ETrafficSourceType || (ETrafficSourceType = {}));
|
|
1095
|
+
|
|
1096
|
+
[
|
|
1097
|
+
{ value: EVisitorType.NEW, label: 'New' },
|
|
1098
|
+
{ value: EVisitorType.RETURNING, label: 'Returning' },
|
|
1099
|
+
];
|
|
1100
|
+
[
|
|
1101
|
+
{ value: EDeviceType.DESKTOP, label: 'Desktop' },
|
|
1102
|
+
{ value: EDeviceType.TABLET, label: 'Tablet' },
|
|
1103
|
+
{ value: EDeviceType.MOBILE, label: 'Mobile' },
|
|
1104
|
+
];
|
|
1105
|
+
[
|
|
1106
|
+
{ value: ETrafficSourceType.DIRECT, label: 'Direct' },
|
|
1107
|
+
{ value: ETrafficSourceType.EMAIL, label: 'Email' },
|
|
1108
|
+
{ value: ETrafficSourceType.REFERRAL, label: 'Referral' },
|
|
1109
|
+
{ value: ETrafficSourceType.ORGANIC_SOCIAL, label: 'Organic social' },
|
|
1110
|
+
{ value: ETrafficSourceType.ORGANIC_SEARCH, label: 'Organic search' },
|
|
1111
|
+
{ value: ETrafficSourceType.PAID_SOCIAL, label: 'Paid social' },
|
|
1112
|
+
{ value: ETrafficSourceType.PAID_SEARCH, label: 'Paid search' },
|
|
1113
|
+
{ value: ETrafficSourceType.SMS, label: 'SMS' },
|
|
1114
|
+
];
|
|
1115
|
+
|
|
1116
|
+
create((set) => ({
|
|
1117
|
+
currencyRates: null,
|
|
1118
|
+
setCurrencyRates: (rates) => set({ currencyRates: rates }),
|
|
1119
|
+
}));
|
|
1120
|
+
|
|
1121
|
+
const ConvertMoneyContext = createContext({
|
|
1122
|
+
getTextPrice: (price) => {
|
|
1123
|
+
if (typeof price === 'string')
|
|
1124
|
+
return price;
|
|
1125
|
+
return `${price ?? 0}`;
|
|
1126
|
+
},
|
|
1127
|
+
});
|
|
1128
|
+
const useConvertMoneyContext = () => useContext(ConvertMoneyContext);
|
|
1129
|
+
|
|
1130
|
+
const useAnalyticData = () => {
|
|
1131
|
+
const { getTextPrice } = useConvertMoneyContext();
|
|
951
1132
|
const formatData = ({ value, formatter, name }) => {
|
|
952
1133
|
return formatAnalyticData({ value, formatter, getTextPrice, name });
|
|
953
1134
|
};
|
package/dist/esm/index.d.ts
CHANGED
package/dist/esm/index.js
CHANGED
|
@@ -8,8 +8,9 @@ import quarterOfYear from 'dayjs/plugin/quarterOfYear.js';
|
|
|
8
8
|
import timezone from 'dayjs/plugin/timezone.js';
|
|
9
9
|
import utc from 'dayjs/plugin/utc.js';
|
|
10
10
|
import { useTranslation } from 'react-i18next';
|
|
11
|
+
import { create } from 'zustand';
|
|
12
|
+
import { useQuery } from '@tanstack/react-query';
|
|
11
13
|
import { PolarisVizProvider, LineChart, DonutChart } from '@shopify/polaris-viz';
|
|
12
|
-
import '@tanstack/react-query';
|
|
13
14
|
|
|
14
15
|
var EMetricKey;
|
|
15
16
|
(function (EMetricKey) {
|
|
@@ -879,6 +880,118 @@ const GChartSkeleton = () => {
|
|
|
879
880
|
return jsx(GSkeletonDisplayText, { height: "188px" });
|
|
880
881
|
};
|
|
881
882
|
|
|
883
|
+
const getPriceByCurrency = (price, currency = DEFAULT_CURRENCY_ANALYTIC, options) => {
|
|
884
|
+
if (typeof price === 'string')
|
|
885
|
+
return price;
|
|
886
|
+
if (typeof price !== 'number')
|
|
887
|
+
return;
|
|
888
|
+
// Support legacy 3rd arg as locale string
|
|
889
|
+
const opts = typeof options === 'string' ? { locale: options } : options;
|
|
890
|
+
const locale = opts?.locale ?? 'en-US';
|
|
891
|
+
if (price >= 1_000_000_000) {
|
|
892
|
+
return `${new Intl.NumberFormat(locale, {
|
|
893
|
+
style: 'currency',
|
|
894
|
+
currency,
|
|
895
|
+
minimumFractionDigits: 2,
|
|
896
|
+
maximumFractionDigits: 2,
|
|
897
|
+
}).format(price / 1_000_000_000)}B`;
|
|
898
|
+
}
|
|
899
|
+
if (price >= 1_000_000) {
|
|
900
|
+
return `${new Intl.NumberFormat(locale, {
|
|
901
|
+
style: 'currency',
|
|
902
|
+
currency,
|
|
903
|
+
minimumFractionDigits: 2,
|
|
904
|
+
maximumFractionDigits: 2,
|
|
905
|
+
}).format(price / 1_000_000)}M`;
|
|
906
|
+
}
|
|
907
|
+
if (opts?.compact && Math.abs(price) >= 1_000) {
|
|
908
|
+
return `${new Intl.NumberFormat(locale, {
|
|
909
|
+
style: 'currency',
|
|
910
|
+
currency,
|
|
911
|
+
minimumFractionDigits: 1,
|
|
912
|
+
maximumFractionDigits: 1,
|
|
913
|
+
}).format(price / 1_000)}K`;
|
|
914
|
+
}
|
|
915
|
+
return new Intl.NumberFormat(locale, {
|
|
916
|
+
style: 'currency',
|
|
917
|
+
currency,
|
|
918
|
+
}).format(price);
|
|
919
|
+
};
|
|
920
|
+
|
|
921
|
+
const useCurrencyRatesStore = create((set) => ({
|
|
922
|
+
currencyRates: null,
|
|
923
|
+
setCurrencyRates: (rates) => set({ currencyRates: rates }),
|
|
924
|
+
}));
|
|
925
|
+
|
|
926
|
+
const SHOPIFY_CURRENCIES_URL = 'https://cdn.shopify.com/s/javascripts/currencies.js';
|
|
927
|
+
const parseCurrencyRates = (scriptText) => {
|
|
928
|
+
const rates = {};
|
|
929
|
+
const match = /var Currency=\{rates:\{(.*?)\}\};/s.exec(scriptText);
|
|
930
|
+
const ratesStr = match?.[1];
|
|
931
|
+
if (!ratesStr)
|
|
932
|
+
return rates;
|
|
933
|
+
const ratePattern = /([A-Z]+):\s*([\d.e+-]+),/g;
|
|
934
|
+
let m;
|
|
935
|
+
while ((m = ratePattern.exec(ratesStr)) !== null) {
|
|
936
|
+
const [, code, value] = m;
|
|
937
|
+
if (code && value)
|
|
938
|
+
rates[code] = parseFloat(value);
|
|
939
|
+
}
|
|
940
|
+
return rates;
|
|
941
|
+
};
|
|
942
|
+
const fetchCurrencyRates = async () => {
|
|
943
|
+
const res = await fetch(SHOPIFY_CURRENCIES_URL);
|
|
944
|
+
if (!res.ok)
|
|
945
|
+
throw new Error('Failed to fetch currency rates');
|
|
946
|
+
const text = await res.text();
|
|
947
|
+
return parseCurrencyRates(text);
|
|
948
|
+
};
|
|
949
|
+
const useFetchCurrencyRates = () => {
|
|
950
|
+
const setCurrencyRates = useCurrencyRatesStore((state) => state.setCurrencyRates);
|
|
951
|
+
const { data } = useQuery({
|
|
952
|
+
queryKey: ['sdk-currency-rates'],
|
|
953
|
+
queryFn: fetchCurrencyRates,
|
|
954
|
+
staleTime: 1000 * 60 * 60, // 1 hour — rates don't change often
|
|
955
|
+
});
|
|
956
|
+
useEffect(() => {
|
|
957
|
+
if (data)
|
|
958
|
+
setCurrencyRates(data);
|
|
959
|
+
}, [data, setCurrencyRates]);
|
|
960
|
+
};
|
|
961
|
+
|
|
962
|
+
const ConvertMoneyContext = createContext({
|
|
963
|
+
getTextPrice: (price) => {
|
|
964
|
+
if (typeof price === 'string')
|
|
965
|
+
return price;
|
|
966
|
+
return `${price ?? 0}`;
|
|
967
|
+
},
|
|
968
|
+
});
|
|
969
|
+
const convertAmount = (amount, from, to, rates) => {
|
|
970
|
+
if (from === to || !rates[from] || !rates[to])
|
|
971
|
+
return amount;
|
|
972
|
+
const converted = (amount * rates[from]) / rates[to];
|
|
973
|
+
return converted ? Number(converted.toFixed(2)) : amount;
|
|
974
|
+
};
|
|
975
|
+
const ConvertMoneyProvider = ({ children, currency, locale = 'en-US' }) => {
|
|
976
|
+
useFetchCurrencyRates();
|
|
977
|
+
const currencyRates = useCurrencyRatesStore((state) => state.currencyRates);
|
|
978
|
+
const getTextPrice = useCallback((price, _hasCurrency, options) => {
|
|
979
|
+
if (typeof price === 'string')
|
|
980
|
+
return price;
|
|
981
|
+
if (typeof price !== 'number')
|
|
982
|
+
return '0';
|
|
983
|
+
if (!currency)
|
|
984
|
+
return price.toString();
|
|
985
|
+
const converted = currencyRates
|
|
986
|
+
? convertAmount(price, DEFAULT_CURRENCY_ANALYTIC, currency, currencyRates)
|
|
987
|
+
: price;
|
|
988
|
+
return trimDecimalZeros(getPriceByCurrency(converted, currency, { locale, compact: options?.compact }) ?? '0');
|
|
989
|
+
}, [currency, locale, currencyRates]);
|
|
990
|
+
const value = useMemo(() => ({ getTextPrice }), [getTextPrice]);
|
|
991
|
+
return jsx(ConvertMoneyContext.Provider, { value: value, children: children });
|
|
992
|
+
};
|
|
993
|
+
const useConvertMoneyContext = () => useContext(ConvertMoneyContext);
|
|
994
|
+
|
|
882
995
|
const LINE_SERIES_COLORS = {
|
|
883
996
|
comparison: SERIES_COLORS.comparison,
|
|
884
997
|
single: SERIES_COLORS.current,
|
|
@@ -1169,7 +1282,8 @@ const readNumeric = (metric, key) => {
|
|
|
1169
1282
|
return typeof raw === 'number' ? raw : 0;
|
|
1170
1283
|
};
|
|
1171
1284
|
|
|
1172
|
-
const useAnalyticData = (
|
|
1285
|
+
const useAnalyticData = () => {
|
|
1286
|
+
const { getTextPrice } = useConvertMoneyContext();
|
|
1173
1287
|
const formatData = ({ value, formatter, name }) => {
|
|
1174
1288
|
return formatAnalyticData({ value, formatter, getTextPrice, name });
|
|
1175
1289
|
};
|
|
@@ -2525,4 +2639,4 @@ const GTimePicker = (props) => {
|
|
|
2525
2639
|
return (jsxs(InlineStack, { gap: "200", children: [jsx(MainTimePicker, { ...timePickerProps }), isCompare && (jsx(CompareTimePicker, { rangeAddition: timePickerProps.rangeAddition, popoverProps: timePickerProps.popoverProps }))] }));
|
|
2526
2640
|
};
|
|
2527
2641
|
|
|
2528
|
-
export { ANALYTICS_METRIC_TOOLTIP, AnalyticModeSelector, CAMPAIGN_BACKGROUND_MAIN, CHART_MIN_HEIGHT, COMPARE_DATE_TIME_FILTERS_MAP, CompareDateTimePickerAlias, CurrencySelector, DATE_TIME_COMPARISON_FILTERS, DEFAULT_CURRENCY_ANALYTIC, DEFAULT_CURRENT_PERIOD_LABEL, DEFAULT_PREVIOUS_PERIOD_LABEL, DateTimeFilterInputs, DateTimeFilters, DateTimePickerContext, DateTimePickerProvider, GSelectableMetricChartCard, GTimePicker, MainDateTimePickerAlias, MetricDonutChartCard, PLACEHOLDER_VALUE$1 as PLACEHOLDER_VALUE, PREVIOUS_PERIOD_FILTER, SERIES_COLORS, SingleMetricChartCard, TARGET_CHANNEL, TARGET_DEVICES, TARGET_VISITOR, THUMB_PRODUCT_DEFAULT, TREND_TONE, convertDateToTz, convertToDateTimeFilters, createLastDaysRange, dayjsTz, dayjsTzToDate, dayjsTzToLocalTZ, formatDate, formatDateTimeRange, formatDayjs, formatMs, formatTime, formatTimeRange, getDateRangeTitle, getDateTimeFilterBase, getDateTimeFilterByAlias, getDateTimeFilterMapping, getEndOfDayBy, getInitialTimezone, getLast12Months, getLast30Days, getLast365Days, getLast7Days, getLast90Days, getLastMonth, getLastYear, getMonthAndYearByDateFilter, getNoComparison, getPreviousMonth, getPreviousPeriod, getPreviousQuarter, getPreviousWeek, getPreviousYear, getToday, getVersionDateDescription, getVersionDateRangeTitle, getYesterday, isDate, isMidnight, isSameDayTimestamp, isValidDate, isValidYearMonthDayDateString, parseYearMonthDayDateString, setTz, useDateTimeFilter, useDateTimePicker, useDateTimePickerContext, useVersionDateTimeFilters };
|
|
2642
|
+
export { ANALYTICS_METRIC_TOOLTIP, AnalyticModeSelector, CAMPAIGN_BACKGROUND_MAIN, CHART_MIN_HEIGHT, COMPARE_DATE_TIME_FILTERS_MAP, CompareDateTimePickerAlias, ConvertMoneyProvider, CurrencySelector, DATE_TIME_COMPARISON_FILTERS, DEFAULT_CURRENCY_ANALYTIC, DEFAULT_CURRENT_PERIOD_LABEL, DEFAULT_PREVIOUS_PERIOD_LABEL, DateTimeFilterInputs, DateTimeFilters, DateTimePickerContext, DateTimePickerProvider, GSelectableMetricChartCard, GTimePicker, MainDateTimePickerAlias, MetricChartProvider, MetricDonutChartCard, PLACEHOLDER_VALUE$1 as PLACEHOLDER_VALUE, PREVIOUS_PERIOD_FILTER, SERIES_COLORS, SingleMetricChartCard, TARGET_CHANNEL, TARGET_DEVICES, TARGET_VISITOR, THUMB_PRODUCT_DEFAULT, TREND_TONE, convertDateToTz, convertToDateTimeFilters, createLastDaysRange, dayjsTz, dayjsTzToDate, dayjsTzToLocalTZ, formatDate, formatDateTimeRange, formatDayjs, formatMs, formatTime, formatTimeRange, getDateRangeTitle, getDateTimeFilterBase, getDateTimeFilterByAlias, getDateTimeFilterMapping, getEndOfDayBy, getInitialTimezone, getLast12Months, getLast30Days, getLast365Days, getLast7Days, getLast90Days, getLastMonth, getLastYear, getMonthAndYearByDateFilter, getNoComparison, getPreviousMonth, getPreviousPeriod, getPreviousQuarter, getPreviousWeek, getPreviousYear, getToday, getVersionDateDescription, getVersionDateRangeTitle, getYesterday, isDate, isMidnight, isSameDayTimestamp, isValidDate, isValidYearMonthDayDateString, parseYearMonthDayDateString, setTz, useConvertMoneyContext, useCurrencyRatesStore, useDateTimeFilter, useDateTimePicker, useDateTimePickerContext, useFetchCurrencyRates, useVersionDateTimeFilters };
|