@umituz/react-native-settings 5.2.34 → 5.2.36

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 (70) hide show
  1. package/package.json +2 -4
  2. package/src/domains/about/presentation/screens/AboutScreenContent.tsx +87 -63
  3. package/src/domains/appearance/data/colorPalettes.ts +0 -23
  4. package/src/domains/appearance/presentation/components/CustomColorsSection.tsx +2 -4
  5. package/src/domains/appearance/presentation/components/ThemeOption.tsx +2 -2
  6. package/src/domains/dev/presentation/components/DevSettingsSection.tsx +5 -2
  7. package/src/domains/faqs/presentation/screens/FAQScreen.tsx +19 -25
  8. package/src/domains/feedback/presentation/components/FeedbackForm.tsx +160 -81
  9. package/src/domains/gamification/components/GamificationScreen/GamificationScreenWithConfig.tsx +11 -11
  10. package/src/domains/localization/infrastructure/components/LanguageSwitcher.tsx +0 -2
  11. package/src/domains/localization/infrastructure/storage/localizationStoreUtils.ts +1 -1
  12. package/src/domains/localization/presentation/screens/LanguageSelectionScreen.tsx +85 -48
  13. package/src/domains/localization/presentation/screens/__tests__/LanguageSelectionScreen.test.tsx +0 -15
  14. package/src/domains/notifications/presentation/screens/NotificationsScreen.tsx +1 -3
  15. package/src/domains/notifications/reminders/presentation/components/ReminderForm.constants.ts +0 -4
  16. package/src/domains/notifications/reminders/presentation/components/ReminderForm.tsx +69 -31
  17. package/src/domains/rating/presentation/components/StarRating.tsx +7 -13
  18. package/src/infrastructure/utils/configFactory.ts +0 -26
  19. package/src/infrastructure/utils/constants/textLimits.ts +0 -2
  20. package/src/infrastructure/utils/sanitizers.ts +1 -25
  21. package/src/infrastructure/utils/validation/core.ts +0 -33
  22. package/src/infrastructure/utils/validation/formValidators.ts +7 -1
  23. package/src/infrastructure/utils/validation/index.ts +2 -33
  24. package/src/infrastructure/utils/validators.ts +0 -6
  25. package/src/presentation/navigation/utils/index.ts +1 -7
  26. package/src/presentation/navigation/utils/navigationHelpers.ts +2 -87
  27. package/src/presentation/screens/components/SettingsContent.tsx +4 -19
  28. package/src/presentation/screens/components/sections/CustomSettingsList.tsx +3 -8
  29. package/src/presentation/screens/components/sections/FeatureSettingsSection.tsx +0 -4
  30. package/src/presentation/screens/components/sections/IdentitySettingsSection.tsx +0 -4
  31. package/src/presentation/screens/components/sections/SupportSettingsSection.tsx +0 -4
  32. package/src/presentation/utils/screenFactory.ts +0 -25
  33. package/src/utils/appUtils.ts +0 -18
  34. package/src/utils/devUtils.ts +0 -10
  35. package/src/utils/errorUtils.ts +0 -22
  36. package/src/domains/about/utils/index.ts +0 -156
  37. package/src/domains/faqs/domain/services/index.ts +0 -1
  38. package/src/domains/faqs/presentation/screens/index.ts +0 -2
  39. package/src/domains/gamification/components/GamificationScreen/Header.tsx +0 -30
  40. package/src/domains/legal/presentation/components/LegalLinks.tsx +0 -137
  41. package/src/domains/legal/presentation/components/index.ts +0 -5
  42. package/src/domains/localization/infrastructure/config/languagesData.ts +0 -26
  43. package/src/domains/localization/infrastructure/hooks/TranslationHook.ts +0 -37
  44. package/src/domains/localization/infrastructure/storage/AsyncStorageWrapper.ts +0 -34
  45. package/src/infrastructure/storage/storeConfig.ts +0 -114
  46. package/src/infrastructure/types/commonComponentTypes.ts +0 -142
  47. package/src/infrastructure/utils/async/core.ts +0 -110
  48. package/src/infrastructure/utils/async/debounceAndBatch.ts +0 -69
  49. package/src/infrastructure/utils/async/index.ts +0 -8
  50. package/src/infrastructure/utils/async/retryAndTimeout.ts +0 -65
  51. package/src/infrastructure/utils/dateUtils.ts +0 -61
  52. package/src/infrastructure/utils/errorHandlers.ts +0 -250
  53. package/src/infrastructure/utils/index.ts +0 -12
  54. package/src/infrastructure/utils/memoComparisonUtils.ts +0 -66
  55. package/src/infrastructure/utils/memoUtils.ts +0 -167
  56. package/src/infrastructure/utils/styleTokens.ts +0 -145
  57. package/src/infrastructure/utils/styles/componentStyles.ts +0 -90
  58. package/src/infrastructure/utils/styles/index.ts +0 -9
  59. package/src/infrastructure/utils/styles/layoutStyles.ts +0 -56
  60. package/src/infrastructure/utils/styles/spacingStyles.ts +0 -33
  61. package/src/infrastructure/utils/styles/styleHelpers.ts +0 -22
  62. package/src/infrastructure/utils/translationHelpers.ts +0 -81
  63. package/src/infrastructure/utils/validation/numericValidators.ts +0 -66
  64. package/src/infrastructure/utils/validation/passwordValidator.ts +0 -53
  65. package/src/infrastructure/utils/validation/textValidators.ts +0 -118
  66. package/src/presentation/components/ErrorBoundary/SettingsErrorBoundary.tsx +0 -105
  67. package/src/presentation/components/ErrorBoundary/index.ts +0 -12
  68. package/src/presentation/components/ErrorBoundary/withErrorBoundary.tsx +0 -45
  69. package/src/utils/hooks/index.ts +0 -6
  70. package/src/utils/index.ts +0 -3
@@ -1,5 +0,0 @@
1
- export { LegalItem } from "./LegalItem";
2
- export { LegalLinks } from "./LegalLinks";
3
- export { LegalSection } from "./LegalSection";
4
- export { LegalScreenHeader } from "./LegalScreenHeader";
5
- export { LegalDocumentsList } from "./LegalDocumentsList";
@@ -1,26 +0,0 @@
1
- /**
2
- * Language Data Exports
3
- * Centralized exports for language management
4
- */
5
-
6
- import { languageRepository } from '../repository/LanguageRepository';
7
- import { DEFAULT_LANGUAGES } from './constants/defaultLanguages';
8
- import type { Language } from '../storage/types/Language';
9
-
10
- export { languageRepository };
11
- export { DEFAULT_LANGUAGES };
12
- export type { Language };
13
-
14
- export const getLanguageByCode = (code: string) =>
15
- languageRepository.getLanguageByCode(code);
16
-
17
- export const searchLanguages = (query: string) =>
18
- languageRepository.searchLanguages(query);
19
-
20
- export const isLanguageSupported = (code: string) =>
21
- languageRepository.isLanguageSupported(code);
22
-
23
- export const getDefaultLanguage = () =>
24
- languageRepository.getDefaultLanguage();
25
-
26
- export const LANGUAGES = languageRepository.getLanguages();
@@ -1,37 +0,0 @@
1
- /**
2
- * Translation Hook
3
- *
4
- * Provides translation function with fallback logic
5
- * - React i18next integration
6
- * - Direct i18n fallback
7
- * - Type-safe translation function
8
- */
9
-
10
- import { useTranslation } from 'react-i18next';
11
- import i18n from '../config/i18n';
12
-
13
- /**
14
- * Custom hook that provides translation function with proper fallbacks
15
- */
16
- export const useTranslationFunction = (): ((key: string, options?: Record<string, unknown>) => string) => {
17
- // Always call useTranslation hook (React hooks rules)
18
- const translationResult = useTranslation(undefined, { i18n });
19
-
20
- // Use react-i18next if available, otherwise fallback to direct i18n
21
- if (translationResult?.t && typeof translationResult.t === 'function' && i18n.isInitialized) {
22
- return (key: string, options?: Record<string, unknown>): string => {
23
- const result = translationResult.t(key, options);
24
- return typeof result === 'string' ? result : String(result);
25
- };
26
- } else {
27
- return (key: string, options?: Record<string, unknown>): string => {
28
- // Fallback to direct i18n.t
29
- if (i18n.isInitialized && typeof i18n.t === 'function') {
30
- const result = i18n.t(key, options);
31
- return typeof result === 'string' ? result : String(result);
32
- }
33
- // Final fallback: return key
34
- return key;
35
- };
36
- }
37
- };
@@ -1,34 +0,0 @@
1
- /**
2
- * Storage Wrapper
3
- * Uses @umituz/react-native-design-system for persistence
4
- */
5
-
6
- import { storageRepository } from '@umituz/react-native-design-system';
7
-
8
- export const STORAGE_KEYS = {
9
- LANGUAGE: '@localization:language',
10
- } as const;
11
-
12
- export const StorageWrapper = {
13
- async getString(key: string, defaultValue: string): Promise<string> {
14
- try {
15
- const result = await storageRepository.getString(key, defaultValue);
16
- if (result.success && result.data !== null) {
17
- return result.data;
18
- }
19
- return defaultValue;
20
- } catch (error) {
21
- console.error('[StorageWrapper] Failed to get string:', key, error);
22
- return defaultValue;
23
- }
24
- },
25
-
26
- async setString(key: string, value: string): Promise<void> {
27
- try {
28
- await storageRepository.setString(key, value);
29
- } catch (error) {
30
- console.error('[StorageWrapper] Failed to set string:', key, error);
31
- throw error;
32
- }
33
- },
34
- };
@@ -1,114 +0,0 @@
1
- /**
2
- * Store Configuration Standards
3
- * Standardized patterns for all Zustand stores
4
- *
5
- * Provides consistent configuration for:
6
- * - Persistence settings
7
- * - Version management
8
- * - State partializing (excluding transient state)
9
- * - Storage service integration
10
- */
11
-
12
- import type { StateStorage } from 'zustand/middleware';
13
- import { storageService } from '@umituz/react-native-design-system';
14
-
15
- /**
16
- * Standard store configuration interface
17
- */
18
- export interface StandardStoreConfig<T> {
19
- /** Unique storage key name */
20
- name: string;
21
- /** Store version for migrations */
22
- version: number;
23
- /** Enable persistence */
24
- persist: boolean;
25
- /** Custom partialize function to control what gets persisted */
26
- partialize?: (state: T) => Partial<T>;
27
- /** Storage service (defaults to design-system's storageService) */
28
- storage?: StateStorage;
29
- }
30
-
31
- /**
32
- * Create standardized store configuration
33
- *
34
- * @param config - Store configuration
35
- * @returns Complete store config with defaults
36
- *
37
- * @example
38
- * ```typescript
39
- * const config = createStoreConfig({
40
- * name: 'my-store',
41
- * version: 1,
42
- * persist: true,
43
- * partialize: excludeTransientState,
44
- * });
45
- * ```
46
- */
47
- export const createStoreConfig = <T extends object>(
48
- config: StandardStoreConfig<T>
49
- ): Required<StandardStoreConfig<T>> => {
50
- return {
51
- name: config.name,
52
- version: config.version,
53
- persist: config.persist,
54
- partialize: config.partialize || ((state) => state),
55
- storage: config.storage || storageService,
56
- };
57
- };
58
-
59
- /**
60
- * Base interface for store state with transient flags
61
- */
62
- export interface BaseStoreState {
63
- /** Loading state (never persisted) */
64
- isLoading?: boolean;
65
- /** Initialization state (never persisted) */
66
- isInitialized?: boolean;
67
- }
68
-
69
- /**
70
- * Standard partialize function that excludes loading/initialization flags
71
- * These flags are runtime state and should never be persisted
72
- *
73
- * @param state - Store state
74
- * @returns State with transient flags excluded
75
- *
76
- * @example
77
- * ```typescript
78
- * const config = createStoreConfig({
79
- * name: 'my-store',
80
- * version: 1,
81
- * persist: true,
82
- * partialize: excludeTransientState,
83
- * });
84
- * ```
85
- */
86
- export const excludeTransientState = <T extends BaseStoreState>(
87
- state: T
88
- ): Partial<T> => {
89
- const { isLoading: _isLoading, isInitialized: _isInitialized, ...persistedState } = state;
90
- return persistedState as Partial<T>;
91
- };
92
-
93
- /**
94
- * Create partialize function that excludes specific keys
95
- *
96
- * @param excludeKeys - Keys to exclude from persistence
97
- * @returns Partialize function
98
- *
99
- * @example
100
- * ```typescript
101
- * const partialize = createPartializeExcluding(['isLoading', 'error', 'tempData']);
102
- * ```
103
- */
104
- export const createPartializeExcluding = <T extends object>(
105
- excludeKeys: (keyof T)[]
106
- ) => {
107
- return (state: T): Partial<T> => {
108
- const result = { ...state };
109
- excludeKeys.forEach((key) => {
110
- delete result[key];
111
- });
112
- return result;
113
- };
114
- };
@@ -1,142 +0,0 @@
1
- /**
2
- * Common Component Types
3
- * Shared interfaces for common component props to reduce duplication
4
- */
5
-
6
- import type { StyleProp, ViewStyle } from "react-native";
7
- import type { IconName } from "@umituz/react-native-design-system";
8
-
9
- /**
10
- * Base props for settings item components
11
- */
12
- export interface BaseSettingsItemProps {
13
- title: string;
14
- description?: string;
15
- icon?: IconName;
16
- onPress?: () => void;
17
- disabled?: boolean;
18
- style?: StyleProp<ViewStyle>;
19
- testID?: string;
20
- }
21
-
22
- /**
23
- * Base props for card components
24
- */
25
- export interface BaseCardProps {
26
- style?: StyleProp<ViewStyle>;
27
- testID?: string;
28
- }
29
-
30
- /**
31
- * Base props for section components
32
- */
33
- export interface BaseSectionProps {
34
- title?: string;
35
- style?: StyleProp<ViewStyle>;
36
- testID?: string;
37
- }
38
-
39
- /**
40
- * Navigation item props
41
- */
42
- export interface NavigationItemProps extends BaseSettingsItemProps {
43
- route?: string;
44
- showChevron?: boolean;
45
- }
46
-
47
- /**
48
- * Toggle item props (items with switches)
49
- */
50
- export interface ToggleItemProps extends BaseSettingsItemProps {
51
- showSwitch: true;
52
- switchValue: boolean;
53
- onSwitchChange: (value: boolean) => void;
54
- }
55
-
56
- /**
57
- * Pressable item props
58
- */
59
- export interface PressableItemProps extends BaseSettingsItemProps {
60
- onPress: () => void;
61
- }
62
-
63
- /**
64
- * Icon styling props
65
- */
66
- export interface IconStyleProps {
67
- iconBgColor?: string;
68
- iconColor?: string;
69
- iconSize?: number;
70
- }
71
-
72
- /**
73
- * Loading state props
74
- */
75
- export interface LoadingStateProps {
76
- loading?: boolean;
77
- }
78
-
79
- /**
80
- * Badge props (for notification counts, etc.)
81
- */
82
- export interface BadgeProps {
83
- badge?: string | number;
84
- badgeColor?: string;
85
- badgeTextColor?: string;
86
- }
87
-
88
- /**
89
- * Screen header props
90
- */
91
- export interface ScreenHeaderProps {
92
- title: string;
93
- subtitle?: string;
94
- showBackButton?: boolean;
95
- onBackPress?: () => void;
96
- rightElement?: React.ReactNode;
97
- style?: StyleProp<ViewStyle>;
98
- }
99
-
100
- /**
101
- * List item props
102
- */
103
- export interface ListItemProps extends BaseSettingsItemProps {
104
- rightElement?: React.ReactNode;
105
- leftElement?: React.ReactNode;
106
- }
107
-
108
- /**
109
- * Modal props
110
- */
111
- export interface BaseModalProps {
112
- visible: boolean;
113
- onClose: () => void;
114
- title?: string;
115
- testID?: string;
116
- }
117
-
118
- /**
119
- * Form input props
120
- */
121
- export interface BaseInputProps {
122
- value: string;
123
- onChangeText: (text: string) => void;
124
- placeholder?: string;
125
- error?: string;
126
- disabled?: boolean;
127
- style?: StyleProp<ViewStyle>;
128
- testID?: string;
129
- }
130
-
131
- /**
132
- * Button props
133
- */
134
- export interface BaseButtonProps {
135
- title: string;
136
- onPress: () => void;
137
- disabled?: boolean;
138
- loading?: boolean;
139
- variant?: "primary" | "secondary" | "danger" | "ghost";
140
- style?: StyleProp<ViewStyle>;
141
- testID?: string;
142
- }
@@ -1,110 +0,0 @@
1
- /**
2
- * Core Async Operation Utilities
3
- * Base types and handlers for async operations
4
- */
5
-
6
- import type { ValidationResult } from "../validation";
7
- import { isDev } from '../../../utils/devUtils';
8
-
9
- /**
10
- * Result type for async operations
11
- */
12
- export type AsyncResult<T, E = Error> =
13
- | { success: true; data: T }
14
- | { success: false; error: E };
15
-
16
- /**
17
- * Generic async handler with error handling
18
- */
19
- export const handleAsyncOperation = async <T>(
20
- operation: () => Promise<T>,
21
- onError?: (error: Error) => void
22
- ): Promise<AsyncResult<T>> => {
23
- try {
24
- const data = await operation();
25
- return { success: true, data };
26
- } catch (error) {
27
- const err = error instanceof Error ? error : new Error(String(error));
28
- if (onError) {
29
- onError(err);
30
- }
31
- return { success: false, error: err };
32
- }
33
- };
34
-
35
- /**
36
- * Async operation with loading state
37
- * FIXED: Properly handles errors in onSuccess callback
38
- */
39
- export const createAsyncHandler = <T extends unknown[], R>(
40
- handler: (...args: T) => Promise<R>,
41
- options: {
42
- onLoadingStart?: () => void;
43
- onLoadingEnd?: () => void;
44
- onError?: (error: Error) => void;
45
- onSuccess?: (result: R) => void;
46
- }
47
- ) => {
48
- return async (...args: T): Promise<void> => {
49
- const { onLoadingStart, onLoadingEnd, onError, onSuccess } = options;
50
-
51
- let loadingStarted = false;
52
-
53
- try {
54
- onLoadingStart?.();
55
- loadingStarted = true;
56
- const result = await handler(...args);
57
- // FIXED: Wrap onSuccess in try-catch to handle errors separately
58
- try {
59
- onSuccess?.(result);
60
- } catch (callbackError) {
61
- // Log callback error but don't treat it as handler error
62
- if (isDev()) {
63
- console.error("[createAsyncHandler] onSuccess callback error:", callbackError);
64
- }
65
- }
66
- } catch (error) {
67
- const err = error instanceof Error ? error : new Error(String(error));
68
- onError?.(err);
69
- } finally {
70
- // FIXED: Only call onLoadingEnd if it was started
71
- if (loadingStarted) {
72
- try {
73
- onLoadingEnd?.();
74
- } catch (callbackError) {
75
- // Log callback error but don't throw
76
- if (isDev()) {
77
- console.error("[createAsyncHandler] onLoadingEnd callback error:", callbackError);
78
- }
79
- }
80
- }
81
- }
82
- };
83
- };
84
-
85
- /**
86
- * Async operation with validation
87
- */
88
- export const createValidatedAsyncHandler = <T, R>(
89
- validator: (data: T) => ValidationResult,
90
- handler: (data: T) => Promise<R>,
91
- options: {
92
- onValidationError?: (error: string) => void;
93
- onError?: (error: Error) => void;
94
- } = {}
95
- ) => {
96
- return async (data: T): Promise<AsyncResult<R>> => {
97
- const { onValidationError, onError } = options;
98
-
99
- // Validate first
100
- const validationResult = validator(data);
101
- if (!validationResult.isValid) {
102
- const error = new Error(validationResult.error || "Validation failed");
103
- onValidationError?.(error.message);
104
- return { success: false, error };
105
- }
106
-
107
- // Execute handler
108
- return handleAsyncOperation(() => handler(data), onError);
109
- };
110
- };
@@ -1,69 +0,0 @@
1
- /**
2
- * Debounce and Batch Utilities
3
- * Utilities for debouncing and batching async operations
4
- */
5
-
6
- import type { AsyncResult } from "./core";
7
-
8
- /**
9
- * Debounced async operation
10
- */
11
- export const createDebouncedAsyncOperation = <T extends unknown[], R>(
12
- operation: (...args: T) => Promise<R>,
13
- delayMs: number
14
- ): ((...args: T) => Promise<R>) => {
15
- let timeoutId: NodeJS.Timeout | null = null;
16
-
17
- return (...args: T): Promise<R> => {
18
- if (timeoutId) {
19
- clearTimeout(timeoutId);
20
- }
21
-
22
- return new Promise((resolve, reject) => {
23
- timeoutId = setTimeout(async () => {
24
- try {
25
- const result = await operation(...args);
26
- resolve(result);
27
- } catch (error) {
28
- reject(error);
29
- }
30
- }, delayMs);
31
- });
32
- };
33
- };
34
-
35
- /**
36
- * Batch async operations
37
- */
38
- export const batchAsyncOperations = async <T, R>(
39
- items: T[],
40
- operation: (item: T) => Promise<R>,
41
- options: {
42
- concurrency?: number;
43
- onProgress?: (completed: number, total: number) => void;
44
- } = {}
45
- ): Promise<AsyncResult<R[]>> => {
46
- const { concurrency = 5, onProgress } = options;
47
-
48
- try {
49
- const results: R[] = [];
50
- const batches: T[][] = [];
51
-
52
- // Create batches
53
- for (let i = 0; i < items.length; i += concurrency) {
54
- batches.push(items.slice(i, i + concurrency));
55
- }
56
-
57
- // Process batches
58
- for (const batch of batches) {
59
- const batchResults = await Promise.all(batch.map(operation));
60
- results.push(...batchResults);
61
- onProgress?.(results.length, items.length);
62
- }
63
-
64
- return { success: true, data: results };
65
- } catch (error) {
66
- const err = error instanceof Error ? error : new Error(String(error));
67
- return { success: false, error: err };
68
- }
69
- };
@@ -1,8 +0,0 @@
1
- /**
2
- * Async Utilities
3
- * Barrel export for all async utility modules
4
- */
5
-
6
- export * from "./core";
7
- export * from "./retryAndTimeout";
8
- export * from "./debounceAndBatch";
@@ -1,65 +0,0 @@
1
- /**
2
- * Retry and Timeout Utilities
3
- * Utilities for handling retries and timeouts in async operations
4
- */
5
-
6
- /**
7
- * Retry utility for async operations
8
- */
9
- export const retryAsyncOperation = async <T>(
10
- operation: () => Promise<T>,
11
- options: {
12
- maxAttempts?: number;
13
- delayMs?: number;
14
- backoffMultiplier?: number;
15
- onRetry?: (attempt: number, error: Error) => void;
16
- } = {}
17
- ): Promise<T> => {
18
- const {
19
- maxAttempts = 3,
20
- delayMs = 1000,
21
- backoffMultiplier = 2,
22
- onRetry,
23
- } = options;
24
-
25
- let lastError: Error | undefined;
26
-
27
- for (let attempt = 1; attempt <= maxAttempts; attempt++) {
28
- try {
29
- return await operation();
30
- } catch (error) {
31
- lastError = error instanceof Error ? error : new Error(String(error));
32
-
33
- if (attempt < maxAttempts) {
34
- onRetry?.(attempt, lastError);
35
- const delay = delayMs * Math.pow(backoffMultiplier, attempt - 1);
36
- await new Promise((resolve) => setTimeout(resolve, delay));
37
- }
38
- }
39
- }
40
-
41
- throw lastError || new Error("Operation failed after retries");
42
- };
43
-
44
- /**
45
- * Timeout wrapper for async operations
46
- */
47
- export const withTimeout = async <T>(
48
- operation: Promise<T>,
49
- timeoutMs: number,
50
- timeoutMessage: string = "Operation timed out"
51
- ): Promise<T> => {
52
- let timeoutId: NodeJS.Timeout | undefined;
53
-
54
- const timeoutPromise = new Promise<never>((_, reject) => {
55
- timeoutId = setTimeout(() => reject(new Error(timeoutMessage)), timeoutMs);
56
- });
57
-
58
- try {
59
- return await Promise.race([operation, timeoutPromise]);
60
- } finally {
61
- if (timeoutId) {
62
- clearTimeout(timeoutId);
63
- }
64
- }
65
- };
@@ -1,61 +0,0 @@
1
- /**
2
- * Date Utilities
3
- *
4
- * Helper functions for date manipulation and calculations.
5
- */
6
-
7
- /**
8
- * Calculate days between two dates
9
- * @param dateString ISO date string
10
- * @param now Current date (defaults to new Date())
11
- * @returns Number of days between dates
12
- */
13
- export function daysBetween(dateString: string, now: Date = new Date()): number {
14
- const date = new Date(dateString);
15
- const diffMs = now.getTime() - date.getTime();
16
- return Math.floor(diffMs / (1000 * 60 * 60 * 24));
17
- }
18
-
19
- /**
20
- * Format date to ISO string
21
- * @param date Date to format
22
- * @returns ISO date string
23
- */
24
- export function toISOString(date: Date = new Date()): string {
25
- return date.toISOString();
26
- }
27
-
28
- /**
29
- * Check if a date is within the last N days
30
- * @param dateString ISO date string to check
31
- * @param days Number of days to check within
32
- * @returns true if date is within the last N days
33
- */
34
- export function isWithinLastDays(dateString: string, days: number): boolean {
35
- const daysDiff = daysBetween(dateString);
36
- return daysDiff >= 0 && daysDiff <= days;
37
- }
38
-
39
- /**
40
- * Check if a date has passed (is older than N days ago)
41
- * @param dateString ISO date string to check
42
- * @param days Number of days threshold
43
- * @returns true if date is older than N days
44
- */
45
- export function isOlderThanDays(dateString: string, days: number): boolean {
46
- const daysDiff = daysBetween(dateString);
47
- return daysDiff > days;
48
- }
49
-
50
- /**
51
- * Add days to a date
52
- * @param dateString ISO date string
53
- * @param days Number of days to add
54
- * @returns New date with days added
55
- */
56
- export function addDays(dateString: string, days: number): Date {
57
- const date = new Date(dateString);
58
- const result = new Date(date);
59
- result.setDate(result.getDate() + days);
60
- return result;
61
- }