holy fkn airball
This commit is contained in:
34
lib/api.ts
34
lib/api.ts
@@ -45,6 +45,28 @@ export {
|
||||
type ShippingOptionsResponse,
|
||||
} from './services/shipping-service';
|
||||
|
||||
// Re-export analytics services
|
||||
export {
|
||||
getAnalyticsOverview,
|
||||
getRevenueTrends,
|
||||
getProductPerformance,
|
||||
getCustomerInsights,
|
||||
getOrderAnalytics,
|
||||
getAnalyticsOverviewWithStore,
|
||||
getRevenueTrendsWithStore,
|
||||
getProductPerformanceWithStore,
|
||||
getCustomerInsightsWithStore,
|
||||
getOrderAnalyticsWithStore,
|
||||
getStoreIdForUser,
|
||||
|
||||
// Types
|
||||
type AnalyticsOverview,
|
||||
type RevenueData,
|
||||
type ProductPerformance,
|
||||
type CustomerInsights,
|
||||
type OrderAnalytics,
|
||||
} from './services/analytics-service';
|
||||
|
||||
// Define the PlatformStats interface to match the expected format
|
||||
export interface PlatformStats {
|
||||
orders: {
|
||||
@@ -70,7 +92,17 @@ export {
|
||||
fetchServer,
|
||||
getCustomersServer,
|
||||
getCustomerDetailsServer,
|
||||
getPlatformStatsServer
|
||||
getPlatformStatsServer,
|
||||
getAnalyticsOverviewServer,
|
||||
getRevenueTrendsServer,
|
||||
getProductPerformanceServer,
|
||||
getCustomerInsightsServer,
|
||||
getOrderAnalyticsServer,
|
||||
type AnalyticsOverview as ServerAnalyticsOverview,
|
||||
type RevenueData as ServerRevenueData,
|
||||
type ProductPerformance as ServerProductPerformance,
|
||||
type CustomerInsights as ServerCustomerInsights,
|
||||
type OrderAnalytics as ServerOrderAnalytics,
|
||||
} from './server-api';
|
||||
|
||||
// Get clientFetch first so we can use it in the compatibility functions
|
||||
|
||||
@@ -161,4 +161,118 @@ export async function getPlatformStatsServer() {
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Analytics Types for server-side
|
||||
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;
|
||||
}
|
||||
|
||||
// Server-side analytics functions
|
||||
export const getAnalyticsOverviewServer = async (storeId?: string): Promise<AnalyticsOverview> => {
|
||||
const url = storeId ? `/analytics/overview?storeId=${storeId}` : '/analytics/overview';
|
||||
return fetchServer<AnalyticsOverview>(url);
|
||||
};
|
||||
|
||||
export const getRevenueTrendsServer = 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 fetchServer<RevenueData[]>(url);
|
||||
};
|
||||
|
||||
export const getProductPerformanceServer = async (storeId?: string): Promise<ProductPerformance[]> => {
|
||||
const url = storeId ? `/analytics/product-performance?storeId=${storeId}` : '/analytics/product-performance';
|
||||
return fetchServer<ProductPerformance[]>(url);
|
||||
};
|
||||
|
||||
export const getCustomerInsightsServer = async (storeId?: string): Promise<CustomerInsights> => {
|
||||
const url = storeId ? `/analytics/customer-insights?storeId=${storeId}` : '/analytics/customer-insights';
|
||||
return fetchServer<CustomerInsights>(url);
|
||||
};
|
||||
|
||||
export const getOrderAnalyticsServer = 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 fetchServer<OrderAnalytics>(url);
|
||||
};
|
||||
190
lib/services/analytics-service.ts
Normal file
190
lib/services/analytics-service.ts
Normal file
@@ -0,0 +1,190 @@
|
||||
'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,
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user