Add modular dashboard widgets and layout editor
Some checks failed
Build Frontend / build (push) Failing after 7s

Introduces a modular dashboard system with draggable, configurable widgets including revenue, low stock, recent customers, and pending chats. Adds a dashboard editor for layout customization, widget visibility, and settings. Refactors dashboard content to use the new widget system and improves UI consistency and interactivity.
This commit is contained in:
g
2026-01-12 10:39:50 +00:00
parent a6b7286b45
commit 318927cd0c
23 changed files with 2435 additions and 317 deletions

View File

@@ -5,14 +5,14 @@ export {
fetchClient,
getAuthToken,
getCookie,
// Customer API
getCustomers,
getCustomerDetails,
// Orders API
exportOrdersToCSV,
// Types
type CustomerStats,
type CustomerResponse,
@@ -28,7 +28,7 @@ export {
uploadProductImage,
getProductStock,
updateProductStock,
// Types
type Product,
type ProductsResponse,
@@ -42,7 +42,7 @@ export {
createShippingOption,
updateShippingOption,
deleteShippingOption,
// Types
type ShippingOption,
type ShippingOptionsResponse,
@@ -61,7 +61,8 @@ export {
getCustomerInsightsWithStore,
getOrderAnalyticsWithStore,
getStoreIdForUser,
formatGBP,
// Types
type AnalyticsOverview,
type RevenueData,
@@ -91,9 +92,9 @@ export {
} from './services/stats-service';
// Re-export server API functions
export {
fetchServer,
getCustomersServer,
export {
fetchServer,
getCustomersServer,
getCustomerDetailsServer,
getPlatformStatsServer,
getAnalyticsOverviewServer,
@@ -127,11 +128,11 @@ export const apiRequest = async (endpoint: string, method = 'GET', data: any = n
headers: { 'Content-Type': 'application/json' },
body: data ? JSON.stringify(data) : undefined,
};
if (token) {
options.headers.Authorization = `Bearer ${token}`;
}
return clientFetch(endpoint, options);
};

View File

@@ -190,10 +190,12 @@ export const getCustomerInsights = async (
storeId?: string,
page: number = 1,
limit: number = 10,
sortBy: string = "spent",
): Promise<CustomerInsights> => {
const params = new URLSearchParams({
page: page.toString(),
limit: limit.toString(),
sort: sortBy,
});
if (storeId) params.append("storeId", storeId);
@@ -272,9 +274,10 @@ export const getProductPerformanceWithStore = async (): Promise<
export const getCustomerInsightsWithStore = async (
page: number = 1,
limit: number = 10,
sortBy: string = "spent",
): Promise<CustomerInsights> => {
const storeId = getStoreIdForUser();
return getCustomerInsights(storeId, page, limit);
return getCustomerInsights(storeId, page, limit, sortBy);
};
export const getOrderAnalyticsWithStore = async (