@umituz/react-native-subscription 2.21.0 → 2.22.0
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-subscription",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.22.0",
|
|
4
4
|
"description": "Complete subscription management with RevenueCat, paywall UI, and credits system for React Native apps",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
package/src/index.ts
CHANGED
|
@@ -14,6 +14,13 @@ export type { ISubscriptionRepository } from "./application/ports/ISubscriptionR
|
|
|
14
14
|
|
|
15
15
|
// Infrastructure Layer
|
|
16
16
|
export { SubscriptionService, initializeSubscriptionService } from "./infrastructure/services/SubscriptionService";
|
|
17
|
+
export {
|
|
18
|
+
submitFeedback,
|
|
19
|
+
submitPaywallFeedback,
|
|
20
|
+
submitSettingsFeedback,
|
|
21
|
+
type FeedbackData,
|
|
22
|
+
type FeedbackSubmitResult,
|
|
23
|
+
} from "./infrastructure/services/FeedbackService";
|
|
17
24
|
export { initializeSubscription, type SubscriptionInitConfig, type CreditPackageConfig } from "./infrastructure/services/SubscriptionInitializer";
|
|
18
25
|
export { CreditsRepository, createCreditsRepository } from "./infrastructure/repositories/CreditsRepository";
|
|
19
26
|
export { configureCreditsRepository, getCreditsRepository, getCreditsConfig, resetCreditsRepository, isCreditsRepositoryConfigured } from "./infrastructure/repositories/CreditsRepositoryProvider";
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feedback Service
|
|
3
|
+
* Handles feedback submission to Firestore
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { getFirestore } from "@umituz/react-native-firebase";
|
|
7
|
+
import { collection, addDoc } from "firebase/firestore";
|
|
8
|
+
|
|
9
|
+
export interface FeedbackData {
|
|
10
|
+
userId: string | null;
|
|
11
|
+
userEmail: string | null;
|
|
12
|
+
type: string;
|
|
13
|
+
title: string;
|
|
14
|
+
description: string;
|
|
15
|
+
rating?: number;
|
|
16
|
+
status?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface FeedbackSubmitResult {
|
|
20
|
+
success: boolean;
|
|
21
|
+
error?: Error;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const FEEDBACK_COLLECTION = "feedback";
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Submit feedback to Firestore
|
|
28
|
+
*/
|
|
29
|
+
export async function submitFeedback(
|
|
30
|
+
data: FeedbackData
|
|
31
|
+
): Promise<FeedbackSubmitResult> {
|
|
32
|
+
const db = getFirestore();
|
|
33
|
+
|
|
34
|
+
if (!db) {
|
|
35
|
+
if (__DEV__) {
|
|
36
|
+
console.warn("[FeedbackService] Firestore not available");
|
|
37
|
+
}
|
|
38
|
+
return { success: false, error: new Error("Firestore not available") };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
if (__DEV__) {
|
|
43
|
+
console.log("[FeedbackService] Submitting feedback:", {
|
|
44
|
+
type: data.type,
|
|
45
|
+
userId: data.userId?.slice(0, 8),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const now = new Date().toISOString();
|
|
50
|
+
|
|
51
|
+
await addDoc(collection(db, FEEDBACK_COLLECTION), {
|
|
52
|
+
userId: data.userId,
|
|
53
|
+
userEmail: data.userEmail,
|
|
54
|
+
type: data.type,
|
|
55
|
+
title: data.title,
|
|
56
|
+
description: data.description,
|
|
57
|
+
rating: data.rating ?? null,
|
|
58
|
+
status: data.status ?? "pending",
|
|
59
|
+
createdAt: now,
|
|
60
|
+
updatedAt: now,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
if (__DEV__) {
|
|
64
|
+
console.log("[FeedbackService] Feedback submitted successfully");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return { success: true };
|
|
68
|
+
} catch (error) {
|
|
69
|
+
if (__DEV__) {
|
|
70
|
+
console.error("[FeedbackService] Submit error:", error);
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
success: false,
|
|
74
|
+
error: error instanceof Error ? error : new Error("Unknown error"),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Submit paywall decline feedback
|
|
81
|
+
*/
|
|
82
|
+
export async function submitPaywallFeedback(
|
|
83
|
+
userId: string | null,
|
|
84
|
+
userEmail: string | null,
|
|
85
|
+
reason: string
|
|
86
|
+
): Promise<FeedbackSubmitResult> {
|
|
87
|
+
return submitFeedback({
|
|
88
|
+
userId,
|
|
89
|
+
userEmail,
|
|
90
|
+
type: "paywall_declined",
|
|
91
|
+
title: "Paywall Declined",
|
|
92
|
+
description: reason,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Submit general settings feedback
|
|
98
|
+
*/
|
|
99
|
+
export async function submitSettingsFeedback(
|
|
100
|
+
userId: string | null,
|
|
101
|
+
userEmail: string | null,
|
|
102
|
+
data: {
|
|
103
|
+
type?: string;
|
|
104
|
+
title?: string;
|
|
105
|
+
description: string;
|
|
106
|
+
rating?: number;
|
|
107
|
+
}
|
|
108
|
+
): Promise<FeedbackSubmitResult> {
|
|
109
|
+
return submitFeedback({
|
|
110
|
+
userId,
|
|
111
|
+
userEmail,
|
|
112
|
+
type: data.type ?? "general",
|
|
113
|
+
title: data.title ?? "Settings Feedback",
|
|
114
|
+
description: data.description,
|
|
115
|
+
rating: data.rating,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feedback Submit Hooks
|
|
3
|
+
* React hooks for submitting feedback to Firestore
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { useCallback } from "react";
|
|
7
|
+
import { useAuth } from "@umituz/react-native-auth";
|
|
8
|
+
import {
|
|
9
|
+
submitPaywallFeedback,
|
|
10
|
+
submitSettingsFeedback,
|
|
11
|
+
} from "../../../infrastructure/services/FeedbackService";
|
|
12
|
+
|
|
13
|
+
export interface UsePaywallFeedbackSubmitOptions {
|
|
14
|
+
onSuccess?: () => void;
|
|
15
|
+
onError?: (error: Error) => void;
|
|
16
|
+
onComplete?: () => void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Hook for submitting paywall decline feedback
|
|
21
|
+
*/
|
|
22
|
+
export function usePaywallFeedbackSubmit(
|
|
23
|
+
options: UsePaywallFeedbackSubmitOptions = {}
|
|
24
|
+
) {
|
|
25
|
+
const { user } = useAuth();
|
|
26
|
+
const { onSuccess, onError, onComplete } = options;
|
|
27
|
+
|
|
28
|
+
const submit = useCallback(
|
|
29
|
+
async (reason: string) => {
|
|
30
|
+
if (__DEV__) {
|
|
31
|
+
console.log("[usePaywallFeedbackSubmit] Submitting:", {
|
|
32
|
+
userId: user?.uid?.slice(0, 8),
|
|
33
|
+
reason: reason.slice(0, 20),
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const result = await submitPaywallFeedback(
|
|
38
|
+
user?.uid ?? null,
|
|
39
|
+
user?.email ?? null,
|
|
40
|
+
reason
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
if (result.success) {
|
|
44
|
+
onSuccess?.();
|
|
45
|
+
} else if (result.error) {
|
|
46
|
+
onError?.(result.error);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
onComplete?.();
|
|
50
|
+
},
|
|
51
|
+
[user, onSuccess, onError, onComplete]
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
return { submit };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface SettingsFeedbackData {
|
|
58
|
+
type?: string;
|
|
59
|
+
title?: string;
|
|
60
|
+
description: string;
|
|
61
|
+
rating?: number;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface UseSettingsFeedbackSubmitOptions {
|
|
65
|
+
onSuccess?: () => void;
|
|
66
|
+
onError?: (error: Error) => void;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Hook for submitting general settings feedback
|
|
71
|
+
*/
|
|
72
|
+
export function useSettingsFeedbackSubmit(
|
|
73
|
+
options: UseSettingsFeedbackSubmitOptions = {}
|
|
74
|
+
) {
|
|
75
|
+
const { user } = useAuth();
|
|
76
|
+
const { onSuccess, onError } = options;
|
|
77
|
+
|
|
78
|
+
const submit = useCallback(
|
|
79
|
+
async (data: SettingsFeedbackData) => {
|
|
80
|
+
if (__DEV__) {
|
|
81
|
+
console.log("[useSettingsFeedbackSubmit] Submitting:", {
|
|
82
|
+
userId: user?.uid?.slice(0, 8),
|
|
83
|
+
type: data.type,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const result = await submitSettingsFeedback(
|
|
88
|
+
user?.uid ?? null,
|
|
89
|
+
user?.email ?? null,
|
|
90
|
+
data
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
if (result.success) {
|
|
94
|
+
onSuccess?.();
|
|
95
|
+
} else if (result.error) {
|
|
96
|
+
onError?.(result.error);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return result;
|
|
100
|
+
},
|
|
101
|
+
[user, onSuccess, onError]
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
return { submit };
|
|
105
|
+
}
|