@umituz/react-native-settings 5.3.43 → 5.3.45

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/dist/account.d.ts CHANGED
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * Usage:
8
8
  * import {
9
- * useSettingsScreenConfigWithAuth,
9
+ * useSettingsScreenConfig,
10
10
  * AccountScreen,
11
11
  * ProfileSection,
12
12
  * } from '@umituz/react-native-settings/account';
@@ -22,6 +22,5 @@ export { AccountScreen, ProfileSection } from "@umituz/react-native-auth";
22
22
  export { useAuth, useUserProfile, useAuthHandlers } from "@umituz/react-native-auth";
23
23
  export type { AccountScreenConfig } from "@umituz/react-native-auth";
24
24
  export { useSettingsScreenConfig } from './presentation/hooks/useSettingsScreenConfig';
25
- export { useSettingsScreenConfig as useSettingsScreenConfigWithAuth } from './presentation/hooks/useSettingsScreenConfig';
26
25
  export type { UseSettingsScreenConfigParams, SettingsScreenConfigResult, SettingsFeatures, } from './presentation/hooks/useSettingsScreenConfig';
27
26
  export type { AccountConfig } from './presentation/navigation/types';
@@ -2,24 +2,4 @@
2
2
  * Feedback Entity
3
3
  */
4
4
  export type FeedbackType = 'general' | 'bug_report' | 'feature_request' | 'improvement' | 'other';
5
- export type FeedbackStatus = 'pending' | 'reviewed' | 'resolved' | 'closed';
6
5
  export type FeedbackRating = 1 | 2 | 3 | 4 | 5;
7
- export interface FeedbackEntity {
8
- id: string;
9
- userId: string | null;
10
- userEmail?: string | null;
11
- type: FeedbackType;
12
- title: string;
13
- description: string;
14
- rating?: FeedbackRating;
15
- status: FeedbackStatus;
16
- deviceInfo?: {
17
- platform: string;
18
- osVersion: string;
19
- appVersion: string;
20
- };
21
- metadata?: Record<string, unknown>;
22
- createdAt: string;
23
- updatedAt: string;
24
- }
25
- export declare function createFeedback(userId: string | null, type: FeedbackType, title: string, description: string, userEmail?: string | null, rating?: FeedbackRating, deviceInfo?: FeedbackEntity['deviceInfo'], metadata?: Record<string, unknown>): Omit<FeedbackEntity, 'id'>;
@@ -4,8 +4,8 @@
4
4
  */
5
5
  export * from './presentation/components/FeedbackForm';
6
6
  export * from './presentation/components/FeedbackModal';
7
- export * from './presentation/components/SupportSection';
7
+ export { SupportSection } from './presentation/components/SupportSection';
8
+ export type { SupportSectionProps, FeedbackModalTexts } from './presentation/components/SupportSection';
8
9
  export * from './presentation/hooks/useFeedbackForm';
9
10
  export * from './domain/entities/FeedbackEntity';
10
11
  export * from './domain/entities/FeatureRequestEntity';
11
- export * from './domain/repositories/IFeedbackRepository';
@@ -1,2 +1,12 @@
1
1
  import React from "react";
2
- export declare const FeatureRequestScreen: React.FC<any>;
2
+ import type { FeedbackFormTexts } from "../components/FeedbackFormProps";
3
+ interface FeatureRequestScreenProps {
4
+ config?: {
5
+ translations?: Record<string, any>;
6
+ };
7
+ texts?: FeedbackFormTexts & {
8
+ title?: string;
9
+ };
10
+ }
11
+ export declare const FeatureRequestScreen: React.FC<FeatureRequestScreenProps>;
12
+ export {};
package/dist/index.d.ts CHANGED
@@ -31,7 +31,7 @@ export * from './domains/disclaimer';
31
31
  export * from './domains/appearance';
32
32
  export * from './domains/feedback';
33
33
  export * from './domains/faqs';
34
- export { StarRating, RatingPromptModal, useAppRating, DEFAULT_RATING_CONFIG, type RatingValue, type Rating, type RatingStats, type RatingConfig as AppStoreRatingConfig, type RatingState as AppStoreRatingState, type RatingTranslations as AppStoreRatingTranslations, type UseAppRatingResult, type StarRatingProps, type RatingPromptModalProps, } from "./domains/rating";
34
+ export * from "./domains/rating";
35
35
  export * from "./domains/video-tutorials";
36
36
  export * from "./domains/cloud-sync";
37
37
  export * from "./domains/dev";
@@ -2,13 +2,7 @@
2
2
  * Configuration Factory
3
3
  * Generic configuration creator to reduce duplication in base-configs
4
4
  */
5
- /**
6
- * Feature visibility configuration
7
- * - true: Always show (if navigation screen exists)
8
- * - false: Never show
9
- * - 'auto': Automatically detect (check if navigation screen exists and package is available)
10
- */
11
- export type FeatureVisibility = boolean | "auto";
5
+ import type { FeatureVisibility } from "../../presentation/screens/types/BaseTypes";
12
6
  /**
13
7
  * Base configuration type for all settings items
14
8
  */
@@ -4,5 +4,4 @@
4
4
  export * from "./config-creators";
5
5
  export * from "./userProfileUtils";
6
6
  export * from "./accountConfigUtils";
7
- export * from "./faqTranslator";
8
7
  export * from "./settingsConfigFactory";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-settings",
3
- "version": "5.3.43",
3
+ "version": "5.3.45",
4
4
  "description": "Complete settings hub for React Native apps - consolidated package with settings, localization, about, legal, appearance, feedback, FAQs, rating, and gamification",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./dist/index.d.ts",
package/src/account.ts CHANGED
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * Usage:
8
8
  * import {
9
- * useSettingsScreenConfigWithAuth,
9
+ * useSettingsScreenConfig,
10
10
  * AccountScreen,
11
11
  * ProfileSection,
12
12
  * } from '@umituz/react-native-settings/account';
@@ -31,9 +31,6 @@ export type { AccountScreenConfig } from "@umituz/react-native-auth";
31
31
  // Base hook (already handles auth internally via useAuth/useUserProfile/useAuthHandlers)
32
32
  export { useSettingsScreenConfig } from './presentation/hooks/useSettingsScreenConfig';
33
33
 
34
- // Alias for clarity - useSettingsScreenConfig already includes auth
35
- export { useSettingsScreenConfig as useSettingsScreenConfigWithAuth } from './presentation/hooks/useSettingsScreenConfig';
36
-
37
34
  // Re-export types
38
35
  export type {
39
36
  UseSettingsScreenConfigParams,
@@ -16,7 +16,7 @@ Provides components and utilities for collecting user feedback including feedbac
16
16
 
17
17
  **Domain:**
18
18
  - `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/feedback/domain/entities/FeedbackEntity.ts`
19
- - `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/feedback/domain/repositories/IFeedbackRepository.ts`
19
+ - `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/feedback/domain/entities/FeatureRequestEntity.ts`
20
20
 
21
21
  **Index:**
22
22
  - `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/feedback/index.ts`
@@ -26,14 +26,12 @@ Provides components and utilities for collecting user feedback including feedbac
26
26
  1. **Form State Management**: Use useFeedbackForm hook for centralized form state and validation
27
27
  2. **Type Categorization**: Categorize feedback by type (bug, feature, general, etc.) for better routing
28
28
  3. **Star Rating Integration**: Integrate with Rating domain for 1-5 star ratings
29
- 4. **Repository Pattern**: Use IFeedbackRepository interface for abstracted feedback submission
30
- 5. **Validation First**: Always validate form state before submission to prevent invalid data
29
+ 4. **Validation First**: Always validate form state before submission to prevent invalid data
31
30
 
32
31
  ## Restrictions (Forbidden)
33
32
 
34
33
  ### DO NOT
35
34
  - ❌ DO NOT submit feedback without validating required fields (type, title)
36
- - ❌ DO NOT bypass the repository pattern when submitting feedback
37
35
  - ❌ DO NOT use FeedbackForm without providing texts configuration
38
36
  - ❌ DO NOT handle feedback submission manually when the hook provides everything needed
39
37
 
@@ -9,51 +9,4 @@ export type FeedbackType =
9
9
  | 'improvement'
10
10
  | 'other';
11
11
 
12
- export type FeedbackStatus = 'pending' | 'reviewed' | 'resolved' | 'closed';
13
-
14
12
  export type FeedbackRating = 1 | 2 | 3 | 4 | 5;
15
-
16
- export interface FeedbackEntity {
17
- id: string;
18
- userId: string | null;
19
- userEmail?: string | null;
20
- type: FeedbackType;
21
- title: string;
22
- description: string;
23
- rating?: FeedbackRating;
24
- status: FeedbackStatus;
25
- deviceInfo?: {
26
- platform: string;
27
- osVersion: string;
28
- appVersion: string;
29
- };
30
- metadata?: Record<string, unknown>;
31
- createdAt: string;
32
- updatedAt: string;
33
- }
34
-
35
- export function createFeedback(
36
- userId: string | null,
37
- type: FeedbackType,
38
- title: string,
39
- description: string,
40
- userEmail?: string | null,
41
- rating?: FeedbackRating,
42
- deviceInfo?: FeedbackEntity['deviceInfo'],
43
- metadata?: Record<string, unknown>
44
- ): Omit<FeedbackEntity, 'id'> {
45
- const now = new Date().toISOString();
46
- return {
47
- userId,
48
- userEmail,
49
- type,
50
- title,
51
- description,
52
- rating,
53
- status: 'pending',
54
- deviceInfo,
55
- metadata,
56
- createdAt: now,
57
- updatedAt: now,
58
- };
59
- }
@@ -5,8 +5,8 @@
5
5
 
6
6
  export * from './presentation/components/FeedbackForm';
7
7
  export * from './presentation/components/FeedbackModal';
8
- export * from './presentation/components/SupportSection';
8
+ export { SupportSection } from './presentation/components/SupportSection';
9
+ export type { SupportSectionProps, FeedbackModalTexts } from './presentation/components/SupportSection';
9
10
  export * from './presentation/hooks/useFeedbackForm';
10
11
  export * from './domain/entities/FeedbackEntity';
11
12
  export * from './domain/entities/FeatureRequestEntity';
12
- export * from './domain/repositories/IFeedbackRepository';
@@ -65,23 +65,12 @@ export const SupportSection: React.FC<SupportSectionProps> = ({
65
65
  if (feedbackConfig.config?.onSubmit) {
66
66
  setIsSubmitting(true);
67
67
  try {
68
- // Add a small delay for better UX if needed, or remove it if instant response is preferred
69
- // await new Promise(resolve => setTimeout(resolve, 300));
70
68
  await feedbackConfig.config.onSubmit(data);
71
-
72
- // Only close on success - or let the parent handle it?
73
- // Since onSubmit in config returns Promise<void> and usually handles errors via callbacks (onError),
74
- // we can assume if it resolves, we should close.
75
- // If the App's onSubmit logic catches errors and resolves, we still close.
76
69
  setModalVisible(false);
77
70
  } catch (error) {
78
- // If the passed onSubmit throws, we log it.
79
71
  if (isDev()) {
80
72
  console.error('[SupportSection] Failed to submit feedback:', error);
81
73
  }
82
- // Optionally keep modal open? Or close it?
83
- // If we keep it open, user can retry.
84
- // But usually we close it.
85
74
  setModalVisible(false);
86
75
  } finally {
87
76
  setIsSubmitting(false);
@@ -100,16 +89,12 @@ export const SupportSection: React.FC<SupportSectionProps> = ({
100
89
 
101
90
  if (config?.storeUrl) {
102
91
  try {
103
- // Safely handle URL for App Store - itunes.apple.com is more reliable for deep links
104
92
  let url = config.storeUrl;
105
93
  if (url.includes('apps.apple.com')) {
106
94
  url = url.replace('apps.apple.com', 'itunes.apple.com');
107
95
  }
108
-
109
- // Try opening the modified URL
110
96
  await Linking.openURL(url);
111
- } catch (error) {
112
- // Final fallback to original URL
97
+ } catch {
113
98
  if (config.storeUrl) {
114
99
  Linking.openURL(config.storeUrl).catch(() => {});
115
100
  }
@@ -14,9 +14,18 @@ import { useAppDesignTokens } from "@umituz/react-native-design-system/theme";
14
14
  import { ScreenLayout } from "@umituz/react-native-design-system/layouts";
15
15
  import { FeedbackModal } from "../components/FeedbackModal";
16
16
  import { useFeatureRequests } from "../../infrastructure/useFeatureRequests";
17
+ import type { FeedbackRating } from "../../domain/entities/FeedbackEntity";
17
18
  import type { FeatureRequestItem, VoteType } from "../../domain/entities/FeatureRequestEntity";
19
+ import type { FeedbackFormTexts } from "../components/FeedbackFormProps";
18
20
 
19
- export const FeatureRequestScreen: React.FC<any> = ({ config, texts }) => {
21
+ interface FeatureRequestScreenProps {
22
+ config?: {
23
+ translations?: Record<string, any>;
24
+ };
25
+ texts?: FeedbackFormTexts & { title?: string };
26
+ }
27
+
28
+ export const FeatureRequestScreen: React.FC<FeatureRequestScreenProps> = ({ config, texts }) => {
20
29
  const tokens = useAppDesignTokens();
21
30
  const { requests, userVotes, isLoading, vote, submitRequest, userId } = useFeatureRequests();
22
31
 
@@ -45,7 +54,7 @@ export const FeatureRequestScreen: React.FC<any> = ({ config, texts }) => {
45
54
  dismissed: t.status?.dismissed || "Dismissed",
46
55
  };
47
56
 
48
- const handleSubmit = useCallback(async (data: any) => {
57
+ const handleSubmit = useCallback(async (data: { title?: string; description: string; type?: string; rating?: FeedbackRating }) => {
49
58
  setIsSubmitting(true);
50
59
  try {
51
60
  await submitRequest({
@@ -91,13 +100,13 @@ export const FeatureRequestScreen: React.FC<any> = ({ config, texts }) => {
91
100
  <View key={item.id} style={[styles.card, { backgroundColor: tokens.colors.surfaceSecondary, borderColor: tokens.colors.borderLight }]}>
92
101
  <View style={styles.voteColumn}>
93
102
  <TouchableOpacity onPress={() => vote(item.id, 'up')}>
94
- <AtomicIcon name="chevron-up" size="md" color={voted === 'up' ? "primary" : "textSecondary" as any} />
103
+ <AtomicIcon name="chevron-up" size="md" color={voted === 'up' ? "primary" : "textSecondary"} />
95
104
  </TouchableOpacity>
96
105
  <AtomicText style={[styles.voteCount, { color: voted === 'up' ? tokens.colors.primary : tokens.colors.textPrimary }]}>
97
106
  {item.votes}
98
107
  </AtomicText>
99
108
  <TouchableOpacity onPress={() => vote(item.id, 'down')}>
100
- <AtomicIcon name="chevron-down" size="md" color={voted === 'down' ? "primary" : "textSecondary" as any} />
109
+ <AtomicIcon name="chevron-down" size="md" color={voted === 'down' ? "primary" : "textSecondary"} />
101
110
  </TouchableOpacity>
102
111
  </View>
103
112
 
package/src/index.ts CHANGED
@@ -106,21 +106,7 @@ export * from './domains/feedback';
106
106
  export * from './domains/faqs';
107
107
 
108
108
  // Rating Domain - Star ratings, reviews, statistics, app store rating
109
- export {
110
- StarRating,
111
- RatingPromptModal,
112
- useAppRating,
113
- DEFAULT_RATING_CONFIG,
114
- type RatingValue,
115
- type Rating,
116
- type RatingStats,
117
- type RatingConfig as AppStoreRatingConfig,
118
- type RatingState as AppStoreRatingState,
119
- type RatingTranslations as AppStoreRatingTranslations,
120
- type UseAppRatingResult,
121
- type StarRatingProps,
122
- type RatingPromptModalProps,
123
- } from "./domains/rating";
109
+ export * from "./domains/rating";
124
110
 
125
111
  // Video Tutorials Domain - Learning resources, tutorials
126
112
  export * from "./domains/video-tutorials";
@@ -3,15 +3,7 @@
3
3
  * Generic configuration creator to reduce duplication in base-configs
4
4
  */
5
5
 
6
-
7
-
8
- /**
9
- * Feature visibility configuration
10
- * - true: Always show (if navigation screen exists)
11
- * - false: Never show
12
- * - 'auto': Automatically detect (check if navigation screen exists and package is available)
13
- */
14
- export type FeatureVisibility = boolean | "auto";
6
+ import type { FeatureVisibility } from "../../presentation/screens/types/BaseTypes";
15
7
 
16
8
  /**
17
9
  * Base configuration type for all settings items
@@ -10,7 +10,6 @@ import { useMemo } from "react";
10
10
  import { useAuth, useUserProfile, useAuthHandlers } from "@umituz/react-native-auth";
11
11
  import { createUserProfileDisplay } from "../utils/userProfileUtils";
12
12
  import { createAccountConfig } from "../utils/accountConfigUtils";
13
- import { translateFAQData } from "../utils/faqTranslator";
14
13
  import { useSettingsConfigFactory } from "../utils/settingsConfigFactory";
15
14
  import type { SettingsConfig, SettingsTranslations } from "../screens/types";
16
15
  import type { FeedbackFormData } from "../utils/config-creators";
@@ -151,16 +150,11 @@ export const useSettingsScreenConfig = (
151
150
  translations: translations?.account as any,
152
151
  }), [user, userProfileData, handleSignIn, handleSignOut, handleDeleteAccount, translations]);
153
152
 
154
- const translatedFaqData = useMemo(() =>
155
- translateFAQData(faqData, appInfo),
156
- [faqData, appInfo]
157
- );
158
-
159
153
  return {
160
154
  settingsConfig,
161
155
  userProfile,
162
156
  accountConfig,
163
- translatedFaqData,
157
+ translatedFaqData: faqData,
164
158
  isLoading: loading,
165
159
  isAuthReady,
166
160
  };
@@ -4,7 +4,12 @@ import { LanguageSelectionScreen } from "../../../domains/localization";
4
4
  import { NotificationSettingsScreen } from "../../../domains/notifications";
5
5
  // AccountScreen is an optional peer — lazy require so the package works without @umituz/react-native-auth
6
6
  const AccountScreen: React.ComponentType<any> | null = (() => {
7
- try { return require("@umituz/react-native-auth").AccountScreen ?? null; } catch { return null; }
7
+ try {
8
+ return require("@umituz/react-native-auth").AccountScreen ?? null;
9
+ } catch (error) {
10
+ if (__DEV__) console.warn("[useSettingsScreens] @umituz/react-native-auth not available:", error);
11
+ return null;
12
+ }
8
13
  })();
9
14
  import { SettingsScreen } from "../../screens/SettingsScreen";
10
15
  import { AppearanceScreen } from "../../screens/AppearanceScreen";
@@ -5,5 +5,4 @@
5
5
  export * from "./config-creators";
6
6
  export * from "./userProfileUtils";
7
7
  export * from "./accountConfigUtils";
8
- export * from "./faqTranslator";
9
8
  export * from "./settingsConfigFactory";
@@ -63,8 +63,8 @@ export const createSettingsConfig = (
63
63
  faqs: features.faqs ? createFAQConfig() : false,
64
64
  rating: features.rating ? createRatingConfig(handleRatePress, appStoreUrl) : false,
65
65
  subscription: features.subscription ? createSubscriptionConfig(isPremium, "SubscriptionDetail" as keyof SettingsStackParamList) : false,
66
- gamification: features.gamification ? true : false,
67
- videoTutorial: features.videoTutorial ? true : false,
66
+ gamification: !!features.gamification,
67
+ videoTutorial: !!features.videoTutorial,
68
68
  disclaimer: false,
69
69
  };
70
70
  };
@@ -1,28 +0,0 @@
1
- /**
2
- * Feedback Repository Interface
3
- */
4
-
5
- import type { FeedbackEntity } from '../entities/FeedbackEntity';
6
-
7
- export interface FeedbackError {
8
- message: string;
9
- code?: 'SUBMIT_FAILED' | 'FETCH_FAILED' | 'DELETE_FAILED' | 'VALIDATION_ERROR';
10
- }
11
-
12
- export type FeedbackResult<T> =
13
- | {
14
- success: true;
15
- data: T;
16
- }
17
- | {
18
- success: false;
19
- error: FeedbackError;
20
- };
21
-
22
- export interface IFeedbackRepository {
23
- submitFeedback(
24
- feedback: FeedbackEntity | Omit<FeedbackEntity, 'id'>
25
- ): Promise<FeedbackResult<FeedbackEntity>>;
26
- getUserFeedback(userId: string): Promise<FeedbackResult<FeedbackEntity[]>>;
27
- deleteFeedback(feedbackId: string): Promise<FeedbackResult<boolean>>;
28
- }
@@ -1,9 +0,0 @@
1
- import type { FAQData } from "../navigation/types";
2
- import type { AppInfo } from "../navigation/types";
3
-
4
- export const translateFAQData = (
5
- faqData: FAQData | undefined,
6
- _appInfo: AppInfo
7
- ): FAQData | undefined => {
8
- return faqData;
9
- };