@umituz/web-dashboard 2.5.2 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@umituz/web-dashboard",
3
- "version": "2.5.2",
4
- "description": "Dashboard Layout System - Customizable, themeable dashboard layouts and settings",
3
+ "version": "3.1.0",
4
+ "description": "Dashboard Layout System - Comprehensive analytics, calendar, customizable layouts, and config-based architecture",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
7
7
  "sideEffects": false,
@@ -33,6 +33,13 @@
33
33
  "./analytics/hooks": "./src/domains/analytics/hooks/index.ts",
34
34
  "./analytics/utils": "./src/domains/analytics/utils/index.ts",
35
35
  "./analytics/types": "./src/domains/analytics/types/index.ts",
36
+ "./analytics/services": "./src/domains/analytics/services/index.ts",
37
+ "./calendar": "./src/domains/calendar/index.ts",
38
+ "./calendar/types": "./src/domains/calendar/types/calendar.types",
39
+ "./calendar/services": "./src/domains/calendar/services/index.ts",
40
+ "./calendar/hooks": "./src/domains/calendar/hooks/index.ts",
41
+ "./calendar/utils": "./src/domains/calendar/utils/index.ts",
42
+ "./config": "./src/domain/config/index.ts",
36
43
  "./billing": "./src/domains/billing/index.ts",
37
44
  "./billing/components": "./src/domains/billing/components/index.ts",
38
45
  "./billing/hooks": "./src/domains/billing/hooks/index.ts",
@@ -85,6 +92,18 @@
85
92
  "login",
86
93
  "register",
87
94
  "analytics",
95
+ "analytics-services",
96
+ "cohort-analysis",
97
+ "funnel-analysis",
98
+ "user-segmentation",
99
+ "behavior-prediction",
100
+ "performance-monitoring",
101
+ "realtime-metrics",
102
+ "calendar",
103
+ "content-calendar",
104
+ "scheduler",
105
+ "content-planning",
106
+ "drag-drop",
88
107
  "charts",
89
108
  "metrics",
90
109
  "kpi",
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Calendar Configuration
3
+ */
4
+
5
+ import type { CalendarConfig } from '../../domains/calendar/types/calendar.types';
6
+
7
+ /**
8
+ * Default calendar configuration
9
+ */
10
+ export const DEFAULT_CALENDAR_CONFIG: CalendarConfig = {
11
+ defaultView: 'month',
12
+ showWeekends: true,
13
+ startOfWeek: 0,
14
+ hourRange: {
15
+ start: 0,
16
+ end: 23,
17
+ },
18
+ enableDragDrop: true,
19
+ showPlatformFilters: true,
20
+ platforms: ['instagram', 'facebook', 'twitter', 'linkedin', 'tiktok', 'youtube'],
21
+ slotDuration: 30,
22
+ };
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Dashboard Configuration
3
+ * Config-based dashboard system
4
+ */
5
+
6
+ import type { ChartType } from '../../domains/analytics/types/analytics';
7
+
8
+ /**
9
+ * Analytics service types
10
+ */
11
+ export type AnalyticsServiceType = 'traffic' | 'cohort' | 'funnel' | 'growth' | 'performance';
12
+
13
+ /**
14
+ * Export format
15
+ */
16
+ export type ExportFormat = 'pdf' | 'excel' | 'csv' | 'json';
17
+
18
+ /**
19
+ * Analytics configuration
20
+ */
21
+ export interface AnalyticsConfig {
22
+ /** Enable analytics */
23
+ enabled?: boolean;
24
+ /** Analytics services to include */
25
+ services?: AnalyticsServiceType[];
26
+ /** Real-time updates */
27
+ realtime?: boolean;
28
+ /** Export configuration */
29
+ export?: {
30
+ enabled?: boolean;
31
+ formats?: ExportFormat[];
32
+ };
33
+ }
34
+
35
+ /**
36
+ * Data refresh configuration
37
+ */
38
+ export interface DataConfig {
39
+ /** Refresh interval in milliseconds */
40
+ refreshInterval?: number;
41
+ /** Cache duration in milliseconds */
42
+ cacheDuration?: number;
43
+ /** Retry attempts for failed requests */
44
+ retryAttempts?: number;
45
+ }
46
+
47
+ /**
48
+ * Charts configuration
49
+ */
50
+ export interface ChartsConfig {
51
+ /** Default chart type */
52
+ defaultType?: ChartType;
53
+ /** Chart theme */
54
+ theme?: 'light' | 'dark' | 'auto';
55
+ /** Enable animations */
56
+ animations?: boolean;
57
+ /** Color palette */
58
+ colors?: string[];
59
+ }
60
+
61
+ /**
62
+ * Performance configuration
63
+ */
64
+ export interface PerformanceConfig {
65
+ /** Enable lazy loading */
66
+ lazyLoad?: boolean;
67
+ /** Enable virtual scrolling */
68
+ virtualScrolling?: boolean;
69
+ /** Pagination size */
70
+ paginationSize?: number;
71
+ }
72
+
73
+ /**
74
+ * Dashboard configuration
75
+ */
76
+ export interface DashboardConfig {
77
+ /** Analytics configuration */
78
+ analytics?: AnalyticsConfig;
79
+ /** Data configuration */
80
+ data?: DataConfig;
81
+ /** Charts configuration */
82
+ charts?: ChartsConfig;
83
+ /** Performance configuration */
84
+ performance?: PerformanceConfig;
85
+ }
86
+
87
+ /**
88
+ * Default dashboard configuration
89
+ */
90
+ export const DEFAULT_DASHBOARD_CONFIG: DashboardConfig = {
91
+ analytics: {
92
+ enabled: true,
93
+ services: ['traffic', 'cohort', 'funnel', 'growth'],
94
+ realtime: true,
95
+ export: {
96
+ enabled: true,
97
+ formats: ['pdf', 'excel', 'csv'],
98
+ },
99
+ },
100
+ data: {
101
+ refreshInterval: 30000, // 30 seconds
102
+ cacheDuration: 300000, // 5 minutes
103
+ retryAttempts: 3,
104
+ },
105
+ charts: {
106
+ defaultType: 'line',
107
+ theme: 'auto',
108
+ animations: true,
109
+ colors: ['#6366f1', '#a855f7', '#f59e0b', '#10b981'],
110
+ },
111
+ performance: {
112
+ lazyLoad: true,
113
+ virtualScrolling: true,
114
+ paginationSize: 20,
115
+ },
116
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Domain Config Index
3
+ */
4
+
5
+ export * from './DashboardConfig';
6
+ export * from './CalendarConfig';
@@ -2,9 +2,10 @@
2
2
  * useAnalytics Hook
3
3
  *
4
4
  * Core analytics hook for fetching and managing analytics data
5
+ * Enhanced with config support and advanced analytics services
5
6
  */
6
7
 
7
- import { useState, useCallback, useEffect } from "react";
8
+ import { useState, useCallback, useEffect, useMemo } from "react";
8
9
  import type {
9
10
  KPIs,
10
11
  TimeSeriesData,
@@ -13,6 +14,8 @@ import type {
13
14
  AnalyticsExportOptions,
14
15
  } from "../types/analytics";
15
16
  import { createKPI } from "../utils/analytics";
17
+ import { analyticsEngineService, performanceService } from "../services";
18
+ import type { DashboardConfig } from "../../../domain/config";
16
19
 
17
20
  interface UseAnalyticsOptions {
18
21
  /** Analytics API base URL */
@@ -21,6 +24,10 @@ interface UseAnalyticsOptions {
21
24
  initialDateRange?: DateRangeValue;
22
25
  /** Auto-refresh interval in ms (0 to disable) */
23
26
  refreshInterval?: number;
27
+ /** Dashboard configuration */
28
+ config?: DashboardConfig;
29
+ /** Error callback */
30
+ onError?: (error: Error) => void;
24
31
  }
25
32
 
26
33
  interface AnalyticsData {
@@ -43,7 +50,19 @@ interface AnalyticsData {
43
50
  * @returns Analytics data and actions
44
51
  */
45
52
  export function useAnalytics(options: UseAnalyticsOptions = {}) {
46
- const { apiUrl = "/api/analytics", initialDateRange, refreshInterval = 0 } = options;
53
+ const {
54
+ apiUrl = "/api/analytics",
55
+ initialDateRange,
56
+ refreshInterval = 0,
57
+ config,
58
+ onError,
59
+ } = options;
60
+
61
+ // Apply config defaults
62
+ const effectiveRefreshInterval = useMemo(
63
+ () => refreshInterval || config?.data?.refreshInterval || 0,
64
+ [refreshInterval, config]
65
+ );
47
66
 
48
67
  // State
49
68
  const [dateRange, setDateRange] = useState<DateRangeValue>(
@@ -162,11 +181,81 @@ export function useAnalytics(options: UseAnalyticsOptions = {}) {
162
181
 
163
182
  // Auto-refresh
164
183
  useEffect(() => {
165
- if (refreshInterval > 0) {
166
- const interval = setInterval(fetchAnalytics, refreshInterval);
184
+ if (effectiveRefreshInterval > 0) {
185
+ const interval = setInterval(fetchAnalytics, effectiveRefreshInterval);
167
186
  return () => clearInterval(interval);
168
187
  }
169
- }, [fetchAnalytics, refreshInterval]);
188
+ }, [fetchAnalytics, effectiveRefreshInterval]);
189
+
190
+ // Advanced analytics methods
191
+ const calculateRetention = useCallback(
192
+ (userData: any[]) => {
193
+ try {
194
+ return analyticsEngineService.calculateRetention(userData);
195
+ } catch (err) {
196
+ onError?.(err as Error);
197
+ return [];
198
+ }
199
+ },
200
+ [onError]
201
+ );
202
+
203
+ const calculateFunnel = useCallback(
204
+ (data: any[], steps: string[]) => {
205
+ try {
206
+ return analyticsEngineService.calculateFunnel(data, steps);
207
+ } catch (err) {
208
+ onError?.(err as Error);
209
+ return null;
210
+ }
211
+ },
212
+ [onError]
213
+ );
214
+
215
+ const segmentUsers = useCallback(
216
+ (userData: any[]) => {
217
+ try {
218
+ return analyticsEngineService.segmentUsers(userData);
219
+ } catch (err) {
220
+ onError?.(err as Error);
221
+ return [];
222
+ }
223
+ },
224
+ [onError]
225
+ );
226
+
227
+ const predictUserBehavior = useCallback(
228
+ (user: any, historicalData: any[]) => {
229
+ try {
230
+ return analyticsEngineService.predictUserBehavior(user, historicalData);
231
+ } catch (err) {
232
+ onError?.(err as Error);
233
+ return null;
234
+ }
235
+ },
236
+ [onError]
237
+ );
238
+
239
+ const getPerformanceMetrics = useCallback(() => {
240
+ try {
241
+ return performanceService.getDashboardMetrics();
242
+ } catch (err) {
243
+ onError?.(err as Error);
244
+ return null;
245
+ }
246
+ }, [onError]);
247
+
248
+ const getRealtimeMetrics = useCallback(
249
+ (previous?: any) => {
250
+ try {
251
+ return performanceService.simulateRealtimeMetrics(previous);
252
+ } catch (err) {
253
+ onError?.(err as Error);
254
+ return null;
255
+ }
256
+ },
257
+ [onError]
258
+ );
170
259
 
171
260
  return {
172
261
  ...data,
@@ -174,5 +263,12 @@ export function useAnalytics(options: UseAnalyticsOptions = {}) {
174
263
  updateDateRange,
175
264
  refresh,
176
265
  exportData,
266
+ // Advanced analytics
267
+ calculateRetention,
268
+ calculateFunnel,
269
+ segmentUsers,
270
+ predictUserBehavior,
271
+ getPerformanceMetrics,
272
+ getRealtimeMetrics,
177
273
  };
178
274
  }
@@ -17,6 +17,26 @@ export {
17
17
  useAnalytics,
18
18
  } from "./hooks";
19
19
 
20
+ // Services
21
+ export {
22
+ AnalyticsEngineService,
23
+ analyticsEngineService,
24
+ PerformanceService,
25
+ performanceService,
26
+ } from "./services";
27
+ export type {
28
+ ConversionPath,
29
+ HeatmapData,
30
+ UserBehaviorPrediction,
31
+ UserData,
32
+ ConversionData,
33
+ FunnelItem,
34
+ ActivityItem,
35
+ PerformanceMetric,
36
+ DashboardMetrics,
37
+ RealtimeMetrics,
38
+ } from "./services";
39
+
20
40
  // Utils
21
41
  export {
22
42
  formatNumber,
@@ -0,0 +1,319 @@
1
+ /**
2
+ * Analytics Engine Service
3
+ *
4
+ * Advanced analytics operations including cohort analysis, funnel analysis,
5
+ * user segmentation, behavior prediction, and conversion path analysis.
6
+ */
7
+
8
+ import type {
9
+ CohortAnalysis,
10
+ FunnelData,
11
+ UserSegment,
12
+ } from '../types/analytics';
13
+
14
+ export interface ConversionPath {
15
+ path: string[];
16
+ conversions: number;
17
+ value: number;
18
+ abandonmentRate: number;
19
+ }
20
+
21
+ export interface HeatmapData {
22
+ day: string;
23
+ hour: number;
24
+ value: number;
25
+ }
26
+
27
+ export interface UserBehaviorPrediction {
28
+ churnProbability: number;
29
+ lifetimeValue: number;
30
+ nextAction: string;
31
+ confidence: number;
32
+ }
33
+
34
+ export interface UserData {
35
+ signup_date?: string | Date;
36
+ last_activity?: string | Date;
37
+ last_login_days?: number;
38
+ session_duration?: number;
39
+ pages_per_session?: number;
40
+ bounce_rate?: number;
41
+ age?: number;
42
+ location?: string;
43
+ churned?: boolean;
44
+ lifetime_value?: number;
45
+ last_action?: string;
46
+ }
47
+
48
+ export interface ConversionData {
49
+ path?: string[];
50
+ value?: number;
51
+ }
52
+
53
+ export interface FunnelItem {
54
+ [key: string]: boolean | number | undefined;
55
+ time_spent?: number;
56
+ }
57
+
58
+ export interface ActivityItem {
59
+ timestamp: string | Date;
60
+ }
61
+
62
+ /**
63
+ * Analytics Engine Service
64
+ *
65
+ * Singleton service for advanced analytics calculations
66
+ */
67
+ export class AnalyticsEngineService {
68
+ private static instance: AnalyticsEngineService;
69
+
70
+ private constructor() {}
71
+
72
+ public static getInstance(): AnalyticsEngineService {
73
+ if (!AnalyticsEngineService.instance) {
74
+ AnalyticsEngineService.instance = new AnalyticsEngineService();
75
+ }
76
+ return AnalyticsEngineService.instance;
77
+ }
78
+
79
+ /**
80
+ * Calculate cohort retention analysis
81
+ *
82
+ * @param data - User data with signup and activity dates
83
+ * @returns Cohort analysis with retention rates
84
+ */
85
+ public calculateRetention(data: UserData[]): CohortAnalysis[] {
86
+ const cohorts: Map<string, UserData[]> = new Map();
87
+
88
+ data.forEach((user) => {
89
+ if (!user.signup_date) return;
90
+ const signupMonth = new Date(user.signup_date).toISOString().slice(0, 7);
91
+ if (!cohorts.has(signupMonth)) {
92
+ cohorts.set(signupMonth, []);
93
+ }
94
+ const cohort = cohorts.get(signupMonth);
95
+ if (cohort) {
96
+ cohort.push(user);
97
+ }
98
+ });
99
+
100
+ const cohortAnalysis: CohortAnalysis[] = [];
101
+
102
+ cohorts.forEach((users, cohort) => {
103
+ const retention: number[] = [];
104
+ for (let month = 0; month < 12; month++) {
105
+ const activeUsersCount = users.filter((user) => {
106
+ if (!user.last_activity) return false;
107
+ const signupDate = new Date(user.signup_date!);
108
+ const targetDate = new Date(signupDate.getFullYear(), signupDate.getMonth() + month, 1);
109
+ return new Date(user.last_activity) >= targetDate;
110
+ }).length;
111
+
112
+ retention.push((activeUsersCount / users.length) * 100);
113
+ }
114
+
115
+ cohortAnalysis.push({
116
+ cohort,
117
+ size: users.length,
118
+ retention,
119
+ averageRetention: retention.reduce((a, b) => a + b, 0) / retention.length,
120
+ });
121
+ });
122
+
123
+ return cohortAnalysis;
124
+ }
125
+
126
+ /**
127
+ * Analyze conversion paths
128
+ *
129
+ * @param data - Conversion data with paths and values
130
+ * @returns Conversion path analysis
131
+ */
132
+ public analyzeConversionPaths(data: ConversionData[]): ConversionPath[] {
133
+ const paths: Map<string, { count: number; value: number }> = new Map();
134
+ let totalConversions = 0;
135
+
136
+ data.forEach((conversion) => {
137
+ if (!conversion.path) return;
138
+ const pathKey = conversion.path.join(' → ');
139
+ if (!paths.has(pathKey)) {
140
+ paths.set(pathKey, { count: 0, value: 0 });
141
+ }
142
+
143
+ const path = paths.get(pathKey);
144
+ if (path) {
145
+ path.count++;
146
+ path.value += conversion.value || 0;
147
+ totalConversions++;
148
+ }
149
+ });
150
+
151
+ return Array.from(paths.entries())
152
+ .map(([pathString, path]) => ({
153
+ path: pathString.split(' → '),
154
+ conversions: path.count,
155
+ value: path.value,
156
+ abandonmentRate:
157
+ totalConversions > 0 ? ((totalConversions - path.count) / totalConversions) * 100 : 0,
158
+ }))
159
+ .sort((a, b) => b.conversions - a.conversions);
160
+ }
161
+
162
+ /**
163
+ * Calculate funnel analysis
164
+ *
165
+ * @param data - Funnel data with step indicators
166
+ * @param steps - Funnel step names
167
+ * @returns Funnel analysis data
168
+ */
169
+ public calculateFunnel(data: FunnelItem[], steps: string[]): FunnelData {
170
+ let previousCount = data.length;
171
+ const funnelSteps = steps.map((step, index) => {
172
+ const stepCount = data.filter((item) => item[step]).length;
173
+ const conversionRate =
174
+ index === 0 ? 100 : previousCount > 0 ? (stepCount / previousCount) * 100 : 0;
175
+ previousCount = stepCount;
176
+
177
+ const stepData = data.filter((item) => item[step]);
178
+ const avgTime =
179
+ stepData.length > 0
180
+ ? stepData.reduce((sum, item) => sum + (item.time_spent || 0), 0) / stepData.length
181
+ : 0;
182
+
183
+ return {
184
+ name: step,
185
+ count: stepCount,
186
+ conversionRate,
187
+ dropOffRate: 100 - conversionRate,
188
+ averageTime: avgTime,
189
+ };
190
+ });
191
+
192
+ return {
193
+ title: 'Conversion Funnel',
194
+ steps: funnelSteps,
195
+ totalUsers: data.length,
196
+ finalConversion: funnelSteps[funnelSteps.length - 1]?.conversionRate || 0,
197
+ };
198
+ }
199
+
200
+ /**
201
+ * Generate activity heatmap
202
+ *
203
+ * @param data - Activity data with timestamps
204
+ * @returns Heatmap data by day and hour
205
+ */
206
+ public generateActivityHeatmap(data: ActivityItem[]): HeatmapData[] {
207
+ const heatmap: HeatmapData[] = [];
208
+ const days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
209
+
210
+ for (let day = 0; day < 7; day++) {
211
+ for (let hour = 0; hour < 24; hour++) {
212
+ const count = data.filter((item) => {
213
+ const d = new Date(item.timestamp);
214
+ return d.getDay() === day && d.getHours() === hour;
215
+ }).length;
216
+
217
+ heatmap.push({ day: days[day], hour, value: count });
218
+ }
219
+ }
220
+ return heatmap;
221
+ }
222
+
223
+ /**
224
+ * Segment users by behavior
225
+ *
226
+ * @param data - User data
227
+ * @returns User segments
228
+ */
229
+ public segmentUsers(data: UserData[]): UserSegment[] {
230
+ const defineSegment = (
231
+ name: string,
232
+ filter: (u: UserData) => boolean,
233
+ chars: string[]
234
+ ) => {
235
+ const users = data.filter(filter);
236
+ const avg = (field: string) =>
237
+ users.length === 0
238
+ ? 0
239
+ : users.reduce((s, i) => s + ((i as any)[field] || 0), 0) / users.length;
240
+
241
+ return {
242
+ name,
243
+ count: users.length,
244
+ percentage: (users.length / data.length) * 100,
245
+ characteristics: chars,
246
+ behavior: {
247
+ avgSessionDuration: avg('session_duration'),
248
+ pagesPerSession: avg('pages_per_session'),
249
+ bounceRate: avg('bounce_rate'),
250
+ },
251
+ };
252
+ };
253
+
254
+ return [
255
+ defineSegment('Active', (u) => u.last_login_days! <= 7, [
256
+ 'Recent login',
257
+ 'High engagement',
258
+ ]),
259
+ defineSegment('Moderate', (u) => u.last_login_days! > 7 && u.last_login_days! <= 30, [
260
+ 'Occasional login',
261
+ ]),
262
+ defineSegment('Inactive', (u) => u.last_login_days! > 30, [
263
+ 'Churn risk',
264
+ 'Low activity',
265
+ ]),
266
+ ];
267
+ }
268
+
269
+ /**
270
+ * Predict user behavior
271
+ *
272
+ * @param user - Target user
273
+ * @param historicalData - Historical user data
274
+ * @returns Behavior prediction
275
+ */
276
+ public predictUserBehavior(
277
+ user: UserData,
278
+ historicalData: UserData[]
279
+ ): UserBehaviorPrediction {
280
+ const similarUsers = historicalData.filter(
281
+ (u) => Math.abs((u.age || 0) - (user.age || 0)) < 5 && u.location === user.location
282
+ );
283
+
284
+ if (similarUsers.length === 0) {
285
+ return {
286
+ churnProbability: 0,
287
+ lifetimeValue: 0,
288
+ nextAction: 'none',
289
+ confidence: 0,
290
+ };
291
+ }
292
+
293
+ const churnCount = similarUsers.filter((u) => u.churned).length;
294
+ const totalLTV = similarUsers.reduce((s, u) => s + (u.lifetime_value || 0), 0);
295
+
296
+ // Predict next action based on frequency in similar users
297
+ const actions = similarUsers.map((u) => u.last_action).filter(Boolean) as string[];
298
+ const actionCounts = actions.reduce((c: Record<string, number>, a) => {
299
+ c[a] = (c[a] || 0) + 1;
300
+ return c;
301
+ }, {});
302
+ const nextAction = Object.keys(actionCounts).reduce(
303
+ (a, b) => (actionCounts[a] > actionCounts[b] ? a : b),
304
+ 'unknown'
305
+ );
306
+
307
+ return {
308
+ churnProbability: churnCount / similarUsers.length,
309
+ lifetimeValue: totalLTV / similarUsers.length,
310
+ nextAction,
311
+ confidence: Math.min(0.9, similarUsers.length / 100),
312
+ };
313
+ }
314
+ }
315
+
316
+ /**
317
+ * Singleton instance
318
+ */
319
+ export const analyticsEngineService = AnalyticsEngineService.getInstance();