@umituz/web-dashboard 2.1.0 → 2.2.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.
@@ -0,0 +1,178 @@
1
+ /**
2
+ * useAnalytics Hook
3
+ *
4
+ * Core analytics hook for fetching and managing analytics data
5
+ */
6
+
7
+ import { useState, useCallback, useEffect } from "react";
8
+ import type {
9
+ KPIs,
10
+ TimeSeriesData,
11
+ ChartConfig,
12
+ DateRangeValue,
13
+ AnalyticsExportOptions,
14
+ } from "../types/analytics";
15
+ import { createKPI } from "../utils/analytics";
16
+
17
+ interface UseAnalyticsOptions {
18
+ /** Analytics API base URL */
19
+ apiUrl?: string;
20
+ /** Initial date range */
21
+ initialDateRange?: DateRangeValue;
22
+ /** Auto-refresh interval in ms (0 to disable) */
23
+ refreshInterval?: number;
24
+ }
25
+
26
+ interface AnalyticsData {
27
+ /** KPI metrics */
28
+ kpis: KPIs;
29
+ /** Time series data */
30
+ timeSeries: TimeSeriesData[];
31
+ /** Loading state */
32
+ isLoading: boolean;
33
+ /** Error state */
34
+ error: string | null;
35
+ }
36
+
37
+ /**
38
+ * useAnalytics hook
39
+ *
40
+ * Manages analytics data fetching and state
41
+ *
42
+ * @param options - Hook options
43
+ * @returns Analytics data and actions
44
+ */
45
+ export function useAnalytics(options: UseAnalyticsOptions = {}) {
46
+ const { apiUrl = "/api/analytics", initialDateRange, refreshInterval = 0 } = options;
47
+
48
+ // State
49
+ const [dateRange, setDateRange] = useState<DateRangeValue>(
50
+ initialDateRange || {
51
+ from: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString().split("T")[0],
52
+ to: new Date().toISOString().split("T")[0],
53
+ preset: "Last 30 Days",
54
+ }
55
+ );
56
+ const [data, setData] = useState<AnalyticsData>({
57
+ kpis: {
58
+ downloads: { current: 0, previous: 0, growth: 0 },
59
+ engagement: { current: 0, previous: 0, growth: 0 },
60
+ users: { current: 0, previous: 0, growth: 0 },
61
+ revenue: { current: 0, previous: 0, growth: 0 },
62
+ retention: { current: 0, previous: 0, growth: 0 },
63
+ },
64
+ timeSeries: [],
65
+ isLoading: false,
66
+ error: null,
67
+ });
68
+
69
+ // Fetch analytics data
70
+ const fetchAnalytics = useCallback(async () => {
71
+ setData((prev) => ({ ...prev, isLoading: true, error: null }));
72
+
73
+ try {
74
+ // In production, call your analytics API
75
+ // const response = await fetch(`${apiUrl}?from=${dateRange.from}&to=${dateRange.to}`);
76
+ // const result = await response.json();
77
+
78
+ // Mock data for demo
79
+ const mockKPIs: KPIs = {
80
+ downloads: { current: 1250, previous: 1100, growth: 13.6 },
81
+ engagement: { current: 68.5, previous: 65.2, growth: 5.1 },
82
+ users: { current: 4500, previous: 4200, growth: 7.1 },
83
+ revenue: { current: 8950, previous: 7800, growth: 14.7 },
84
+ retention: { current: 72.3, previous: 69.8, growth: 3.6 },
85
+ };
86
+
87
+ const mockTimeSeries: TimeSeriesData[] = Array.from({ length: 30 }, (_, i) => {
88
+ const date = new Date();
89
+ date.setDate(date.getDate() - (29 - i));
90
+ return {
91
+ date: date.toISOString().split("T")[0],
92
+ downloads: Math.floor(1000 + Math.random() * 500),
93
+ engagement: 60 + Math.random() * 20,
94
+ revenue: Math.floor(7000 + Math.random() * 3000),
95
+ users: Math.floor(4000 + Math.random() * 1000),
96
+ retention: 65 + Math.random() * 15,
97
+ };
98
+ });
99
+
100
+ setData({
101
+ kpis: mockKPIs,
102
+ timeSeries: mockTimeSeries,
103
+ isLoading: false,
104
+ error: null,
105
+ });
106
+ } catch (err) {
107
+ const errorMessage = err instanceof Error ? err.message : "Failed to fetch analytics";
108
+ setData((prev) => ({
109
+ ...prev,
110
+ isLoading: false,
111
+ error: errorMessage,
112
+ }));
113
+ }
114
+ }, [apiUrl, dateRange]);
115
+
116
+ // Update date range
117
+ const updateDateRange = useCallback((newDateRange: DateRangeValue) => {
118
+ setDateRange(newDateRange);
119
+ }, []);
120
+
121
+ // Export analytics data
122
+ const exportData = useCallback(async (options: AnalyticsExportOptions) => {
123
+ try {
124
+ // In production, implement export API call
125
+ const exportData = {
126
+ dateRange,
127
+ kpis: data.kpis,
128
+ timeSeries: data.timeSeries,
129
+ format: options.format,
130
+ };
131
+
132
+ console.log("Exporting analytics:", exportData);
133
+
134
+ // Mock export
135
+ const blob = new Blob([JSON.stringify(exportData, null, 2)], {
136
+ type: options.format === "json" ? "application/json" : "text/plain",
137
+ });
138
+
139
+ const url = URL.createObjectURL(blob);
140
+ const link = document.createElement("a");
141
+ link.href = url;
142
+ link.download = options.filename || `analytics-${dateRange.from}-${dateRange.to}.${options.format}`;
143
+ document.body.appendChild(link);
144
+ link.click();
145
+ document.body.removeChild(link);
146
+ URL.revokeObjectURL(url);
147
+ } catch (err) {
148
+ console.error("Export failed:", err);
149
+ throw err;
150
+ }
151
+ }, [dateRange, data]);
152
+
153
+ // Refresh data
154
+ const refresh = useCallback(() => {
155
+ fetchAnalytics();
156
+ }, [fetchAnalytics]);
157
+
158
+ // Fetch on mount and date range change
159
+ useEffect(() => {
160
+ fetchAnalytics();
161
+ }, [fetchAnalytics]);
162
+
163
+ // Auto-refresh
164
+ useEffect(() => {
165
+ if (refreshInterval > 0) {
166
+ const interval = setInterval(fetchAnalytics, refreshInterval);
167
+ return () => clearInterval(interval);
168
+ }
169
+ }, [fetchAnalytics, refreshInterval]);
170
+
171
+ return {
172
+ ...data,
173
+ dateRange,
174
+ updateDateRange,
175
+ refresh,
176
+ exportData,
177
+ };
178
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Analytics Domain
3
+ *
4
+ * Main entry point for analytics domain
5
+ */
6
+
7
+ // Components
8
+ export {
9
+ MetricCard,
10
+ AnalyticsChart,
11
+ AnalyticsCard,
12
+ AnalyticsLayout,
13
+ } from "./components";
14
+
15
+ // Hooks
16
+ export {
17
+ useAnalytics,
18
+ } from "./hooks";
19
+
20
+ // Utils
21
+ export {
22
+ formatNumber,
23
+ formatPercentage,
24
+ formatCurrency,
25
+ calculateGrowth,
26
+ getTrend,
27
+ createKPI,
28
+ createMetric,
29
+ formatMetricValue,
30
+ calculateConversionRate,
31
+ calculateDropOffRate,
32
+ createDateRangePreset,
33
+ getDateRangePresets,
34
+ aggregateByPeriod,
35
+ calculateMovingAverage,
36
+ detectOutliers,
37
+ roundTo,
38
+ generateColor,
39
+ generateChartColors,
40
+ } from "./utils";
41
+
42
+ // Types
43
+ export type {
44
+ Metric,
45
+ TimeSeriesData,
46
+ ChartData,
47
+ FunnelStep,
48
+ FunnelData,
49
+ CohortAnalysis,
50
+ UserSegment,
51
+ KPIData,
52
+ KPIs,
53
+ ChartType,
54
+ ChartConfig,
55
+ MetricCardProps,
56
+ AnalyticsCardProps,
57
+ AnalyticsLayoutProps,
58
+ DateRangePreset,
59
+ DateRangeValue,
60
+ ExportFormat,
61
+ AnalyticsExportOptions,
62
+ } from "./types";
@@ -0,0 +1,291 @@
1
+ /**
2
+ * Analytics Types
3
+ *
4
+ * Type definitions for analytics system
5
+ */
6
+
7
+ import type { ComponentType, ReactElement } from "react";
8
+
9
+ /**
10
+ * Metric card data
11
+ */
12
+ export interface Metric {
13
+ /** Unique identifier */
14
+ id: string;
15
+ /** Metric name */
16
+ name: string;
17
+ /** Current value */
18
+ value: number;
19
+ /** Previous period value */
20
+ previousValue?: number;
21
+ /** Unit (%, $, etc.) */
22
+ unit?: string;
23
+ /** Trend direction */
24
+ trend?: "up" | "down" | "stable";
25
+ /** Icon component */
26
+ icon?: ComponentType<{ className?: string }>;
27
+ }
28
+
29
+ /**
30
+ * Time series data point
31
+ */
32
+ export interface TimeSeriesData {
33
+ /** Date/label */
34
+ date: string;
35
+ /** Metric values */
36
+ [key: string]: string | number;
37
+ }
38
+
39
+ /**
40
+ * Chart data point
41
+ */
42
+ export interface ChartData {
43
+ /** X-axis label */
44
+ label: string;
45
+ /** Y-axis value */
46
+ value: number;
47
+ /** Additional data */
48
+ [key: string]: string | number | boolean;
49
+ }
50
+
51
+ /**
52
+ * Funnel step
53
+ */
54
+ export interface FunnelStep {
55
+ /** Step name */
56
+ name: string;
57
+ /** User count at this step */
58
+ count: number;
59
+ /** Conversion rate to this step */
60
+ conversionRate: number;
61
+ /** Drop-off rate from previous step */
62
+ dropOffRate: number;
63
+ /** Average time spent at step */
64
+ averageTime?: number;
65
+ }
66
+
67
+ /**
68
+ * Funnel data
69
+ */
70
+ export interface FunnelData {
71
+ /** Funnel title */
72
+ title: string;
73
+ /** Funnel steps */
74
+ steps: FunnelStep[];
75
+ /** Total starting users */
76
+ totalUsers: number;
77
+ /** Final conversion rate */
78
+ finalConversion: number;
79
+ }
80
+
81
+ /**
82
+ * Cohort analysis data
83
+ */
84
+ export interface CohortAnalysis {
85
+ /** Cohort identifier */
86
+ cohort: string;
87
+ /** Cohort size */
88
+ size: number;
89
+ /** Retention rates over time */
90
+ retention: number[];
91
+ /** Average retention rate */
92
+ averageRetention: number;
93
+ }
94
+
95
+ /**
96
+ * User segment
97
+ */
98
+ export interface UserSegment {
99
+ /** Segment name */
100
+ name: string;
101
+ /** User count */
102
+ count: number;
103
+ /** Percentage of total users */
104
+ percentage: number;
105
+ /** Segment characteristics */
106
+ characteristics: string[];
107
+ /** Behavioral metrics */
108
+ behavior: {
109
+ avgSessionDuration: number;
110
+ pagesPerSession: number;
111
+ bounceRate: number;
112
+ };
113
+ }
114
+
115
+ /**
116
+ * KPI data with comparison
117
+ */
118
+ export interface KPIData {
119
+ /** Current period value */
120
+ current: number;
121
+ /** Previous period value */
122
+ previous: number;
123
+ /** Growth rate percentage */
124
+ growth: number;
125
+ }
126
+
127
+ /**
128
+ * KPIs container
129
+ */
130
+ export interface KPIs {
131
+ downloads: KPIData;
132
+ engagement: KPIData;
133
+ users: KPIData;
134
+ revenue: KPIData;
135
+ retention: KPIData;
136
+ }
137
+
138
+ /**
139
+ * Chart types
140
+ */
141
+ export type ChartType =
142
+ | "line"
143
+ | "bar"
144
+ | "area"
145
+ | "pie"
146
+ | "donut"
147
+ | "funnel"
148
+ | "heatmap"
149
+ | "metric"
150
+ | "table";
151
+
152
+ /**
153
+ * Chart configuration
154
+ */
155
+ export interface ChartConfig {
156
+ /** Chart type */
157
+ type: ChartType;
158
+ /** Chart title */
159
+ title?: string;
160
+ /** Chart description */
161
+ description?: string;
162
+ /** Data */
163
+ data: TimeSeriesData[] | ChartData[] | Metric[];
164
+ /** X-axis key */
165
+ xAxisKey?: string;
166
+ /** Y-axis keys */
167
+ yAxisKeys?: string[];
168
+ /** Color scheme */
169
+ colors?: string[];
170
+ /** Show legend */
171
+ showLegend?: boolean;
172
+ /** Show grid */
173
+ showGrid?: boolean;
174
+ /** Show tooltip */
175
+ showTooltip?: boolean;
176
+ /** Chart height */
177
+ height?: number | string;
178
+ /** Chart aspect ratio */
179
+ aspectRatio?: string;
180
+ }
181
+
182
+ /**
183
+ * Metric card props
184
+ */
185
+ export interface MetricCardProps {
186
+ /** Metric data */
187
+ metric: Metric;
188
+ /** Card size variant */
189
+ size?: "sm" | "md" | "lg";
190
+ /** Show trend indicator */
191
+ showTrend?: boolean;
192
+ /** Show icon */
193
+ showIcon?: boolean;
194
+ /** Custom class name */
195
+ className?: string;
196
+ /** On click handler */
197
+ onClick?: () => void;
198
+ }
199
+
200
+ /**
201
+ * Analytics card props
202
+ */
203
+ export interface AnalyticsCardProps {
204
+ /** Card title */
205
+ title?: string;
206
+ /** Card description */
207
+ description?: string;
208
+ /** Chart configuration */
209
+ chart?: ChartConfig;
210
+ /** Metrics to display */
211
+ metrics?: Metric[];
212
+ /** Card size */
213
+ size?: "sm" | "md" | "lg" | "full";
214
+ /** Loading state */
215
+ loading?: boolean;
216
+ /** Error message */
217
+ error?: string;
218
+ /** Custom class name */
219
+ className?: string;
220
+ /** Children content */
221
+ children?: React.ReactNode;
222
+ }
223
+
224
+ /**
225
+ * Analytics layout props
226
+ */
227
+ export interface AnalyticsLayoutProps {
228
+ /** Page title */
229
+ title?: string;
230
+ /** Page description */
231
+ description?: string;
232
+ /** Date range selector */
233
+ showDateRange?: boolean;
234
+ /** Refresh button */
235
+ showRefresh?: boolean;
236
+ /** Export button */
237
+ showExport?: boolean;
238
+ /** KPI cards */
239
+ kpis?: KPIs;
240
+ /** Charts configuration */
241
+ charts?: ChartConfig[];
242
+ /** Custom header content */
243
+ headerContent?: React.ReactNode;
244
+ /** Children content */
245
+ children?: React.ReactNode;
246
+ }
247
+
248
+ /**
249
+ * Date range preset
250
+ */
251
+ export interface DateRangePreset {
252
+ /** Preset label */
253
+ label: string;
254
+ /** Preset value */
255
+ value: string;
256
+ /** Number of days */
257
+ days: number;
258
+ }
259
+
260
+ /**
261
+ * Date range value
262
+ */
263
+ export interface DateRangeValue {
264
+ /** Start date */
265
+ from: string;
266
+ /** End date */
267
+ to: string;
268
+ /** Preset label */
269
+ preset?: string;
270
+ }
271
+
272
+ /**
273
+ * Export format
274
+ */
275
+ export type ExportFormat = "csv" | "json" | "xlsx" | "pdf";
276
+
277
+ /**
278
+ * Analytics export options
279
+ */
280
+ export interface AnalyticsExportOptions {
281
+ /** Export format */
282
+ format: ExportFormat;
283
+ /** Include charts */
284
+ includeCharts?: boolean;
285
+ /** Include metrics */
286
+ includeMetrics?: boolean;
287
+ /** Date range */
288
+ dateRange?: DateRangeValue;
289
+ /** Filename */
290
+ filename?: string;
291
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Analytics Types
3
+ *
4
+ * Export all analytics-related types
5
+ */
6
+
7
+ export type {
8
+ Metric,
9
+ TimeSeriesData,
10
+ ChartData,
11
+ FunnelStep,
12
+ FunnelData,
13
+ CohortAnalysis,
14
+ UserSegment,
15
+ KPIData,
16
+ KPIs,
17
+ ChartType,
18
+ ChartConfig,
19
+ MetricCardProps,
20
+ AnalyticsCardProps,
21
+ AnalyticsLayoutProps,
22
+ DateRangePreset,
23
+ DateRangeValue,
24
+ ExportFormat,
25
+ AnalyticsExportOptions,
26
+ } from "./analytics";