@growth-rail/react-native 1.0.0 → 2.0.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/CHANGELOG.md +6 -0
- package/README.md +29 -21
- package/dist/index.d.mts +91 -99
- package/dist/index.d.ts +91 -99
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -32,7 +32,7 @@ import { GrowthRailProvider } from '@growth-rail/react-native';
|
|
|
32
32
|
const App = () => {
|
|
33
33
|
return (
|
|
34
34
|
<GrowthRailProvider
|
|
35
|
-
|
|
35
|
+
projectSecretKey="YOUR_PROJECT_SECRET_KEY"
|
|
36
36
|
userId="USER_UNIQUE_ID" // optional at start
|
|
37
37
|
>
|
|
38
38
|
<YourAppContent />
|
|
@@ -69,16 +69,15 @@ Add an intent filter for your deep link scheme:
|
|
|
69
69
|
</intent-filter>
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
-
## Usage
|
|
73
|
-
|
|
74
72
|
### User Initialization
|
|
75
73
|
If you didn't provide a `userId` to the provider, or if the user logs in later:
|
|
76
74
|
|
|
77
75
|
```tsx
|
|
78
|
-
import {
|
|
76
|
+
import { useGrowthRail } from '@growth-rail/react-native';
|
|
79
77
|
|
|
80
78
|
const handleLogin = async (user) => {
|
|
81
|
-
|
|
79
|
+
const { initAppUser } = useGrowthRail();
|
|
80
|
+
await initAppUser(user.id);
|
|
82
81
|
};
|
|
83
82
|
```
|
|
84
83
|
|
|
@@ -86,10 +85,11 @@ const handleLogin = async (user) => {
|
|
|
86
85
|
Attribute successful actions (like purchases or sign-ups) to the referrer:
|
|
87
86
|
|
|
88
87
|
```tsx
|
|
89
|
-
import {
|
|
88
|
+
import { useGrowthRail } from '@growth-rail/react-native';
|
|
90
89
|
|
|
91
90
|
const onPurchaseComplete = async () => {
|
|
92
|
-
|
|
91
|
+
const { trackRewardEvent } = useGrowthRail();
|
|
92
|
+
await trackRewardEvent('purchase_completed');
|
|
93
93
|
};
|
|
94
94
|
```
|
|
95
95
|
|
|
@@ -101,15 +101,16 @@ import { useGrowthRail } from '@growth-rail/react-native';
|
|
|
101
101
|
|
|
102
102
|
const MyComponent = () => {
|
|
103
103
|
const {
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
initAppUser,
|
|
105
|
+
trackRewardEvent,
|
|
106
106
|
showReferralDashboard,
|
|
107
107
|
isLoading,
|
|
108
|
+
isUserReady,
|
|
108
109
|
error
|
|
109
110
|
} = useGrowthRail();
|
|
110
111
|
|
|
111
112
|
const handleAction = async () => {
|
|
112
|
-
await
|
|
113
|
+
await trackRewardEvent('custom_action');
|
|
113
114
|
};
|
|
114
115
|
|
|
115
116
|
return (
|
|
@@ -125,13 +126,13 @@ const MyComponent = () => {
|
|
|
125
126
|
Display a beautiful, pre-built dashboard for users to manage their referrals.
|
|
126
127
|
|
|
127
128
|
```tsx
|
|
128
|
-
import {
|
|
129
|
+
import { useGrowthRail } from '@growth-rail/react-native';
|
|
129
130
|
|
|
130
131
|
const MyProfile = () => {
|
|
131
|
-
const {
|
|
132
|
+
const { showReferralDashboard } = useGrowthRail();
|
|
132
133
|
|
|
133
134
|
return (
|
|
134
|
-
<Button title="Refer & Earn" onPress={() =>
|
|
135
|
+
<Button title="Refer & Earn" onPress={() => showReferralDashboard()} />
|
|
135
136
|
);
|
|
136
137
|
};
|
|
137
138
|
```
|
|
@@ -140,10 +141,11 @@ const MyProfile = () => {
|
|
|
140
141
|
If you need to build a custom UI, you can generate the referral link directly:
|
|
141
142
|
|
|
142
143
|
```tsx
|
|
143
|
-
import {
|
|
144
|
+
import { useGrowthRail } from '@growth-rail/react-native';
|
|
144
145
|
|
|
145
146
|
const getLink = async () => {
|
|
146
|
-
const {
|
|
147
|
+
const { getReferralLink } = useGrowthRail();
|
|
148
|
+
const referralLink = await getReferralLink();
|
|
147
149
|
console.log('Share this link:', referralLink);
|
|
148
150
|
};
|
|
149
151
|
```
|
|
@@ -153,16 +155,22 @@ const getLink = async () => {
|
|
|
153
155
|
### `GrowthRailProvider` Props
|
|
154
156
|
| Prop | Type | Description |
|
|
155
157
|
| :--- | :--- | :--- |
|
|
156
|
-
| `
|
|
158
|
+
| `projectSecretKey` | `string` | Your GrowthRail Project Secret Key. |
|
|
157
159
|
| `userId` | `string` | (Optional) The current user's unique ID. |
|
|
158
160
|
| `apiUrl` | `string` | (Optional) Custom API endpoint. |
|
|
159
161
|
|
|
160
|
-
### `
|
|
161
|
-
Provides access to SDK methods:
|
|
162
|
-
- `
|
|
163
|
-
- `
|
|
164
|
-
- `
|
|
162
|
+
### `useGrowthRail()`
|
|
163
|
+
Provides access to SDK methods and state:
|
|
164
|
+
- `initAppUser(userId)`: Initializes a user in the GrowthRail system.
|
|
165
|
+
- `trackRewardEvent(eventName)`: Tracks a reward-eligible event.
|
|
166
|
+
- `showReferralDashboard(options)`: Opens the referral dashboard modal.
|
|
167
|
+
- `hideReferralDashboard()`: Closes the referral dashboard modal.
|
|
168
|
+
- `getReferralLink()`: Returns the user's referral link.
|
|
169
|
+
- `getReferralTrackingId()`: Returns the current tracking ID.
|
|
165
170
|
- `isInitialized`: Boolean indicating if the SDK is ready.
|
|
171
|
+
- `isUserReady`: Boolean indicating if the user is initialized.
|
|
172
|
+
- `isLoading`: Boolean indicating if an operation is in progress.
|
|
173
|
+
- `error`: The last error that occurred.
|
|
166
174
|
|
|
167
175
|
## License
|
|
168
176
|
MIT
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
3
|
type GrowthRailOptions = {
|
|
4
|
-
|
|
4
|
+
projectSecretKey: string;
|
|
5
5
|
cookieDomain?: string;
|
|
6
6
|
autoPageTrack?: boolean;
|
|
7
7
|
};
|
|
@@ -14,19 +14,10 @@ type AppUserType = {
|
|
|
14
14
|
referralLink: string;
|
|
15
15
|
referrerExperience: ReferrerExperience;
|
|
16
16
|
};
|
|
17
|
-
type AppUserTypeWithId = AppUserType & {
|
|
18
|
-
id: string;
|
|
19
|
-
};
|
|
20
17
|
type ReferralLink = {
|
|
21
18
|
referralCode: string;
|
|
22
19
|
referralLink: string;
|
|
23
20
|
};
|
|
24
|
-
type EventPayload = {
|
|
25
|
-
event: string;
|
|
26
|
-
userId?: string;
|
|
27
|
-
properties?: Record<string, any>;
|
|
28
|
-
timestamp: string;
|
|
29
|
-
};
|
|
30
21
|
type TrackReferralResponse = {
|
|
31
22
|
referralTrackingId: string;
|
|
32
23
|
promotionalText: string;
|
|
@@ -60,112 +51,113 @@ interface NewUserExperience {
|
|
|
60
51
|
themeColor: string;
|
|
61
52
|
};
|
|
62
53
|
}
|
|
63
|
-
interface DeviceFingerprint {
|
|
64
|
-
os: string;
|
|
65
|
-
osVersion: string;
|
|
66
|
-
deviceModel?: string;
|
|
67
|
-
deviceBrand?: string;
|
|
68
|
-
screenWidth?: number;
|
|
69
|
-
screenHeight?: number;
|
|
70
|
-
timezoneOffsetInMinutes: string;
|
|
71
|
-
locale?: string;
|
|
72
|
-
language?: string;
|
|
73
|
-
platform?: string;
|
|
74
|
-
pixelRatio?: number;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
declare class GrowthRail {
|
|
78
|
-
private static api;
|
|
79
|
-
private static options;
|
|
80
|
-
private static currentUser;
|
|
81
|
-
private static referralObject;
|
|
82
|
-
private static initialized;
|
|
83
|
-
private static userReadyPromise;
|
|
84
|
-
private static userReadyResolver;
|
|
85
|
-
private constructor();
|
|
86
|
-
static init(options: GrowthRailOptions): Promise<void>;
|
|
87
|
-
private static handleInitialUrl;
|
|
88
|
-
private static setupLinkListeners;
|
|
89
|
-
private static checkDeferredReferral;
|
|
90
|
-
private static checkInstallReferrer;
|
|
91
|
-
static getDeviceFingerprint(): DeviceFingerprint;
|
|
92
|
-
private static checkDeferredDeepLinkFingerprint;
|
|
93
|
-
private static handleDeepLink;
|
|
94
|
-
private static ensureInitialized;
|
|
95
|
-
static initAppUser(clientProvidedId: string): Promise<AppUserType>;
|
|
96
|
-
static trackReferral(referralCode: string, rewardEventName?: string): Promise<TrackReferralResponse>;
|
|
97
|
-
static trackRewardEvent(eventName?: string): Promise<void>;
|
|
98
|
-
static createReferralLink(rewardEventName?: string): Promise<ReferralLink>;
|
|
99
|
-
static isInitialized(): boolean;
|
|
100
|
-
static getReferralLink(): string;
|
|
101
|
-
static getReferralCode(): string | undefined;
|
|
102
|
-
static getUserId(): string | undefined;
|
|
103
|
-
static isUserReady(): boolean;
|
|
104
|
-
static getReferrerExperience(): ReferrerExperience | undefined;
|
|
105
|
-
static ensureUserReady(): Promise<AppUserTypeWithId>;
|
|
106
|
-
static getNewUserExperience(): Promise<NewUserExperience>;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
declare class StorageManager {
|
|
110
|
-
static setTrackedReferral(id: string): Promise<void>;
|
|
111
|
-
static getTrackedReferral(): Promise<string | null>;
|
|
112
|
-
static isFirstLaunch(): Promise<boolean>;
|
|
113
|
-
}
|
|
114
54
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
constructor(options: GrowthRailOptions);
|
|
119
|
-
private request;
|
|
120
|
-
getNewUserExperience(): Promise<NewUserExperience>;
|
|
121
|
-
initAppUser(clientProvidedId: string): Promise<AppUserType>;
|
|
122
|
-
createReferralLink(referrerId: string, rewardEventName?: string): Promise<{
|
|
123
|
-
referralCode: string;
|
|
124
|
-
referralLink: string;
|
|
125
|
-
}>;
|
|
126
|
-
trackReferral(referralCode: string, rewardEventName?: string): Promise<TrackReferralResponse>;
|
|
127
|
-
trackRewardEvent(refereeId: string, referralTrackingId: string, eventName?: string): Promise<any>;
|
|
128
|
-
checkDeferredDeepLink(fingerprint: DeviceFingerprint): Promise<TrackReferralResponse>;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
interface GrowthRailContextType {
|
|
132
|
-
isInitialized: boolean;
|
|
133
|
-
isUserReady: boolean;
|
|
134
|
-
showDashboard: (options?: Partial<ReferrerModalOptions>) => void;
|
|
135
|
-
hideDashboard: () => void;
|
|
136
|
-
showFloatingButton: (options?: Partial<ReferrerTriggerButton>) => void;
|
|
137
|
-
hideFloatingButton: () => void;
|
|
138
|
-
}
|
|
55
|
+
/**
|
|
56
|
+
* Props for the GrowthRailProvider component in React Native.
|
|
57
|
+
*/
|
|
139
58
|
interface GrowthRailProviderProps extends GrowthRailOptions {
|
|
59
|
+
/** The unique ID for the current application user. */
|
|
140
60
|
userId?: string;
|
|
61
|
+
/** Your application components. */
|
|
141
62
|
children: React.ReactNode;
|
|
142
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Root provider component for GrowthRail in React Native applications.
|
|
66
|
+
* This component initializes the SDK, handles deep links, and manages user state.
|
|
67
|
+
*
|
|
68
|
+
* Wrap your root app component with this provider.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* <GrowthRailProvider projectSecretKey="your-api-key" userId="user-123">
|
|
72
|
+
* <App />
|
|
73
|
+
* </GrowthRailProvider>
|
|
74
|
+
*/
|
|
143
75
|
declare const GrowthRailProvider: React.FC<GrowthRailProviderProps>;
|
|
144
|
-
declare const useGrowthRailContext: () => GrowthRailContextType;
|
|
145
76
|
|
|
77
|
+
/**
|
|
78
|
+
* The return type of the useGrowthRail hook in React Native.
|
|
79
|
+
*/
|
|
80
|
+
interface UseGrowthRailReturn {
|
|
81
|
+
/**
|
|
82
|
+
* Initializes a user in the GrowthRail system.
|
|
83
|
+
* @param userId - Unique identifier for the user.
|
|
84
|
+
*/
|
|
85
|
+
initAppUser: (userId: string) => Promise<AppUserType>;
|
|
86
|
+
/**
|
|
87
|
+
* Tracks a reward-eligible event for the current user.
|
|
88
|
+
* @param eventName - Optional name of the event.
|
|
89
|
+
*/
|
|
90
|
+
trackRewardEvent: (eventName?: string) => Promise<void>;
|
|
91
|
+
/**
|
|
92
|
+
* Manually triggers the referral dashboard modal.
|
|
93
|
+
* @param options - Customization options for the modal.
|
|
94
|
+
*/
|
|
95
|
+
showReferralDashboard: (options?: Partial<ReferrerModalOptions>) => void;
|
|
96
|
+
/** Hides the referral dashboard. */
|
|
97
|
+
hideReferralDashboard: () => void;
|
|
98
|
+
/** Gets the current referral tracking ID if one is stored. */
|
|
99
|
+
getReferralTrackingId: () => Promise<string | null>;
|
|
100
|
+
/** Gets the user's referral link. */
|
|
101
|
+
getReferralLink: () => Promise<string | undefined>;
|
|
102
|
+
/** Whether an asynchronous operation (like init or track) is in progress. */
|
|
103
|
+
isLoading: boolean;
|
|
104
|
+
/** Whether the SDK is initialized. */
|
|
105
|
+
isInitialized: boolean;
|
|
106
|
+
/** Whether the user is fully initialized and ready. */
|
|
107
|
+
isUserReady: boolean;
|
|
108
|
+
/** The last error that occurred during an operation. */
|
|
109
|
+
error: Error | null;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* A hook that provides access to GrowthRail SDK methods and state in React Native.
|
|
113
|
+
*
|
|
114
|
+
* @returns An object containing methods to manage referrals and track state.
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* const { showReferralDashboard, trackRewardEvent } = useGrowthRail();
|
|
118
|
+
*/
|
|
119
|
+
declare const useGrowthRail: () => UseGrowthRailReturn;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Props for the ReferralDashboard component in React Native.
|
|
123
|
+
*/
|
|
146
124
|
interface ReferralDashboardProps {
|
|
125
|
+
/** Whether the dashboard modal is currently visible. */
|
|
147
126
|
visible: boolean;
|
|
127
|
+
/** Customization options for the dashboard's appearance. */
|
|
148
128
|
options?: Partial<ReferrerModalOptions>;
|
|
129
|
+
/** Callback fired when the dashboard is closed. */
|
|
149
130
|
onClose: () => void;
|
|
150
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* A modal-based referral dashboard for React Native.
|
|
134
|
+
* Usually managed by the `GrowthRailProvider`, but can be used standalone.
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* <ReferralDashboard
|
|
138
|
+
* visible={showDashboard}
|
|
139
|
+
* onClose={() => setShowDashboard(false)}
|
|
140
|
+
* />
|
|
141
|
+
*/
|
|
151
142
|
declare const ReferralDashboard: React.FC<ReferralDashboardProps>;
|
|
152
143
|
|
|
144
|
+
/**
|
|
145
|
+
* Props for the TriggerButton component in React Native.
|
|
146
|
+
*/
|
|
153
147
|
interface TriggerButtonProps {
|
|
148
|
+
/** Callback fired when the button is pressed. */
|
|
154
149
|
onPress: () => void;
|
|
150
|
+
/** Customization options for the button's appearance and behavior. */
|
|
155
151
|
options?: Partial<ReferrerExperience>;
|
|
156
152
|
}
|
|
153
|
+
/**
|
|
154
|
+
* A floating or edge-attached trigger button for the referral dashboard.
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* <TriggerButton
|
|
158
|
+
* onPress={() => setShowDashboard(true)}
|
|
159
|
+
* />
|
|
160
|
+
*/
|
|
157
161
|
declare const TriggerButton: React.FC<TriggerButtonProps>;
|
|
158
162
|
|
|
159
|
-
|
|
160
|
-
initUser: (userId: string) => Promise<AppUserType>;
|
|
161
|
-
trackReward: (eventName?: string) => Promise<void>;
|
|
162
|
-
showReferralDashboard: (options?: Partial<ReferrerModalOptions>) => void;
|
|
163
|
-
showFloatingButton: (options: Partial<ReferrerTriggerButton>) => void;
|
|
164
|
-
hideFloatingButton: () => void;
|
|
165
|
-
isLoading: boolean;
|
|
166
|
-
isInitialized: boolean;
|
|
167
|
-
error: Error | null;
|
|
168
|
-
}
|
|
169
|
-
declare const useGrowthRail: () => UseGrowthRailReturn;
|
|
170
|
-
|
|
171
|
-
export { APIClient, type AppUserType, type AppUserTypeWithId, type DeviceFingerprint, type EventPayload, GrowthRail, type GrowthRailOptions, GrowthRailProvider, type NewUserExperience, ReferralDashboard, type ReferralLink, type ReferrerExperience, type ReferrerModalOptions, type ReferrerTriggerButton, StorageManager, type TrackReferralResponse, TriggerButton, type TriggerButtonPosition, type UseGrowthRailReturn, useGrowthRail, useGrowthRailContext };
|
|
163
|
+
export { type AppUserType, type GrowthRailOptions, GrowthRailProvider, type NewUserExperience, ReferralDashboard, type ReferralLink, type ReferrerExperience, type ReferrerModalOptions, type ReferrerTriggerButton, type TrackReferralResponse, TriggerButton, type TriggerButtonPosition, type UseGrowthRailReturn, useGrowthRail };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
3
|
type GrowthRailOptions = {
|
|
4
|
-
|
|
4
|
+
projectSecretKey: string;
|
|
5
5
|
cookieDomain?: string;
|
|
6
6
|
autoPageTrack?: boolean;
|
|
7
7
|
};
|
|
@@ -14,19 +14,10 @@ type AppUserType = {
|
|
|
14
14
|
referralLink: string;
|
|
15
15
|
referrerExperience: ReferrerExperience;
|
|
16
16
|
};
|
|
17
|
-
type AppUserTypeWithId = AppUserType & {
|
|
18
|
-
id: string;
|
|
19
|
-
};
|
|
20
17
|
type ReferralLink = {
|
|
21
18
|
referralCode: string;
|
|
22
19
|
referralLink: string;
|
|
23
20
|
};
|
|
24
|
-
type EventPayload = {
|
|
25
|
-
event: string;
|
|
26
|
-
userId?: string;
|
|
27
|
-
properties?: Record<string, any>;
|
|
28
|
-
timestamp: string;
|
|
29
|
-
};
|
|
30
21
|
type TrackReferralResponse = {
|
|
31
22
|
referralTrackingId: string;
|
|
32
23
|
promotionalText: string;
|
|
@@ -60,112 +51,113 @@ interface NewUserExperience {
|
|
|
60
51
|
themeColor: string;
|
|
61
52
|
};
|
|
62
53
|
}
|
|
63
|
-
interface DeviceFingerprint {
|
|
64
|
-
os: string;
|
|
65
|
-
osVersion: string;
|
|
66
|
-
deviceModel?: string;
|
|
67
|
-
deviceBrand?: string;
|
|
68
|
-
screenWidth?: number;
|
|
69
|
-
screenHeight?: number;
|
|
70
|
-
timezoneOffsetInMinutes: string;
|
|
71
|
-
locale?: string;
|
|
72
|
-
language?: string;
|
|
73
|
-
platform?: string;
|
|
74
|
-
pixelRatio?: number;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
declare class GrowthRail {
|
|
78
|
-
private static api;
|
|
79
|
-
private static options;
|
|
80
|
-
private static currentUser;
|
|
81
|
-
private static referralObject;
|
|
82
|
-
private static initialized;
|
|
83
|
-
private static userReadyPromise;
|
|
84
|
-
private static userReadyResolver;
|
|
85
|
-
private constructor();
|
|
86
|
-
static init(options: GrowthRailOptions): Promise<void>;
|
|
87
|
-
private static handleInitialUrl;
|
|
88
|
-
private static setupLinkListeners;
|
|
89
|
-
private static checkDeferredReferral;
|
|
90
|
-
private static checkInstallReferrer;
|
|
91
|
-
static getDeviceFingerprint(): DeviceFingerprint;
|
|
92
|
-
private static checkDeferredDeepLinkFingerprint;
|
|
93
|
-
private static handleDeepLink;
|
|
94
|
-
private static ensureInitialized;
|
|
95
|
-
static initAppUser(clientProvidedId: string): Promise<AppUserType>;
|
|
96
|
-
static trackReferral(referralCode: string, rewardEventName?: string): Promise<TrackReferralResponse>;
|
|
97
|
-
static trackRewardEvent(eventName?: string): Promise<void>;
|
|
98
|
-
static createReferralLink(rewardEventName?: string): Promise<ReferralLink>;
|
|
99
|
-
static isInitialized(): boolean;
|
|
100
|
-
static getReferralLink(): string;
|
|
101
|
-
static getReferralCode(): string | undefined;
|
|
102
|
-
static getUserId(): string | undefined;
|
|
103
|
-
static isUserReady(): boolean;
|
|
104
|
-
static getReferrerExperience(): ReferrerExperience | undefined;
|
|
105
|
-
static ensureUserReady(): Promise<AppUserTypeWithId>;
|
|
106
|
-
static getNewUserExperience(): Promise<NewUserExperience>;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
declare class StorageManager {
|
|
110
|
-
static setTrackedReferral(id: string): Promise<void>;
|
|
111
|
-
static getTrackedReferral(): Promise<string | null>;
|
|
112
|
-
static isFirstLaunch(): Promise<boolean>;
|
|
113
|
-
}
|
|
114
54
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
constructor(options: GrowthRailOptions);
|
|
119
|
-
private request;
|
|
120
|
-
getNewUserExperience(): Promise<NewUserExperience>;
|
|
121
|
-
initAppUser(clientProvidedId: string): Promise<AppUserType>;
|
|
122
|
-
createReferralLink(referrerId: string, rewardEventName?: string): Promise<{
|
|
123
|
-
referralCode: string;
|
|
124
|
-
referralLink: string;
|
|
125
|
-
}>;
|
|
126
|
-
trackReferral(referralCode: string, rewardEventName?: string): Promise<TrackReferralResponse>;
|
|
127
|
-
trackRewardEvent(refereeId: string, referralTrackingId: string, eventName?: string): Promise<any>;
|
|
128
|
-
checkDeferredDeepLink(fingerprint: DeviceFingerprint): Promise<TrackReferralResponse>;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
interface GrowthRailContextType {
|
|
132
|
-
isInitialized: boolean;
|
|
133
|
-
isUserReady: boolean;
|
|
134
|
-
showDashboard: (options?: Partial<ReferrerModalOptions>) => void;
|
|
135
|
-
hideDashboard: () => void;
|
|
136
|
-
showFloatingButton: (options?: Partial<ReferrerTriggerButton>) => void;
|
|
137
|
-
hideFloatingButton: () => void;
|
|
138
|
-
}
|
|
55
|
+
/**
|
|
56
|
+
* Props for the GrowthRailProvider component in React Native.
|
|
57
|
+
*/
|
|
139
58
|
interface GrowthRailProviderProps extends GrowthRailOptions {
|
|
59
|
+
/** The unique ID for the current application user. */
|
|
140
60
|
userId?: string;
|
|
61
|
+
/** Your application components. */
|
|
141
62
|
children: React.ReactNode;
|
|
142
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Root provider component for GrowthRail in React Native applications.
|
|
66
|
+
* This component initializes the SDK, handles deep links, and manages user state.
|
|
67
|
+
*
|
|
68
|
+
* Wrap your root app component with this provider.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* <GrowthRailProvider projectSecretKey="your-api-key" userId="user-123">
|
|
72
|
+
* <App />
|
|
73
|
+
* </GrowthRailProvider>
|
|
74
|
+
*/
|
|
143
75
|
declare const GrowthRailProvider: React.FC<GrowthRailProviderProps>;
|
|
144
|
-
declare const useGrowthRailContext: () => GrowthRailContextType;
|
|
145
76
|
|
|
77
|
+
/**
|
|
78
|
+
* The return type of the useGrowthRail hook in React Native.
|
|
79
|
+
*/
|
|
80
|
+
interface UseGrowthRailReturn {
|
|
81
|
+
/**
|
|
82
|
+
* Initializes a user in the GrowthRail system.
|
|
83
|
+
* @param userId - Unique identifier for the user.
|
|
84
|
+
*/
|
|
85
|
+
initAppUser: (userId: string) => Promise<AppUserType>;
|
|
86
|
+
/**
|
|
87
|
+
* Tracks a reward-eligible event for the current user.
|
|
88
|
+
* @param eventName - Optional name of the event.
|
|
89
|
+
*/
|
|
90
|
+
trackRewardEvent: (eventName?: string) => Promise<void>;
|
|
91
|
+
/**
|
|
92
|
+
* Manually triggers the referral dashboard modal.
|
|
93
|
+
* @param options - Customization options for the modal.
|
|
94
|
+
*/
|
|
95
|
+
showReferralDashboard: (options?: Partial<ReferrerModalOptions>) => void;
|
|
96
|
+
/** Hides the referral dashboard. */
|
|
97
|
+
hideReferralDashboard: () => void;
|
|
98
|
+
/** Gets the current referral tracking ID if one is stored. */
|
|
99
|
+
getReferralTrackingId: () => Promise<string | null>;
|
|
100
|
+
/** Gets the user's referral link. */
|
|
101
|
+
getReferralLink: () => Promise<string | undefined>;
|
|
102
|
+
/** Whether an asynchronous operation (like init or track) is in progress. */
|
|
103
|
+
isLoading: boolean;
|
|
104
|
+
/** Whether the SDK is initialized. */
|
|
105
|
+
isInitialized: boolean;
|
|
106
|
+
/** Whether the user is fully initialized and ready. */
|
|
107
|
+
isUserReady: boolean;
|
|
108
|
+
/** The last error that occurred during an operation. */
|
|
109
|
+
error: Error | null;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* A hook that provides access to GrowthRail SDK methods and state in React Native.
|
|
113
|
+
*
|
|
114
|
+
* @returns An object containing methods to manage referrals and track state.
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* const { showReferralDashboard, trackRewardEvent } = useGrowthRail();
|
|
118
|
+
*/
|
|
119
|
+
declare const useGrowthRail: () => UseGrowthRailReturn;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Props for the ReferralDashboard component in React Native.
|
|
123
|
+
*/
|
|
146
124
|
interface ReferralDashboardProps {
|
|
125
|
+
/** Whether the dashboard modal is currently visible. */
|
|
147
126
|
visible: boolean;
|
|
127
|
+
/** Customization options for the dashboard's appearance. */
|
|
148
128
|
options?: Partial<ReferrerModalOptions>;
|
|
129
|
+
/** Callback fired when the dashboard is closed. */
|
|
149
130
|
onClose: () => void;
|
|
150
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* A modal-based referral dashboard for React Native.
|
|
134
|
+
* Usually managed by the `GrowthRailProvider`, but can be used standalone.
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* <ReferralDashboard
|
|
138
|
+
* visible={showDashboard}
|
|
139
|
+
* onClose={() => setShowDashboard(false)}
|
|
140
|
+
* />
|
|
141
|
+
*/
|
|
151
142
|
declare const ReferralDashboard: React.FC<ReferralDashboardProps>;
|
|
152
143
|
|
|
144
|
+
/**
|
|
145
|
+
* Props for the TriggerButton component in React Native.
|
|
146
|
+
*/
|
|
153
147
|
interface TriggerButtonProps {
|
|
148
|
+
/** Callback fired when the button is pressed. */
|
|
154
149
|
onPress: () => void;
|
|
150
|
+
/** Customization options for the button's appearance and behavior. */
|
|
155
151
|
options?: Partial<ReferrerExperience>;
|
|
156
152
|
}
|
|
153
|
+
/**
|
|
154
|
+
* A floating or edge-attached trigger button for the referral dashboard.
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* <TriggerButton
|
|
158
|
+
* onPress={() => setShowDashboard(true)}
|
|
159
|
+
* />
|
|
160
|
+
*/
|
|
157
161
|
declare const TriggerButton: React.FC<TriggerButtonProps>;
|
|
158
162
|
|
|
159
|
-
|
|
160
|
-
initUser: (userId: string) => Promise<AppUserType>;
|
|
161
|
-
trackReward: (eventName?: string) => Promise<void>;
|
|
162
|
-
showReferralDashboard: (options?: Partial<ReferrerModalOptions>) => void;
|
|
163
|
-
showFloatingButton: (options: Partial<ReferrerTriggerButton>) => void;
|
|
164
|
-
hideFloatingButton: () => void;
|
|
165
|
-
isLoading: boolean;
|
|
166
|
-
isInitialized: boolean;
|
|
167
|
-
error: Error | null;
|
|
168
|
-
}
|
|
169
|
-
declare const useGrowthRail: () => UseGrowthRailReturn;
|
|
170
|
-
|
|
171
|
-
export { APIClient, type AppUserType, type AppUserTypeWithId, type DeviceFingerprint, type EventPayload, GrowthRail, type GrowthRailOptions, GrowthRailProvider, type NewUserExperience, ReferralDashboard, type ReferralLink, type ReferrerExperience, type ReferrerModalOptions, type ReferrerTriggerButton, StorageManager, type TrackReferralResponse, TriggerButton, type TriggerButtonPosition, type UseGrowthRailReturn, useGrowthRail, useGrowthRailContext };
|
|
163
|
+
export { type AppUserType, type GrowthRailOptions, GrowthRailProvider, type NewUserExperience, ReferralDashboard, type ReferralLink, type ReferrerExperience, type ReferrerModalOptions, type ReferrerTriggerButton, type TrackReferralResponse, TriggerButton, type TriggerButtonPosition, type UseGrowthRailReturn, useGrowthRail };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var pe=Object.create;var $=Object.defineProperty;var ue=Object.getOwnPropertyDescriptor;var ge=Object.getOwnPropertyNames;var he=Object.getPrototypeOf,me=Object.prototype.hasOwnProperty;var we=(a,e,r)=>e in a?$(a,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):a[e]=r;var ye=(a,e)=>{for(var r in e)$(a,r,{get:e[r],enumerable:!0})},ne=(a,e,r,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let l of ge(e))!me.call(a,l)&&l!==r&&$(a,l,{get:()=>e[l],enumerable:!(o=ue(e,l))||o.enumerable});return a};var N=(a,e,r)=>(r=a!=null?pe(he(a)):{},ne(e||!a||!a.__esModule?$(r,"default",{value:a,enumerable:!0}):r,a)),be=a=>ne($({},"__esModule",{value:!0}),a);var P=(a,e,r)=>we(a,typeof e!="symbol"?e+"":e,r);var xe={};ye(xe,{APIClient:()=>j,GrowthRail:()=>g,GrowthRailProvider:()=>ke,ReferralDashboard:()=>re,StorageManager:()=>B,TriggerButton:()=>ie,useGrowthRail:()=>ve,useGrowthRailContext:()=>oe});module.exports=be(xe);var b=require("react-native"),ae=N(require("react-native-play-install-referrer"));var j=class{constructor(e){P(this,"baseUrl");P(this,"apiKey");let r=typeof process<"u"&&process.env?.ENV_BASE_URL;this.baseUrl=r||"https://api.growthrail.dev",this.apiKey=e.apiKey}async request(e,r,o){let l={"Content-Type":"application/json","X-GrowthRail-ProjectSecret":this.apiKey,Origin:this.baseUrl};try{let c=await fetch(`${this.baseUrl}${e}`,{method:r,headers:l,body:o?JSON.stringify(o):void 0});if(!c.ok){let p="";try{p=await c.text()}catch{}throw new Error(`GrowthRail API Error ${c.status} (${this.baseUrl}${e}): ${c.statusText} - ${p}`)}return c.json()}catch(c){throw console.error("GrowthRail SDK Error:",c),c}}async getNewUserExperience(){return this.request("/api/v1/sdk/new-user-experience","POST")}async initAppUser(e){return this.request("/api/v1/sdk/init-app-user","POST",{clientProvidedId:e})}async createReferralLink(e,r){return this.request("/api/v1/sdk/create-referral-link","POST",{referrerId:e,rewardEventName:r})}async trackReferral(e,r){return this.request("/api/v1/sdk/track-referral","POST",{referralCode:e,rewardEventName:r})}async trackRewardEvent(e,r,o){return this.request("/api/v1/sdk/track-reward-event","POST",{refereeId:e,referralTrackingId:r,eventName:o})}async checkDeferredDeepLink(e){return this.request("/api/v1/sdk/match-link","POST",{fingerprint:e})}};var H=N(require("@react-native-async-storage/async-storage")),Y={TRACKED_REFERRAL:"growth-rail-tracked-referral",IS_FIRST_LAUNCH:"growth-rail-is-first-launch"},B=class{static async setTrackedReferral(e){await H.default.setItem(Y.TRACKED_REFERRAL,e)}static async getTrackedReferral(){return await H.default.getItem(Y.TRACKED_REFERRAL)}static async isFirstLaunch(){return await H.default.getItem(Y.IS_FIRST_LAUNCH)===null?(await H.default.setItem(Y.IS_FIRST_LAUNCH,"false"),!0):!1}};var i=class i{constructor(){}static async init(e){i.initialized||(i.options=e,i.api=new j(e),i.initialized=!0,await i.handleInitialUrl(),await i.setupLinkListeners(),await i.checkDeferredReferral())}static async handleInitialUrl(){try{let e=await b.Linking.getInitialURL();e&&await i.handleDeepLink(e)}catch(e){console.error("GrowthRail: Error getting initial URL",e)}}static setupLinkListeners(){b.Linking.addEventListener("url",({url:e})=>{i.handleDeepLink(e)})}static async checkDeferredReferral(){await B.isFirstLaunch()&&(b.Platform.OS==="android"?await i.checkInstallReferrer():await i.checkDeferredDeepLinkFingerprint())}static checkInstallReferrer(){return new Promise(e=>{ae.default.getInstallReferrerInfo(async(r,o)=>{if(!o&&r&&r.installReferrer)try{let c=decodeURIComponent(r.installReferrer).match(/[?&]referralCode=([^&]+)/);if(c){let{referralTrackingId:p}=await i.trackReferral(c[1]);await B.setTrackedReferral(p),console.log("GrowthRail: Tracked referral via Install Referrer")}}catch(l){console.warn("GrowthRail: Failed to process install referrer",l)}else await i.checkDeferredDeepLinkFingerprint();e()})})}static getDeviceFingerprint(){let{width:e,height:r}=b.Dimensions.get("window"),o=Intl.DateTimeFormat().resolvedOptions().locale,l=b.PixelRatio.get(),c,p;if(b.Platform.OS==="android"){let m=b.Platform.constants;c=m.Model,p=m.Brand||m.Manufacturer}return{os:b.Platform.OS,platform:b.Platform.OS,osVersion:String(b.Platform.Version),screenWidth:e,screenHeight:r,timezoneOffsetInMinutes:String(new Date().getTimezoneOffset()),locale:o,language:o,deviceModel:c,deviceBrand:p,pixelRatio:l}}static async checkDeferredDeepLinkFingerprint(){try{let e=i.getDeviceFingerprint();console.log("GrowthRail executing deferred fingerprint check to API...");let{referralTrackingId:r}=await i.api.checkDeferredDeepLink(e);r&&(console.log("GrowthRail: Found deferred referral via fingerprinting",r),await B.setTrackedReferral(r))}catch(e){console.warn("GrowthRail: Fingerprint check failed",e)}}static async handleDeepLink(e){try{let r=new URL(e),o=r.searchParams.get("referralCode"),l=r.searchParams.get("rewardEventName");o&&(console.log("GrowthRail: Tracking referral from deep link",o),await i.trackReferral(o,l||void 0))}catch{let o=e.match(/[?&]referralCode=([^&]+)/);o&&await i.trackReferral(o[1])}}static ensureInitialized(){if(!i.initialized)throw new Error("GrowthRail.init() must be called before using the SDK")}static async initAppUser(e){i.ensureInitialized();let r=await i.api.initAppUser(e);return i.currentUser={...r,id:e},i.userReadyResolver&&i.userReadyResolver(i.currentUser),r}static async trackReferral(e,r){i.ensureInitialized();let o=await i.api.trackReferral(e,r);return await B.setTrackedReferral(o.referralTrackingId),o}static async trackRewardEvent(e){i.ensureInitialized();let r=i.currentUser?.id;if(!r)throw new Error("GrowthRail: User must be initialized before tracking a reward event.");let o=await B.getTrackedReferral();if(!o){console.warn("GrowthRail: No referral tracking ID found. Reward event not attributed.");return}return i.api.trackRewardEvent(r,o,e)}static async createReferralLink(e){i.ensureInitialized();let r=i.currentUser?.id;if(!r)throw new Error("GrowthRail: User must be initialized before creating a referral link.");if(i.referralObject)return i.referralObject;let o=await i.api.createReferralLink(r,e);return i.referralObject=o,o}static isInitialized(){return i.initialized}static getReferralLink(){if(!i.referralObject?.referralLink)throw new Error("GrowthRail: Referral Link not loaded or user not initialized");return i.referralObject.referralLink}static getReferralCode(){return i.referralObject?.referralCode||i.currentUser?.referralCode}static getUserId(){return i.currentUser?.id}static isUserReady(){return i.currentUser!==null}static getReferrerExperience(){return i.currentUser?.referrerExperience}static ensureUserReady(){return i.currentUser?Promise.resolve(i.currentUser):(i.userReadyPromise||(i.userReadyPromise=new Promise(e=>{i.userReadyResolver=e})),i.userReadyPromise)}static async getNewUserExperience(){return i.ensureInitialized(),i.api.getNewUserExperience()}};P(i,"api"),P(i,"options"),P(i,"currentUser",null),P(i,"referralObject",null),P(i,"initialized",!1),P(i,"userReadyPromise",null),P(i,"userReadyResolver",null);var g=i;var f=N(require("react"));var n=N(require("react")),t=require("react-native");var{width:se,height:te}=t.Dimensions.get("window"),re=({visible:a,options:e,onClose:r})=>{let[o,l]=(0,n.useState)(null),[c,p]=(0,n.useState)(!1),[m,T]=(0,n.useState)(!1),u=(0,n.useRef)(new t.Animated.Value(0)).current,d=(0,n.useRef)(new t.Animated.Value(0)).current,y=e?.title||"Invite Friends & Earn",R=e?.theme?.primaryColor||"#2563eb",G=e?.theme?.backgroundColor||"#ffffff",D=e?.theme?.tintColor||"#000000",X=e?.theme?.tintAlpha??.5,C=(e?.componentType||"modal")==="drawer",S=e?.position||"bottom-right",Q="#111827",M="#6b7280";(0,n.useEffect)(()=>{a?(o||Z(),t.Animated.parallel([t.Animated.timing(d,{toValue:1,duration:300,useNativeDriver:!0}),t.Animated.spring(u,{toValue:1,useNativeDriver:!0,tension:50,friction:8})]).start()):(u.setValue(0),d.setValue(0))},[a]);let L=()=>{t.Animated.parallel([t.Animated.timing(d,{toValue:0,duration:250,useNativeDriver:!0}),t.Animated.timing(u,{toValue:0,duration:250,useNativeDriver:!0})]).start(()=>{r()})},Z=async()=>{p(!0);try{if(g.isUserReady()){let A=await g.createReferralLink();l(A.referralLink)}}catch(A){console.error("GrowthRail: Failed to load referral link",A)}finally{p(!1)}},_=()=>{o&&(t.Clipboard.setString(o),T(!0),setTimeout(()=>T(!1),2e3))},I=A=>{if(!o)return;let O="",F=encodeURIComponent(o),ee=encodeURIComponent("Check this out!");switch(A){case"twitter":O=`https://twitter.com/intent/tweet?url=${F}&text=${ee}`;break;case"facebook":O=`https://www.facebook.com/sharer/sharer.php?u=${F}`;break;case"linkedin":O=`https://www.linkedin.com/sharing/share-offsite/?url=${F}`;break;case"whatsapp":O=`whatsapp://send?text=${ee}%20${F}`;break;case"email":O=`mailto:?subject=Check this out&body=${ee}%20${F}`;break}O&&t.Linking.openURL(O).catch(()=>{})},k=()=>{if(D.startsWith("#")){let A=parseInt(D.slice(1,3),16),O=parseInt(D.slice(3,5),16),F=parseInt(D.slice(5,7),16);return`rgba(${A}, ${O}, ${F}, ${X})`}return`rgba(0, 0, 0, ${X})`},W=[];C?S.includes("right")?W=[{translateX:u.interpolate({inputRange:[0,1],outputRange:[se,0]})}]:S.includes("left")?W=[{translateX:u.interpolate({inputRange:[0,1],outputRange:[-se,0]})}]:W=[{translateY:u.interpolate({inputRange:[0,1],outputRange:[te,0]})}]:W=[{scale:u.interpolate({inputRange:[0,1],outputRange:[.9,1]})},{translateY:u.interpolate({inputRange:[0,1],outputRange:[20,0]})}];let de=S.includes("top"),V=S.includes("right"),z=S.includes("left"),fe=C?{position:"absolute",...de?{top:100}:{bottom:100},...V?{right:0}:z?{left:0}:{left:0,right:0},width:V||z?"85%":"100%",maxHeight:V||z?te-200:"80%"}:{};return n.default.createElement(t.Modal,{visible:a,transparent:!0,animationType:"none",onRequestClose:L},n.default.createElement(t.View,{style:s.fullScreen},n.default.createElement(t.Animated.View,{style:[s.overlay,{backgroundColor:k(),opacity:d}]},n.default.createElement(t.TouchableOpacity,{style:s.fullScreen,activeOpacity:1,onPress:L})),n.default.createElement(t.Animated.View,{style:[C?fe:s.centeredModalContainer,{backgroundColor:G,transform:W},C&&V&&{borderTopLeftRadius:24,borderBottomLeftRadius:24},C&&z&&{borderTopRightRadius:24,borderBottomRightRadius:24},C&&!V&&!z&&S.includes("bottom")&&{borderTopLeftRadius:24,borderTopRightRadius:24},C&&!V&&!z&&S.includes("top")&&{borderBottomLeftRadius:24,borderBottomRightRadius:24},!C&&{borderRadius:24,opacity:u}]},n.default.createElement(t.View,{style:s.contentWrapper},C&&!V&&!z&&S.includes("bottom")&&n.default.createElement(t.View,{style:s.drawerHandle}),n.default.createElement(t.TouchableOpacity,{style:s.closeBtn,onPress:L},n.default.createElement(t.Text,{style:s.closeIcon},"\u2715")),n.default.createElement(t.ScrollView,{contentContainerStyle:s.scrollContent,showsVerticalScrollIndicator:!1},n.default.createElement(t.View,{style:s.header},n.default.createElement(t.Text,{style:s.iconLg},"\u{1F381}"),n.default.createElement(t.Text,{style:[s.title,{color:Q}]},y),n.default.createElement(t.Text,{style:[s.subtitle,{color:M}]},e?.description||"Share your unique link and earn rewards for every friend who signs up.")),g.isUserReady()?c?n.default.createElement(t.ActivityIndicator,{size:"large",color:R,style:s.loader}):n.default.createElement(t.View,{style:s.mainContent},n.default.createElement(t.Text,{style:s.label},"YOUR UNIQUE LINK"),n.default.createElement(t.View,{style:s.inputGroup},n.default.createElement(t.Text,{numberOfLines:1,style:s.input},o||"Initializing..."),n.default.createElement(t.TouchableOpacity,{style:[s.copyBtn,{backgroundColor:m?"#10b981":R}],onPress:_},n.default.createElement(t.Text,{style:s.copyBtnText},m?"Copied!":"Copy"))),n.default.createElement(t.View,{style:s.shareLabelContainer},n.default.createElement(t.View,{style:s.divider}),n.default.createElement(t.Text,{style:s.shareLabel},"Share via"),n.default.createElement(t.View,{style:s.divider})),n.default.createElement(t.View,{style:s.socialContainer},n.default.createElement(K,{platform:"twitter",color:"#000000",onPress:()=>I("twitter"),icon:"\u{1D54F}"}),n.default.createElement(K,{platform:"facebook",color:"#1877F2",onPress:()=>I("facebook"),icon:"f"}),n.default.createElement(K,{platform:"linkedin",color:"#0A66C2",onPress:()=>I("linkedin"),icon:"in"}),n.default.createElement(K,{platform:"whatsapp",color:"#25D366",onPress:()=>I("whatsapp"),icon:"W"}),n.default.createElement(K,{platform:"email",color:"#888888",onPress:()=>I("email"),icon:"\u2709"}))):n.default.createElement(t.View,{style:s.loadingBox},n.default.createElement(t.Text,{style:{color:M,textAlign:"center"}},"Please log in to view your referral dashboard.")),n.default.createElement(t.View,{style:s.footer},n.default.createElement(t.Text,{style:s.poweredBy},"Powered by ",n.default.createElement(t.Text,{style:s.brand,onPress:()=>t.Linking.openURL("https://growthrail.com")},"Growth Rail"))))))))},K=({color:a,onPress:e,icon:r})=>n.default.createElement(t.TouchableOpacity,{style:[s.socialBtn,{borderColor:"#e5e7eb"}],onPress:e},n.default.createElement(t.Text,{style:[s.socialIcon,{color:a}]},r)),s=t.StyleSheet.create({fullScreen:{flex:1},overlay:{...t.StyleSheet.absoluteFillObject},centeredModalContainer:{width:"90%",maxWidth:400,alignSelf:"center",marginTop:te*.15,overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:20},shadowOpacity:.25,shadowRadius:30,elevation:20},contentWrapper:{paddingTop:t.Platform.OS==="ios"?20:0},drawerHandle:{width:40,height:4,backgroundColor:"#e5e7eb",borderRadius:2,alignSelf:"center",marginTop:12},scrollContent:{padding:32,alignItems:"center"},closeBtn:{position:"absolute",top:20,right:20,zIndex:10,width:32,height:32,borderRadius:16,backgroundColor:"#f3f4f6",justifyContent:"center",alignItems:"center"},closeIcon:{fontSize:14,color:"#9ca3af"},header:{alignItems:"center",marginBottom:28},iconLg:{fontSize:32,marginBottom:12},title:{fontSize:22,fontWeight:"700",letterSpacing:-.5,marginBottom:8,textAlign:"center"},subtitle:{fontSize:14,lineHeight:20,textAlign:"center",paddingHorizontal:10},loadingBox:{padding:16,backgroundColor:"#f9fafb",borderRadius:12,width:"100%",alignItems:"center"},loader:{marginVertical:20},mainContent:{width:"100%"},label:{fontSize:12,fontWeight:"600",color:"#6b7280",marginBottom:8,letterSpacing:.5},inputGroup:{flexDirection:"row",alignItems:"center",backgroundColor:"#f9fafb",borderWidth:1,borderColor:"#e5e7eb",borderRadius:12,padding:6,marginBottom:24},input:{flex:1,paddingHorizontal:12,fontSize:14,color:"#111827",fontFamily:t.Platform.OS==="ios"?"Menlo":"monospace"},copyBtn:{paddingVertical:8,paddingHorizontal:16,borderRadius:8},copyBtnText:{color:"#fff",fontSize:13,fontWeight:"600"},shareLabelContainer:{flexDirection:"row",alignItems:"center",marginBottom:16},divider:{flex:1,height:1,backgroundColor:"#e5e7eb"},shareLabel:{marginHorizontal:12,fontSize:13,fontWeight:"500",color:"#6b7280"},socialContainer:{flexDirection:"row",justifyContent:"center",gap:12},socialBtn:{width:44,height:44,borderRadius:22,backgroundColor:"#fff",borderWidth:1,justifyContent:"center",alignItems:"center"},socialIcon:{fontSize:18,fontWeight:"bold"},footer:{marginTop:32,alignItems:"center"},poweredBy:{fontSize:11,color:"#9ca3af"},brand:{fontWeight:"600",textDecorationLine:"underline"}});var v=N(require("react")),w=require("react-native"),ie=({onPress:a,options:e})=>{let r=e?.modal?.theme?.primaryColor||"#2563eb",o=e?.trigger?.position||"bottom-right",c=(e?.trigger?.displayMode||"floating")==="edge",p=o.includes("right"),m=o.includes("top"),T=(0,v.useRef)(new w.Animated.Value(-1)).current;(0,v.useEffect)(()=>{let R=()=>{T.setValue(-1),w.Animated.timing(T,{toValue:2,duration:3e3,easing:w.Easing.linear,useNativeDriver:!0}).start(()=>{setTimeout(R,1e3)})};R()},[]);let u=T.interpolate({inputRange:[-1,2],outputRange:c?[-50,100]:[-60,120]}),d={"bottom-right":{bottom:100,right:0},"bottom-left":{bottom:100,left:0},"top-right":{top:100,right:0},"top-left":{top:100,left:0}};c||(d["bottom-right"]={bottom:30,right:20},d["bottom-left"]={bottom:30,left:20},d["top-right"]={top:60,right:20},d["top-left"]={top:60,left:20});let y=()=>v.default.createElement(w.View,{style:U.iconContainer},v.default.createElement(w.View,{style:U.giftBody},v.default.createElement(w.View,{style:U.giftLid}),v.default.createElement(w.View,{style:U.giftRibbonV}),v.default.createElement(w.View,{style:U.giftRibbonH})));return v.default.createElement(w.TouchableOpacity,{style:[c?U.edgeButton:U.floatingButton,{backgroundColor:r},d[o],c&&(p?U.edgeRight:U.edgeLeft)],onPress:a,activeOpacity:.9},v.default.createElement(w.View,{style:U.content},y()),v.default.createElement(w.Animated.View,{style:[U.shimmer,{transform:[{translateX:u},{skewX:"-15deg"}]}]}))},U=w.StyleSheet.create({floatingButton:{position:"absolute",width:60,height:60,borderRadius:30,justifyContent:"center",alignItems:"center",overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:8},shadowOpacity:.2,shadowRadius:12,elevation:8,zIndex:2147483646},edgeButton:{position:"absolute",width:50,height:50,justifyContent:"center",alignItems:"center",overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:4},shadowOpacity:.1,shadowRadius:8,elevation:4,zIndex:2147483646},edgeRight:{borderTopLeftRadius:8,borderBottomLeftRadius:8,paddingLeft:4},edgeLeft:{borderTopRightRadius:8,borderBottomRightRadius:8,paddingRight:4},content:{justifyContent:"center",alignItems:"center"},iconContainer:{width:24,height:24,justifyContent:"center",alignItems:"center"},giftBody:{width:16,height:14,backgroundColor:"rgba(255, 255, 255, 0.9)",borderRadius:1.5,marginTop:3,position:"relative"},giftLid:{position:"absolute",top:-3,left:-1.5,width:19,height:3,backgroundColor:"#fff",borderRadius:.5},giftRibbonV:{position:"absolute",top:-3,left:7,width:2.5,height:17,backgroundColor:"rgba(0, 0, 0, 0.1)"},giftRibbonH:{position:"absolute",top:5,left:0,width:16,height:2,backgroundColor:"rgba(0, 0, 0, 0.05)"},shimmer:{position:"absolute",top:0,left:0,width:50,height:"100%",backgroundColor:"rgba(255, 255, 255, 0.25)"}});var x=N(require("react")),h=require("react-native"),{width:Re}=h.Dimensions.get("window"),le=({visible:a,options:e,onClose:r})=>{let o=(0,x.useRef)(new h.Animated.Value(0)).current,[l,c]=(0,x.useState)(a),p=e.position.includes("bottom")?"bottom":"top",m=e.position.includes("left")?"left":e.position.includes("right")?"right":"center";if((0,x.useEffect)(()=>{a?(c(!0),h.Animated.spring(o,{toValue:1,useNativeDriver:!0,tension:50,friction:8}).start()):h.Animated.timing(o,{toValue:0,duration:250,useNativeDriver:!0}).start(()=>{c(!1)})},[a]),!l)return null;let T=o.interpolate({inputRange:[0,1],outputRange:[p==="top"?-100:100,0]}),u=o.interpolate({inputRange:[0,1],outputRange:[0,1]}),d={position:"absolute",[p]:h.Platform.OS==="ios"?60:40,zIndex:9999};return m==="center"?(d.left=20,d.right=20,d.alignItems="center"):d[m]=20,x.default.createElement(h.Animated.View,{style:[d,{transform:[{translateY:T}],opacity:u}]},x.default.createElement(h.View,{style:[q.banner,{backgroundColor:e.themeColor||"#2563eb"}]},x.default.createElement(h.Text,{style:q.icon},"\u{1F381}"),x.default.createElement(h.Text,{style:q.text},e.text),x.default.createElement(h.TouchableOpacity,{onPress:r,style:q.closeBtn},x.default.createElement(h.Text,{style:q.closeIcon},"\u2715"))))},q=h.StyleSheet.create({banner:{flexDirection:"row",alignItems:"center",padding:12,paddingHorizontal:16,borderRadius:12,shadowColor:"#000",shadowOffset:{width:0,height:4},shadowOpacity:.15,shadowRadius:10,elevation:5,maxWidth:Re-40},icon:{fontSize:18,marginRight:10},text:{color:"#fff",fontSize:14,fontWeight:"600",flex:1},closeBtn:{marginLeft:10,padding:4},closeIcon:{color:"rgba(255, 255, 255, 0.8)",fontSize:14,fontWeight:"bold"}});var ce=(0,f.createContext)(void 0),ke=({children:a,userId:e,...r})=>{let[o,l]=(0,f.useState)(g.isInitialized()),[c,p]=(0,f.useState)(g.isUserReady()),m=(0,f.useRef)(!1),[T,u]=(0,f.useState)(!1),[d,y]=(0,f.useState)(),[R,G]=(0,f.useState)(!1),[D,X]=(0,f.useState)(),[J,C]=(0,f.useState)(!1),[S,Q]=(0,f.useState)();(0,f.useEffect)(()=>{if(m.current)return;m.current=!0,(async()=>{if(await g.init(r),e)try{let k=await g.initAppUser(e);p(!0),k.referrerExperience?.trigger?.show&&G(!0)}catch(k){console.error("GrowthRail: User init failed",k)}try{let k=await g.getNewUserExperience();k.banner?.show&&(Q(k.banner),C(!0))}catch{}l(!0)})()},[]),(0,f.useEffect)(()=>{(async()=>{if(m.current&&e&&g.getUserId()!==e)try{let k=await g.initAppUser(e);p(!0),k.referrerExperience?.trigger?.show&&G(!0)}catch(k){console.error("GrowthRail: User init failed",k)}})()},[e]);let M={isInitialized:o,isUserReady:c,showDashboard:I=>{y(I),u(!0)},hideDashboard:()=>u(!1),showFloatingButton:I=>{X({trigger:I}),G(!0)},hideFloatingButton:()=>G(!1)};if(!o)return null;let L=g.getReferrerExperience(),Z={...L?.modal,...d,position:L?.trigger?.position||d?.position||"bottom-right",theme:{...L?.modal?.theme||{},...d?.theme||{}}},_={...L,...D,trigger:{...L?.trigger||{},...D?.trigger||{}}};return f.default.createElement(ce.Provider,{value:M},a,f.default.createElement(re,{visible:T,options:Z,onClose:()=>u(!1)}),R&&f.default.createElement(ie,{options:_,onPress:()=>M.showDashboard()}),J&&f.default.createElement(le,{visible:J,options:S,onClose:()=>C(!1)}))},oe=()=>{let a=(0,f.useContext)(ce);if(!a)throw new Error("useGrowthRail must be used within a GrowthRailProvider");return a};var E=require("react");var ve=()=>{let[a,e]=(0,E.useState)(!1),[r,o]=(0,E.useState)(null),l=oe(),c=(0,E.useCallback)(async d=>{e(!0),o(null);try{return await g.initAppUser(d)}catch(y){let R=y instanceof Error?y:new Error(String(y));throw o(R),R}finally{e(!1)}},[]),p=(0,E.useCallback)(async d=>{e(!0),o(null);try{await g.trackRewardEvent(d)}catch(y){let R=y instanceof Error?y:new Error(String(y));throw o(R),R}finally{e(!1)}},[]),m=(0,E.useCallback)(d=>{l.showDashboard(d)},[l]),T=(0,E.useCallback)(d=>{l.showFloatingButton(d)},[l]),u=(0,E.useCallback)(()=>{l.hideFloatingButton()},[l]);return{initUser:c,trackReward:p,showReferralDashboard:m,showFloatingButton:T,hideFloatingButton:u,isLoading:a,isInitialized:l.isInitialized,error:r}};0&&(module.exports={APIClient,GrowthRail,GrowthRailProvider,ReferralDashboard,StorageManager,TriggerButton,useGrowthRail,useGrowthRailContext});
|
|
1
|
+
"use strict";var Ce=Object.create;var _=Object.defineProperty;var ke=Object.getOwnPropertyDescriptor;var Te=Object.getOwnPropertyNames;var xe=Object.getPrototypeOf,ve=Object.prototype.hasOwnProperty;var Le=(o,e,a)=>e in o?_(o,e,{enumerable:!0,configurable:!0,writable:!0,value:a}):o[e]=a;var Ie=(o,e)=>{for(var a in e)_(o,a,{get:e[a],enumerable:!0})},ue=(o,e,a,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let l of Te(e))!ve.call(o,l)&&l!==a&&_(o,l,{get:()=>e[l],enumerable:!(s=ke(e,l))||s.enumerable});return o};var W=(o,e,a)=>(a=o!=null?Ce(xe(o)):{},ue(e||!o||!o.__esModule?_(a,"default",{value:o,enumerable:!0}):a,o)),Se=o=>ue(_({},"__esModule",{value:!0}),o);var de=(o,e,a)=>Le(o,typeof e!="symbol"?e+"":e,a);var Be={};Ie(Be,{GrowthRailProvider:()=>be,ReferralDashboard:()=>te,TriggerButton:()=>oe,useGrowthRail:()=>ye});module.exports=Se(Be);var n=W(require("react")),C=require("react-native"),we=W(require("react-native-play-install-referrer"));var Z=class{constructor(e){de(this,"baseUrl");de(this,"projectSecretKey");let a=typeof process<"u"&&process.env?.ENV_BASE_URL;this.baseUrl=a||"https://api.growthrail.dev",this.projectSecretKey=e.projectSecretKey}async request(e,a,s){let l={"Content-Type":"application/json","X-GrowthRail-ProjectSecret":this.projectSecretKey,Origin:this.baseUrl};try{let f=await fetch(`${this.baseUrl}${e}`,{method:a,headers:l,body:s?JSON.stringify(s):void 0});if(!f.ok){let k="";try{k=await f.text()}catch{}throw new Error(`GrowthRail API Error ${f.status} (${this.baseUrl}${e}): ${f.statusText} - ${k}`)}return f.json()}catch(f){throw console.error("GrowthRail SDK Error:",f),f}}async getNewUserExperience(){return this.request("/api/v1/sdk/new-user-experience","POST")}async initAppUser(e){return this.request("/api/v1/sdk/init-app-user","POST",{clientProvidedId:e})}async trackReferral(e,a){return this.request("/api/v1/sdk/track-referral","POST",{referralCode:e,rewardEventName:a})}async trackRewardEvent(e,a,s){return this.request("/api/v1/sdk/track-reward-event","POST",{refereeId:e,referralTrackingId:a,eventName:s})}async checkDeferredDeepLink(e){return this.request("/api/v1/sdk/match-link","POST",{fingerprint:e})}};var K=W(require("@react-native-async-storage/async-storage")),ee={TRACKED_REFERRAL:"growth-rail-tracked-referral",IS_FIRST_LAUNCH:"growth-rail-is-first-launch"},D=class{static async setTrackedReferral(e){await K.default.setItem(ee.TRACKED_REFERRAL,e)}static async getTrackedReferral(){return await K.default.getItem(ee.TRACKED_REFERRAL)}static async isFirstLaunch(){return await K.default.getItem(ee.IS_FIRST_LAUNCH)===null?(await K.default.setItem(ee.IS_FIRST_LAUNCH,"false"),!0):!1}};var r=W(require("react")),t=require("react-native");var{width:pe,height:fe}=t.Dimensions.get("window"),te=({visible:o,options:e,onClose:a})=>{let s=re(),[l,f]=(0,r.useState)(null),[k,d]=(0,r.useState)(!1),[p,m]=(0,r.useState)(!1),g=(0,r.useRef)(new t.Animated.Value(0)).current,T=(0,r.useRef)(new t.Animated.Value(0)).current,z=e?.title||"Invite Friends & Earn",B=e?.theme?.primaryColor||"#2563eb",M=e?.theme?.backgroundColor||"#ffffff",ie=e?.theme?.tintColor||"#000000",ne=e?.theme?.tintAlpha??.5,v=(e?.componentType||"modal")==="drawer",E=e?.position||"bottom-right",Y="#111827",j="#6b7280";(0,r.useEffect)(()=>{o?(l||ae(),t.Animated.parallel([t.Animated.timing(T,{toValue:1,duration:300,useNativeDriver:!0}),t.Animated.spring(g,{toValue:1,useNativeDriver:!0,tension:50,friction:8})]).start()):(g.setValue(0),T.setValue(0))},[o]);let $=()=>{t.Animated.parallel([t.Animated.timing(T,{toValue:0,duration:250,useNativeDriver:!0}),t.Animated.timing(g,{toValue:0,duration:250,useNativeDriver:!0})]).start(()=>{a()})},ae=async()=>{d(!0);try{if(s.isUserReady){let G=await s.getReferralLink();f(G||null)}}catch(G){console.error("GrowthRail: Failed to load referral link",G)}finally{d(!1)}},J=()=>{l&&(t.Clipboard.setString(l),m(!0),setTimeout(()=>m(!1),2e3))},V=G=>{if(!l)return;let O="",I=encodeURIComponent(l),H=encodeURIComponent("Check this out!");switch(G){case"twitter":O=`https://twitter.com/intent/tweet?url=${I}&text=${H}`;break;case"facebook":O=`https://www.facebook.com/sharer/sharer.php?u=${I}`;break;case"linkedin":O=`https://www.linkedin.com/sharing/share-offsite/?url=${I}`;break;case"whatsapp":O=`whatsapp://send?text=${H}%20${I}`;break;case"email":O=`mailto:?subject=Check this out&body=${H}%20${I}`;break}O&&t.Linking.openURL(O).catch(()=>{})},Q=()=>ie||"#000000",U=[];v?E.includes("right")?U=[{translateX:g.interpolate({inputRange:[0,1],outputRange:[pe,0]})}]:E.includes("left")?U=[{translateX:g.interpolate({inputRange:[0,1],outputRange:[-pe,0]})}]:U=[{translateY:g.interpolate({inputRange:[0,1],outputRange:[fe,0]})}]:U=[{scale:g.interpolate({inputRange:[0,1],outputRange:[.9,1]})},{translateY:g.interpolate({inputRange:[0,1],outputRange:[20,0]})}];let se=E.includes("top"),L=E.includes("right"),A=E.includes("left"),le=v?{position:"absolute",...se?{top:100}:{bottom:100},...L?{right:0}:A?{left:0}:{left:0,right:0},width:L||A?"85%":"100%",maxHeight:L||A?fe-200:"80%"}:{};return r.default.createElement(t.Modal,{visible:o,transparent:!0,animationType:"none",onRequestClose:$},r.default.createElement(t.View,{style:i.fullScreen},r.default.createElement(t.Animated.View,{style:[i.overlay,{backgroundColor:Q(),opacity:T.interpolate({inputRange:[0,1],outputRange:[0,ne]})}]},r.default.createElement(t.TouchableOpacity,{style:i.fullScreen,activeOpacity:1,onPress:$})),r.default.createElement(t.Animated.View,{style:[v?le:i.centeredModalContainer,{backgroundColor:M,transform:U},v&&L&&{borderTopLeftRadius:24,borderBottomLeftRadius:24},v&&A&&{borderTopRightRadius:24,borderBottomRightRadius:24},v&&!L&&!A&&E.includes("bottom")&&{borderTopLeftRadius:24,borderTopRightRadius:24},v&&!L&&!A&&E.includes("top")&&{borderBottomLeftRadius:24,borderBottomRightRadius:24},!v&&{borderRadius:24,opacity:g}]},r.default.createElement(t.View,{style:i.contentWrapper},v&&!L&&!A&&E.includes("bottom")&&r.default.createElement(t.View,{style:i.drawerHandle}),r.default.createElement(t.TouchableOpacity,{style:i.closeBtn,onPress:$},r.default.createElement(t.Text,{style:i.closeIcon},"\u2715")),r.default.createElement(t.ScrollView,{contentContainerStyle:i.scrollContent,showsVerticalScrollIndicator:!1},r.default.createElement(t.View,{style:i.header},r.default.createElement(t.View,{style:i.iconLgContainer},r.default.createElement(t.View,{style:i.bowContainerLg},r.default.createElement(t.View,{style:[i.bowLoopLg,i.bowLeftLg,{borderColor:B}]}),r.default.createElement(t.View,{style:[i.bowLoopLg,i.bowRightLg,{borderColor:B}]})),r.default.createElement(t.View,{style:[i.giftLidLg,{backgroundColor:B}]}),r.default.createElement(t.View,{style:[i.giftBodyLg,{borderColor:B}]},r.default.createElement(t.View,{style:[i.ribbonVerticalLg,{backgroundColor:"#fff",opacity:.3}]}))),r.default.createElement(t.Text,{style:[i.title,{color:Y}]},z),r.default.createElement(t.Text,{style:[i.subtitle,{color:j}]},e?.description||"Share your unique link and earn rewards for every friend who signs up.")),s.isUserReady?k?r.default.createElement(t.ActivityIndicator,{size:"large",color:B,style:i.loader}):r.default.createElement(t.View,{style:i.mainContent},r.default.createElement(t.Text,{style:i.label},"YOUR UNIQUE LINK"),r.default.createElement(t.View,{style:i.inputGroup},r.default.createElement(t.Text,{numberOfLines:1,style:i.input},l||"Initializing..."),r.default.createElement(t.TouchableOpacity,{style:[i.copyBtn,{backgroundColor:p?"#10b981":B}],onPress:J},r.default.createElement(t.Text,{style:i.copyBtnText},p?"Copied!":"Copy"))),r.default.createElement(t.View,{style:i.shareLabelContainer},r.default.createElement(t.View,{style:i.divider}),r.default.createElement(t.Text,{style:i.shareLabel},"Share via"),r.default.createElement(t.View,{style:i.divider})),r.default.createElement(t.View,{style:i.socialContainer},r.default.createElement(q,{platform:"twitter",color:"#000000",onPress:()=>V("twitter"),icon:"\u{1D54F}"}),r.default.createElement(q,{platform:"facebook",color:"#1877F2",onPress:()=>V("facebook"),icon:"f"}),r.default.createElement(q,{platform:"linkedin",color:"#0A66C2",onPress:()=>V("linkedin"),icon:"in"}),r.default.createElement(q,{platform:"whatsapp",color:"#25D366",onPress:()=>V("whatsapp"),icon:"W"}),r.default.createElement(q,{platform:"email",color:"#888888",onPress:()=>V("email"),icon:"\u2709"}))):r.default.createElement(t.View,{style:i.loadingBox},r.default.createElement(t.Text,{style:{color:j,textAlign:"center"}},"Please log in to view your referral dashboard.")),r.default.createElement(t.View,{style:i.footer},r.default.createElement(t.Text,{style:i.poweredBy},"Powered by ",r.default.createElement(t.Text,{style:i.brand,onPress:()=>t.Linking.openURL("https://growthrail.com")},"Growth Rail"))))))))},q=({color:o,onPress:e,icon:a})=>r.default.createElement(t.TouchableOpacity,{style:[i.socialBtn,{borderColor:"#e5e7eb"}],onPress:e},r.default.createElement(t.Text,{style:[i.socialIcon,{color:o}]},a)),i=t.StyleSheet.create({fullScreen:{flex:1},overlay:{...t.StyleSheet.absoluteFillObject},centeredModalContainer:{width:"90%",maxWidth:400,alignSelf:"center",marginTop:fe*.15,overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:20},shadowOpacity:.25,shadowRadius:30,elevation:20},contentWrapper:{paddingTop:t.Platform.OS==="ios"?20:0},drawerHandle:{width:40,height:4,backgroundColor:"#e5e7eb",borderRadius:2,alignSelf:"center",marginTop:12},scrollContent:{padding:32,alignItems:"center"},closeBtn:{position:"absolute",top:20,right:20,zIndex:10,width:32,height:32,borderRadius:16,backgroundColor:"#f3f4f6",justifyContent:"center",alignItems:"center"},closeIcon:{fontSize:14,color:"#9ca3af"},header:{alignItems:"center",marginBottom:28,width:"100%"},socialIcon:{fontSize:18,fontWeight:"bold"},title:{fontSize:22,fontWeight:"700",letterSpacing:-.5,marginBottom:8,textAlign:"center"},subtitle:{fontSize:14,lineHeight:20,textAlign:"center",paddingHorizontal:10},loadingBox:{padding:16,backgroundColor:"#f9fafb",borderRadius:12,width:"100%",alignItems:"center",borderWidth:1,borderColor:"#e5e7eb",marginTop:20},loader:{marginVertical:20},mainContent:{width:"100%"},label:{fontSize:12,fontWeight:"600",color:"#6b7280",marginBottom:8,letterSpacing:.5},inputGroup:{flexDirection:"row",alignItems:"center",backgroundColor:"#f9fafb",borderWidth:1,borderColor:"#e5e7eb",borderRadius:12,padding:6,marginBottom:24},input:{flex:1,paddingHorizontal:12,fontSize:14,color:"#111827",fontFamily:t.Platform.OS==="ios"?"Menlo":"monospace"},copyBtn:{paddingVertical:8,paddingHorizontal:16,borderRadius:8,justifyContent:"center",alignItems:"center"},copyBtnText:{color:"#fff",fontSize:13,fontWeight:"600"},shareLabelContainer:{flexDirection:"row",alignItems:"center",marginBottom:16,marginTop:8},divider:{flex:1,height:1,backgroundColor:"#e5e7eb"},shareLabel:{marginHorizontal:12,fontSize:13,fontWeight:"500",color:"#6b7280"},socialContainer:{flexDirection:"row",justifyContent:"center",gap:12},socialBtn:{width:44,height:44,borderRadius:22,backgroundColor:"#fff",borderWidth:1,justifyContent:"center",alignItems:"center"},iconLgContainer:{width:60,height:60,justifyContent:"center",alignItems:"center",marginBottom:16},bowContainerLg:{flexDirection:"row",position:"absolute",top:2,zIndex:2},bowLoopLg:{width:20,height:16,borderWidth:3,borderColor:"#e5e7eb",borderRadius:10},bowLeftLg:{marginRight:-2,transform:[{rotate:"-15deg"}]},bowRightLg:{marginLeft:-2,transform:[{rotate:"15deg"}]},giftLidLg:{width:44,height:10,backgroundColor:"#f3f4f6",borderRadius:2,marginTop:12,zIndex:3},giftBodyLg:{width:36,height:24,borderWidth:3,borderTopWidth:0,borderBottomLeftRadius:4,borderBottomRightRadius:4,justifyContent:"center",alignItems:"center",marginTop:-2},ribbonVerticalLg:{width:4,height:"100%",opacity:.1},footer:{marginTop:32,alignItems:"center"},poweredBy:{fontSize:11,color:"#9ca3af"},brand:{fontWeight:"600",textDecorationLine:"underline"}});var R=W(require("react")),h=require("react-native"),oe=({onPress:o,options:e})=>{let a=e?.modal?.theme?.primaryColor||"#2563eb",s=e?.trigger?.position||"bottom-right",f=(e?.trigger?.displayMode||"floating")==="edge",k=s.includes("right"),d=s.includes("top"),p=(0,R.useRef)(new h.Animated.Value(-1)).current;(0,R.useEffect)(()=>{let z=()=>{p.setValue(-1),h.Animated.timing(p,{toValue:2,duration:3e3,easing:h.Easing.linear,useNativeDriver:!0}).start(()=>{setTimeout(z,1e3)})};z()},[]);let m=p.interpolate({inputRange:[-1,2],outputRange:f?[-50,100]:[-60,120]}),g={"bottom-right":{bottom:100,right:0},"bottom-left":{bottom:100,left:0},"top-right":{top:100,right:0},"top-left":{top:100,left:0}};f||(g["bottom-right"]={bottom:30,right:20},g["bottom-left"]={bottom:30,left:20},g["top-right"]={top:60,right:20},g["top-left"]={top:60,left:20});let T=()=>R.default.createElement(h.View,{style:y.iconContainer},R.default.createElement(h.View,{style:y.bowContainer},R.default.createElement(h.View,{style:[y.bowLoop,y.bowLeft]}),R.default.createElement(h.View,{style:[y.bowLoop,y.bowRight]})),R.default.createElement(h.View,{style:y.giftLid}),R.default.createElement(h.View,{style:y.giftBody},R.default.createElement(h.View,{style:y.ribbonVertical})));return R.default.createElement(h.TouchableOpacity,{style:[f?y.edgeButton:y.floatingButton,{backgroundColor:a},g[s],f&&(k?y.edgeRight:y.edgeLeft)],onPress:o,activeOpacity:.9},R.default.createElement(h.View,{style:y.content},T()),R.default.createElement(h.Animated.View,{style:[y.shimmer,{transform:[{translateX:m},{skewX:"-15deg"}]}]}))},y=h.StyleSheet.create({floatingButton:{position:"absolute",width:60,height:60,borderRadius:30,justifyContent:"center",alignItems:"center",overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:8},shadowOpacity:.2,shadowRadius:12,elevation:8,zIndex:2147483646},edgeButton:{position:"absolute",width:50,height:50,justifyContent:"center",alignItems:"center",overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:4},shadowOpacity:.1,shadowRadius:8,elevation:4,zIndex:2147483646},edgeRight:{borderTopLeftRadius:8,borderBottomLeftRadius:8,paddingLeft:4},edgeLeft:{borderTopRightRadius:8,borderBottomRightRadius:8,paddingRight:4},content:{justifyContent:"center",alignItems:"center"},iconContainer:{width:28,height:28,justifyContent:"center",alignItems:"center"},bowContainer:{flexDirection:"row",position:"absolute",top:0,zIndex:2},bowLoop:{width:10,height:8,borderWidth:2,borderColor:"#fff",borderRadius:5},bowLeft:{marginRight:-1,transform:[{rotate:"-15deg"}]},bowRight:{marginLeft:-1,transform:[{rotate:"15deg"}]},giftLid:{width:22,height:5,backgroundColor:"#fff",borderRadius:1,marginTop:6,zIndex:3},giftBody:{width:18,height:12,borderWidth:2,borderColor:"#fff",borderTopWidth:0,borderBottomLeftRadius:2,borderBottomRightRadius:2,justifyContent:"center",alignItems:"center",marginTop:-1},ribbonVertical:{width:2,height:"100%",backgroundColor:"#fff",opacity:.8},shimmer:{position:"absolute",top:0,left:0,width:50,height:"100%",backgroundColor:"rgba(255, 255, 255, 0.25)"}});var x=W(require("react")),w=require("react-native"),{width:Pe}=w.Dimensions.get("window"),he=({visible:o,options:e,onClose:a})=>{let s=(0,x.useRef)(new w.Animated.Value(0)).current,[l,f]=(0,x.useState)(o),k=e.position.includes("bottom")?"bottom":"top",d=e.position.includes("left")?"left":e.position.includes("right")?"right":"center";if((0,x.useEffect)(()=>{o?(f(!0),w.Animated.spring(s,{toValue:1,useNativeDriver:!0,tension:50,friction:8}).start()):w.Animated.timing(s,{toValue:0,duration:250,useNativeDriver:!0}).start(()=>{f(!1)})},[o]),!l)return null;let p=s.interpolate({inputRange:[0,1],outputRange:[k==="top"?-100:100,0]}),m=s.interpolate({inputRange:[0,1],outputRange:[0,1]}),g={position:"absolute",[k]:w.Platform.OS==="ios"?60:40,zIndex:9999};return d==="center"?(g.left=20,g.right=20,g.alignItems="center"):g[d]=20,x.default.createElement(w.Animated.View,{style:[g,{transform:[{translateY:p}],opacity:m}]},x.default.createElement(w.View,{style:[X.banner,{backgroundColor:e.themeColor||"#2563eb"}]},x.default.createElement(w.Text,{style:X.icon},"\u{1F381}"),x.default.createElement(w.Text,{style:X.text},e.text),x.default.createElement(w.TouchableOpacity,{onPress:a,style:X.closeBtn},x.default.createElement(w.Text,{style:X.closeIcon},"\u2715"))))},X=w.StyleSheet.create({banner:{flexDirection:"row",alignItems:"center",padding:12,paddingHorizontal:16,borderRadius:12,shadowColor:"#000",shadowOffset:{width:0,height:4},shadowOpacity:.15,shadowRadius:10,elevation:5,maxWidth:Pe-40},icon:{fontSize:18,marginRight:10},text:{color:"#fff",fontSize:14,fontWeight:"600",flex:1},closeBtn:{marginLeft:10,padding:4},closeIcon:{color:"rgba(255, 255, 255, 0.8)",fontSize:14,fontWeight:"bold"}});var me=(0,n.createContext)(void 0),be=({children:o,userId:e,...a})=>{let[s,l]=(0,n.useState)(!1),[f,k]=(0,n.useState)(!1),[d,p]=(0,n.useState)(null),m=(0,n.useRef)(new Z(a)),g=(0,n.useRef)(!1),T=(0,n.useRef)(null),[z,B]=(0,n.useState)(!1),[M,ie]=(0,n.useState)(),[ne,ge]=(0,n.useState)(!1),[v,E]=(0,n.useState)(),[Y,j]=(0,n.useState)(!1),[$,ae]=(0,n.useState)(),J=(0,n.useCallback)(()=>{let{width:u,height:c}=C.Dimensions.get("window"),b=Intl.DateTimeFormat().resolvedOptions().locale,S=C.PixelRatio.get(),P,F;if(C.Platform.OS==="android"){let ce=C.Platform.constants;P=ce.Model,F=ce.Brand||ce.Manufacturer}return{os:C.Platform.OS,platform:C.Platform.OS,osVersion:String(C.Platform.Version),screenWidth:u,screenHeight:c,timezoneOffsetInMinutes:String(new Date().getTimezoneOffset()),locale:b,language:b,deviceModel:P,deviceBrand:F,pixelRatio:S}},[]),V=(0,n.useCallback)(async(u,c)=>{let b=await m.current.trackReferral(u,c);return await D.setTrackedReferral(b.referralTrackingId),b},[]),Q=(0,n.useCallback)(async u=>{try{let c=u.match(/[?&]referralCode=([^&]+)/);c&&(console.log("GrowthRail: Tracking referral from deep link",c[1]),await V(c[1]))}catch(c){console.warn("GrowthRail: Error handling deep link",c)}},[V]),U=(0,n.useCallback)(async()=>{try{let u=J(),{referralTrackingId:c}=await m.current.checkDeferredDeepLink(u);c&&(console.log("GrowthRail: Found deferred referral via fingerprinting",c),await D.setTrackedReferral(c))}catch(u){console.warn("GrowthRail: Fingerprint check failed",u)}},[J]),se=(0,n.useCallback)(()=>new Promise(u=>{we.default.getInstallReferrerInfo(async(c,b)=>{if(!b&&c&&c.installReferrer)try{let P=decodeURIComponent(c.installReferrer).match(/[?&]referralCode=([^&]+)/);if(P){let{referralTrackingId:F}=await V(P[1]);await D.setTrackedReferral(F),console.log("GrowthRail: Tracked referral via Install Referrer")}}catch(S){console.warn("GrowthRail: Failed to process install referrer",S)}else await U();u()})}),[V,U]),L=(0,n.useCallback)(async u=>{if(d?.id===u&&f)return d;let c=(async()=>{try{let b=await m.current.initAppUser(u),S={...b,id:u};return p(S),k(!0),b.referrerExperience?.trigger?.show&&ge(!0),S}catch(b){throw T.current=null,b}})();return T.current=c,c},[d,f]),A=(0,n.useCallback)(async u=>{let c=d;!c&&T.current&&(c=await T.current);let b=c?.id||e;if(!b)throw new Error("GrowthRail: User must be initialized before tracking a reward event.");let S=await D.getTrackedReferral();if(!S){console.warn("GrowthRail: No referral tracking ID found. Reward event not attributed.");return}return m.current.trackRewardEvent(b,S,u)},[d,e]),le=(0,n.useCallback)(async()=>await D.getTrackedReferral(),[]),G=(0,n.useCallback)(async()=>{if(d)return d.referralLink;if(T.current)return(await T.current).referralLink},[d]);(0,n.useEffect)(()=>{if(g.current)return;g.current=!0,(async()=>{let c=await C.Linking.getInitialURL();c&&await Q(c);let b=C.Linking.addEventListener("url",({url:P})=>Q(P));await D.isFirstLaunch()&&(C.Platform.OS==="android"?await se():await U()),e&&await L(e);try{let P=await m.current.getNewUserExperience(),F=await D.getTrackedReferral();P.banner?.show&&F&&(ae(P.banner),j(!0))}catch{}return l(!0),()=>b.remove()})()},[]),(0,n.useEffect)(()=>{s&&e&&d?.id!==e&&L(e)},[e,s]);let O={isInitialized:s,isUserReady:f,currentUser:d,referralCode:d?.referralCode,referralLink:d?.referralLink,showDashboard:u=>{ie(u),B(!0)},hideDashboard:()=>B(!1),initUser:L,trackReward:A,getReferralTrackingId:le,getReferralLink:G};if(!s)return null;let I=d?.referrerExperience,H={...I?.modal,...M,position:I?.trigger?.position||M?.position||"bottom-right",theme:{...I?.modal?.theme||{},...M?.theme||{}}},Re={...I,...v,trigger:{...I?.trigger||{},...v?.trigger||{}}};return n.default.createElement(me.Provider,{value:O},o,n.default.createElement(te,{visible:z,options:H,onClose:()=>B(!1)}),ne&&n.default.createElement(oe,{options:Re,onPress:()=>O.showDashboard()}),Y&&n.default.createElement(he,{visible:Y,options:$,onClose:()=>j(!1)}))},re=()=>{let o=(0,n.useContext)(me);if(!o)throw new Error("useGrowthRail must be used within a GrowthRailProvider");return o};var N=require("react");var ye=()=>{let[o,e]=(0,N.useState)(!1),[a,s]=(0,N.useState)(null),l=re(),f=(0,N.useCallback)(async d=>{e(!0),s(null);try{return await l.initUser(d)}catch(p){let m=p instanceof Error?p:new Error(String(p));throw s(m),m}finally{e(!1)}},[l]),k=(0,N.useCallback)(async d=>{e(!0),s(null);try{await l.trackReward(d)}catch(p){let m=p instanceof Error?p:new Error(String(p));throw s(m),m}finally{e(!1)}},[l]);return{initAppUser:f,trackRewardEvent:k,showReferralDashboard:l.showDashboard,hideReferralDashboard:l.hideDashboard,getReferralTrackingId:l.getReferralTrackingId,getReferralLink:l.getReferralLink,isLoading:o,isInitialized:l.isInitialized,isUserReady:l.isUserReady,error:a}};0&&(module.exports={GrowthRailProvider,ReferralDashboard,TriggerButton,useGrowthRail});
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var ve=Object.defineProperty;var xe=(l,e,r)=>e in l?ve(l,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):l[e]=r;var v=(l,e,r)=>xe(l,typeof e!="symbol"?e+"":e,r);import{Linking as se,Platform as A,Dimensions as Te,PixelRatio as Ce}from"react-native";import Ie from"react-native-play-install-referrer";var K=class{constructor(e){v(this,"baseUrl");v(this,"apiKey");let r=typeof process<"u"&&process.env?.ENV_BASE_URL;this.baseUrl=r||"https://api.growthrail.dev",this.apiKey=e.apiKey}async request(e,r,i){let c={"Content-Type":"application/json","X-GrowthRail-ProjectSecret":this.apiKey,Origin:this.baseUrl};try{let a=await fetch(`${this.baseUrl}${e}`,{method:r,headers:c,body:i?JSON.stringify(i):void 0});if(!a.ok){let d="";try{d=await a.text()}catch{}throw new Error(`GrowthRail API Error ${a.status} (${this.baseUrl}${e}): ${a.statusText} - ${d}`)}return a.json()}catch(a){throw console.error("GrowthRail SDK Error:",a),a}}async getNewUserExperience(){return this.request("/api/v1/sdk/new-user-experience","POST")}async initAppUser(e){return this.request("/api/v1/sdk/init-app-user","POST",{clientProvidedId:e})}async createReferralLink(e,r){return this.request("/api/v1/sdk/create-referral-link","POST",{referrerId:e,rewardEventName:r})}async trackReferral(e,r){return this.request("/api/v1/sdk/track-referral","POST",{referralCode:e,rewardEventName:r})}async trackRewardEvent(e,r,i){return this.request("/api/v1/sdk/track-reward-event","POST",{refereeId:e,referralTrackingId:r,eventName:i})}async checkDeferredDeepLink(e){return this.request("/api/v1/sdk/match-link","POST",{fingerprint:e})}};import q from"@react-native-async-storage/async-storage";var X={TRACKED_REFERRAL:"growth-rail-tracked-referral",IS_FIRST_LAUNCH:"growth-rail-is-first-launch"},U=class{static async setTrackedReferral(e){await q.setItem(X.TRACKED_REFERRAL,e)}static async getTrackedReferral(){return await q.getItem(X.TRACKED_REFERRAL)}static async isFirstLaunch(){return await q.getItem(X.IS_FIRST_LAUNCH)===null?(await q.setItem(X.IS_FIRST_LAUNCH,"false"),!0):!1}};var t=class t{constructor(){}static async init(e){t.initialized||(t.options=e,t.api=new K(e),t.initialized=!0,await t.handleInitialUrl(),await t.setupLinkListeners(),await t.checkDeferredReferral())}static async handleInitialUrl(){try{let e=await se.getInitialURL();e&&await t.handleDeepLink(e)}catch(e){console.error("GrowthRail: Error getting initial URL",e)}}static setupLinkListeners(){se.addEventListener("url",({url:e})=>{t.handleDeepLink(e)})}static async checkDeferredReferral(){await U.isFirstLaunch()&&(A.OS==="android"?await t.checkInstallReferrer():await t.checkDeferredDeepLinkFingerprint())}static checkInstallReferrer(){return new Promise(e=>{Ie.getInstallReferrerInfo(async(r,i)=>{if(!i&&r&&r.installReferrer)try{let a=decodeURIComponent(r.installReferrer).match(/[?&]referralCode=([^&]+)/);if(a){let{referralTrackingId:d}=await t.trackReferral(a[1]);await U.setTrackedReferral(d),console.log("GrowthRail: Tracked referral via Install Referrer")}}catch(c){console.warn("GrowthRail: Failed to process install referrer",c)}else await t.checkDeferredDeepLinkFingerprint();e()})})}static getDeviceFingerprint(){let{width:e,height:r}=Te.get("window"),i=Intl.DateTimeFormat().resolvedOptions().locale,c=Ce.get(),a,d;if(A.OS==="android"){let u=A.constants;a=u.Model,d=u.Brand||u.Manufacturer}return{os:A.OS,platform:A.OS,osVersion:String(A.Version),screenWidth:e,screenHeight:r,timezoneOffsetInMinutes:String(new Date().getTimezoneOffset()),locale:i,language:i,deviceModel:a,deviceBrand:d,pixelRatio:c}}static async checkDeferredDeepLinkFingerprint(){try{let e=t.getDeviceFingerprint();console.log("GrowthRail executing deferred fingerprint check to API...");let{referralTrackingId:r}=await t.api.checkDeferredDeepLink(e);r&&(console.log("GrowthRail: Found deferred referral via fingerprinting",r),await U.setTrackedReferral(r))}catch(e){console.warn("GrowthRail: Fingerprint check failed",e)}}static async handleDeepLink(e){try{let r=new URL(e),i=r.searchParams.get("referralCode"),c=r.searchParams.get("rewardEventName");i&&(console.log("GrowthRail: Tracking referral from deep link",i),await t.trackReferral(i,c||void 0))}catch{let i=e.match(/[?&]referralCode=([^&]+)/);i&&await t.trackReferral(i[1])}}static ensureInitialized(){if(!t.initialized)throw new Error("GrowthRail.init() must be called before using the SDK")}static async initAppUser(e){t.ensureInitialized();let r=await t.api.initAppUser(e);return t.currentUser={...r,id:e},t.userReadyResolver&&t.userReadyResolver(t.currentUser),r}static async trackReferral(e,r){t.ensureInitialized();let i=await t.api.trackReferral(e,r);return await U.setTrackedReferral(i.referralTrackingId),i}static async trackRewardEvent(e){t.ensureInitialized();let r=t.currentUser?.id;if(!r)throw new Error("GrowthRail: User must be initialized before tracking a reward event.");let i=await U.getTrackedReferral();if(!i){console.warn("GrowthRail: No referral tracking ID found. Reward event not attributed.");return}return t.api.trackRewardEvent(r,i,e)}static async createReferralLink(e){t.ensureInitialized();let r=t.currentUser?.id;if(!r)throw new Error("GrowthRail: User must be initialized before creating a referral link.");if(t.referralObject)return t.referralObject;let i=await t.api.createReferralLink(r,e);return t.referralObject=i,i}static isInitialized(){return t.initialized}static getReferralLink(){if(!t.referralObject?.referralLink)throw new Error("GrowthRail: Referral Link not loaded or user not initialized");return t.referralObject.referralLink}static getReferralCode(){return t.referralObject?.referralCode||t.currentUser?.referralCode}static getUserId(){return t.currentUser?.id}static isUserReady(){return t.currentUser!==null}static getReferrerExperience(){return t.currentUser?.referrerExperience}static ensureUserReady(){return t.currentUser?Promise.resolve(t.currentUser):(t.userReadyPromise||(t.userReadyPromise=new Promise(e=>{t.userReadyResolver=e})),t.userReadyPromise)}static async getNewUserExperience(){return t.ensureInitialized(),t.api.getNewUserExperience()}};v(t,"api"),v(t,"options"),v(t,"currentUser",null),v(t,"referralObject",null),v(t,"initialized",!1),v(t,"userReadyPromise",null),v(t,"userReadyResolver",null);var p=t;import Q,{createContext as qe,useContext as Xe,useEffect as me,useState as L,useRef as Ye}from"react";import o,{useEffect as Pe,useState as ie,useRef as le}from"react";import{Modal as Ue,View as b,Text as R,StyleSheet as ce,TouchableOpacity as Y,Clipboard as Se,ActivityIndicator as Le,Linking as de,ScrollView as Oe,Platform as fe,Animated as C,Dimensions as Be}from"react-native";var{width:pe,height:oe}=Be.get("window"),ue=({visible:l,options:e,onClose:r})=>{let[i,c]=ie(null),[a,d]=ie(!1),[u,w]=ie(!1),f=le(new C.Value(0)).current,s=le(new C.Value(0)).current,g=e?.title||"Invite Friends & Earn",h=e?.theme?.primaryColor||"#2563eb",z=e?.theme?.backgroundColor||"#ffffff",O=e?.theme?.tintColor||"#000000",H=e?.theme?.tintAlpha??.5,y=(e?.componentType||"modal")==="drawer",T=e?.position||"bottom-right",_="#111827",N="#6b7280";Pe(()=>{l?(i||ee(),C.parallel([C.timing(s,{toValue:1,duration:300,useNativeDriver:!0}),C.spring(f,{toValue:1,useNativeDriver:!0,tension:50,friction:8})]).start()):(f.setValue(0),s.setValue(0))},[l]);let I=()=>{C.parallel([C.timing(s,{toValue:0,duration:250,useNativeDriver:!0}),C.timing(f,{toValue:0,duration:250,useNativeDriver:!0})]).start(()=>{r()})},ee=async()=>{d(!0);try{if(p.isUserReady()){let D=await p.createReferralLink();c(D.referralLink)}}catch(D){console.error("GrowthRail: Failed to load referral link",D)}finally{d(!1)}},te=()=>{i&&(Se.setString(i),w(!0),setTimeout(()=>w(!1),2e3))},k=D=>{if(!i)return;let P="",V=encodeURIComponent(i),re=encodeURIComponent("Check this out!");switch(D){case"twitter":P=`https://twitter.com/intent/tweet?url=${V}&text=${re}`;break;case"facebook":P=`https://www.facebook.com/sharer/sharer.php?u=${V}`;break;case"linkedin":P=`https://www.linkedin.com/sharing/share-offsite/?url=${V}`;break;case"whatsapp":P=`whatsapp://send?text=${re}%20${V}`;break;case"email":P=`mailto:?subject=Check this out&body=${re}%20${V}`;break}P&&de.openURL(P).catch(()=>{})},m=()=>{if(O.startsWith("#")){let D=parseInt(O.slice(1,3),16),P=parseInt(O.slice(3,5),16),V=parseInt(O.slice(5,7),16);return`rgba(${D}, ${P}, ${V}, ${H})`}return`rgba(0, 0, 0, ${H})`},M=[];y?T.includes("right")?M=[{translateX:f.interpolate({inputRange:[0,1],outputRange:[pe,0]})}]:T.includes("left")?M=[{translateX:f.interpolate({inputRange:[0,1],outputRange:[-pe,0]})}]:M=[{translateY:f.interpolate({inputRange:[0,1],outputRange:[oe,0]})}]:M=[{scale:f.interpolate({inputRange:[0,1],outputRange:[.9,1]})},{translateY:f.interpolate({inputRange:[0,1],outputRange:[20,0]})}];let Re=T.includes("top"),B=T.includes("right"),E=T.includes("left"),ke=y?{position:"absolute",...Re?{top:100}:{bottom:100},...B?{right:0}:E?{left:0}:{left:0,right:0},width:B||E?"85%":"100%",maxHeight:B||E?oe-200:"80%"}:{};return o.createElement(Ue,{visible:l,transparent:!0,animationType:"none",onRequestClose:I},o.createElement(b,{style:n.fullScreen},o.createElement(C.View,{style:[n.overlay,{backgroundColor:m(),opacity:s}]},o.createElement(Y,{style:n.fullScreen,activeOpacity:1,onPress:I})),o.createElement(C.View,{style:[y?ke:n.centeredModalContainer,{backgroundColor:z,transform:M},y&&B&&{borderTopLeftRadius:24,borderBottomLeftRadius:24},y&&E&&{borderTopRightRadius:24,borderBottomRightRadius:24},y&&!B&&!E&&T.includes("bottom")&&{borderTopLeftRadius:24,borderTopRightRadius:24},y&&!B&&!E&&T.includes("top")&&{borderBottomLeftRadius:24,borderBottomRightRadius:24},!y&&{borderRadius:24,opacity:f}]},o.createElement(b,{style:n.contentWrapper},y&&!B&&!E&&T.includes("bottom")&&o.createElement(b,{style:n.drawerHandle}),o.createElement(Y,{style:n.closeBtn,onPress:I},o.createElement(R,{style:n.closeIcon},"\u2715")),o.createElement(Oe,{contentContainerStyle:n.scrollContent,showsVerticalScrollIndicator:!1},o.createElement(b,{style:n.header},o.createElement(R,{style:n.iconLg},"\u{1F381}"),o.createElement(R,{style:[n.title,{color:_}]},g),o.createElement(R,{style:[n.subtitle,{color:N}]},e?.description||"Share your unique link and earn rewards for every friend who signs up.")),p.isUserReady()?a?o.createElement(Le,{size:"large",color:h,style:n.loader}):o.createElement(b,{style:n.mainContent},o.createElement(R,{style:n.label},"YOUR UNIQUE LINK"),o.createElement(b,{style:n.inputGroup},o.createElement(R,{numberOfLines:1,style:n.input},i||"Initializing..."),o.createElement(Y,{style:[n.copyBtn,{backgroundColor:u?"#10b981":h}],onPress:te},o.createElement(R,{style:n.copyBtnText},u?"Copied!":"Copy"))),o.createElement(b,{style:n.shareLabelContainer},o.createElement(b,{style:n.divider}),o.createElement(R,{style:n.shareLabel},"Share via"),o.createElement(b,{style:n.divider})),o.createElement(b,{style:n.socialContainer},o.createElement(W,{platform:"twitter",color:"#000000",onPress:()=>k("twitter"),icon:"\u{1D54F}"}),o.createElement(W,{platform:"facebook",color:"#1877F2",onPress:()=>k("facebook"),icon:"f"}),o.createElement(W,{platform:"linkedin",color:"#0A66C2",onPress:()=>k("linkedin"),icon:"in"}),o.createElement(W,{platform:"whatsapp",color:"#25D366",onPress:()=>k("whatsapp"),icon:"W"}),o.createElement(W,{platform:"email",color:"#888888",onPress:()=>k("email"),icon:"\u2709"}))):o.createElement(b,{style:n.loadingBox},o.createElement(R,{style:{color:N,textAlign:"center"}},"Please log in to view your referral dashboard.")),o.createElement(b,{style:n.footer},o.createElement(R,{style:n.poweredBy},"Powered by ",o.createElement(R,{style:n.brand,onPress:()=>de.openURL("https://growthrail.com")},"Growth Rail"))))))))},W=({color:l,onPress:e,icon:r})=>o.createElement(Y,{style:[n.socialBtn,{borderColor:"#e5e7eb"}],onPress:e},o.createElement(R,{style:[n.socialIcon,{color:l}]},r)),n=ce.create({fullScreen:{flex:1},overlay:{...ce.absoluteFillObject},centeredModalContainer:{width:"90%",maxWidth:400,alignSelf:"center",marginTop:oe*.15,overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:20},shadowOpacity:.25,shadowRadius:30,elevation:20},contentWrapper:{paddingTop:fe.OS==="ios"?20:0},drawerHandle:{width:40,height:4,backgroundColor:"#e5e7eb",borderRadius:2,alignSelf:"center",marginTop:12},scrollContent:{padding:32,alignItems:"center"},closeBtn:{position:"absolute",top:20,right:20,zIndex:10,width:32,height:32,borderRadius:16,backgroundColor:"#f3f4f6",justifyContent:"center",alignItems:"center"},closeIcon:{fontSize:14,color:"#9ca3af"},header:{alignItems:"center",marginBottom:28},iconLg:{fontSize:32,marginBottom:12},title:{fontSize:22,fontWeight:"700",letterSpacing:-.5,marginBottom:8,textAlign:"center"},subtitle:{fontSize:14,lineHeight:20,textAlign:"center",paddingHorizontal:10},loadingBox:{padding:16,backgroundColor:"#f9fafb",borderRadius:12,width:"100%",alignItems:"center"},loader:{marginVertical:20},mainContent:{width:"100%"},label:{fontSize:12,fontWeight:"600",color:"#6b7280",marginBottom:8,letterSpacing:.5},inputGroup:{flexDirection:"row",alignItems:"center",backgroundColor:"#f9fafb",borderWidth:1,borderColor:"#e5e7eb",borderRadius:12,padding:6,marginBottom:24},input:{flex:1,paddingHorizontal:12,fontSize:14,color:"#111827",fontFamily:fe.OS==="ios"?"Menlo":"monospace"},copyBtn:{paddingVertical:8,paddingHorizontal:16,borderRadius:8},copyBtnText:{color:"#fff",fontSize:13,fontWeight:"600"},shareLabelContainer:{flexDirection:"row",alignItems:"center",marginBottom:16},divider:{flex:1,height:1,backgroundColor:"#e5e7eb"},shareLabel:{marginHorizontal:12,fontSize:13,fontWeight:"500",color:"#6b7280"},socialContainer:{flexDirection:"row",justifyContent:"center",gap:12},socialBtn:{width:44,height:44,borderRadius:22,backgroundColor:"#fff",borderWidth:1,justifyContent:"center",alignItems:"center"},socialIcon:{fontSize:18,fontWeight:"bold"},footer:{marginTop:32,alignItems:"center"},poweredBy:{fontSize:11,color:"#9ca3af"},brand:{fontWeight:"600",textDecorationLine:"underline"}});import S,{useEffect as Ee,useRef as De}from"react";import{TouchableOpacity as Ve,View as F,StyleSheet as ze,Animated as ne,Easing as Ae}from"react-native";var ge=({onPress:l,options:e})=>{let r=e?.modal?.theme?.primaryColor||"#2563eb",i=e?.trigger?.position||"bottom-right",a=(e?.trigger?.displayMode||"floating")==="edge",d=i.includes("right"),u=i.includes("top"),w=De(new ne.Value(-1)).current;Ee(()=>{let h=()=>{w.setValue(-1),ne.timing(w,{toValue:2,duration:3e3,easing:Ae.linear,useNativeDriver:!0}).start(()=>{setTimeout(h,1e3)})};h()},[]);let f=w.interpolate({inputRange:[-1,2],outputRange:a?[-50,100]:[-60,120]}),s={"bottom-right":{bottom:100,right:0},"bottom-left":{bottom:100,left:0},"top-right":{top:100,right:0},"top-left":{top:100,left:0}};a||(s["bottom-right"]={bottom:30,right:20},s["bottom-left"]={bottom:30,left:20},s["top-right"]={top:60,right:20},s["top-left"]={top:60,left:20});let g=()=>S.createElement(F,{style:x.iconContainer},S.createElement(F,{style:x.giftBody},S.createElement(F,{style:x.giftLid}),S.createElement(F,{style:x.giftRibbonV}),S.createElement(F,{style:x.giftRibbonH})));return S.createElement(Ve,{style:[a?x.edgeButton:x.floatingButton,{backgroundColor:r},s[i],a&&(d?x.edgeRight:x.edgeLeft)],onPress:l,activeOpacity:.9},S.createElement(F,{style:x.content},g()),S.createElement(ne.View,{style:[x.shimmer,{transform:[{translateX:f},{skewX:"-15deg"}]}]}))},x=ze.create({floatingButton:{position:"absolute",width:60,height:60,borderRadius:30,justifyContent:"center",alignItems:"center",overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:8},shadowOpacity:.2,shadowRadius:12,elevation:8,zIndex:2147483646},edgeButton:{position:"absolute",width:50,height:50,justifyContent:"center",alignItems:"center",overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:4},shadowOpacity:.1,shadowRadius:8,elevation:4,zIndex:2147483646},edgeRight:{borderTopLeftRadius:8,borderBottomLeftRadius:8,paddingLeft:4},edgeLeft:{borderTopRightRadius:8,borderBottomRightRadius:8,paddingRight:4},content:{justifyContent:"center",alignItems:"center"},iconContainer:{width:24,height:24,justifyContent:"center",alignItems:"center"},giftBody:{width:16,height:14,backgroundColor:"rgba(255, 255, 255, 0.9)",borderRadius:1.5,marginTop:3,position:"relative"},giftLid:{position:"absolute",top:-3,left:-1.5,width:19,height:3,backgroundColor:"#fff",borderRadius:.5},giftRibbonV:{position:"absolute",top:-3,left:7,width:2.5,height:17,backgroundColor:"rgba(0, 0, 0, 0.1)"},giftRibbonH:{position:"absolute",top:5,left:0,width:16,height:2,backgroundColor:"rgba(0, 0, 0, 0.05)"},shimmer:{position:"absolute",top:0,left:0,width:50,height:"100%",backgroundColor:"rgba(255, 255, 255, 0.25)"}});import G,{useEffect as Fe,useRef as Ge,useState as Ne}from"react";import{View as Me,Text as ae,StyleSheet as We,Animated as J,Dimensions as $e,TouchableOpacity as je,Platform as He}from"react-native";var{width:Ke}=$e.get("window"),he=({visible:l,options:e,onClose:r})=>{let i=Ge(new J.Value(0)).current,[c,a]=Ne(l),d=e.position.includes("bottom")?"bottom":"top",u=e.position.includes("left")?"left":e.position.includes("right")?"right":"center";if(Fe(()=>{l?(a(!0),J.spring(i,{toValue:1,useNativeDriver:!0,tension:50,friction:8}).start()):J.timing(i,{toValue:0,duration:250,useNativeDriver:!0}).start(()=>{a(!1)})},[l]),!c)return null;let w=i.interpolate({inputRange:[0,1],outputRange:[d==="top"?-100:100,0]}),f=i.interpolate({inputRange:[0,1],outputRange:[0,1]}),s={position:"absolute",[d]:He.OS==="ios"?60:40,zIndex:9999};return u==="center"?(s.left=20,s.right=20,s.alignItems="center"):s[u]=20,G.createElement(J.View,{style:[s,{transform:[{translateY:w}],opacity:f}]},G.createElement(Me,{style:[$.banner,{backgroundColor:e.themeColor||"#2563eb"}]},G.createElement(ae,{style:$.icon},"\u{1F381}"),G.createElement(ae,{style:$.text},e.text),G.createElement(je,{onPress:r,style:$.closeBtn},G.createElement(ae,{style:$.closeIcon},"\u2715"))))},$=We.create({banner:{flexDirection:"row",alignItems:"center",padding:12,paddingHorizontal:16,borderRadius:12,shadowColor:"#000",shadowOffset:{width:0,height:4},shadowOpacity:.15,shadowRadius:10,elevation:5,maxWidth:Ke-40},icon:{fontSize:18,marginRight:10},text:{color:"#fff",fontSize:14,fontWeight:"600",flex:1},closeBtn:{marginLeft:10,padding:4},closeIcon:{color:"rgba(255, 255, 255, 0.8)",fontSize:14,fontWeight:"bold"}});var we=qe(void 0),Tt=({children:l,userId:e,...r})=>{let[i,c]=L(p.isInitialized()),[a,d]=L(p.isUserReady()),u=Ye(!1),[w,f]=L(!1),[s,g]=L(),[h,z]=L(!1),[O,H]=L(),[Z,y]=L(!1),[T,_]=L();me(()=>{if(u.current)return;u.current=!0,(async()=>{if(await p.init(r),e)try{let m=await p.initAppUser(e);d(!0),m.referrerExperience?.trigger?.show&&z(!0)}catch(m){console.error("GrowthRail: User init failed",m)}try{let m=await p.getNewUserExperience();m.banner?.show&&(_(m.banner),y(!0))}catch{}c(!0)})()},[]),me(()=>{(async()=>{if(u.current&&e&&p.getUserId()!==e)try{let m=await p.initAppUser(e);d(!0),m.referrerExperience?.trigger?.show&&z(!0)}catch(m){console.error("GrowthRail: User init failed",m)}})()},[e]);let N={isInitialized:i,isUserReady:a,showDashboard:k=>{g(k),f(!0)},hideDashboard:()=>f(!1),showFloatingButton:k=>{H({trigger:k}),z(!0)},hideFloatingButton:()=>z(!1)};if(!i)return null;let I=p.getReferrerExperience(),ee={...I?.modal,...s,position:I?.trigger?.position||s?.position||"bottom-right",theme:{...I?.modal?.theme||{},...s?.theme||{}}},te={...I,...O,trigger:{...I?.trigger||{},...O?.trigger||{}}};return Q.createElement(we.Provider,{value:N},l,Q.createElement(ue,{visible:w,options:ee,onClose:()=>f(!1)}),h&&Q.createElement(ge,{options:te,onPress:()=>N.showDashboard()}),Z&&Q.createElement(he,{visible:Z,options:T,onClose:()=>y(!1)}))},ye=()=>{let l=Xe(we);if(!l)throw new Error("useGrowthRail must be used within a GrowthRailProvider");return l};import{useState as be,useCallback as j}from"react";var St=()=>{let[l,e]=be(!1),[r,i]=be(null),c=ye(),a=j(async s=>{e(!0),i(null);try{return await p.initAppUser(s)}catch(g){let h=g instanceof Error?g:new Error(String(g));throw i(h),h}finally{e(!1)}},[]),d=j(async s=>{e(!0),i(null);try{await p.trackRewardEvent(s)}catch(g){let h=g instanceof Error?g:new Error(String(g));throw i(h),h}finally{e(!1)}},[]),u=j(s=>{c.showDashboard(s)},[c]),w=j(s=>{c.showFloatingButton(s)},[c]),f=j(()=>{c.hideFloatingButton()},[c]);return{initUser:a,trackReward:d,showReferralDashboard:u,showFloatingButton:w,hideFloatingButton:f,isLoading:l,isInitialized:c.isInitialized,error:r}};export{K as APIClient,p as GrowthRail,Tt as GrowthRailProvider,ue as ReferralDashboard,U as StorageManager,ge as TriggerButton,St as useGrowthRail,ye as useGrowthRailContext};
|
|
1
|
+
var Ve=Object.defineProperty;var Oe=(n,e,s)=>e in n?Ve(n,e,{enumerable:!0,configurable:!0,writable:!0,value:s}):n[e]=s;var de=(n,e,s)=>Oe(n,typeof e!="symbol"?e+"":e,s);import oe,{createContext as Ze,useContext as et,useEffect as ve,useState as E,useRef as me,useCallback as U}from"react";import{Linking as Le,Platform as N,Dimensions as tt,PixelRatio as rt}from"react-native";import ot from"react-native-play-install-referrer";var J=class{constructor(e){de(this,"baseUrl");de(this,"projectSecretKey");let s=typeof process<"u"&&process.env?.ENV_BASE_URL;this.baseUrl=s||"https://api.growthrail.dev",this.projectSecretKey=e.projectSecretKey}async request(e,s,o){let l={"Content-Type":"application/json","X-GrowthRail-ProjectSecret":this.projectSecretKey,Origin:this.baseUrl};try{let c=await fetch(`${this.baseUrl}${e}`,{method:s,headers:l,body:o?JSON.stringify(o):void 0});if(!c.ok){let m="";try{m=await c.text()}catch{}throw new Error(`GrowthRail API Error ${c.status} (${this.baseUrl}${e}): ${c.statusText} - ${m}`)}return c.json()}catch(c){throw console.error("GrowthRail SDK Error:",c),c}}async getNewUserExperience(){return this.request("/api/v1/sdk/new-user-experience","POST")}async initAppUser(e){return this.request("/api/v1/sdk/init-app-user","POST",{clientProvidedId:e})}async trackReferral(e,s){return this.request("/api/v1/sdk/track-referral","POST",{referralCode:e,rewardEventName:s})}async trackRewardEvent(e,s,o){return this.request("/api/v1/sdk/track-reward-event","POST",{refereeId:e,referralTrackingId:s,eventName:o})}async checkDeferredDeepLink(e){return this.request("/api/v1/sdk/match-link","POST",{fingerprint:e})}};import Q from"@react-native-async-storage/async-storage";var Z={TRACKED_REFERRAL:"growth-rail-tracked-referral",IS_FIRST_LAUNCH:"growth-rail-is-first-launch"},S=class{static async setTrackedReferral(e){await Q.setItem(Z.TRACKED_REFERRAL,e)}static async getTrackedReferral(){return await Q.getItem(Z.TRACKED_REFERRAL)}static async isFirstLaunch(){return await Q.getItem(Z.IS_FIRST_LAUNCH)===null?(await Q.setItem(Z.IS_FIRST_LAUNCH,"false"),!0):!1}};import t,{useEffect as De,useState as fe,useRef as ye}from"react";import{Modal as Ee,View as u,Text as x,StyleSheet as Re,TouchableOpacity as ee,Clipboard as Ue,ActivityIndicator as Ae,Linking as Ce,ScrollView as Ge,Platform as ke,Animated as P,Dimensions as ze}from"react-native";var{width:Te,height:ge}=ze.get("window"),ue=({visible:n,options:e,onClose:s})=>{let o=te(),[l,c]=fe(null),[m,a]=fe(!1),[g,p]=fe(!1),d=ye(new P.Value(0)).current,b=ye(new P.Value(0)).current,z=e?.title||"Invite Friends & Earn",v=e?.theme?.primaryColor||"#2563eb",M=e?.theme?.backgroundColor||"#ffffff",ie=e?.theme?.tintColor||"#000000",ne=e?.theme?.tintAlpha??.5,y=(e?.componentType||"modal")==="drawer",V=e?.position||"bottom-right",q="#111827",j="#6b7280";De(()=>{n?(l||ae(),P.parallel([P.timing(b,{toValue:1,duration:300,useNativeDriver:!0}),P.spring(d,{toValue:1,useNativeDriver:!0,tension:50,friction:8})]).start()):(d.setValue(0),b.setValue(0))},[n]);let $=()=>{P.parallel([P.timing(b,{toValue:0,duration:250,useNativeDriver:!0}),P.timing(d,{toValue:0,duration:250,useNativeDriver:!0})]).start(()=>{s()})},ae=async()=>{a(!0);try{if(o.isUserReady){let G=await o.getReferralLink();c(G||null)}}catch(G){console.error("GrowthRail: Failed to load referral link",G)}finally{a(!1)}},X=()=>{l&&(Ue.setString(l),p(!0),setTimeout(()=>p(!1),2e3))},L=G=>{if(!l)return;let I="",C=encodeURIComponent(l),H=encodeURIComponent("Check this out!");switch(G){case"twitter":I=`https://twitter.com/intent/tweet?url=${C}&text=${H}`;break;case"facebook":I=`https://www.facebook.com/sharer/sharer.php?u=${C}`;break;case"linkedin":I=`https://www.linkedin.com/sharing/share-offsite/?url=${C}`;break;case"whatsapp":I=`whatsapp://send?text=${H}%20${C}`;break;case"email":I=`mailto:?subject=Check this out&body=${H}%20${C}`;break}I&&Ce.openURL(I).catch(()=>{})},Y=()=>ie||"#000000",O=[];y?V.includes("right")?O=[{translateX:d.interpolate({inputRange:[0,1],outputRange:[Te,0]})}]:V.includes("left")?O=[{translateX:d.interpolate({inputRange:[0,1],outputRange:[-Te,0]})}]:O=[{translateY:d.interpolate({inputRange:[0,1],outputRange:[ge,0]})}]:O=[{scale:d.interpolate({inputRange:[0,1],outputRange:[.9,1]})},{translateY:d.interpolate({inputRange:[0,1],outputRange:[20,0]})}];let se=V.includes("top"),R=V.includes("right"),D=V.includes("left"),le=y?{position:"absolute",...se?{top:100}:{bottom:100},...R?{right:0}:D?{left:0}:{left:0,right:0},width:R||D?"85%":"100%",maxHeight:R||D?ge-200:"80%"}:{};return t.createElement(Ee,{visible:n,transparent:!0,animationType:"none",onRequestClose:$},t.createElement(u,{style:r.fullScreen},t.createElement(P.View,{style:[r.overlay,{backgroundColor:Y(),opacity:b.interpolate({inputRange:[0,1],outputRange:[0,ne]})}]},t.createElement(ee,{style:r.fullScreen,activeOpacity:1,onPress:$})),t.createElement(P.View,{style:[y?le:r.centeredModalContainer,{backgroundColor:M,transform:O},y&&R&&{borderTopLeftRadius:24,borderBottomLeftRadius:24},y&&D&&{borderTopRightRadius:24,borderBottomRightRadius:24},y&&!R&&!D&&V.includes("bottom")&&{borderTopLeftRadius:24,borderTopRightRadius:24},y&&!R&&!D&&V.includes("top")&&{borderBottomLeftRadius:24,borderBottomRightRadius:24},!y&&{borderRadius:24,opacity:d}]},t.createElement(u,{style:r.contentWrapper},y&&!R&&!D&&V.includes("bottom")&&t.createElement(u,{style:r.drawerHandle}),t.createElement(ee,{style:r.closeBtn,onPress:$},t.createElement(x,{style:r.closeIcon},"\u2715")),t.createElement(Ge,{contentContainerStyle:r.scrollContent,showsVerticalScrollIndicator:!1},t.createElement(u,{style:r.header},t.createElement(u,{style:r.iconLgContainer},t.createElement(u,{style:r.bowContainerLg},t.createElement(u,{style:[r.bowLoopLg,r.bowLeftLg,{borderColor:v}]}),t.createElement(u,{style:[r.bowLoopLg,r.bowRightLg,{borderColor:v}]})),t.createElement(u,{style:[r.giftLidLg,{backgroundColor:v}]}),t.createElement(u,{style:[r.giftBodyLg,{borderColor:v}]},t.createElement(u,{style:[r.ribbonVerticalLg,{backgroundColor:"#fff",opacity:.3}]}))),t.createElement(x,{style:[r.title,{color:q}]},z),t.createElement(x,{style:[r.subtitle,{color:j}]},e?.description||"Share your unique link and earn rewards for every friend who signs up.")),o.isUserReady?m?t.createElement(Ae,{size:"large",color:v,style:r.loader}):t.createElement(u,{style:r.mainContent},t.createElement(x,{style:r.label},"YOUR UNIQUE LINK"),t.createElement(u,{style:r.inputGroup},t.createElement(x,{numberOfLines:1,style:r.input},l||"Initializing..."),t.createElement(ee,{style:[r.copyBtn,{backgroundColor:g?"#10b981":v}],onPress:X},t.createElement(x,{style:r.copyBtnText},g?"Copied!":"Copy"))),t.createElement(u,{style:r.shareLabelContainer},t.createElement(u,{style:r.divider}),t.createElement(x,{style:r.shareLabel},"Share via"),t.createElement(u,{style:r.divider})),t.createElement(u,{style:r.socialContainer},t.createElement(_,{platform:"twitter",color:"#000000",onPress:()=>L("twitter"),icon:"\u{1D54F}"}),t.createElement(_,{platform:"facebook",color:"#1877F2",onPress:()=>L("facebook"),icon:"f"}),t.createElement(_,{platform:"linkedin",color:"#0A66C2",onPress:()=>L("linkedin"),icon:"in"}),t.createElement(_,{platform:"whatsapp",color:"#25D366",onPress:()=>L("whatsapp"),icon:"W"}),t.createElement(_,{platform:"email",color:"#888888",onPress:()=>L("email"),icon:"\u2709"}))):t.createElement(u,{style:r.loadingBox},t.createElement(x,{style:{color:j,textAlign:"center"}},"Please log in to view your referral dashboard.")),t.createElement(u,{style:r.footer},t.createElement(x,{style:r.poweredBy},"Powered by ",t.createElement(x,{style:r.brand,onPress:()=>Ce.openURL("https://growthrail.com")},"Growth Rail"))))))))},_=({color:n,onPress:e,icon:s})=>t.createElement(ee,{style:[r.socialBtn,{borderColor:"#e5e7eb"}],onPress:e},t.createElement(x,{style:[r.socialIcon,{color:n}]},s)),r=Re.create({fullScreen:{flex:1},overlay:{...Re.absoluteFillObject},centeredModalContainer:{width:"90%",maxWidth:400,alignSelf:"center",marginTop:ge*.15,overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:20},shadowOpacity:.25,shadowRadius:30,elevation:20},contentWrapper:{paddingTop:ke.OS==="ios"?20:0},drawerHandle:{width:40,height:4,backgroundColor:"#e5e7eb",borderRadius:2,alignSelf:"center",marginTop:12},scrollContent:{padding:32,alignItems:"center"},closeBtn:{position:"absolute",top:20,right:20,zIndex:10,width:32,height:32,borderRadius:16,backgroundColor:"#f3f4f6",justifyContent:"center",alignItems:"center"},closeIcon:{fontSize:14,color:"#9ca3af"},header:{alignItems:"center",marginBottom:28,width:"100%"},socialIcon:{fontSize:18,fontWeight:"bold"},title:{fontSize:22,fontWeight:"700",letterSpacing:-.5,marginBottom:8,textAlign:"center"},subtitle:{fontSize:14,lineHeight:20,textAlign:"center",paddingHorizontal:10},loadingBox:{padding:16,backgroundColor:"#f9fafb",borderRadius:12,width:"100%",alignItems:"center",borderWidth:1,borderColor:"#e5e7eb",marginTop:20},loader:{marginVertical:20},mainContent:{width:"100%"},label:{fontSize:12,fontWeight:"600",color:"#6b7280",marginBottom:8,letterSpacing:.5},inputGroup:{flexDirection:"row",alignItems:"center",backgroundColor:"#f9fafb",borderWidth:1,borderColor:"#e5e7eb",borderRadius:12,padding:6,marginBottom:24},input:{flex:1,paddingHorizontal:12,fontSize:14,color:"#111827",fontFamily:ke.OS==="ios"?"Menlo":"monospace"},copyBtn:{paddingVertical:8,paddingHorizontal:16,borderRadius:8,justifyContent:"center",alignItems:"center"},copyBtnText:{color:"#fff",fontSize:13,fontWeight:"600"},shareLabelContainer:{flexDirection:"row",alignItems:"center",marginBottom:16,marginTop:8},divider:{flex:1,height:1,backgroundColor:"#e5e7eb"},shareLabel:{marginHorizontal:12,fontSize:13,fontWeight:"500",color:"#6b7280"},socialContainer:{flexDirection:"row",justifyContent:"center",gap:12},socialBtn:{width:44,height:44,borderRadius:22,backgroundColor:"#fff",borderWidth:1,justifyContent:"center",alignItems:"center"},iconLgContainer:{width:60,height:60,justifyContent:"center",alignItems:"center",marginBottom:16},bowContainerLg:{flexDirection:"row",position:"absolute",top:2,zIndex:2},bowLoopLg:{width:20,height:16,borderWidth:3,borderColor:"#e5e7eb",borderRadius:10},bowLeftLg:{marginRight:-2,transform:[{rotate:"-15deg"}]},bowRightLg:{marginLeft:-2,transform:[{rotate:"15deg"}]},giftLidLg:{width:44,height:10,backgroundColor:"#f3f4f6",borderRadius:2,marginTop:12,zIndex:3},giftBodyLg:{width:36,height:24,borderWidth:3,borderTopWidth:0,borderBottomLeftRadius:4,borderBottomRightRadius:4,justifyContent:"center",alignItems:"center",marginTop:-2},ribbonVerticalLg:{width:4,height:"100%",opacity:.1},footer:{marginTop:32,alignItems:"center"},poweredBy:{fontSize:11,color:"#9ca3af"},brand:{fontWeight:"600",textDecorationLine:"underline"}});import B,{useEffect as Fe,useRef as We}from"react";import{TouchableOpacity as Ne,View as A,StyleSheet as Me,Animated as pe,Easing as je}from"react-native";var he=({onPress:n,options:e})=>{let s=e?.modal?.theme?.primaryColor||"#2563eb",o=e?.trigger?.position||"bottom-right",c=(e?.trigger?.displayMode||"floating")==="edge",m=o.includes("right"),a=o.includes("top"),g=We(new pe.Value(-1)).current;Fe(()=>{let z=()=>{g.setValue(-1),pe.timing(g,{toValue:2,duration:3e3,easing:je.linear,useNativeDriver:!0}).start(()=>{setTimeout(z,1e3)})};z()},[]);let p=g.interpolate({inputRange:[-1,2],outputRange:c?[-50,100]:[-60,120]}),d={"bottom-right":{bottom:100,right:0},"bottom-left":{bottom:100,left:0},"top-right":{top:100,right:0},"top-left":{top:100,left:0}};c||(d["bottom-right"]={bottom:30,right:20},d["bottom-left"]={bottom:30,left:20},d["top-right"]={top:60,right:20},d["top-left"]={top:60,left:20});let b=()=>B.createElement(A,{style:w.iconContainer},B.createElement(A,{style:w.bowContainer},B.createElement(A,{style:[w.bowLoop,w.bowLeft]}),B.createElement(A,{style:[w.bowLoop,w.bowRight]})),B.createElement(A,{style:w.giftLid}),B.createElement(A,{style:w.giftBody},B.createElement(A,{style:w.ribbonVertical})));return B.createElement(Ne,{style:[c?w.edgeButton:w.floatingButton,{backgroundColor:s},d[o],c&&(m?w.edgeRight:w.edgeLeft)],onPress:n,activeOpacity:.9},B.createElement(A,{style:w.content},b()),B.createElement(pe.View,{style:[w.shimmer,{transform:[{translateX:p},{skewX:"-15deg"}]}]}))},w=Me.create({floatingButton:{position:"absolute",width:60,height:60,borderRadius:30,justifyContent:"center",alignItems:"center",overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:8},shadowOpacity:.2,shadowRadius:12,elevation:8,zIndex:2147483646},edgeButton:{position:"absolute",width:50,height:50,justifyContent:"center",alignItems:"center",overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:4},shadowOpacity:.1,shadowRadius:8,elevation:4,zIndex:2147483646},edgeRight:{borderTopLeftRadius:8,borderBottomLeftRadius:8,paddingLeft:4},edgeLeft:{borderTopRightRadius:8,borderBottomRightRadius:8,paddingRight:4},content:{justifyContent:"center",alignItems:"center"},iconContainer:{width:28,height:28,justifyContent:"center",alignItems:"center"},bowContainer:{flexDirection:"row",position:"absolute",top:0,zIndex:2},bowLoop:{width:10,height:8,borderWidth:2,borderColor:"#fff",borderRadius:5},bowLeft:{marginRight:-1,transform:[{rotate:"-15deg"}]},bowRight:{marginLeft:-1,transform:[{rotate:"15deg"}]},giftLid:{width:22,height:5,backgroundColor:"#fff",borderRadius:1,marginTop:6,zIndex:3},giftBody:{width:18,height:12,borderWidth:2,borderColor:"#fff",borderTopWidth:0,borderBottomLeftRadius:2,borderBottomRightRadius:2,justifyContent:"center",alignItems:"center",marginTop:-1},ribbonVertical:{width:2,height:"100%",backgroundColor:"#fff",opacity:.8},shimmer:{position:"absolute",top:0,left:0,width:50,height:"100%",backgroundColor:"rgba(255, 255, 255, 0.25)"}});import W,{useEffect as $e,useRef as He,useState as _e}from"react";import{View as Ke,Text as we,StyleSheet as qe,Animated as re,Dimensions as Xe,TouchableOpacity as Ye,Platform as Je}from"react-native";var{width:Qe}=Xe.get("window"),xe=({visible:n,options:e,onClose:s})=>{let o=He(new re.Value(0)).current,[l,c]=_e(n),m=e.position.includes("bottom")?"bottom":"top",a=e.position.includes("left")?"left":e.position.includes("right")?"right":"center";if($e(()=>{n?(c(!0),re.spring(o,{toValue:1,useNativeDriver:!0,tension:50,friction:8}).start()):re.timing(o,{toValue:0,duration:250,useNativeDriver:!0}).start(()=>{c(!1)})},[n]),!l)return null;let g=o.interpolate({inputRange:[0,1],outputRange:[m==="top"?-100:100,0]}),p=o.interpolate({inputRange:[0,1],outputRange:[0,1]}),d={position:"absolute",[m]:Je.OS==="ios"?60:40,zIndex:9999};return a==="center"?(d.left=20,d.right=20,d.alignItems="center"):d[a]=20,W.createElement(re.View,{style:[d,{transform:[{translateY:g}],opacity:p}]},W.createElement(Ke,{style:[K.banner,{backgroundColor:e.themeColor||"#2563eb"}]},W.createElement(we,{style:K.icon},"\u{1F381}"),W.createElement(we,{style:K.text},e.text),W.createElement(Ye,{onPress:s,style:K.closeBtn},W.createElement(we,{style:K.closeIcon},"\u2715"))))},K=qe.create({banner:{flexDirection:"row",alignItems:"center",padding:12,paddingHorizontal:16,borderRadius:12,shadowColor:"#000",shadowOffset:{width:0,height:4},shadowOpacity:.15,shadowRadius:10,elevation:5,maxWidth:Qe-40},icon:{fontSize:18,marginRight:10},text:{color:"#fff",fontSize:14,fontWeight:"600",flex:1},closeBtn:{marginLeft:10,padding:4},closeIcon:{color:"rgba(255, 255, 255, 0.8)",fontSize:14,fontWeight:"bold"}});var Ie=Ze(void 0),it=({children:n,userId:e,...s})=>{let[o,l]=E(!1),[c,m]=E(!1),[a,g]=E(null),p=me(new J(s)),d=me(!1),b=me(null),[z,v]=E(!1),[M,ie]=E(),[ne,be]=E(!1),[y,V]=E(),[q,j]=E(!1),[$,ae]=E(),X=U(()=>{let{width:f,height:i}=tt.get("window"),h=Intl.DateTimeFormat().resolvedOptions().locale,k=rt.get(),T,F;if(N.OS==="android"){let ce=N.constants;T=ce.Model,F=ce.Brand||ce.Manufacturer}return{os:N.OS,platform:N.OS,osVersion:String(N.Version),screenWidth:f,screenHeight:i,timezoneOffsetInMinutes:String(new Date().getTimezoneOffset()),locale:h,language:h,deviceModel:T,deviceBrand:F,pixelRatio:k}},[]),L=U(async(f,i)=>{let h=await p.current.trackReferral(f,i);return await S.setTrackedReferral(h.referralTrackingId),h},[]),Y=U(async f=>{try{let i=f.match(/[?&]referralCode=([^&]+)/);i&&(console.log("GrowthRail: Tracking referral from deep link",i[1]),await L(i[1]))}catch(i){console.warn("GrowthRail: Error handling deep link",i)}},[L]),O=U(async()=>{try{let f=X(),{referralTrackingId:i}=await p.current.checkDeferredDeepLink(f);i&&(console.log("GrowthRail: Found deferred referral via fingerprinting",i),await S.setTrackedReferral(i))}catch(f){console.warn("GrowthRail: Fingerprint check failed",f)}},[X]),se=U(()=>new Promise(f=>{ot.getInstallReferrerInfo(async(i,h)=>{if(!h&&i&&i.installReferrer)try{let T=decodeURIComponent(i.installReferrer).match(/[?&]referralCode=([^&]+)/);if(T){let{referralTrackingId:F}=await L(T[1]);await S.setTrackedReferral(F),console.log("GrowthRail: Tracked referral via Install Referrer")}}catch(k){console.warn("GrowthRail: Failed to process install referrer",k)}else await O();f()})}),[L,O]),R=U(async f=>{if(a?.id===f&&c)return a;let i=(async()=>{try{let h=await p.current.initAppUser(f),k={...h,id:f};return g(k),m(!0),h.referrerExperience?.trigger?.show&&be(!0),k}catch(h){throw b.current=null,h}})();return b.current=i,i},[a,c]),D=U(async f=>{let i=a;!i&&b.current&&(i=await b.current);let h=i?.id||e;if(!h)throw new Error("GrowthRail: User must be initialized before tracking a reward event.");let k=await S.getTrackedReferral();if(!k){console.warn("GrowthRail: No referral tracking ID found. Reward event not attributed.");return}return p.current.trackRewardEvent(h,k,f)},[a,e]),le=U(async()=>await S.getTrackedReferral(),[]),G=U(async()=>{if(a)return a.referralLink;if(b.current)return(await b.current).referralLink},[a]);ve(()=>{if(d.current)return;d.current=!0,(async()=>{let i=await Le.getInitialURL();i&&await Y(i);let h=Le.addEventListener("url",({url:T})=>Y(T));await S.isFirstLaunch()&&(N.OS==="android"?await se():await O()),e&&await R(e);try{let T=await p.current.getNewUserExperience(),F=await S.getTrackedReferral();T.banner?.show&&F&&(ae(T.banner),j(!0))}catch{}return l(!0),()=>h.remove()})()},[]),ve(()=>{o&&e&&a?.id!==e&&R(e)},[e,o]);let I={isInitialized:o,isUserReady:c,currentUser:a,referralCode:a?.referralCode,referralLink:a?.referralLink,showDashboard:f=>{ie(f),v(!0)},hideDashboard:()=>v(!1),initUser:R,trackReward:D,getReferralTrackingId:le,getReferralLink:G};if(!o)return null;let C=a?.referrerExperience,H={...C?.modal,...M,position:C?.trigger?.position||M?.position||"bottom-right",theme:{...C?.modal?.theme||{},...M?.theme||{}}},Be={...C,...y,trigger:{...C?.trigger||{},...y?.trigger||{}}};return oe.createElement(Ie.Provider,{value:I},n,oe.createElement(ue,{visible:z,options:H,onClose:()=>v(!1)}),ne&&oe.createElement(he,{options:Be,onPress:()=>I.showDashboard()}),q&&oe.createElement(xe,{visible:q,options:$,onClose:()=>j(!1)}))},te=()=>{let n=et(Ie);if(!n)throw new Error("useGrowthRail must be used within a GrowthRailProvider");return n};import{useState as Se,useCallback as Pe}from"react";var nt=()=>{let[n,e]=Se(!1),[s,o]=Se(null),l=te(),c=Pe(async a=>{e(!0),o(null);try{return await l.initUser(a)}catch(g){let p=g instanceof Error?g:new Error(String(g));throw o(p),p}finally{e(!1)}},[l]),m=Pe(async a=>{e(!0),o(null);try{await l.trackReward(a)}catch(g){let p=g instanceof Error?g:new Error(String(g));throw o(p),p}finally{e(!1)}},[l]);return{initAppUser:c,trackRewardEvent:m,showReferralDashboard:l.showDashboard,hideReferralDashboard:l.hideDashboard,getReferralTrackingId:l.getReferralTrackingId,getReferralLink:l.getReferralLink,isLoading:n,isInitialized:l.isInitialized,isUserReady:l.isUserReady,error:s}};export{it as GrowthRailProvider,ue as ReferralDashboard,he as TriggerButton,nt as useGrowthRail};
|