@umituz/react-native-design-system 4.25.8 → 4.25.10
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 +1 -1
- package/src/atoms/AtomicAvatar.tsx +0 -5
- package/src/atoms/AtomicInput.tsx +0 -2
- package/src/atoms/AtomicProgress.tsx +0 -5
- package/src/atoms/AtomicTextArea.tsx +0 -4
- package/src/atoms/card/AtomicCard.tsx +111 -54
- package/src/atoms/input/types.ts +0 -2
- package/src/atoms/skeleton/AtomicSkeleton.tsx +2 -2
- package/src/image/presentation/components/ImageGallery.tsx +16 -15
- package/src/image/presentation/components/editor/StickerPickerSheet.tsx +4 -7
- package/src/index.ts +5 -0
- package/src/layouts/ScreenHeader/ScreenHeader.tsx +0 -2
- package/src/loading/presentation/providers/LoadingProvider.tsx +13 -4
- package/src/molecules/SearchBar/SearchBar.tsx +0 -2
- package/src/molecules/SearchBar/SearchSuggestions.tsx +1 -1
- package/src/molecules/SearchBar/types.ts +0 -1
- package/src/molecules/StepHeader/StepHeader.tsx +1 -1
- package/src/molecules/avatar/Avatar.tsx +76 -71
- package/src/molecules/avatar/AvatarGroup.tsx +1 -1
- package/src/molecules/calendar/presentation/components/CalendarDayCell.tsx +2 -3
- package/src/molecules/calendar/presentation/components/CalendarWeekdayHeader.tsx +1 -1
- package/src/molecules/countdown/components/Countdown.tsx +14 -11
- package/src/molecules/info-grid/InfoGrid.tsx +2 -2
- package/src/onboarding/presentation/components/BackgroundImageCollage.tsx +2 -2
- package/src/onboarding/presentation/components/OnboardingBackground.tsx +63 -49
- package/src/onboarding/presentation/components/OnboardingSlide.tsx +2 -2
- package/src/theme/infrastructure/providers/DesignSystemProvider.tsx +3 -1
- package/src/gallery/gallery-download.service.ts +0 -69
- package/src/gallery/gallery-save.service.ts +0 -80
- package/src/gallery/index.ts +0 -3
- package/src/gallery/types.ts +0 -11
- package/src/image/domain/entities/EditorTypes.ts +0 -23
- package/src/image/domain/entities/editor/EditorConfigTypes.ts +0 -35
- package/src/image/domain/entities/editor/EditorElementTypes.ts +0 -60
- package/src/image/domain/entities/editor/EditorFilterTypes.ts +0 -9
- package/src/image/domain/entities/editor/EditorLayerTypes.ts +0 -34
- package/src/image/domain/entities/editor/EditorStateTypes.ts +0 -35
- package/src/image/domain/entities/editor/EditorToolTypes.ts +0 -33
- package/src/image/infrastructure/services/ImageEditorService.ts +0 -134
- package/src/image/infrastructure/utils/ImageAnalysisUtils.ts +0 -120
- package/src/image/infrastructure/utils/ImageEditorHistoryUtils.ts +0 -63
- package/src/image/infrastructure/utils/LayerManager.ts +0 -65
- package/src/media/infrastructure/hooks/useGenericMediaGeneration.ts +0 -170
- package/src/molecules/ConfirmationModal.tsx +0 -42
- package/src/molecules/calendar/infrastructure/storage/CalendarStore.types.ts +0 -64
- package/src/molecules/calendar/infrastructure/storage/CalendarStore.utils.ts +0 -56
- package/src/molecules/calendar/infrastructure/storage/EventActions.ts +0 -140
- package/src/molecules/calendar/infrastructure/storage/NavigationActions.ts +0 -118
- package/src/molecules/calendar/presentation/hooks/useCalendar.ts +0 -185
- package/src/molecules/confirmation-modal/index.ts +0 -7
- package/src/molecules/listitem/index.ts +0 -6
- package/src/molecules/navigation/components/index.ts +0 -4
- package/src/molecules/navigation/utils/NavigationTheme.ts +0 -21
- package/src/presentation/utils/variants/compound.ts +0 -34
- package/src/services/api/ApiClient.ts +0 -180
- package/src/services/api/index.ts +0 -9
- package/src/services/api/types/ApiTypes.ts +0 -50
- package/src/services/api/utils/requestBuilder.ts +0 -92
- package/src/services/api/utils/responseHandler.ts +0 -130
- package/src/storage/cache/index.ts +0 -28
- package/src/theme/core/tokens/BorderRadius.ts +0 -16
- package/src/utilities/clipboard/ClipboardUtils.ts +0 -67
- package/src/utilities/clipboard/index.ts +0 -5
- package/src/utilities/index.ts +0 -6
- package/src/utilities/sharing/domain/entities/Share.ts +0 -104
- package/src/utilities/sharing/domain/entities/SharingUtils.ts +0 -111
- package/src/utilities/sharing/index.ts +0 -33
- package/src/utilities/sharing/infrastructure/services/SharingService.ts +0 -165
- package/src/utilities/sharing/presentation/hooks/useSharing.ts +0 -116
- package/src/utils/colorMapper.ts +0 -193
- package/src/utils/errors/adapters/CacheErrorAdapter.ts +0 -68
- package/src/utils/errors/adapters/ImageErrorAdapter.ts +0 -91
- package/src/utils/errors/adapters/StorageErrorAdapter.ts +0 -107
- package/src/utils/formatHelper.ts +0 -16
- package/src/utils/formatters/dateFormatter.ts +0 -64
- package/src/utils/formatters/numberFormatter.ts +0 -130
- package/src/utils/index.ts +0 -16
- package/src/utils/styleComposer.ts +0 -94
- package/src/utils/validationHelper.ts +0 -16
- package/src/utils/validators/dataValidators.ts +0 -111
- package/src/utils/validators/numericValidators.ts +0 -106
- package/src/utils/validators/stringValidators.ts +0 -85
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generic Media Generation Hook
|
|
3
|
-
* Shared implementation for both Media and CardMedia generation
|
|
4
|
-
* Eliminates ~600 LOC duplication
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { useState, useCallback } from "react";
|
|
8
|
-
|
|
9
|
-
interface GenericMediaAttachment {
|
|
10
|
-
id: string;
|
|
11
|
-
type: string;
|
|
12
|
-
position: string;
|
|
13
|
-
url: string;
|
|
14
|
-
filename: string;
|
|
15
|
-
fileSize: number;
|
|
16
|
-
mimeType: string;
|
|
17
|
-
duration?: number;
|
|
18
|
-
thumbnailUrl?: string;
|
|
19
|
-
caption?: string;
|
|
20
|
-
isDownloaded: boolean;
|
|
21
|
-
createdAt: string;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
interface GenericMediaGenerationRequest {
|
|
25
|
-
type: "text_to_image" | "text_to_audio" | "image_search";
|
|
26
|
-
input: {
|
|
27
|
-
text?: string;
|
|
28
|
-
prompt?: string;
|
|
29
|
-
language?: string;
|
|
30
|
-
voice?: "male" | "female" | "neutral";
|
|
31
|
-
style?: "realistic" | "cartoon" | "artistic";
|
|
32
|
-
};
|
|
33
|
-
options: {
|
|
34
|
-
maxResults?: number;
|
|
35
|
-
quality?: "low" | "medium" | "high";
|
|
36
|
-
format?: "jpeg" | "png" | "mp3" | "wav";
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
interface GenericMediaGenerationResult<TAttachment> {
|
|
41
|
-
success: boolean;
|
|
42
|
-
attachments: TAttachment[];
|
|
43
|
-
creditsUsed: number;
|
|
44
|
-
processingTime: number;
|
|
45
|
-
error?: string;
|
|
46
|
-
requestId: string;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export interface UseGenericMediaGenerationResult<TAttachment, TRequest> {
|
|
50
|
-
generateMedia: (request: TRequest) => Promise<GenericMediaGenerationResult<TAttachment>>;
|
|
51
|
-
isGenerating: boolean;
|
|
52
|
-
generationResult: GenericMediaGenerationResult<TAttachment> | null;
|
|
53
|
-
error: string | null;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Generic implementation of media generation logic
|
|
58
|
-
* Type-safe through attachment factory pattern
|
|
59
|
-
*/
|
|
60
|
-
export function useGenericMediaGeneration<
|
|
61
|
-
TAttachment extends GenericMediaAttachment,
|
|
62
|
-
TRequest extends GenericMediaGenerationRequest
|
|
63
|
-
>(
|
|
64
|
-
attachmentFactory: (baseAttachment: GenericMediaAttachment) => TAttachment
|
|
65
|
-
): UseGenericMediaGenerationResult<TAttachment, TRequest> {
|
|
66
|
-
const [isGenerating, setIsGenerating] = useState(false);
|
|
67
|
-
const [generationResult, setGenerationResult] =
|
|
68
|
-
useState<GenericMediaGenerationResult<TAttachment> | null>(null);
|
|
69
|
-
const [error, setError] = useState<string | null>(null);
|
|
70
|
-
|
|
71
|
-
const generateMedia = useCallback(
|
|
72
|
-
async (request: TRequest): Promise<GenericMediaGenerationResult<TAttachment>> => {
|
|
73
|
-
try {
|
|
74
|
-
setIsGenerating(true);
|
|
75
|
-
setError(null);
|
|
76
|
-
|
|
77
|
-
// Simulate generation
|
|
78
|
-
await new Promise((resolve) => setTimeout(resolve, 3000));
|
|
79
|
-
|
|
80
|
-
const baseAttachments: GenericMediaAttachment[] = [];
|
|
81
|
-
|
|
82
|
-
switch (request.type) {
|
|
83
|
-
case "text_to_image":
|
|
84
|
-
for (let i = 0; i < (request.options.maxResults || 1); i++) {
|
|
85
|
-
baseAttachments.push({
|
|
86
|
-
id: `ai_img_${Date.now()}_${i}`,
|
|
87
|
-
type: "image",
|
|
88
|
-
position: "both",
|
|
89
|
-
url: `https://picsum.photos/400/300?random=${Date.now() + i}`,
|
|
90
|
-
filename: `ai_generated_${i}.jpg`,
|
|
91
|
-
fileSize: 150000,
|
|
92
|
-
mimeType: "image/jpeg",
|
|
93
|
-
isDownloaded: false,
|
|
94
|
-
createdAt: new Date().toISOString(),
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
break;
|
|
98
|
-
|
|
99
|
-
case "text_to_audio":
|
|
100
|
-
baseAttachments.push({
|
|
101
|
-
id: `ai_audio_${Date.now()}`,
|
|
102
|
-
type: "audio",
|
|
103
|
-
position: "back",
|
|
104
|
-
url: `https://example.com/audio_${Date.now()}.mp3`,
|
|
105
|
-
filename: `ai_generated_${Date.now()}.mp3`,
|
|
106
|
-
fileSize: 80000,
|
|
107
|
-
mimeType: "audio/mp3",
|
|
108
|
-
duration: 10,
|
|
109
|
-
isDownloaded: false,
|
|
110
|
-
createdAt: new Date().toISOString(),
|
|
111
|
-
});
|
|
112
|
-
break;
|
|
113
|
-
|
|
114
|
-
case "image_search":
|
|
115
|
-
for (let i = 0; i < (request.options.maxResults || 5); i++) {
|
|
116
|
-
baseAttachments.push({
|
|
117
|
-
id: `search_img_${Date.now()}_${i}`,
|
|
118
|
-
type: "image",
|
|
119
|
-
position: "both",
|
|
120
|
-
url: `https://picsum.photos/400/300?random=${Date.now() + i}`,
|
|
121
|
-
filename: `search_result_${i}.jpg`,
|
|
122
|
-
fileSize: 120000,
|
|
123
|
-
mimeType: "image/jpeg",
|
|
124
|
-
isDownloaded: false,
|
|
125
|
-
createdAt: new Date().toISOString(),
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
break;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const attachments = baseAttachments.map(attachmentFactory);
|
|
132
|
-
|
|
133
|
-
const result: GenericMediaGenerationResult<TAttachment> = {
|
|
134
|
-
success: true,
|
|
135
|
-
attachments,
|
|
136
|
-
creditsUsed: request.type === "text_to_image" ? 5 : request.type === "text_to_audio" ? 3 : 2,
|
|
137
|
-
processingTime: 3000,
|
|
138
|
-
requestId: `req_${Date.now()}`,
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
setGenerationResult(result);
|
|
142
|
-
return result;
|
|
143
|
-
} catch (err) {
|
|
144
|
-
const errorMessage =
|
|
145
|
-
err instanceof Error ? err.message : "Generation failed";
|
|
146
|
-
setError(errorMessage);
|
|
147
|
-
setIsGenerating(false);
|
|
148
|
-
|
|
149
|
-
return {
|
|
150
|
-
success: false,
|
|
151
|
-
attachments: [],
|
|
152
|
-
creditsUsed: 0,
|
|
153
|
-
processingTime: 0,
|
|
154
|
-
error: errorMessage,
|
|
155
|
-
requestId: "",
|
|
156
|
-
};
|
|
157
|
-
} finally {
|
|
158
|
-
setIsGenerating(false);
|
|
159
|
-
}
|
|
160
|
-
},
|
|
161
|
-
[attachmentFactory],
|
|
162
|
-
);
|
|
163
|
-
|
|
164
|
-
return {
|
|
165
|
-
generateMedia,
|
|
166
|
-
isGenerating,
|
|
167
|
-
generationResult,
|
|
168
|
-
error,
|
|
169
|
-
};
|
|
170
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ConfirmationModal - Universal Confirmation Dialog
|
|
3
|
-
*
|
|
4
|
-
* A reusable confirmation modal for destructive and important actions.
|
|
5
|
-
* Follows Material Design 3 dialog patterns and accessibility guidelines.
|
|
6
|
-
*
|
|
7
|
-
* Features:
|
|
8
|
-
* - Multiple variants (default, destructive, warning, success)
|
|
9
|
-
* - Configurable text and icons
|
|
10
|
-
* - Backdrop dismissal
|
|
11
|
-
* - Full keyboard and screen reader support
|
|
12
|
-
* - Theme-aware styling
|
|
13
|
-
*
|
|
14
|
-
* @example
|
|
15
|
-
* ```tsx
|
|
16
|
-
* // Destructive confirmation (delete)
|
|
17
|
-
* <ConfirmationModal
|
|
18
|
-
* visible={showDeleteModal}
|
|
19
|
-
* variant="destructive"
|
|
20
|
-
* title="Delete Item?"
|
|
21
|
-
* message="This action cannot be undone. All data will be permanently deleted."
|
|
22
|
-
* confirmText="Delete"
|
|
23
|
-
* cancelText="Cancel"
|
|
24
|
-
* onConfirm={handleDelete}
|
|
25
|
-
* onCancel={() => setShowDeleteModal(false)}
|
|
26
|
-
* />
|
|
27
|
-
*
|
|
28
|
-
* // Generic confirmation
|
|
29
|
-
* <ConfirmationModal
|
|
30
|
-
* visible={showConfirmModal}
|
|
31
|
-
* variant="default"
|
|
32
|
-
* title="Confirm Action"
|
|
33
|
-
* message="Are you sure you want to proceed?"
|
|
34
|
-
* onConfirm={handleConfirm}
|
|
35
|
-
* onCancel={() => setShowConfirmModal(false)}
|
|
36
|
-
* />
|
|
37
|
-
* ```
|
|
38
|
-
*/
|
|
39
|
-
|
|
40
|
-
export { ConfirmationModal } from './ConfirmationModalMain';
|
|
41
|
-
export { useConfirmationModal } from './confirmation-modal/useConfirmationModal';
|
|
42
|
-
export type { ConfirmationModalProps, ConfirmationModalVariant } from './confirmation-modal/types';
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Calendar Store Types
|
|
3
|
-
* Type definitions for calendar store
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { CalendarEvent, CreateCalendarEventRequest, UpdateCalendarEventRequest } from '../../domain/entities/CalendarEvent.entity';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Calendar view mode
|
|
10
|
-
*/
|
|
11
|
-
export type CalendarViewMode = 'month' | 'week' | 'day' | 'list';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Calendar state (data only)
|
|
15
|
-
*/
|
|
16
|
-
export interface CalendarState {
|
|
17
|
-
events: CalendarEvent[];
|
|
18
|
-
selectedDate: Date;
|
|
19
|
-
currentMonth: Date;
|
|
20
|
-
viewMode: CalendarViewMode;
|
|
21
|
-
isLoading: boolean;
|
|
22
|
-
error: string | null;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Calendar actions
|
|
27
|
-
*/
|
|
28
|
-
export interface CalendarActions {
|
|
29
|
-
// Event CRUD
|
|
30
|
-
loadEvents: () => Promise<void>;
|
|
31
|
-
addEvent: (request: CreateCalendarEventRequest) => Promise<void>;
|
|
32
|
-
updateEvent: (request: UpdateCalendarEventRequest) => Promise<void>;
|
|
33
|
-
deleteEvent: (id: string) => Promise<void>;
|
|
34
|
-
completeEvent: (id: string) => Promise<void>;
|
|
35
|
-
uncompleteEvent: (id: string) => Promise<void>;
|
|
36
|
-
|
|
37
|
-
// Navigation
|
|
38
|
-
setSelectedDate: (date: Date) => void;
|
|
39
|
-
goToToday: () => void;
|
|
40
|
-
navigateMonth: (direction: 'prev' | 'next') => void;
|
|
41
|
-
navigateWeek: (direction: 'prev' | 'next') => void;
|
|
42
|
-
setCurrentMonth: (date: Date) => void;
|
|
43
|
-
|
|
44
|
-
// View mode
|
|
45
|
-
setViewMode: (mode: CalendarViewMode) => void;
|
|
46
|
-
|
|
47
|
-
// Utilities
|
|
48
|
-
getEventsForDate: (date: Date) => CalendarEvent[];
|
|
49
|
-
getEventsForMonth: (year: number, month: number) => CalendarEvent[];
|
|
50
|
-
clearError: () => void;
|
|
51
|
-
clearAllEvents: () => Promise<void>;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Initial state
|
|
56
|
-
*/
|
|
57
|
-
export const initialState: CalendarState = {
|
|
58
|
-
events: [],
|
|
59
|
-
selectedDate: new Date(),
|
|
60
|
-
currentMonth: new Date(),
|
|
61
|
-
viewMode: 'month',
|
|
62
|
-
isLoading: false,
|
|
63
|
-
error: null,
|
|
64
|
-
};
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Calendar Store Utilities
|
|
3
|
-
* Helper functions for calendar store operations
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { CalendarEvent } from '../../domain/entities/CalendarEvent.entity';
|
|
7
|
-
import type { CalendarState } from './CalendarStore.types';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Storage key for calendar events
|
|
11
|
-
*/
|
|
12
|
-
export const STORAGE_KEY = 'calendar_events';
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Generate unique ID for events
|
|
16
|
-
*/
|
|
17
|
-
export const generateId = (): string => {
|
|
18
|
-
return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Hydrate date strings in events back to Date objects
|
|
23
|
-
*/
|
|
24
|
-
export const hydrateEvents = (events: CalendarEvent[]): CalendarEvent[] => {
|
|
25
|
-
return events.map((event) => ({
|
|
26
|
-
...event,
|
|
27
|
-
createdAt: new Date(event.createdAt),
|
|
28
|
-
updatedAt: new Date(event.updatedAt),
|
|
29
|
-
}));
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Handle storage operation error
|
|
34
|
-
*/
|
|
35
|
-
export const handleStorageError = (
|
|
36
|
-
set: (state: Partial<CalendarState>) => void,
|
|
37
|
-
errorMessage: string
|
|
38
|
-
): void => {
|
|
39
|
-
set({
|
|
40
|
-
error: errorMessage,
|
|
41
|
-
isLoading: false,
|
|
42
|
-
});
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Handle storage operation success
|
|
47
|
-
*/
|
|
48
|
-
export const handleStorageSuccess = (
|
|
49
|
-
set: (state: Partial<CalendarState>) => void,
|
|
50
|
-
updates: Partial<CalendarState>
|
|
51
|
-
): void => {
|
|
52
|
-
set({
|
|
53
|
-
...updates,
|
|
54
|
-
isLoading: false,
|
|
55
|
-
});
|
|
56
|
-
};
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Calendar Event Actions
|
|
3
|
-
* Event CRUD operations for calendar store
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { storageRepository, unwrap } from '../../../../storage';
|
|
7
|
-
import type { CalendarEvent, CreateCalendarEventRequest, UpdateCalendarEventRequest } from '../../domain/entities/CalendarEvent.entity';
|
|
8
|
-
import { generateId, STORAGE_KEY, hydrateEvents, handleStorageError, handleStorageSuccess } from './CalendarStore.utils';
|
|
9
|
-
import type { CalendarState } from './CalendarStore.types';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Load events from storage
|
|
13
|
-
*/
|
|
14
|
-
export const loadEvents = async (
|
|
15
|
-
set: (state: Partial<CalendarState>) => void
|
|
16
|
-
): Promise<void> => {
|
|
17
|
-
set({ isLoading: true, error: null });
|
|
18
|
-
try {
|
|
19
|
-
const result = await storageRepository.getItem<CalendarEvent[]>(STORAGE_KEY, []);
|
|
20
|
-
const events = unwrap(result, []);
|
|
21
|
-
|
|
22
|
-
if (events && events.length > 0) {
|
|
23
|
-
const hydratedEvents = hydrateEvents(events);
|
|
24
|
-
set({ events: hydratedEvents, isLoading: false });
|
|
25
|
-
} else {
|
|
26
|
-
set({ isLoading: false });
|
|
27
|
-
}
|
|
28
|
-
} catch {
|
|
29
|
-
handleStorageError(set, 'Failed to load events');
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Add a new event
|
|
35
|
-
*/
|
|
36
|
-
export const addEvent = async (
|
|
37
|
-
request: CreateCalendarEventRequest,
|
|
38
|
-
set: (state: Partial<CalendarState>) => void,
|
|
39
|
-
get: () => CalendarState
|
|
40
|
-
): Promise<void> => {
|
|
41
|
-
set({ isLoading: true, error: null });
|
|
42
|
-
try {
|
|
43
|
-
const newEvent: CalendarEvent = {
|
|
44
|
-
id: generateId(),
|
|
45
|
-
...request,
|
|
46
|
-
isCompleted: false,
|
|
47
|
-
createdAt: new Date(),
|
|
48
|
-
updatedAt: new Date(),
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
const events = [...get().events, newEvent];
|
|
52
|
-
await storageRepository.setItem(STORAGE_KEY, events);
|
|
53
|
-
handleStorageSuccess(set, { events });
|
|
54
|
-
} catch {
|
|
55
|
-
handleStorageError(set, 'Failed to add event');
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Update an existing event
|
|
61
|
-
*/
|
|
62
|
-
export const updateEvent = async (
|
|
63
|
-
request: UpdateCalendarEventRequest,
|
|
64
|
-
set: (state: Partial<CalendarState>) => void,
|
|
65
|
-
get: () => CalendarState
|
|
66
|
-
): Promise<void> => {
|
|
67
|
-
set({ isLoading: true, error: null });
|
|
68
|
-
try {
|
|
69
|
-
const events = get().events.map((event) => {
|
|
70
|
-
if (event.id === request.id) {
|
|
71
|
-
return {
|
|
72
|
-
...event,
|
|
73
|
-
...request,
|
|
74
|
-
updatedAt: new Date(),
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
return event;
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
await storageRepository.setItem(STORAGE_KEY, events);
|
|
81
|
-
handleStorageSuccess(set, { events });
|
|
82
|
-
} catch {
|
|
83
|
-
handleStorageError(set, 'Failed to update event');
|
|
84
|
-
}
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Delete an event
|
|
89
|
-
*/
|
|
90
|
-
export const deleteEvent = async (
|
|
91
|
-
id: string,
|
|
92
|
-
set: (state: Partial<CalendarState>) => void,
|
|
93
|
-
get: () => CalendarState
|
|
94
|
-
): Promise<void> => {
|
|
95
|
-
set({ isLoading: true, error: null });
|
|
96
|
-
try {
|
|
97
|
-
const events = get().events.filter((event) => event.id !== id);
|
|
98
|
-
await storageRepository.setItem(STORAGE_KEY, events);
|
|
99
|
-
handleStorageSuccess(set, { events });
|
|
100
|
-
} catch {
|
|
101
|
-
handleStorageError(set, 'Failed to delete event');
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Mark event as completed
|
|
107
|
-
*/
|
|
108
|
-
export const completeEvent = async (
|
|
109
|
-
id: string,
|
|
110
|
-
get: () => CalendarState,
|
|
111
|
-
updateEvent: (request: UpdateCalendarEventRequest) => Promise<void>
|
|
112
|
-
): Promise<void> => {
|
|
113
|
-
await updateEvent({ id, isCompleted: true });
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Mark event as incomplete
|
|
118
|
-
*/
|
|
119
|
-
export const uncompleteEvent = async (
|
|
120
|
-
id: string,
|
|
121
|
-
get: () => CalendarState,
|
|
122
|
-
updateEvent: (request: UpdateCalendarEventRequest) => Promise<void>
|
|
123
|
-
): Promise<void> => {
|
|
124
|
-
await updateEvent({ id, isCompleted: false });
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Clear all events (for testing/reset)
|
|
129
|
-
*/
|
|
130
|
-
export const clearAllEvents = async (
|
|
131
|
-
set: (state: Partial<CalendarState>) => void
|
|
132
|
-
): Promise<void> => {
|
|
133
|
-
set({ isLoading: true, error: null });
|
|
134
|
-
try {
|
|
135
|
-
await storageRepository.removeItem(STORAGE_KEY);
|
|
136
|
-
handleStorageSuccess(set, { events: [] });
|
|
137
|
-
} catch {
|
|
138
|
-
handleStorageError(set, 'Failed to clear events');
|
|
139
|
-
}
|
|
140
|
-
};
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Calendar Navigation Actions
|
|
3
|
-
* Navigation and view mode operations for calendar store
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { CalendarService } from '../services/CalendarService';
|
|
7
|
-
import type { CalendarState, CalendarViewMode } from './CalendarStore.types';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Set selected date
|
|
11
|
-
*/
|
|
12
|
-
export const setSelectedDate = (
|
|
13
|
-
date: Date,
|
|
14
|
-
set: (state: Partial<CalendarState>) => void
|
|
15
|
-
): void => {
|
|
16
|
-
set({ selectedDate: date });
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Go to today's date
|
|
21
|
-
*/
|
|
22
|
-
export const goToToday = (
|
|
23
|
-
set: (state: Partial<CalendarState>) => void
|
|
24
|
-
): void => {
|
|
25
|
-
const today = new Date();
|
|
26
|
-
set({
|
|
27
|
-
selectedDate: today,
|
|
28
|
-
currentMonth: today,
|
|
29
|
-
});
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Navigate to previous/next month
|
|
34
|
-
*/
|
|
35
|
-
export const navigateMonth = (
|
|
36
|
-
direction: 'prev' | 'next',
|
|
37
|
-
set: (state: Partial<CalendarState>) => void,
|
|
38
|
-
get: () => CalendarState
|
|
39
|
-
): void => {
|
|
40
|
-
const currentMonth = get().currentMonth;
|
|
41
|
-
const newMonth =
|
|
42
|
-
direction === 'prev'
|
|
43
|
-
? CalendarService.getPreviousMonth(currentMonth)
|
|
44
|
-
: CalendarService.getNextMonth(currentMonth);
|
|
45
|
-
|
|
46
|
-
set({ currentMonth: newMonth });
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Navigate to previous/next week
|
|
51
|
-
*/
|
|
52
|
-
export const navigateWeek = (
|
|
53
|
-
direction: 'prev' | 'next',
|
|
54
|
-
set: (state: Partial<CalendarState>) => void,
|
|
55
|
-
get: () => CalendarState
|
|
56
|
-
): void => {
|
|
57
|
-
const selectedDate = get().selectedDate;
|
|
58
|
-
const newDate =
|
|
59
|
-
direction === 'prev'
|
|
60
|
-
? CalendarService.getPreviousWeek(selectedDate)
|
|
61
|
-
: CalendarService.getNextWeek(selectedDate);
|
|
62
|
-
|
|
63
|
-
set({ selectedDate: newDate });
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Set current month directly
|
|
68
|
-
*/
|
|
69
|
-
export const setCurrentMonth = (
|
|
70
|
-
date: Date,
|
|
71
|
-
set: (state: Partial<CalendarState>) => void
|
|
72
|
-
): void => {
|
|
73
|
-
set({ currentMonth: date });
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Set view mode
|
|
78
|
-
*/
|
|
79
|
-
export const setViewMode = (
|
|
80
|
-
mode: CalendarViewMode,
|
|
81
|
-
set: (state: Partial<CalendarState>) => void
|
|
82
|
-
): void => {
|
|
83
|
-
set({ viewMode: mode });
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Get events for a specific date
|
|
88
|
-
*/
|
|
89
|
-
export const getEventsForDate = (
|
|
90
|
-
date: Date,
|
|
91
|
-
get: () => CalendarState
|
|
92
|
-
): ReturnType<typeof CalendarService.getEventsForDate> => {
|
|
93
|
-
const events = get().events;
|
|
94
|
-
return CalendarService.getEventsForDate(date, events);
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Get events for a specific month
|
|
99
|
-
*/
|
|
100
|
-
export const getEventsForMonth = (
|
|
101
|
-
year: number,
|
|
102
|
-
month: number,
|
|
103
|
-
get: () => CalendarState
|
|
104
|
-
): ReturnType<typeof CalendarService.getEventsInRange> => {
|
|
105
|
-
const events = get().events;
|
|
106
|
-
const firstDay = new Date(year, month, 1);
|
|
107
|
-
const lastDay = new Date(year, month + 1, 0);
|
|
108
|
-
return CalendarService.getEventsInRange(firstDay, lastDay, events);
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Clear error state
|
|
113
|
-
*/
|
|
114
|
-
export const clearError = (
|
|
115
|
-
set: (state: Partial<CalendarState>) => void
|
|
116
|
-
): void => {
|
|
117
|
-
set({ error: null });
|
|
118
|
-
};
|