holy fkn airball

This commit is contained in:
NotII
2025-06-29 04:13:50 +01:00
parent e9b943a00a
commit 236a676ac5
11 changed files with 638 additions and 164 deletions

View File

@@ -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

View File

@@ -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);
};

View 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,
});
}