@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.21.0",
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
+ }
@@ -21,3 +21,4 @@ export * from "./useSubscriptionStatus";
21
21
  export * from "./useUserTier";
22
22
  export * from "./useUserTierWithRepository";
23
23
  export * from "./feedback/usePaywallFeedback";
24
+ export * from "./feedback/useFeedbackSubmit";