190 lines
5.0 KiB
TypeScript
190 lines
5.0 KiB
TypeScript
'use client';
|
|
|
|
import { clientFetch } from '../api-client';
|
|
|
|
// Analytics Types
|
|
export interface AnalyticsOverview {
|
|
orders: {
|
|
total: number;
|
|
completed: number;
|
|
pending: number;
|
|
completionRate: string;
|
|
};
|
|
revenue: {
|
|
total: number;
|
|
monthly: number;
|
|
weekly: number;
|
|
averageOrderValue: number;
|
|
};
|
|
products: {
|
|
total: number;
|
|
};
|
|
customers: {
|
|
unique: number;
|
|
};
|
|
userType?: 'vendor' | 'staff';
|
|
}
|
|
|
|
export interface RevenueData {
|
|
_id: {
|
|
year: number;
|
|
month: number;
|
|
day: number;
|
|
};
|
|
revenue: number;
|
|
orders: number;
|
|
}
|
|
|
|
export interface ProductPerformance {
|
|
productId: string;
|
|
name: string;
|
|
image: string;
|
|
unitType: string;
|
|
currentStock: number;
|
|
stockStatus: string;
|
|
totalSold: number;
|
|
totalRevenue: number;
|
|
orderCount: number;
|
|
averagePrice: number;
|
|
}
|
|
|
|
export interface CustomerInsights {
|
|
totalCustomers: number;
|
|
segments: {
|
|
new: number;
|
|
returning: number;
|
|
loyal: number;
|
|
vip: number;
|
|
};
|
|
topCustomers: Array<{
|
|
_id: string;
|
|
orderCount: number;
|
|
totalSpent: number;
|
|
averageOrderValue: number;
|
|
firstOrder: string;
|
|
lastOrder: string;
|
|
}>;
|
|
averageOrdersPerCustomer: string;
|
|
}
|
|
|
|
export interface OrderAnalytics {
|
|
statusDistribution: Array<{
|
|
_id: string;
|
|
count: number;
|
|
}>;
|
|
dailyOrders: Array<{
|
|
_id: {
|
|
year: number;
|
|
month: number;
|
|
day: number;
|
|
};
|
|
orders: number;
|
|
revenue: number;
|
|
}>;
|
|
averageProcessingDays: number;
|
|
}
|
|
|
|
// Analytics Service Functions
|
|
|
|
/**
|
|
* Get analytics overview data
|
|
* @param storeId Optional storeId for staff users
|
|
*/
|
|
export const getAnalyticsOverview = async (storeId?: string): Promise<AnalyticsOverview> => {
|
|
const url = storeId ? `/analytics/overview?storeId=${storeId}` : '/analytics/overview';
|
|
return clientFetch<AnalyticsOverview>(url);
|
|
};
|
|
|
|
/**
|
|
* Get revenue trends data
|
|
* @param period Time period in days (7, 30, 90)
|
|
* @param storeId Optional storeId for staff users
|
|
*/
|
|
export const getRevenueTrends = async (period: string = '30', storeId?: string): Promise<RevenueData[]> => {
|
|
const params = new URLSearchParams({ period });
|
|
if (storeId) params.append('storeId', storeId);
|
|
|
|
const url = `/analytics/revenue-trends?${params.toString()}`;
|
|
return clientFetch<RevenueData[]>(url);
|
|
};
|
|
|
|
/**
|
|
* Get product performance data
|
|
* @param storeId Optional storeId for staff users
|
|
*/
|
|
export const getProductPerformance = async (storeId?: string): Promise<ProductPerformance[]> => {
|
|
const url = storeId ? `/analytics/product-performance?storeId=${storeId}` : '/analytics/product-performance';
|
|
return clientFetch<ProductPerformance[]>(url);
|
|
};
|
|
|
|
/**
|
|
* Get customer insights data
|
|
* @param storeId Optional storeId for staff users
|
|
*/
|
|
export const getCustomerInsights = async (storeId?: string): Promise<CustomerInsights> => {
|
|
const url = storeId ? `/analytics/customer-insights?storeId=${storeId}` : '/analytics/customer-insights';
|
|
return clientFetch<CustomerInsights>(url);
|
|
};
|
|
|
|
/**
|
|
* Get order analytics data
|
|
* @param period Time period in days (7, 30, 90)
|
|
* @param storeId Optional storeId for staff users
|
|
*/
|
|
export const getOrderAnalytics = async (period: string = '30', storeId?: string): Promise<OrderAnalytics> => {
|
|
const params = new URLSearchParams({ period });
|
|
if (storeId) params.append('storeId', storeId);
|
|
|
|
const url = `/analytics/order-analytics?${params.toString()}`;
|
|
return clientFetch<OrderAnalytics>(url);
|
|
};
|
|
|
|
// Helper function to determine if user is staff and get storeId
|
|
export const getStoreIdForUser = (): string | undefined => {
|
|
if (typeof window === 'undefined') return undefined;
|
|
|
|
// Check if user is staff (you might need to adjust this based on your auth system)
|
|
const userType = localStorage.getItem('userType');
|
|
const storeId = localStorage.getItem('storeId');
|
|
|
|
if (userType === 'staff' && storeId) {
|
|
return storeId;
|
|
}
|
|
|
|
return undefined;
|
|
};
|
|
|
|
// Enhanced analytics functions that automatically handle storeId for staff users
|
|
export const getAnalyticsOverviewWithStore = async (): Promise<AnalyticsOverview> => {
|
|
const storeId = getStoreIdForUser();
|
|
return getAnalyticsOverview(storeId);
|
|
};
|
|
|
|
export const getRevenueTrendsWithStore = async (period: string = '30'): Promise<RevenueData[]> => {
|
|
const storeId = getStoreIdForUser();
|
|
return getRevenueTrends(period, storeId);
|
|
};
|
|
|
|
export const getProductPerformanceWithStore = async (): Promise<ProductPerformance[]> => {
|
|
const storeId = getStoreIdForUser();
|
|
return getProductPerformance(storeId);
|
|
};
|
|
|
|
export const getCustomerInsightsWithStore = async (): Promise<CustomerInsights> => {
|
|
const storeId = getStoreIdForUser();
|
|
return getCustomerInsights(storeId);
|
|
};
|
|
|
|
export const getOrderAnalyticsWithStore = async (period: string = '30'): Promise<OrderAnalytics> => {
|
|
const storeId = getStoreIdForUser();
|
|
return getOrderAnalytics(period, storeId);
|
|
};
|
|
|
|
export function formatGBP(value: number) {
|
|
return value.toLocaleString('en-GB', {
|
|
style: 'currency',
|
|
currency: 'GBP',
|
|
minimumFractionDigits: 2,
|
|
maximumFractionDigits: 2,
|
|
});
|
|
}
|