Revamp growth analytics to show all-time cumulative data

Refactors GrowthAnalyticsChart to display all-time growth since first sale, removes period selection, and introduces tabbed charts for daily, monthly, and customer segment analytics. Updates the GrowthAnalytics interface and service to return cumulative and segmented data, and simplifies API usage to always fetch all-time analytics. Improves customer segment breakdown and chart visualizations.
This commit is contained in:
g
2026-01-07 12:58:52 +00:00
parent 3e27a4b1f2
commit f17d623570
2 changed files with 500 additions and 383 deletions

View File

@@ -87,58 +87,53 @@ export interface OrderAnalytics {
}
export interface GrowthAnalytics {
period: {
start: string;
end: string;
days: number;
granularity: "daily" | "weekly" | "monthly";
};
summary: {
currentPeriod: {
revenue: number;
orders: number;
avgOrderValue: number;
customers: number;
};
previousPeriod: {
revenue: number;
orders: number;
avgOrderValue: number;
customers: number;
};
growthRates: {
revenue: number;
orders: number;
avgOrderValue: number;
customers: number;
};
};
customerInsights: {
newCustomers: number;
returningCustomers: number;
totalCustomers: number;
newCustomerRate: number;
avgOrdersPerCustomer: number;
avgSpentPerCustomer: number;
};
timeSeries: Array<{
launchDate: string;
generatedAt: string;
daily: Array<{
date: string;
revenue: number;
orders: number;
revenue: number;
customers: number;
avgOrderValue: number;
uniqueCustomers: number;
cumulativeRevenue: number;
cumulativeOrders: number;
}>;
topGrowingProducts: Array<{
productId: string;
productName: string;
currentPeriodRevenue: number;
previousPeriodRevenue: number;
revenueGrowth: number;
currentPeriodQuantity: number;
previousPeriodQuantity: number;
monthly: Array<{
month: string;
orders: number;
revenue: number;
customers: number;
avgOrderValue: number;
newCustomers: number;
}>;
customers: {
total: number;
segments: {
new: number;
returning: number;
loyal: number;
vip: number;
};
segmentDetails: {
[key: string]: {
count: number;
totalRevenue: number;
avgOrderCount: number;
avgSpent: number;
};
};
segmentPercentages: {
new: number;
returning: number;
loyal: number;
vip: number;
};
};
cumulative: {
orders: number;
revenue: number;
customers: number;
products: number;
avgOrderValue: number;
};
}
// Analytics Service Functions
@@ -223,21 +218,18 @@ export const getOrderAnalytics = async (
};
/**
* Get growth analytics data
* @param period Time period: "7", "30", "90", "365", or "all" (default: "30")
* @param granularity Data granularity: "daily", "weekly", "monthly" (auto-selected if not specified)
* Get growth analytics data (since first order)
* @param storeId Optional storeId for staff users
*/
export const getGrowthAnalytics = async (
period: string = "30",
granularity?: string,
storeId?: string,
): Promise<GrowthAnalytics> => {
const params = new URLSearchParams({ period });
if (granularity) params.append("granularity", granularity);
const params = new URLSearchParams();
if (storeId) params.append("storeId", storeId);
const url = `/analytics/growth?${params.toString()}`;
const url = params.toString()
? `/analytics/growth?${params.toString()}`
: "/analytics/growth";
return clientFetch<GrowthAnalytics>(url);
};
@@ -292,13 +284,11 @@ export const getOrderAnalyticsWithStore = async (
return getOrderAnalytics(period, storeId);
};
export const getGrowthAnalyticsWithStore = async (
period: string = "30",
granularity?: string,
): Promise<GrowthAnalytics> => {
const storeId = getStoreIdForUser();
return getGrowthAnalytics(period, granularity, storeId);
};
export const getGrowthAnalyticsWithStore =
async (): Promise<GrowthAnalytics> => {
const storeId = getStoreIdForUser();
return getGrowthAnalytics(storeId);
};
export function formatGBP(value: number) {
return value.toLocaleString("en-GB", {