@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.
- package/package.json +1 -1
- package/src/domains/about/domain/entities/AppInfo.ts +1 -0
- package/src/domains/about/presentation/components/AboutContent.tsx +6 -6
- package/src/domains/about/presentation/screens/AboutScreen.tsx +2 -4
- package/src/domains/appearance/presentation/screens/AppearanceScreen.tsx +9 -12
- package/src/domains/disclaimer/presentation/components/DisclaimerSetting.tsx +9 -20
- package/src/domains/disclaimer/presentation/screens/DisclaimerScreen.tsx +2 -6
- package/src/domains/gamification/types/index.ts +12 -12
- package/src/domains/localization/presentation/components/LanguageSection.tsx +3 -3
- package/src/domains/localization/presentation/screens/LanguageSelectionScreen.tsx +1 -1
- package/src/domains/notifications/presentation/components/NotificationsSection.tsx +2 -4
- package/src/domains/notifications/presentation/screens/NotificationSettingsScreen.tsx +1 -3
- package/src/infrastructure/utils/configFactory.ts +3 -14
- package/src/presentation/hooks/useSettingsScreenConfig.ts +27 -12
- package/src/presentation/navigation/SettingsStackNavigator.tsx +9 -8
- package/src/presentation/navigation/hooks/useNavigationHandlers.ts +4 -2
- package/src/presentation/navigation/hooks/useSettingsScreens.ts +10 -10
- package/src/presentation/navigation/utils/navigationTranslations.ts +29 -32
- package/src/presentation/screens/SettingsScreen.tsx +5 -1
- package/src/presentation/screens/components/GamificationSettingsItem.tsx +3 -6
- package/src/presentation/screens/components/SettingsContent.tsx +9 -5
- package/src/presentation/screens/components/SettingsHeader.tsx +4 -3
- package/src/presentation/screens/components/SubscriptionSettingsItem.tsx +3 -4
- package/src/presentation/screens/components/VideoTutorialSettingsItem.tsx +2 -4
- package/src/presentation/screens/components/WalletSettingsItem.tsx +3 -4
- package/src/presentation/screens/components/sections/FeatureSettingsSection.tsx +11 -13
- package/src/presentation/screens/components/sections/IdentitySettingsSection.tsx +5 -6
- package/src/presentation/screens/components/sections/ProfileSectionLoader.tsx +11 -9
- package/src/presentation/screens/components/sections/SupportSettingsSection.tsx +22 -23
- package/src/presentation/screens/types/SettingsConfig.ts +97 -6
- package/src/presentation/utils/accountConfigUtils.ts +9 -17
- package/src/presentation/utils/config-creators/base-configs.ts +0 -22
- package/src/presentation/utils/config-creators/feature-configs.ts +0 -20
- package/src/presentation/utils/config-creators/support-configs.ts +2 -12
- package/src/presentation/utils/faqTranslator.ts +5 -18
- package/src/presentation/utils/settingsConfigFactory.ts +10 -13
- package/src/presentation/utils/useAuthHandlers.ts +13 -20
- package/src/presentation/utils/userProfileUtils.ts +2 -16
- package/src/domains/disclaimer/README.md +0 -87
- package/src/domains/disclaimer/presentation/components/DisclaimerCard.test.tsx +0 -208
- package/src/domains/disclaimer/presentation/components/DisclaimerModal.test.tsx +0 -236
- package/src/domains/disclaimer/presentation/components/DisclaimerSetting.test.tsx +0 -74
- package/src/domains/disclaimer/presentation/components/README.md +0 -97
- 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 ||
|
|
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:
|
|
45
|
+
editProfileText: "",
|
|
54
46
|
onSignIn,
|
|
55
47
|
accountActions: {
|
|
56
48
|
onLogout,
|
|
57
49
|
onDeleteAccount,
|
|
58
|
-
logoutText:
|
|
59
|
-
logoutConfirmTitle:
|
|
60
|
-
logoutConfirmMessage:
|
|
61
|
-
cancelText:
|
|
62
|
-
deleteAccountText:
|
|
63
|
-
deleteConfirmTitle:
|
|
64
|
-
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 {
|
|
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
|
-
|
|
6
|
+
|
|
7
7
|
import type { FAQData } from "../navigation/types";
|
|
8
8
|
import type { AppInfo } from "../navigation/types";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
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
|
-
|
|
16
|
+
_t: (key: string, params?: any) => string,
|
|
16
17
|
_appInfo: AppInfo
|
|
17
18
|
): FAQData | undefined => {
|
|
18
|
-
|
|
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 {
|
|
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(
|
|
56
|
-
language: features.language ? createLanguageConfig(
|
|
57
|
-
notifications: features.notifications ? createNotificationsConfig(
|
|
58
|
-
feedback: features.feedback ? createFeedbackConfig(
|
|
59
|
-
about: features.about ? createAboutConfig(
|
|
60
|
-
legal: features.legal ? createLegalConfig(
|
|
61
|
-
faqs: features.faqs ? createFAQConfig(
|
|
62
|
-
rating: features.rating ? createRatingConfig(
|
|
63
|
-
subscription: createSubscriptionConfig(
|
|
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
|
-
|
|
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
|
-
|
|
43
|
-
|
|
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(
|
|
49
|
+
Alert.alert(translations?.common || "", translations?.failedToOpenAppStore || "");
|
|
54
50
|
}
|
|
55
|
-
}, [appInfo.appStoreUrl,
|
|
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
|
-
|
|
67
|
-
|
|
61
|
+
translations?.common || "",
|
|
62
|
+
translations?.unknown || ""
|
|
68
63
|
);
|
|
69
64
|
}
|
|
70
|
-
}, [signOut,
|
|
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
|
-
|
|
82
|
-
|
|
75
|
+
translations?.common || "",
|
|
76
|
+
translations?.deleteAccountError || ""
|
|
83
77
|
);
|
|
84
78
|
}
|
|
85
|
-
}, [deleteAccount,
|
|
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,
|
|
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
|
|
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
|