@umituz/web-dashboard 3.2.2 → 4.0.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.
Files changed (125) hide show
  1. package/README.md +202 -14
  2. package/package.json +21 -29
  3. package/src/domains/analytics/components/AnalyticsCard.tsx +23 -21
  4. package/src/domains/analytics/components/AnalyticsChart.tsx +345 -149
  5. package/src/domains/analytics/components/AnalyticsLayout.tsx +93 -112
  6. package/src/domains/analytics/components/MetricCard.tsx +42 -64
  7. package/src/domains/analytics/hooks/index.ts +7 -1
  8. package/src/domains/analytics/hooks/useAnalytics.ts +144 -139
  9. package/src/domains/analytics/index.ts +11 -0
  10. package/src/domains/analytics/services/AnalyticsEngineService.ts +103 -55
  11. package/src/domains/analytics/services/PerformanceService.ts +117 -69
  12. package/src/domains/analytics/types/analytics.ts +20 -6
  13. package/src/domains/analytics/types/index.ts +3 -0
  14. package/src/domains/analytics/utils/analytics.test.ts +183 -0
  15. package/src/domains/analytics/utils/analytics.ts +26 -9
  16. package/src/domains/analytics/utils/i18nKeys.ts +40 -0
  17. package/src/domains/analytics/utils/index.ts +2 -0
  18. package/src/domains/auth/components/AuthLayout.tsx +63 -54
  19. package/src/domains/auth/components/ForgotPasswordForm.tsx +96 -98
  20. package/src/domains/auth/components/LoginForm.tsx +167 -226
  21. package/src/domains/auth/components/RegisterForm.tsx +202 -272
  22. package/src/domains/auth/components/ResetPasswordForm.tsx +105 -151
  23. package/src/domains/auth/components/shared/AuthErrorBanner.tsx +35 -0
  24. package/src/domains/auth/components/shared/EmailInput.tsx +91 -0
  25. package/src/domains/auth/components/shared/PasswordInput.tsx +119 -0
  26. package/src/domains/auth/components/shared/PasswordStrengthIndicator.tsx +75 -0
  27. package/src/domains/auth/components/shared/SocialLoginButtons.tsx +58 -0
  28. package/src/domains/auth/components/shared/SocialProviderIcons.tsx +48 -0
  29. package/src/domains/auth/components/shared/index.ts +20 -0
  30. package/src/domains/auth/hooks/index.ts +1 -0
  31. package/src/domains/auth/hooks/useAuth.ts +151 -232
  32. package/src/domains/auth/index.ts +8 -4
  33. package/src/domains/auth/types/auth.ts +26 -5
  34. package/src/domains/auth/types/index.ts +1 -0
  35. package/src/domains/auth/utils/auth.test.ts +182 -0
  36. package/src/domains/auth/utils/auth.ts +71 -130
  37. package/src/domains/auth/utils/i18nKeys.ts +127 -0
  38. package/src/domains/auth/utils/index.ts +7 -1
  39. package/src/domains/auth/utils/secureToken.ts +33 -0
  40. package/src/domains/auth/utils/validationKeys.ts +23 -0
  41. package/src/domains/calendar/hooks/useCalendar.ts +145 -151
  42. package/src/domains/calendar/index.ts +0 -1
  43. package/src/domains/calendar/services/CalendarService.ts +122 -179
  44. package/src/domains/calendar/utils/contentItemMapper.test.ts +108 -0
  45. package/src/domains/calendar/utils/contentItemMapper.ts +99 -0
  46. package/src/domains/calendar/utils/index.ts +33 -30
  47. package/src/domains/layouts/components/BrandLogo.tsx +12 -9
  48. package/src/domains/layouts/components/DashboardHeader.tsx +78 -80
  49. package/src/domains/layouts/components/DashboardLayout.tsx +45 -21
  50. package/src/domains/layouts/components/DashboardSidebar.tsx +48 -51
  51. package/src/domains/layouts/types/layout.ts +7 -1
  52. package/src/domains/layouts/types/user.ts +3 -1
  53. package/src/domains/modules/build.test.tsx +97 -0
  54. package/src/domains/modules/build.tsx +71 -0
  55. package/src/domains/modules/index.ts +2 -0
  56. package/src/domains/modules/types.ts +29 -0
  57. package/src/domains/onboarding/components/AppFocusStep.tsx +99 -68
  58. package/src/domains/onboarding/components/OnboardingWizard.tsx +109 -183
  59. package/src/domains/onboarding/components/PlanStep.tsx +156 -123
  60. package/src/domains/onboarding/components/PlatformsStep.tsx +74 -54
  61. package/src/domains/onboarding/components/StepNavigation.tsx +108 -0
  62. package/src/domains/onboarding/components/StepProgress.tsx +62 -0
  63. package/src/domains/onboarding/components/UserTypeStep.tsx +59 -80
  64. package/src/domains/onboarding/components/index.ts +4 -0
  65. package/src/domains/onboarding/hooks/useOnboarding.ts +76 -66
  66. package/src/domains/onboarding/index.ts +1 -0
  67. package/src/domains/onboarding/types/onboarding.ts +57 -17
  68. package/src/domains/onboarding/utils/i18nKeys.ts +72 -0
  69. package/src/domains/onboarding/utils/index.ts +2 -0
  70. package/src/domains/permissions/PermissionsContext.tsx +103 -0
  71. package/src/domains/permissions/hasPermission.test.ts +50 -0
  72. package/src/domains/permissions/hasPermission.ts +38 -0
  73. package/src/domains/permissions/index.ts +19 -0
  74. package/src/domains/permissions/types.ts +35 -0
  75. package/src/domains/permissions/utils/i18nKeys.ts +11 -0
  76. package/src/domains/session/DemoLogin.tsx +50 -0
  77. package/src/domains/session/OrgSwitcher.tsx +110 -0
  78. package/src/domains/session/SessionContext.tsx +150 -0
  79. package/src/domains/session/inMemoryAuthAdapter.ts +53 -0
  80. package/src/domains/session/index.ts +18 -0
  81. package/src/domains/session/types.ts +47 -0
  82. package/src/domains/session/utils/i18nKeys.ts +12 -0
  83. package/src/domains/settings/components/AuditLogList.tsx +59 -0
  84. package/src/domains/settings/components/PermissionMatrixScreen.tsx +80 -0
  85. package/src/domains/settings/components/SettingsLayout.tsx +75 -60
  86. package/src/domains/settings/components/SettingsSection.tsx +35 -22
  87. package/src/domains/settings/components/UserManagementTable.tsx +87 -0
  88. package/src/domains/settings/components/index.ts +10 -0
  89. package/src/domains/settings/hooks/useSettings.ts +77 -52
  90. package/src/domains/settings/types/settings.ts +2 -0
  91. package/src/domains/settings/utils/i18nKeys.ts +18 -0
  92. package/src/domains/settings/utils/settings.ts +11 -4
  93. package/src/i18n/I18nContext.tsx +33 -0
  94. package/src/i18n/defaultT.test.ts +43 -0
  95. package/src/i18n/defaultT.ts +34 -0
  96. package/src/i18n/index.ts +7 -0
  97. package/src/i18n/types.ts +13 -0
  98. package/src/index.ts +1 -7
  99. package/src/primitives/Button.tsx +30 -0
  100. package/src/primitives/Checkbox.tsx +40 -0
  101. package/src/primitives/Input.tsx +19 -0
  102. package/src/primitives/Skeleton.tsx +26 -0
  103. package/src/primitives/cn.ts +15 -0
  104. package/src/primitives/index.ts +23 -0
  105. package/src/styles/dashboard.css +3045 -0
  106. package/src/styles/tokens.contract.test.ts +66 -0
  107. package/src/styles/tokens.css +124 -0
  108. package/src/domains/billing/components/BillingLayout.tsx +0 -63
  109. package/src/domains/billing/components/BillingPage.tsx +0 -49
  110. package/src/domains/billing/components/BillingPortal.tsx +0 -198
  111. package/src/domains/billing/components/InvoiceCard.tsx +0 -143
  112. package/src/domains/billing/components/PaymentMethodsList.tsx +0 -116
  113. package/src/domains/billing/components/PlanComparison.tsx +0 -199
  114. package/src/domains/billing/components/UsageCard.tsx +0 -103
  115. package/src/domains/billing/components/index.ts +0 -13
  116. package/src/domains/billing/constants/billing.ts +0 -69
  117. package/src/domains/billing/hooks/index.ts +0 -7
  118. package/src/domains/billing/hooks/useBilling.ts +0 -385
  119. package/src/domains/billing/index.ts +0 -73
  120. package/src/domains/billing/types/billing.ts +0 -342
  121. package/src/domains/billing/types/index.ts +0 -30
  122. package/src/domains/billing/utils/billing.ts +0 -360
  123. package/src/domains/billing/utils/index.ts +0 -31
  124. package/src/domains/billing/utils/polar.ts +0 -63
  125. package/src/domains/calendar/components/index.ts +0 -7
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Auth Utilities - Secure Token
3
+ *
4
+ * Cryptographically secure token generation utilities
5
+ */
6
+
7
+ /**
8
+ * Generate a cryptographically secure random token.
9
+ *
10
+ * Requires the Web Crypto API (`crypto.getRandomValues`), available in
11
+ * all modern browsers, Node.js >= 19 (and >= 15 via `globalThis.crypto`),
12
+ * and React Native with a crypto polyfill. Throws instead of silently
13
+ * degrading to an insecure PRNG — predictable tokens are worse than
14
+ * a loud failure.
15
+ *
16
+ * @param length - Token length in bytes (default: 32)
17
+ * @returns Hex-encoded random token
18
+ * @throws Error when no CSPRNG is available in the runtime
19
+ */
20
+ export function generateResetToken(length: number = 32): string {
21
+ if (typeof crypto === 'undefined' || typeof crypto.getRandomValues !== 'function') {
22
+ throw new Error(
23
+ 'generateResetToken: no cryptographic random source available in this runtime ' +
24
+ '(requires crypto.getRandomValues — Web Crypto, Node >= 19, or a polyfill)',
25
+ );
26
+ }
27
+
28
+ const byteLength = Math.max(1, Math.floor(length));
29
+ const bytes = new Uint8Array(byteLength);
30
+ crypto.getRandomValues(bytes);
31
+
32
+ return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');
33
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Auth Validation Error Keys
3
+ *
4
+ * Stable i18n keys for validation errors. The auth UI maps these to
5
+ * localized messages via the consumer's translation system.
6
+ *
7
+ * Why keys instead of literal strings:
8
+ * - No hardcoded user-facing strings in source code
9
+ * - Centralized catalog: easier to audit and translate
10
+ * - Validators stay pure and testable
11
+ */
12
+
13
+ export const AUTH_VALIDATION_KEYS = {
14
+ emailRequired: 'auth.validation.emailRequired',
15
+ emailInvalid: 'auth.validation.emailInvalid',
16
+ passwordRequired: 'auth.validation.passwordRequired',
17
+ passwordTooShort: 'auth.validation.passwordTooShort',
18
+ passwordsDoNotMatch: 'auth.validation.passwordsDoNotMatch',
19
+ nameRequired: 'auth.validation.nameRequired',
20
+ invalidResetToken: 'auth.validation.invalidResetToken',
21
+ } as const;
22
+
23
+ export type AuthValidationKey = (typeof AUTH_VALIDATION_KEYS)[keyof typeof AUTH_VALIDATION_KEYS];
@@ -1,25 +1,36 @@
1
1
  /**
2
- * useCalendar Hook
2
+ * useCalendar
3
3
  *
4
- * React hook for calendar functionality with config support
4
+ * React hook for the calendar domain. Delegates persistence
5
+ * to the injected `CalendarService`, guards refreshes with a
6
+ * request id so a stale response can never overwrite a newer one,
7
+ * and returns a clean discriminated CRUD contract.
5
8
  */
6
9
 
7
- import { useState, useCallback, useEffect, useMemo } from 'react';
8
- import type { CalendarConfig, ContentItem, CalendarFilter } from '../types/calendar.types';
9
- import { calendarService } from '../services';
10
+ import { useState, useCallback, useEffect, useMemo, useRef } from 'react';
11
+ import type {
12
+ CalendarConfig,
13
+ ContentItem,
14
+ CalendarFilter,
15
+ } from '../types/calendar.types';
16
+ import { calendarService, applyCalendarFilter } from '../services';
10
17
  import { DEFAULT_CALENDAR_CONFIG } from '../utils';
18
+ import type { ICalendarService } from '../types/calendar.types';
11
19
 
12
- interface UseCalendarOptions {
13
- /** Calendar configuration */
20
+ type CalendarView = 'month' | 'week' | 'day' | 'timeline';
21
+
22
+ export interface UseCalendarOptions {
23
+ /** Calendar configuration overrides */
14
24
  config?: Partial<CalendarConfig>;
15
- /** User ID */
25
+ /** User ID (required to fetch items) */
16
26
  userId: string;
17
- /** Error callback */
27
+ /** Error callback — receives the original Error */
18
28
  onError?: (error: Error) => void;
29
+ /** Override the default service (useful for tests) */
30
+ service?: ICalendarService;
19
31
  }
20
32
 
21
- interface UseCalendarReturn {
22
- // Data
33
+ export interface UseCalendarReturn {
23
34
  items: ContentItem[];
24
35
  loading: boolean;
25
36
  error: string | null;
@@ -28,182 +39,171 @@ interface UseCalendarReturn {
28
39
  selectedDate: Date;
29
40
  filter: CalendarFilter;
30
41
 
31
- // Actions
32
42
  setCurrentView: (view: CalendarView) => void;
33
43
  setCurrentDate: (date: Date) => void;
34
44
  setSelectedDate: (date: Date) => void;
35
45
  setFilter: (filter: Partial<CalendarFilter>) => void;
36
46
  refresh: () => Promise<void>;
37
47
 
38
- // CRUD
39
- createItem: (item: Omit<ContentItem, 'id' | 'created_at' | 'updated_at'>) => Promise<ContentItem>;
48
+ createItem: (
49
+ item: Omit<ContentItem, 'id' | 'created_at' | 'updated_at'>,
50
+ ) => Promise<ContentItem>;
40
51
  updateItem: (id: string, updates: Partial<ContentItem>) => Promise<void>;
41
52
  deleteItem: (id: string) => Promise<void>;
42
53
  moveItem: (id: string, newDate: Date) => Promise<void>;
43
54
 
44
- // Computed
45
55
  filteredItems: ContentItem[];
46
56
  itemsForDate: (date: Date) => ContentItem[];
47
57
  }
48
58
 
49
- type CalendarView = 'month' | 'week' | 'day' | 'timeline';
59
+ const toError = (err: unknown, fallback: string): Error =>
60
+ err instanceof Error ? err : new Error(fallback);
50
61
 
51
- /**
52
- * useCalendar hook
53
- *
54
- * Manages calendar state and operations with config support
55
- */
56
62
  export function useCalendar(options: UseCalendarOptions): UseCalendarReturn {
57
- const { config: userConfig, userId, onError } = options;
63
+ const { config: userConfig, userId, onError, service = calendarService } = options;
58
64
 
59
- // Merge config with defaults
60
- const config = useMemo(() => ({
61
- ...DEFAULT_CALENDAR_CONFIG,
62
- ...userConfig,
63
- }), [userConfig]);
65
+ const config = useMemo(
66
+ () => ({ ...DEFAULT_CALENDAR_CONFIG, ...userConfig }),
67
+ [userConfig],
68
+ );
64
69
 
65
- // State
66
70
  const [items, setItems] = useState<ContentItem[]>([]);
67
71
  const [loading, setLoading] = useState(false);
68
72
  const [error, setError] = useState<string | null>(null);
69
- const [currentView, setCurrentView] = useState<CalendarView>(config.defaultView || 'month');
70
- const [currentDate, setCurrentDate] = useState(new Date());
71
- const [selectedDate, setSelectedDate] = useState(new Date());
72
- const [filter, setFilter] = useState<CalendarFilter>({});
73
+ const [currentView, setCurrentView] = useState<CalendarView>(
74
+ config.defaultView ?? 'month',
75
+ );
76
+ const [currentDate, setCurrentDate] = useState(() => new Date());
77
+ const [selectedDate, setSelectedDate] = useState(() => new Date());
78
+ const [filter, setFilterState] = useState<CalendarFilter>({});
79
+
80
+ // Keep the latest onError in a ref so refresh identity stays stable
81
+ // when consumers pass a fresh closure each render.
82
+ const onErrorRef = useRef(onError);
83
+ useEffect(() => {
84
+ onErrorRef.current = onError;
85
+ }, [onError]);
86
+
87
+ // Guards against out-of-order responses: only the most recent
88
+ // refresh may commit state (e.g. user changes the filter while a
89
+ // previous fetch is still resolving).
90
+ const requestIdRef = useRef(0);
73
91
 
74
- // Fetch items
75
92
  const refresh = useCallback(async () => {
76
- if (!userId) return;
93
+ if (!userId) {
94
+ setError('User ID is required to load calendar items');
95
+ return;
96
+ }
77
97
 
98
+ const requestId = ++requestIdRef.current;
78
99
  setLoading(true);
79
100
  setError(null);
80
-
81
101
  try {
82
- const data = await calendarService.getContentItems(userId, filter);
83
- setItems(data);
102
+ const data = await service.getContentItems(userId, filter);
103
+ if (requestIdRef.current === requestId) {
104
+ setItems(data);
105
+ }
84
106
  } catch (err) {
85
- const errorMessage = err instanceof Error ? err.message : 'Failed to fetch calendar items';
86
- setError(errorMessage);
87
- onError?.(err as Error);
107
+ if (requestIdRef.current === requestId) {
108
+ const wrapped = toError(err, 'Failed to fetch calendar items');
109
+ setError(wrapped.message);
110
+ onErrorRef.current?.(wrapped);
111
+ }
88
112
  } finally {
89
- setLoading(false);
90
- }
91
- }, [userId, filter, onError]);
92
-
93
- // Create item
94
- const createItem = useCallback(async (item: Omit<ContentItem, 'id' | 'created_at' | 'updated_at'>): Promise<ContentItem> => {
95
- if (!userId) {
96
- throw new Error('User ID is required');
97
- }
98
-
99
- try {
100
- const created = await calendarService.createContentItem(userId, item);
101
- await refresh();
102
- return created;
103
- } catch (err) {
104
- onError?.(err as Error);
105
- throw err;
106
- }
107
- }, [userId, refresh, onError]);
108
-
109
- // Update item
110
- const updateItem = useCallback(async (id: string, updates: Partial<ContentItem>): Promise<void> => {
111
- try {
112
- await calendarService.updateContentItem(id, updates);
113
- await refresh();
114
- } catch (err) {
115
- onError?.(err as Error);
116
- throw err;
117
- }
118
- }, [refresh, onError]);
119
-
120
- // Delete item
121
- const deleteItem = useCallback(async (id: string): Promise<void> => {
122
- try {
123
- await calendarService.deleteContentItem(id);
124
- await refresh();
125
- } catch (err) {
126
- onError?.(err as Error);
127
- throw err;
128
- }
129
- }, [refresh, onError]);
130
-
131
- // Move item
132
- const moveItem = useCallback(async (id: string, newDate: Date): Promise<void> => {
133
- try {
134
- await calendarService.moveContentItem(id, newDate);
135
- await refresh();
136
- } catch (err) {
137
- onError?.(err as Error);
138
- throw err;
113
+ if (requestIdRef.current === requestId) {
114
+ setLoading(false);
115
+ }
139
116
  }
140
- }, [refresh, onError]);
141
-
142
- // Filter update
143
- const updateFilter = useCallback((updates: Partial<CalendarFilter>) => {
144
- setFilter(prev => ({ ...prev, ...updates }));
145
- }, []);
146
-
147
- // Get filtered items
148
- const filteredItems = useMemo(() => {
149
- return items.filter(item => {
150
- // Search filter
151
- if (filter.search && !item.title.toLowerCase().includes(filter.search.toLowerCase())) {
152
- return false;
117
+ }, [userId, filter, service]);
118
+
119
+ const createItem = useCallback(
120
+ async (item: Omit<ContentItem, 'id' | 'created_at' | 'updated_at'>) => {
121
+ if (!userId) throw new Error('User ID is required');
122
+ try {
123
+ const created = await service.createContentItem(userId, item);
124
+ await refresh();
125
+ return created;
126
+ } catch (err) {
127
+ const wrapped = toError(err, 'Failed to create item');
128
+ onErrorRef.current?.(wrapped);
129
+ throw wrapped;
153
130
  }
154
-
155
- // Platform filter
156
- if (filter.platforms && filter.platforms.length > 0) {
157
- if (!item.platforms.some(p => filter.platforms?.includes(p))) {
158
- return false;
159
- }
131
+ },
132
+ [userId, service, refresh],
133
+ );
134
+
135
+ const updateItem = useCallback(
136
+ async (id: string, updates: Partial<ContentItem>) => {
137
+ try {
138
+ await service.updateContentItem(id, updates);
139
+ await refresh();
140
+ } catch (err) {
141
+ const wrapped = toError(err, 'Failed to update item');
142
+ onErrorRef.current?.(wrapped);
143
+ throw wrapped;
160
144
  }
161
-
162
- // Type filter
163
- if (filter.types && filter.types.length > 0) {
164
- if (!item.type || !filter.types.includes(item.type)) {
165
- return false;
166
- }
145
+ },
146
+ [service, refresh],
147
+ );
148
+
149
+ const deleteItem = useCallback(
150
+ async (id: string) => {
151
+ try {
152
+ await service.deleteContentItem(id);
153
+ await refresh();
154
+ } catch (err) {
155
+ const wrapped = toError(err, 'Failed to delete item');
156
+ onErrorRef.current?.(wrapped);
157
+ throw wrapped;
167
158
  }
168
-
169
- // Status filter
170
- if (filter.status && item.status !== filter.status) {
171
- return false;
172
- }
173
-
174
- // Date range filter
175
- if (filter.dateRange) {
176
- const itemDate = new Date(item.scheduled_at);
177
- if (itemDate < filter.dateRange.start || itemDate > filter.dateRange.end) {
178
- return false;
179
- }
159
+ },
160
+ [service, refresh],
161
+ );
162
+
163
+ const moveItem = useCallback(
164
+ async (id: string, newDate: Date) => {
165
+ try {
166
+ await service.moveContentItem(id, newDate);
167
+ await refresh();
168
+ } catch (err) {
169
+ const wrapped = toError(err, 'Failed to move item');
170
+ onErrorRef.current?.(wrapped);
171
+ throw wrapped;
180
172
  }
173
+ },
174
+ [service, refresh],
175
+ );
181
176
 
182
- return true;
183
- });
184
- }, [items, filter]);
185
-
186
- // Get items for specific date
187
- const itemsForDate = useCallback((date: Date): ContentItem[] => {
188
- const dateStart = new Date(date);
189
- dateStart.setHours(0, 0, 0, 0);
190
-
191
- const dateEnd = new Date(date);
192
- dateEnd.setHours(23, 59, 59, 999);
177
+ const updateFilter = useCallback((updates: Partial<CalendarFilter>) => {
178
+ setFilterState((prev) => ({ ...prev, ...updates }));
179
+ }, []);
193
180
 
194
- return filteredItems.filter(item => {
195
- const itemDate = new Date(item.scheduled_at);
196
- return itemDate >= dateStart && itemDate <= dateEnd;
197
- });
198
- }, [filteredItems]);
181
+ // Single source of truth for filtering (shared with the service layer)
182
+ // so client-side refiltering can never drift from server-side semantics.
183
+ const filteredItems = useMemo(
184
+ () => applyCalendarFilter(items, filter),
185
+ [items, filter],
186
+ );
187
+
188
+ const itemsForDate = useCallback(
189
+ (date: Date): ContentItem[] => {
190
+ const dateStart = new Date(date);
191
+ dateStart.setHours(0, 0, 0, 0);
192
+ const dateEnd = new Date(date);
193
+ dateEnd.setHours(23, 59, 59, 999);
194
+ return filteredItems.filter((item) => {
195
+ const itemDate = new Date(item.scheduled_at);
196
+ return itemDate >= dateStart && itemDate <= dateEnd;
197
+ });
198
+ },
199
+ [filteredItems],
200
+ );
199
201
 
200
- // Initial fetch
201
202
  useEffect(() => {
202
203
  refresh();
203
204
  }, [refresh]);
204
205
 
205
206
  return {
206
- // Data
207
207
  items,
208
208
  loading,
209
209
  error,
@@ -211,21 +211,15 @@ export function useCalendar(options: UseCalendarOptions): UseCalendarReturn {
211
211
  currentDate,
212
212
  selectedDate,
213
213
  filter,
214
-
215
- // Actions
216
214
  setCurrentView,
217
215
  setCurrentDate,
218
216
  setSelectedDate,
219
217
  setFilter: updateFilter,
220
218
  refresh,
221
-
222
- // CRUD
223
219
  createItem,
224
220
  updateItem,
225
221
  deleteItem,
226
222
  moveItem,
227
-
228
- // Computed
229
223
  filteredItems,
230
224
  itemsForDate,
231
225
  };
@@ -6,4 +6,3 @@ export * from './types/calendar.types';
6
6
  export * from './services';
7
7
  export * from './hooks';
8
8
  export * from './utils';
9
- export * from './components';