@umituz/react-native-settings 4.23.97 → 4.23.99

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 (44) hide show
  1. package/package.json +1 -1
  2. package/src/domains/about/domain/entities/AppInfo.ts +1 -0
  3. package/src/domains/about/presentation/components/AboutContent.tsx +6 -6
  4. package/src/domains/about/presentation/screens/AboutScreen.tsx +2 -4
  5. package/src/domains/appearance/presentation/screens/AppearanceScreen.tsx +9 -12
  6. package/src/domains/disclaimer/presentation/components/DisclaimerSetting.tsx +9 -20
  7. package/src/domains/disclaimer/presentation/screens/DisclaimerScreen.tsx +2 -6
  8. package/src/domains/gamification/types/index.ts +12 -12
  9. package/src/domains/localization/presentation/components/LanguageSection.tsx +3 -3
  10. package/src/domains/localization/presentation/screens/LanguageSelectionScreen.tsx +1 -1
  11. package/src/domains/notifications/presentation/components/NotificationsSection.tsx +2 -4
  12. package/src/domains/notifications/presentation/screens/NotificationSettingsScreen.tsx +1 -3
  13. package/src/infrastructure/utils/configFactory.ts +3 -14
  14. package/src/presentation/hooks/useSettingsScreenConfig.ts +27 -12
  15. package/src/presentation/navigation/SettingsStackNavigator.tsx +9 -8
  16. package/src/presentation/navigation/hooks/useNavigationHandlers.ts +4 -2
  17. package/src/presentation/navigation/hooks/useSettingsScreens.ts +10 -10
  18. package/src/presentation/navigation/utils/navigationTranslations.ts +29 -32
  19. package/src/presentation/screens/SettingsScreen.tsx +5 -1
  20. package/src/presentation/screens/components/GamificationSettingsItem.tsx +3 -6
  21. package/src/presentation/screens/components/SettingsContent.tsx +9 -5
  22. package/src/presentation/screens/components/SettingsHeader.tsx +4 -3
  23. package/src/presentation/screens/components/SubscriptionSettingsItem.tsx +3 -4
  24. package/src/presentation/screens/components/VideoTutorialSettingsItem.tsx +2 -4
  25. package/src/presentation/screens/components/WalletSettingsItem.tsx +3 -4
  26. package/src/presentation/screens/components/sections/FeatureSettingsSection.tsx +11 -13
  27. package/src/presentation/screens/components/sections/IdentitySettingsSection.tsx +5 -6
  28. package/src/presentation/screens/components/sections/ProfileSectionLoader.tsx +11 -9
  29. package/src/presentation/screens/components/sections/SupportSettingsSection.tsx +22 -23
  30. package/src/presentation/screens/types/SettingsConfig.ts +97 -6
  31. package/src/presentation/utils/accountConfigUtils.ts +9 -17
  32. package/src/presentation/utils/config-creators/base-configs.ts +0 -22
  33. package/src/presentation/utils/config-creators/feature-configs.ts +0 -20
  34. package/src/presentation/utils/config-creators/support-configs.ts +2 -12
  35. package/src/presentation/utils/faqTranslator.ts +5 -18
  36. package/src/presentation/utils/settingsConfigFactory.ts +10 -13
  37. package/src/presentation/utils/useAuthHandlers.ts +13 -20
  38. package/src/presentation/utils/userProfileUtils.ts +2 -16
  39. package/src/domains/disclaimer/README.md +0 -87
  40. package/src/domains/disclaimer/presentation/components/DisclaimerCard.test.tsx +0 -208
  41. package/src/domains/disclaimer/presentation/components/DisclaimerModal.test.tsx +0 -236
  42. package/src/domains/disclaimer/presentation/components/DisclaimerSetting.test.tsx +0 -74
  43. package/src/domains/disclaimer/presentation/components/README.md +0 -97
  44. package/src/domains/localization/presentation/components/__tests__/LanguageItem.test.tsx +0 -106
@@ -15,7 +15,6 @@ export interface CreateAccountConfigParams {
15
15
  onSignIn: () => void;
16
16
  onLogout: () => Promise<void>;
17
17
  onDeleteAccount: () => Promise<void>;
18
- t: (key: string) => string;
19
18
  }
20
19
 
21
20
  /**
@@ -31,37 +30,30 @@ export function createAccountConfig(params: CreateAccountConfigParams): AccountS
31
30
  onSignIn,
32
31
  onLogout,
33
32
  onDeleteAccount,
34
- t,
35
33
  } = params;
36
34
 
37
35
  const anonymous = isAnonymous ?? true;
38
36
 
39
37
  return {
40
38
  profile: {
41
- displayName: displayName || t("settings.profile.anonymousName"),
39
+ displayName: displayName || "",
42
40
  userId: userId ?? undefined,
43
41
  isAnonymous: anonymous,
44
42
  avatarUrl: avatarUrl ?? photoURL ?? undefined,
45
- benefits: anonymous ? [
46
- t("settings.profile.benefits.saveHistory"),
47
- t("settings.profile.benefits.syncDevices"),
48
- t("settings.profile.benefits.cloudSync"),
49
- t("settings.profile.benefits.secureBackup"),
50
- ] : undefined,
51
43
  },
52
44
  isAnonymous: anonymous,
53
- editProfileText: t("settings.account.editProfile"),
45
+ editProfileText: "",
54
46
  onSignIn,
55
47
  accountActions: {
56
48
  onLogout,
57
49
  onDeleteAccount,
58
- logoutText: t("settings.account.logout"),
59
- logoutConfirmTitle: t("settings.account.logoutConfirmTitle"),
60
- logoutConfirmMessage: t("settings.account.logoutConfirmMessage"),
61
- cancelText: t("common.cancel"),
62
- deleteAccountText: t("settings.account.deleteAccount"),
63
- deleteConfirmTitle: t("settings.account.deleteConfirmTitle"),
64
- deleteConfirmMessage: t("settings.account.deleteConfirmMessage"),
50
+ logoutText: "",
51
+ logoutConfirmTitle: "",
52
+ logoutConfirmMessage: "",
53
+ cancelText: "",
54
+ deleteAccountText: "",
55
+ deleteConfirmTitle: "",
56
+ deleteConfirmMessage: "",
65
57
  },
66
58
  };
67
59
  }
@@ -11,20 +11,15 @@ import type {
11
11
  AboutConfig,
12
12
  LegalConfig,
13
13
  } from "../../screens/types";
14
- import type { TranslationFunction } from "./types";
15
14
  import { createBaseConfig, createConfigWithExtensions } from "../../../infrastructure/utils/configFactory";
16
15
 
17
16
  /**
18
17
  * Create appearance configuration
19
18
  */
20
19
  export const createAppearanceConfig = (
21
- t: TranslationFunction,
22
20
  routeOrOnPress?: string | (() => void),
23
21
  ): AppearanceConfig => {
24
22
  return createBaseConfig<AppearanceConfig>({
25
- t,
26
- titleKey: "settings.appearance.title",
27
- descriptionKey: "settings.appearance.description",
28
23
  icon: "color-palette-outline",
29
24
  routeOrOnPress,
30
25
  });
@@ -34,13 +29,9 @@ export const createAppearanceConfig = (
34
29
  * Create language configuration
35
30
  */
36
31
  export const createLanguageConfig = (
37
- t: TranslationFunction,
38
32
  routeOrOnPress?: string | (() => void),
39
33
  ): LanguageConfig => {
40
34
  return createBaseConfig<LanguageConfig>({
41
- t,
42
- titleKey: "settings.language.title",
43
- descriptionKey: "settings.language.description",
44
35
  icon: "globe-outline",
45
36
  routeOrOnPress,
46
37
  });
@@ -50,21 +41,16 @@ export const createLanguageConfig = (
50
41
  * Create notifications configuration
51
42
  */
52
43
  export const createNotificationsConfig = (
53
- t: TranslationFunction,
54
44
  routeOrOnPress?: string | (() => void),
55
45
  ): NotificationsConfig => {
56
46
  return createConfigWithExtensions<NotificationsConfig>(
57
47
  {
58
- t,
59
- titleKey: "settings.notifications.title",
60
- descriptionKey: "settings.notifications.description",
61
48
  icon: "notifications-outline",
62
49
  routeOrOnPress,
63
50
  defaultRoute: "Notifications",
64
51
  },
65
52
  {
66
53
  showToggle: false,
67
- sectionTitle: t("settings.notifications.sectionTitle"),
68
54
  }
69
55
  );
70
56
  };
@@ -73,13 +59,9 @@ export const createNotificationsConfig = (
73
59
  * Create about configuration
74
60
  */
75
61
  export const createAboutConfig = (
76
- t: TranslationFunction,
77
62
  routeOrOnPress?: string | (() => void),
78
63
  ): AboutConfig => {
79
64
  return createBaseConfig<AboutConfig>({
80
- t,
81
- titleKey: "settings.about.title",
82
- descriptionKey: "settings.about.description",
83
65
  icon: "information-circle-outline",
84
66
  routeOrOnPress,
85
67
  });
@@ -89,13 +71,9 @@ export const createAboutConfig = (
89
71
  * Create legal configuration
90
72
  */
91
73
  export const createLegalConfig = (
92
- t: TranslationFunction,
93
74
  routeOrOnPress?: string | (() => void),
94
75
  ): LegalConfig => {
95
76
  return createBaseConfig<LegalConfig>({
96
- t,
97
- titleKey: "settings.legal.title",
98
- descriptionKey: "settings.legal.description",
99
77
  icon: "document-text-outline",
100
78
  routeOrOnPress,
101
79
  });
@@ -17,17 +17,11 @@ import type { TranslationFunction } from "./types";
17
17
  * @param onPress - Callback function (use route instead when possible)
18
18
  */
19
19
  export const createSubscriptionConfig = (
20
- t: TranslationFunction,
21
20
  isPremium: boolean,
22
21
  routeOrOnPress: string | (() => void),
23
22
  ): SubscriptionConfig => ({
24
23
  enabled: true,
25
- title: t("settings.subscription.title"),
26
- description: isPremium
27
- ? t("subscription.premiumDetails.statusActive")
28
- : t("settings.subscription.description"),
29
24
  icon: "diamond",
30
- sectionTitle: t("settings.sections.subscription").toUpperCase(),
31
25
  route: typeof routeOrOnPress === "string" ? routeOrOnPress : undefined,
32
26
  onPress: typeof routeOrOnPress === "function" ? routeOrOnPress : undefined,
33
27
  isPremium,
@@ -37,7 +31,6 @@ export const createSubscriptionConfig = (
37
31
  * Create gamification configuration
38
32
  */
39
33
  export const createGamificationConfig = (
40
- t: TranslationFunction,
41
34
  storageKey: string,
42
35
  achievements: AchievementDefinition[],
43
36
  levels: LevelDefinition[],
@@ -47,17 +40,4 @@ export const createGamificationConfig = (
47
40
  storageKey,
48
41
  achievements,
49
42
  levels,
50
- translations: {
51
- title: t("settings.gamification.title"),
52
- statsTitle: t("settings.gamification.stats.title"),
53
- pointsLabel: t("settings.gamification.stats.points"),
54
- totalCompletedLabel: t("settings.gamification.stats.totalCompleted"),
55
- achievementsTitle: t("settings.gamification.achievements.title"),
56
- streakTitle: t("settings.gamification.streak.title"),
57
- bestStreak: t("settings.gamification.streak.best"),
58
- currentStreak: t("settings.gamification.streak.current"),
59
- days: t("settings.gamification.streak.days"),
60
- levelTitle: t("settings.gamification.level.title"),
61
- emptyAchievements: t("settings.gamification.achievements.empty"),
62
- },
63
43
  });
@@ -8,20 +8,16 @@ import type {
8
8
  RatingConfig,
9
9
  FAQConfig,
10
10
  } from "../../screens/types";
11
- import type { TranslationFunction, FeedbackFormData } from "./types";
11
+ import type { FeedbackFormData } from "./types";
12
12
 
13
13
  /**
14
14
  * Create feedback configuration
15
15
  */
16
16
  export const createFeedbackConfig = (
17
- t: TranslationFunction,
18
17
  onSubmit: (data: FeedbackFormData) => Promise<void>,
19
18
  ): FeedbackConfig => ({
20
19
  enabled: true,
21
- title: t("settings.feedback.title"),
22
- description: t("settings.feedback.description"),
23
20
  icon: "chatbubble-outline",
24
- sectionTitle: t("settings.sections.support"),
25
21
  onSubmit,
26
22
  });
27
23
 
@@ -29,7 +25,6 @@ export const createFeedbackConfig = (
29
25
  * Create rating configuration
30
26
  */
31
27
  export const createRatingConfig = (
32
- t: TranslationFunction,
33
28
  onRate: () => void,
34
29
  storeUrl?: string,
35
30
  ): RatingConfig => ({
@@ -42,12 +37,7 @@ export const createRatingConfig = (
42
37
  * Create FAQ configuration
43
38
  * Navigation is handled internally by the package - no callback needed
44
39
  */
45
- export const createFAQConfig = (
46
- t: TranslationFunction,
47
- ): FAQConfig => ({
40
+ export const createFAQConfig = (): FAQConfig => ({
48
41
  enabled: true,
49
- title: t("settings.faqs.title"),
50
- description: t("settings.faqs.description"),
51
42
  icon: "help-circle-outline",
52
- sectionTitle: t("settings.sections.support").toUpperCase(),
53
43
  });
@@ -3,31 +3,18 @@
3
3
  * Handles translation of FAQ data
4
4
  */
5
5
 
6
- import type { TranslationFunction } from "./config-creators/types";
6
+
7
7
  import type { FAQData } from "../navigation/types";
8
8
  import type { AppInfo } from "../navigation/types";
9
9
 
10
10
  /**
11
- * Translates FAQ data using the provided translation function
11
+ * Utility for handling FAQ data
12
+ * Ensures data is in consistent format
12
13
  */
13
14
  export const translateFAQData = (
14
15
  faqData: FAQData | undefined,
15
- t: TranslationFunction,
16
+ _t: (key: string, params?: any) => string,
16
17
  _appInfo: AppInfo
17
18
  ): FAQData | undefined => {
18
- if (!faqData) return undefined;
19
-
20
- const interpolationValues = { appName: _appInfo.appName || _appInfo.name };
21
-
22
- return {
23
- categories: faqData.categories.map((category) => ({
24
- id: category.id,
25
- title: t(category.title, interpolationValues),
26
- items: category.items.map((item) => ({
27
- id: item.id,
28
- question: t(item.question, interpolationValues),
29
- answer: t(item.answer, interpolationValues),
30
- })),
31
- })),
32
- };
19
+ return faqData;
33
20
  };
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { useMemo } from "react";
7
- import type { TranslationFunction, FeedbackFormData } from "./config-creators/types";
7
+ import type { FeedbackFormData } from "./config-creators/types";
8
8
  import type { SettingsConfig } from "../screens/types";
9
9
  import {
10
10
  createAppearanceConfig,
@@ -19,7 +19,6 @@ import {
19
19
  } from "./config-creators";
20
20
 
21
21
  export interface SettingsConfigFactoryParams {
22
- t: TranslationFunction;
23
22
  onFeedbackSubmit: (data: FeedbackFormData) => Promise<void>;
24
23
  handleRatePress: () => void;
25
24
  appStoreUrl: string;
@@ -43,7 +42,6 @@ export const createSettingsConfig = (
43
42
  params: SettingsConfigFactoryParams
44
43
  ): SettingsConfig => {
45
44
  const {
46
- t,
47
45
  onFeedbackSubmit,
48
46
  handleRatePress,
49
47
  appStoreUrl,
@@ -52,15 +50,15 @@ export const createSettingsConfig = (
52
50
  } = params;
53
51
 
54
52
  return {
55
- appearance: features.appearance ? createAppearanceConfig(t) : false,
56
- language: features.language ? createLanguageConfig(t) : false,
57
- notifications: features.notifications ? createNotificationsConfig(t) : false,
58
- feedback: features.feedback ? createFeedbackConfig(t, onFeedbackSubmit) : false,
59
- about: features.about ? createAboutConfig(t) : false,
60
- legal: features.legal ? createLegalConfig(t) : false,
61
- faqs: features.faqs ? createFAQConfig(t) : false,
62
- rating: features.rating ? createRatingConfig(t, handleRatePress, appStoreUrl) : false,
63
- subscription: createSubscriptionConfig(t, isPremium, "SubscriptionDetail"),
53
+ appearance: features.appearance ? createAppearanceConfig() : false,
54
+ language: features.language ? createLanguageConfig() : false,
55
+ notifications: features.notifications ? createNotificationsConfig() : false,
56
+ feedback: features.feedback ? createFeedbackConfig(onFeedbackSubmit) : false,
57
+ about: features.about ? createAboutConfig() : false,
58
+ legal: features.legal ? createLegalConfig() : false,
59
+ faqs: features.faqs ? createFAQConfig() : false,
60
+ rating: features.rating ? createRatingConfig(handleRatePress, appStoreUrl) : false,
61
+ subscription: createSubscriptionConfig(isPremium, "SubscriptionDetail"),
64
62
  disclaimer: false,
65
63
  };
66
64
  };
@@ -72,7 +70,6 @@ export const useSettingsConfigFactory = (
72
70
  params: SettingsConfigFactoryParams
73
71
  ): SettingsConfig => {
74
72
  return useMemo(() => createSettingsConfig(params), [
75
- params.t,
76
73
  params.onFeedbackSubmit,
77
74
  params.handleRatePress,
78
75
  params.appStoreUrl,
@@ -12,16 +12,15 @@ import {
12
12
  useAuthModalStore,
13
13
  } from "@umituz/react-native-auth";
14
14
  import { AlertService } from "@umituz/react-native-design-system";
15
- import { useLocalization } from "../../domains/localization";
16
15
  import type { AppInfo } from "../navigation/types";
16
+ import type { SettingsTranslations } from "../screens/types/SettingsConfig";
17
17
 
18
18
  declare const __DEV__: boolean;
19
19
 
20
20
  /**
21
21
  * Hook that provides authentication-related handlers
22
22
  */
23
- export const useAuthHandlers = (appInfo: AppInfo) => {
24
- const { t } = useLocalization();
23
+ export const useAuthHandlers = (appInfo: AppInfo, translations?: SettingsTranslations["errors"]) => {
25
24
  const { signOut } = useAuth();
26
25
  const { deleteAccount } = useAccountManagement();
27
26
  const { showAuthModal } = useAuthModalStore();
@@ -29,63 +28,57 @@ export const useAuthHandlers = (appInfo: AppInfo) => {
29
28
  const handleRatePress = useCallback(async () => {
30
29
  const url = appInfo.appStoreUrl;
31
30
  if (!url) {
32
- // FIXED: Provide feedback when URL is missing
33
- Alert.alert(t("common.error"), "App store URL not configured");
31
+ Alert.alert(translations?.common || "", translations?.appStoreUrlNotConfigured || "");
34
32
  return;
35
33
  }
36
34
 
37
35
  try {
38
36
  const canOpen = await Linking.canOpenURL(url);
39
37
  if (!canOpen) {
40
- // FIXED: Provide feedback when URL cannot be opened
41
38
  Alert.alert(
42
- t("common.error"),
43
- "Unable to open app store. Please check your device settings."
39
+ translations?.common || "",
40
+ translations?.unableToOpenAppStore || ""
44
41
  );
45
42
  return;
46
43
  }
47
44
  await Linking.openURL(url);
48
45
  } catch (error) {
49
- // FIXED: Log actual error for debugging
50
46
  if (typeof __DEV__ !== "undefined" && __DEV__) {
51
47
  console.error("[useAuthHandlers] Failed to open app store:", error);
52
48
  }
53
- Alert.alert(t("common.error"), "Failed to open app store");
49
+ Alert.alert(translations?.common || "", translations?.failedToOpenAppStore || "");
54
50
  }
55
- }, [appInfo.appStoreUrl, t]);
51
+ }, [appInfo.appStoreUrl, translations]);
56
52
 
57
53
  const handleSignOut = useCallback(async () => {
58
54
  try {
59
55
  await signOut();
60
56
  } catch (error) {
61
- // FIXED: Log actual error for debugging
62
57
  if (typeof __DEV__ !== "undefined" && __DEV__) {
63
58
  console.error("[useAuthHandlers] Sign out failed:", error);
64
59
  }
65
60
  AlertService.createErrorAlert(
66
- t("common.error"),
67
- t("auth.errors.unknownError")
61
+ translations?.common || "",
62
+ translations?.unknown || ""
68
63
  );
69
64
  }
70
- }, [signOut, t]);
65
+ }, [signOut, translations]);
71
66
 
72
67
  const handleDeleteAccount = useCallback(async () => {
73
68
  try {
74
69
  await deleteAccount();
75
70
  } catch (error) {
76
- // FIXED: Log actual error for debugging
77
71
  if (typeof __DEV__ !== "undefined" && __DEV__) {
78
72
  console.error("[useAuthHandlers] Delete account failed:", error);
79
73
  }
80
74
  AlertService.createErrorAlert(
81
- t("common.error"),
82
- t("settings.account.deleteError")
75
+ translations?.common || "",
76
+ translations?.deleteAccountError || ""
83
77
  );
84
78
  }
85
- }, [deleteAccount, t]);
79
+ }, [deleteAccount, translations]);
86
80
 
87
81
  const handleSignIn = useCallback(() => {
88
- // FIXED: Remove empty callback - pass undefined instead
89
82
  showAuthModal(undefined, "login");
90
83
  }, [showAuthModal]);
91
84
 
@@ -15,7 +15,6 @@ export interface UserProfileConfig {
15
15
 
16
16
  export interface CreateUserProfileParams {
17
17
  profileData?: UserProfileConfig;
18
- t: (key: string, params?: Record<string, string | number>) => string;
19
18
  onSignIn?: () => void;
20
19
  }
21
20
 
@@ -23,13 +22,12 @@ export interface CreateUserProfileParams {
23
22
  * Create user profile display configuration
24
23
  */
25
24
  export function createUserProfileDisplay(params: CreateUserProfileParams): UserProfileDisplay {
26
- const { profileData, t, onSignIn } = params;
25
+ const { profileData, onSignIn } = params;
27
26
 
28
27
  const isAnonymous = profileData?.isAnonymous ?? true;
29
- const anonymousName = t("settings.profile.anonymousName");
30
28
 
31
29
  return {
32
- displayName: profileData?.displayName || anonymousName,
30
+ displayName: profileData?.displayName,
33
31
  userId: profileData?.userId ?? undefined,
34
32
  isAnonymous,
35
33
  avatarUrl: profileData?.avatarUrl ?? undefined,
@@ -37,15 +35,3 @@ export function createUserProfileDisplay(params: CreateUserProfileParams): UserP
37
35
  accountSettingsRoute: isAnonymous ? undefined : "Account",
38
36
  };
39
37
  }
40
-
41
- /**
42
- * Create benefits list for anonymous users
43
- */
44
- export function createAnonymousBenefits(t: (key: string) => string): string[] {
45
- return [
46
- t("settings.profile.benefits.saveHistory"),
47
- t("settings.profile.benefits.syncDevices"),
48
- t("settings.profile.benefits.cloudSync"),
49
- t("settings.profile.benefits.secureBackup"),
50
- ];
51
- }
@@ -1,87 +0,0 @@
1
- # Disclaimer Domain
2
-
3
- ## Purpose
4
-
5
- Provides components for displaying legal notices, warnings, and important information through cards, modals, and dedicated screens with full i18n support.
6
-
7
- ## File Paths
8
-
9
- **Screens:**
10
- - `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/disclaimer/presentation/screens/DisclaimerScreen.tsx`
11
-
12
- **Components:**
13
- - `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/disclaimer/presentation/components/DisclaimerSetting.tsx`
14
- - `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/disclaimer/presentation/components/DisclaimerCard.tsx`
15
- - `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/disclaimer/presentation/components/DisclaimerModal.tsx`
16
-
17
- **Index:**
18
- - `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/disclaimer/index.ts`
19
-
20
- ## Strategy
21
-
22
- 1. **Internationalization First**: Use translation keys for all text content with support for i18n
23
- 2. **Modular Design**: Compose disclaimers from card and modal components for flexibility
24
- 3. **Color Coding**: Use appropriate colors for different warning levels (red for critical, amber for caution, blue for info)
25
- 4. **Card + Modal Pattern**: Display summary in card, full content in modal for better UX
26
- 5. **Icon Integration**: Use design system icons with customizable colors for visual hierarchy
27
-
28
- ## Restrictions (Forbidden)
29
-
30
- ### DO NOT
31
- - ❌ DO NOT use DisclaimerSetting without proper translation keys in i18n configuration
32
- - ❌ DO NOT hardcode disclaimer text - always use translation keys or modalContent prop
33
- - ❌ DO NOT use DisclaimerCard without providing all required props (title, shortMessage, iconName, iconColor, backgroundColor, onPress)
34
- - ❌ DO NOT bypass the card + modal pattern for displaying disclaimers
35
-
36
- ### NEVER
37
- - ❌ NEVER use DisclaimerSetting in production without verifying i18n keys exist
38
- - ❌ NEVER show modal without a proper close mechanism
39
- - ❌ NEVER use inappropriate colors for warning levels (e.g., green for critical warnings)
40
- - ❌ NEVER mix disclaimer content with business logic
41
-
42
- ### AVOID
43
- - ❌ AVOID creating custom disclaimer components when existing ones can be configured
44
- - ❌ AVOID using long text in DisclaimerCard - use modal for full content
45
- - ❌ AVOID using DisclaimerSetting for critical legal notices that require explicit acceptance
46
- - ❌ AVOID hardcoding colors - use design system tokens or semantic color names
47
-
48
- ## Rules
49
-
50
- ### ALWAYS
51
- - ✅ ALWAYS provide translation keys for DisclaimerSetting (titleKey, messageKey, shortMessageKey)
52
- - ✅ ALWAYS provide all required props to DisclaimerCard (title, shortMessage, iconName, iconColor, backgroundColor, onPress)
53
- - ✅ ALWAYS use modalTitle and modalContent props for custom content that bypasses i18n
54
- - ✅ ALWAYS ensure modal can be closed with a clear close button
55
- - ✅ ALWAYS use appropriate colors for warning levels
56
-
57
- ### MUST
58
- - ✅ MUST include translation keys in all language files before using DisclaimerSetting
59
- - ✅ MUST provide custom modalTitle and modalContent when bypassing i18n
60
- - ✅ MUST ensure disclaimer text is clear and non-technical
61
- - ✅ MUST test disclaimer rendering on all platforms (iOS, Android, Web)
62
- - ✅ MUST ensure modal content is scrollable for long disclaimers
63
-
64
- ### SHOULD
65
- - ✅ SHOULD use red/amber colors for critical warnings, blue for informational
66
- - ✅ SHOULD keep card messages short and concise
67
- - ✅ SHOULD provide specific icons for different warning types (alert-triangle, flask, heart-pulse)
68
- - ✅ SHOULD ensure disclaimer modals are accessible with proper labels
69
- - ✅ SHOULD test disclaimer components with different screen sizes
70
-
71
- ## AI Agent Guidelines
72
-
73
- 1. **Component Selection**: Use DisclaimerSetting for settings integration (card + modal), DisclaimerCard for custom cards, DisclaimerModal for standalone modals, DisclaimerScreen for dedicated screens
74
- 2. **i18n Usage**: Always use translation keys with DisclaimerSetting - only use modalTitle/modalContent for truly static content
75
- 3. **Color Guidelines**: Always match colors to warning severity - red for critical/legal, amber for caution, blue for informational, emerald for confirmations
76
- 4. **Content Structure**: Always keep card messages short (1-2 lines) with full content in modal
77
- 5. **Platform Testing**: Always test disclaimer rendering on iOS, Android, and Web platforms
78
-
79
- ## Related
80
-
81
- - **Legal**: Privacy policy, terms of service
82
- - **Settings**: Main settings management
83
- - **Design System**: Icons, colors, and typography
84
-
85
- ## License
86
-
87
- MIT