@growth-rail/react-native 2.0.1 → 2.0.3

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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # @growth-rail/react-native
2
2
 
3
+ ## 2.0.3
4
+
5
+ ### Patch Changes
6
+
7
+ - Build failure fix
8
+
9
+ ## 2.0.2
10
+
11
+ ### Patch Changes
12
+
13
+ - Debug mode
14
+
3
15
  ## 2.0.1
4
16
 
5
17
  ### Patch Changes
package/README.md CHANGED
@@ -34,6 +34,8 @@ const App = () => {
34
34
  <GrowthRailProvider
35
35
  projectSecretKey="YOUR_PROJECT_SECRET_KEY"
36
36
  userId="USER_UNIQUE_ID" // optional at start
37
+ appearance="dark" // "light", "dark", or omit for system default
38
+ debug={true} // Enable verbose console logging
37
39
  >
38
40
  <YourAppContent />
39
41
  </GrowthRailProvider>
@@ -132,7 +134,10 @@ const MyProfile = () => {
132
134
  const { showReferralDashboard } = useGrowthRail();
133
135
 
134
136
  return (
135
- <Button title="Refer & Earn" onPress={() => showReferralDashboard()} />
137
+ <Button
138
+ title="Refer & Earn"
139
+ onPress={() => showReferralDashboard({ appearance: 'dark' })}
140
+ />
136
141
  );
137
142
  };
138
143
  ```
@@ -150,6 +155,19 @@ const getLink = async () => {
150
155
  };
151
156
  ```
152
157
 
158
+ ## Theme & Appearance
159
+
160
+ The SDK supports light and dark modes out of the box.
161
+
162
+ - **System Default**: If no appearance is specified, the SDK follows the user's system setting using `useColorScheme()`.
163
+ - **Global Setting**: Set the `appearance` prop on `GrowthRailProvider`.
164
+ - **Manual Override**: Pass `appearance` to `showReferralDashboard({ appearance: 'dark' })`.
165
+
166
+ ### Standard Colors
167
+ The SDK uses a premium, neutral color palette designed to fit seamlessly into any application:
168
+ - **Light**: Clean white background with high-contrast Gray 900 text.
169
+ - **Dark**: Deep Gray 900 background with soft Gray 50 text for reduced eye strain and optimal readability.
170
+
153
171
  ## API Reference
154
172
 
155
173
  ### `GrowthRailProvider` Props
@@ -157,8 +175,17 @@ const getLink = async () => {
157
175
  | :--- | :--- | :--- |
158
176
  | `projectSecretKey` | `string` | Your GrowthRail Project Secret Key. |
159
177
  | `userId` | `string` | (Optional) The current user's unique ID. |
178
+ | `appearance` | `'light' \| 'dark'` | (Optional) Force a specific theme. Defaults to system. |
179
+ | `debug` | `boolean` | (Optional) Enable verbose console logging. |
160
180
  | `apiUrl` | `string` | (Optional) Custom API endpoint. |
161
181
 
182
+ ### `ReferrerModalOptions`
183
+ Options passed to `showReferralDashboard(options)`:
184
+ - `title`: `string` - Override the dashboard title.
185
+ - `description`: `string` - Override the dashboard description.
186
+ - `appearance`: `'light' \| 'dark'` - Override the appearance for this call.
187
+ - `theme.primaryColor`: `string` - Your brand color (e.g., `#2563eb`).
188
+
162
189
  ### `useGrowthRail()`
163
190
  Provides access to SDK methods and state:
164
191
  - `initAppUser(userId)`: Initializes a user in the GrowthRail system.
package/dist/index.d.mts CHANGED
@@ -4,6 +4,7 @@ type GrowthRailOptions = {
4
4
  projectSecretKey: string;
5
5
  cookieDomain?: string;
6
6
  autoPageTrack?: boolean;
7
+ appearance?: 'light' | 'dark';
7
8
  };
8
9
  type AppUserType = {
9
10
  attributes: Record<string, unknown>;
@@ -24,19 +25,16 @@ type TrackReferralResponse = {
24
25
  };
25
26
  type TriggerButtonPosition = 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
26
27
  type ReferrerTriggerButton = {
27
- show: boolean;
28
28
  position: TriggerButtonPosition;
29
- displayMode: 'floating' | 'edge';
29
+ displayMode: 'floating' | 'edge' | 'none';
30
30
  };
31
31
  type ReferrerModalOptions = {
32
32
  title: string;
33
33
  description: string;
34
34
  componentType: 'modal' | 'drawer';
35
+ appearance?: 'light' | 'dark';
35
36
  theme: {
36
37
  primaryColor: string;
37
- tintColor: string;
38
- tintAlpha: number;
39
- backgroundColor: string;
40
38
  };
41
39
  };
42
40
  interface ReferrerExperience {
@@ -58,6 +56,8 @@ interface NewUserExperience {
58
56
  interface GrowthRailProviderProps extends GrowthRailOptions {
59
57
  /** The unique ID for the current application user. */
60
58
  userId?: string;
59
+ /** Enable the debug overlay for inspecting SDK state, events, and API calls. */
60
+ debug?: boolean;
61
61
  /** Your application components. */
62
62
  children: React.ReactNode;
63
63
  }
@@ -107,6 +107,8 @@ interface UseGrowthRailReturn {
107
107
  isUserReady: boolean;
108
108
  /** The last error that occurred during an operation. */
109
109
  error: Error | null;
110
+ /** Whether the debug overlay is enabled. */
111
+ isDebugEnabled: boolean;
110
112
  }
111
113
  /**
112
114
  * A hook that provides access to GrowthRail SDK methods and state in React Native.
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@ type GrowthRailOptions = {
4
4
  projectSecretKey: string;
5
5
  cookieDomain?: string;
6
6
  autoPageTrack?: boolean;
7
+ appearance?: 'light' | 'dark';
7
8
  };
8
9
  type AppUserType = {
9
10
  attributes: Record<string, unknown>;
@@ -24,19 +25,16 @@ type TrackReferralResponse = {
24
25
  };
25
26
  type TriggerButtonPosition = 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
26
27
  type ReferrerTriggerButton = {
27
- show: boolean;
28
28
  position: TriggerButtonPosition;
29
- displayMode: 'floating' | 'edge';
29
+ displayMode: 'floating' | 'edge' | 'none';
30
30
  };
31
31
  type ReferrerModalOptions = {
32
32
  title: string;
33
33
  description: string;
34
34
  componentType: 'modal' | 'drawer';
35
+ appearance?: 'light' | 'dark';
35
36
  theme: {
36
37
  primaryColor: string;
37
- tintColor: string;
38
- tintAlpha: number;
39
- backgroundColor: string;
40
38
  };
41
39
  };
42
40
  interface ReferrerExperience {
@@ -58,6 +56,8 @@ interface NewUserExperience {
58
56
  interface GrowthRailProviderProps extends GrowthRailOptions {
59
57
  /** The unique ID for the current application user. */
60
58
  userId?: string;
59
+ /** Enable the debug overlay for inspecting SDK state, events, and API calls. */
60
+ debug?: boolean;
61
61
  /** Your application components. */
62
62
  children: React.ReactNode;
63
63
  }
@@ -107,6 +107,8 @@ interface UseGrowthRailReturn {
107
107
  isUserReady: boolean;
108
108
  /** The last error that occurred during an operation. */
109
109
  error: Error | null;
110
+ /** Whether the debug overlay is enabled. */
111
+ isDebugEnabled: boolean;
110
112
  }
111
113
  /**
112
114
  * A hook that provides access to GrowthRail SDK methods and state in React Native.
package/dist/index.js CHANGED
@@ -1 +1 @@
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 ce=(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){ce(this,"baseUrl");ce(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"},E=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:de}=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",U=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 D="",I=encodeURIComponent(l),H=encodeURIComponent("Check this out!");switch(G){case"twitter":D=`https://twitter.com/intent/tweet?url=${I}&text=${H}`;break;case"facebook":D=`https://www.facebook.com/sharer/sharer.php?u=${I}`;break;case"linkedin":D=`https://www.linkedin.com/sharing/share-offsite/?url=${I}`;break;case"whatsapp":D=`whatsapp://send?text=${H}%20${I}`;break;case"email":D=`mailto:?subject=Check this out&body=${H}%20${I}`;break}D&&t.Linking.openURL(D).catch(()=>{})},Q=()=>ie||"#000000",O=[];v?U.includes("right")?O=[{translateX:g.interpolate({inputRange:[0,1],outputRange:[pe,0]})}]:U.includes("left")?O=[{translateX:g.interpolate({inputRange:[0,1],outputRange:[-pe,0]})}]:O=[{translateY:g.interpolate({inputRange:[0,1],outputRange:[de,0]})}]:O=[{scale:g.interpolate({inputRange:[0,1],outputRange:[.9,1]})},{translateY:g.interpolate({inputRange:[0,1],outputRange:[20,0]})}];let ge=U.includes("top"),L=U.includes("right"),A=U.includes("left"),se=v?{position:"absolute",...ge?{top:100}:{bottom:100},...L?{right:0}:A?{left:0}:{left:0,right:0},width:L||A?"85%":"100%",maxHeight:L||A?de-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?se:i.centeredModalContainer,{backgroundColor:M,transform:O},v&&L&&{borderTopLeftRadius:24,borderBottomLeftRadius:24},v&&A&&{borderTopRightRadius:24,borderBottomRightRadius:24},v&&!L&&!A&&U.includes("bottom")&&{borderTopLeftRadius:24,borderTopRightRadius:24},v&&!L&&!A&&U.includes("top")&&{borderBottomLeftRadius:24,borderBottomRightRadius:24},!v&&{borderRadius:24,opacity:g}]},r.default.createElement(t.View,{style:i.contentWrapper},v&&!L&&!A&&U.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:de*.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,fe]=(0,n.useState)(!1),[v,U]=(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 le=C.Platform.constants;P=le.Model,F=le.Brand||le.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 E.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]),O=(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 E.setTrackedReferral(c))}catch(u){console.warn("GrowthRail: Fingerprint check failed",u)}},[J]),ge=(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 E.setTrackedReferral(F),console.log("GrowthRail: Tracked referral via Install Referrer")}}catch(S){console.warn("GrowthRail: Failed to process install referrer",S)}else await O();u()})}),[V,O]),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&&fe(!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 E.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]),se=(0,n.useCallback)(async()=>await E.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 E.isFirstLaunch()&&(C.Platform.OS==="android"?await O():await O()),e&&await L(e);try{let P=await m.current.getNewUserExperience(),F=await E.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 D={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:se,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:D},o,n.default.createElement(te,{visible:z,options:H,onClose:()=>B(!1)}),ne&&n.default.createElement(oe,{options:Re,onPress:()=>D.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});
1
+ "use strict";var Ce=Object.create;var Y=Object.defineProperty;var xe=Object.getOwnPropertyDescriptor;var Te=Object.getOwnPropertyNames;var ve=Object.getPrototypeOf,Le=Object.prototype.hasOwnProperty;var Se=(i,e,r)=>e in i?Y(i,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):i[e]=r;var Ie=(i,e)=>{for(var r in e)Y(i,r,{get:e[r],enumerable:!0})},ge=(i,e,r,l)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Te(e))!Le.call(i,n)&&n!==r&&Y(i,n,{get:()=>e[n],enumerable:!(l=xe(e,n))||l.enumerable});return i};var N=(i,e,r)=>(r=i!=null?Ce(ve(i)):{},ge(e||!i||!i.__esModule?Y(r,"default",{value:i,enumerable:!0}):r,i)),De=i=>ge(Y({},"__esModule",{value:!0}),i);var re=(i,e,r)=>Se(i,typeof e!="symbol"?e+"":e,r);var Ve={};Ie(Ve,{GrowthRailProvider:()=>be,ReferralDashboard:()=>ie,TriggerButton:()=>ae,useGrowthRail:()=>me});module.exports=De(Ve);var s=N(require("react")),T=require("react-native"),pe=N(require("react-native-play-install-referrer"));var Be="[GrowthRail]",g={log(i,e,r,l){let n=`${Be} [${e}] ${r}`;switch(i){case"error":console.error(n,l||"");break;case"warn":console.warn(n,l||"");break;default:console.log(n,l||"");break}}};var te=class{constructor(e){re(this,"baseUrl");re(this,"projectSecretKey");re(this,"_debug",!1);let r=typeof process<"u"&&process.env?.ENV_BASE_URL;this.baseUrl=r||"https://api.growthrail.dev",this.projectSecretKey=e.projectSecretKey}setDebug(e){this._debug=e}async request(e,r,l){let n={"Content-Type":"application/json","X-GrowthRail-ProjectSecret":this.projectSecretKey,Origin:this.baseUrl},R=Date.now();this._debug&&g.log("api","APIClient",`${r} ${e}`,{method:r,endpoint:e,body:l??null});try{let p=await fetch(`${this.baseUrl}${e}`,{method:r,headers:n,body:l?JSON.stringify(l):void 0}),y=Date.now()-R;if(!p.ok){let c="";try{c=await p.text()}catch{}let k=`GrowthRail API Error ${p.status} (${this.baseUrl}${e}): ${p.statusText} - ${c}`;throw this._debug&&g.log("api","APIClient",`\u2717 ${r} ${e}`,{method:r,endpoint:e,status:p.status,duration:y,error:c}),new Error(k)}return this._debug&&g.log("api","APIClient",`\u2713 ${r} ${e}`,{method:r,endpoint:e,status:p.status,duration:y}),p.json()}catch(p){let y=Date.now()-R;throw this._debug&&g.log("api","APIClient",`\u2717 ${r} ${e} \u2014 Network error`,{method:r,endpoint:e,duration:y,error:String(p)}),console.error("GrowthRail SDK Error:",p),p}}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,r){return this.request("/api/v1/sdk/track-referral","POST",{referralCode:e,rewardEventName:r})}async trackRewardEvent(e,r,l){return this.request("/api/v1/sdk/track-reward-event","POST",{refereeId:e,referralTrackingId:r,eventName:l})}async checkDeferredDeepLink(e){return this.request("/api/v1/sdk/match-link","POST",{fingerprint:e})}};var X=N(require("@react-native-async-storage/async-storage")),oe={TRACKED_REFERRAL:"growth-rail-tracked-referral",IS_FIRST_LAUNCH:"growth-rail-is-first-launch"},B=class{static async setTrackedReferral(e){await X.default.setItem(oe.TRACKED_REFERRAL,e)}static async getTrackedReferral(){return await X.default.getItem(oe.TRACKED_REFERRAL)}static async isFirstLaunch(){return await X.default.getItem(oe.IS_FIRST_LAUNCH)===null?(await X.default.setItem(oe.IS_FIRST_LAUNCH,"false"),!0):!1}};var o=N(require("react")),t=require("react-native");var{width:We,height:ue}=t.Dimensions.get("window"),ie=({visible:i,options:e,onClose:r})=>{let l=ne(),[n,R]=(0,o.useState)(null),[p,y]=(0,o.useState)(!1),[c,k]=(0,o.useState)(!1),h=(0,o.useRef)(new t.Animated.Value(0)).current,O=(0,o.useRef)(new t.Animated.Value(0)).current,D=(0,t.useColorScheme)(),v=(e?.appearance||D||"light")==="dark",_=e?.title||"Invite Friends & Earn",V=e?.theme?.primaryColor||"#2563eb",E=(e?.componentType||"modal")==="drawer",G=e?.position||"bottom-right",d={background:v?"#111827":"#ffffff",text:v?"#f9fafb":"#111827",textSecondary:v?"#9ca3af":"#6b7280",border:v?"#374151":"#e5e7eb",inputBg:v?"#1f2937":"#f9fafb",closeBtnBg:v?"#1f2937":"#f3f4f6",closeIcon:v?"#6b7280":"#9ca3af",drawerHandle:v?"#4b5563":"#e5e7eb",overlay:"#000000",overlayOpacity:.5};(0,o.useEffect)(()=>{i?(n||Z(),t.Animated.parallel([t.Animated.timing(O,{toValue:1,duration:300,useNativeDriver:!0}),t.Animated.spring(h,{toValue:1,useNativeDriver:!0,tension:50,friction:8})]).start()):(h.setValue(0),O.setValue(0))},[i]);let $=()=>{t.Animated.parallel([t.Animated.timing(O,{toValue:0,duration:250,useNativeDriver:!0}),t.Animated.timing(h,{toValue:0,duration:250,useNativeDriver:!0})]).start(()=>{r()})},Z=async()=>{y(!0);try{if(l.isUserReady){let A=await l.getReferralLink();R(A||null)}}catch(A){console.error("GrowthRail: Failed to load referral link",A)}finally{y(!1)}},se=()=>{n&&(t.Clipboard.setString(n),k(!0),setTimeout(()=>k(!1),2e3))},z=A=>{if(!n)return;let U="",F=encodeURIComponent(n),W=encodeURIComponent("Check this out!");switch(A){case"twitter":U=`https://twitter.com/intent/tweet?url=${F}&text=${W}`;break;case"facebook":U=`https://www.facebook.com/sharer/sharer.php?u=${F}`;break;case"linkedin":U=`https://www.linkedin.com/sharing/share-offsite/?url=${F}`;break;case"whatsapp":U=`whatsapp://send?text=${W}%20${F}`;break;case"email":U=`mailto:?subject=Check this out&body=${W}%20${F}`;break}U&&t.Linking.openURL(U).catch(()=>{})},ee=()=>d.overlay,P=[];E?P=[{translateY:h.interpolate({inputRange:[0,1],outputRange:[ue,0]})}]:P=[{scale:h.interpolate({inputRange:[0,1],outputRange:[.9,1]})},{translateY:h.interpolate({inputRange:[0,1],outputRange:[20,0]})}];let le=G.includes("top"),H=G.includes("right"),ye=G.includes("left"),K=E?{position:"absolute",bottom:0,left:0,right:0,width:"100%",maxHeight:"90%"}:{};return o.default.createElement(t.Modal,{visible:i,transparent:!0,animationType:"none",onRequestClose:$},o.default.createElement(t.View,{style:a.fullScreen},o.default.createElement(t.Animated.View,{style:[a.overlay,{backgroundColor:ee(),opacity:O.interpolate({inputRange:[0,1],outputRange:[0,d.overlayOpacity]})}]},o.default.createElement(t.TouchableOpacity,{style:a.fullScreen,activeOpacity:1,onPress:$})),o.default.createElement(t.Animated.View,{style:[E?K:a.centeredModalContainer,{backgroundColor:d.background,transform:P},E&&{borderTopLeftRadius:24,borderTopRightRadius:24,borderBottomLeftRadius:0,borderBottomRightRadius:0},!E&&{borderRadius:24,opacity:h,borderColor:d.border,borderWidth:v?1:0}]},o.default.createElement(t.View,{style:a.contentWrapper},E&&o.default.createElement(t.View,{style:[a.drawerHandle,{backgroundColor:d.drawerHandle}]}),o.default.createElement(t.TouchableOpacity,{style:[a.closeBtn,{backgroundColor:d.closeBtnBg}],onPress:$},o.default.createElement(t.Text,{style:[a.closeIcon,{color:d.closeIcon}]},"\u2715")),o.default.createElement(t.ScrollView,{contentContainerStyle:a.scrollContent,showsVerticalScrollIndicator:!1},o.default.createElement(t.View,{style:a.header},o.default.createElement(t.View,{style:a.iconLgContainer},o.default.createElement(t.View,{style:a.bowContainerLg},o.default.createElement(t.View,{style:[a.bowLoopLg,a.bowLeftLg,{borderColor:V}]}),o.default.createElement(t.View,{style:[a.bowLoopLg,a.bowRightLg,{borderColor:V}]})),o.default.createElement(t.View,{style:[a.giftLidLg,{backgroundColor:V}]}),o.default.createElement(t.View,{style:[a.giftBodyLg,{borderColor:V}]},o.default.createElement(t.View,{style:[a.ribbonVerticalLg,{backgroundColor:"#fff",opacity:.3}]}))),o.default.createElement(t.Text,{style:[a.title,{color:d.text}]},_),o.default.createElement(t.Text,{style:[a.subtitle,{color:d.textSecondary}]},e?.description||"Share your unique link and earn rewards for every friend who signs up.")),l.isUserReady?p?o.default.createElement(t.ActivityIndicator,{size:"large",color:V,style:a.loader}):o.default.createElement(t.View,{style:a.mainContent},o.default.createElement(t.Text,{style:[a.label,{color:d.textSecondary}]},"YOUR UNIQUE LINK"),o.default.createElement(t.View,{style:[a.inputGroup,{backgroundColor:d.inputBg,borderColor:d.border}]},o.default.createElement(t.Text,{numberOfLines:1,style:[a.input,{color:d.text}]},n||"Initializing..."),o.default.createElement(t.TouchableOpacity,{style:[a.copyBtn,{backgroundColor:c?"#10b981":V}],onPress:se},o.default.createElement(t.Text,{style:a.copyBtnText},c?"Copied!":"Copy"))),o.default.createElement(t.View,{style:a.shareLabelContainer},o.default.createElement(t.View,{style:[a.divider,{backgroundColor:d.border}]}),o.default.createElement(t.Text,{style:[a.shareLabel,{color:d.textSecondary}]},"Share via"),o.default.createElement(t.View,{style:[a.divider,{backgroundColor:d.border}]})),o.default.createElement(t.View,{style:a.socialContainer},o.default.createElement(J,{platform:"twitter",color:v?"#FFFFFF":"#000000",onPress:()=>z("twitter"),icon:"\u{1D54F}",borderColor:d.border,bgColor:d.background}),o.default.createElement(J,{platform:"facebook",color:"#1877F2",onPress:()=>z("facebook"),icon:"f",borderColor:d.border,bgColor:d.background}),o.default.createElement(J,{platform:"linkedin",color:"#0A66C2",onPress:()=>z("linkedin"),icon:"in",borderColor:d.border,bgColor:d.background}),o.default.createElement(J,{platform:"whatsapp",color:"#25D366",onPress:()=>z("whatsapp"),icon:"W",borderColor:d.border,bgColor:d.background}),o.default.createElement(J,{platform:"email",color:d.textSecondary,onPress:()=>z("email"),icon:"\u2709",borderColor:d.border,bgColor:d.background}))):o.default.createElement(t.View,{style:[a.loadingBox,{backgroundColor:d.inputBg,borderColor:d.border}]},o.default.createElement(t.Text,{style:{color:d.textSecondary,textAlign:"center"}},"Please log in to view your referral dashboard.")),o.default.createElement(t.View,{style:a.footer},o.default.createElement(t.Text,{style:[a.poweredBy,{color:d.textSecondary}]},"Powered by ",o.default.createElement(t.Text,{style:[a.brand,{color:V}],onPress:()=>t.Linking.openURL("https://growthrail.com")},"Growth Rail"))))))))},J=({color:i,onPress:e,icon:r,borderColor:l,bgColor:n})=>o.default.createElement(t.TouchableOpacity,{style:[a.socialBtn,{borderColor:l,backgroundColor:n}],onPress:e},o.default.createElement(t.Text,{style:[a.socialIcon,{color:i}]},r)),a=t.StyleSheet.create({fullScreen:{flex:1},overlay:{...t.StyleSheet.absoluteFillObject},centeredModalContainer:{width:"90%",maxWidth:400,alignSelf:"center",marginTop:ue*.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 x=N(require("react")),b=require("react-native"),ae=({onPress:i,options:e})=>{let r=e?.modal?.theme?.primaryColor||"#2563eb",l=e?.trigger?.position||"bottom-right",R=(e?.trigger?.displayMode||"floating")==="edge",p=l.includes("right"),y=l.includes("top"),c=(0,x.useRef)(new b.Animated.Value(-1)).current;(0,x.useEffect)(()=>{let D=()=>{c.setValue(-1),b.Animated.timing(c,{toValue:2,duration:3e3,easing:b.Easing.linear,useNativeDriver:!0}).start(()=>{setTimeout(D,1e3)})};D()},[]);let k=c.interpolate({inputRange:[-1,2],outputRange:R?[-50,100]:[-60,120]}),h={"bottom-right":{bottom:100,right:0},"bottom-left":{bottom:100,left:0},"top-right":{top:100,right:0},"top-left":{top:100,left:0}};R||(h["bottom-right"]={bottom:30,right:20},h["bottom-left"]={bottom:30,left:20},h["top-right"]={top:60,right:20},h["top-left"]={top:60,left:20});let O=()=>x.default.createElement(b.View,{style:C.iconContainer},x.default.createElement(b.View,{style:C.bowContainer},x.default.createElement(b.View,{style:[C.bowLoop,C.bowLeft]}),x.default.createElement(b.View,{style:[C.bowLoop,C.bowRight]})),x.default.createElement(b.View,{style:C.giftLid}),x.default.createElement(b.View,{style:C.giftBody},x.default.createElement(b.View,{style:C.ribbonVertical})));return x.default.createElement(b.TouchableOpacity,{style:[R?C.edgeButton:C.floatingButton,{backgroundColor:r},h[l],R&&(p?C.edgeRight:C.edgeLeft)],onPress:i,activeOpacity:.9},x.default.createElement(b.View,{style:C.content},O()),x.default.createElement(b.Animated.View,{style:[C.shimmer,{transform:[{translateX:k},{skewX:"-15deg"}]}]}))},C=b.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 I=N(require("react")),m=require("react-native"),{width:Oe}=m.Dimensions.get("window"),he=({visible:i,options:e,onClose:r})=>{let l=(0,I.useRef)(new m.Animated.Value(0)).current,[n,R]=(0,I.useState)(i),p=e.position.includes("bottom")?"bottom":"top",y=e.position.includes("left")?"left":e.position.includes("right")?"right":"center";if((0,I.useEffect)(()=>{i?(R(!0),m.Animated.spring(l,{toValue:1,useNativeDriver:!0,tension:50,friction:8}).start()):m.Animated.timing(l,{toValue:0,duration:250,useNativeDriver:!0}).start(()=>{R(!1)})},[i]),!n)return null;let c=l.interpolate({inputRange:[0,1],outputRange:[p==="top"?-100:100,0]}),k=l.interpolate({inputRange:[0,1],outputRange:[0,1]}),h={position:"absolute",[p]:m.Platform.OS==="ios"?60:40,zIndex:9999};return y==="center"?(h.left=20,h.right=20,h.alignItems="center"):h[y]=20,I.default.createElement(m.Animated.View,{style:[h,{transform:[{translateY:c}],opacity:k}]},I.default.createElement(m.View,{style:[Q.banner,{backgroundColor:e.themeColor||"#2563eb"}]},I.default.createElement(m.Text,{style:Q.icon},"\u{1F381}"),I.default.createElement(m.Text,{style:Q.text},e.text),I.default.createElement(m.TouchableOpacity,{onPress:r,style:Q.closeBtn},I.default.createElement(m.Text,{style:Q.closeIcon},"\u2715"))))},Q=m.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:Oe-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=(0,s.createContext)(void 0),be=({children:i,userId:e,debug:r=!1,...l})=>{let[n,R]=(0,s.useState)(!1),[p,y]=(0,s.useState)(!1),[c,k]=(0,s.useState)(null),h=(0,s.useRef)(new te(l)),O=(0,s.useRef)(!1),D=(0,s.useRef)(null),[de,v]=(0,s.useState)(!1),[_,V]=(0,s.useState)(),[fe,E]=(0,s.useState)(!1),[G,d]=(0,s.useState)(),[$,Z]=(0,s.useState)(!1),[se,z]=(0,s.useState)();(0,s.useEffect)(()=>{h.current.setDebug(r),r&&g.log("info","Provider","Debug mode enabled")},[r]);let ee=(0,s.useCallback)(()=>{let{width:u,height:f}=T.Dimensions.get("window"),w=Intl.DateTimeFormat().resolvedOptions().locale,S=T.PixelRatio.get(),L,M;if(T.Platform.OS==="android"){let ce=T.Platform.constants;L=ce.Model,M=ce.Brand||ce.Manufacturer}return{os:T.Platform.OS,platform:T.Platform.OS,osVersion:String(T.Platform.Version),screenWidth:u,screenHeight:f,timezoneOffsetInMinutes:String(new Date().getTimezoneOffset()),locale:w,language:w,deviceModel:L,deviceBrand:M,pixelRatio:S}},[]),P=(0,s.useCallback)(async(u,f)=>{r&&g.log("info","Referral",`Tracking referral code: ${u}`,{referralCode:u,rewardEventName:f});let w=await h.current.trackReferral(u,f);return await B.setTrackedReferral(w.referralTrackingId),r&&g.log("success","Referral",`Referral tracked \u2192 ${w.referralTrackingId}`,w),w},[r]),le=(0,s.useCallback)(async u=>{try{r&&g.log("info","DeepLink",`Received deep link: ${u}`);let f=u.match(/[?&]referralCode=([^&]+)/);f&&(console.log("GrowthRail: Tracking referral from deep link",f[1]),r&&g.log("info","DeepLink",`Found referral code in deep link: ${f[1]}`),await P(f[1]))}catch(f){console.warn("GrowthRail: Error handling deep link",f),r&&g.log("error","DeepLink","Deep link handling failed",{error:String(f)})}},[P,r]),H=(0,s.useCallback)(async()=>{try{r&&g.log("info","Deferred","Checking deferred deep link via fingerprint");let u=ee(),{referralTrackingId:f}=await h.current.checkDeferredDeepLink(u);f?(console.log("GrowthRail: Found deferred referral via fingerprinting",f),r&&g.log("success","Deferred",`Deferred referral matched \u2192 ${f}`),await B.setTrackedReferral(f)):r&&g.log("info","Deferred","No deferred referral match found")}catch(u){console.warn("GrowthRail: Fingerprint check failed",u),r&&g.log("error","Deferred","Fingerprint check failed",{error:String(u)})}},[ee,r]),ye=(0,s.useCallback)(()=>new Promise(u=>{pe.default.getInstallReferrerInfo(async(f,w)=>{if(!w&&f&&f.installReferrer)try{let L=decodeURIComponent(f.installReferrer).match(/[?&]referralCode=([^&]+)/);if(L){let{referralTrackingId:M}=await P(L[1]);await B.setTrackedReferral(M),console.log("GrowthRail: Tracked referral via Install Referrer")}}catch(S){console.warn("GrowthRail: Failed to process install referrer",S)}else await H();u()})}),[P,H]),K=(0,s.useCallback)(async u=>{if(c?.id===u&&p)return r&&g.log("info","User",`User ${u} already initialized, skipping`),c;r&&g.log("info","User",`Initializing user: ${u}`);let f=(async()=>{try{let w=await h.current.initAppUser(u),S={...w,id:u};return k(S),y(!0),r&&g.log("success","User",`User initialized: ${u}`,{referralCode:w.referralCode,referralLink:w.referralLink}),w.referrerExperience?.trigger?.displayMode!=="none"&&(E(!0),r&&g.log("info","UI","Trigger button shown (server-configured)")),S}catch(w){throw D.current=null,r&&g.log("error","User",`User init failed for ${u}`,{error:String(w)}),w}})();return D.current=f,f},[c,p,r]),A=(0,s.useCallback)(async u=>{r&&g.log("info","Reward",`Tracking reward event: ${u||"(default)"}`);let f=c;!f&&D.current&&(f=await D.current);let w=f?.id||e;if(!w)throw r&&g.log("error","Reward","Cannot track reward \u2014 user not initialized"),new Error("GrowthRail: User must be initialized before tracking a reward event.");let S=await B.getTrackedReferral();if(!S){console.warn("GrowthRail: No referral tracking ID found. Reward event not attributed."),r&&g.log("warn","Reward","No referral tracking ID in storage \u2014 reward not attributed");return}let L=await h.current.trackRewardEvent(w,S,u);return r&&g.log("success","Reward",`Reward event tracked for user ${w}`),L},[c,e,r]),U=(0,s.useCallback)(async()=>await B.getTrackedReferral(),[]),F=(0,s.useCallback)(async()=>{if(c)return c.referralLink;if(D.current)return(await D.current).referralLink},[c]);(0,s.useEffect)(()=>{if(O.current)return;O.current=!0,r&&g.log("info","Provider","SDK initializing\u2026",{platform:T.Platform.OS}),(async()=>{let f=await T.Linking.getInitialURL();r&&g.log("info","DeepLink",`Initial URL: ${f??"(none)"}`),f&&await le(f);let w=T.Linking.addEventListener("url",({url:L})=>le(L)),S=await B.isFirstLaunch();r&&g.log("info","Provider",`First launch: ${S}`),S&&(T.Platform.OS==="android"?await H():await H()),e&&await K(e);try{let L=await h.current.getNewUserExperience(),M=await B.getTrackedReferral();L.banner?.show&&M&&(z(L.banner),Z(!0),r&&g.log("info","UI","Banner shown for new user experience"))}catch(L){r&&g.log("warn","Provider","New user experience fetch failed",{error:String(L)})}return R(!0),r&&g.log("success","Provider","SDK initialization complete \u2713"),()=>w.remove()})()},[]),(0,s.useEffect)(()=>{n&&e&&c?.id!==e&&K(e)},[e,n]);let W={isInitialized:n,isUserReady:p,currentUser:c,referralCode:c?.referralCode,referralLink:c?.referralLink,showDashboard:u=>{V(u),v(!0)},hideDashboard:()=>v(!1),initUser:K,trackReward:A,getReferralTrackingId:U,getReferralLink:F,isDebugEnabled:r};if(!n)return null;let q=c?.referrerExperience,Re={...q?.modal,..._,appearance:_?.appearance||q?.modal?.appearance||l.appearance,theme:{...q?.modal?.theme||{},..._?.theme||{}}},ke={...q,...G,trigger:{...q?.trigger||{},...G?.trigger||{}}};return s.default.createElement(we.Provider,{value:W},i,s.default.createElement(ie,{visible:de,options:Re,onClose:()=>v(!1)}),fe&&s.default.createElement(ae,{options:ke,onPress:()=>W.showDashboard()}),$&&s.default.createElement(he,{visible:$,options:se,onClose:()=>Z(!1)}))},ne=()=>{let i=(0,s.useContext)(we);if(!i)throw new Error("useGrowthRail must be used within a GrowthRailProvider");return i};var j=require("react");var me=()=>{let[i,e]=(0,j.useState)(!1),[r,l]=(0,j.useState)(null),n=ne(),R=(0,j.useCallback)(async y=>{e(!0),l(null);try{return await n.initUser(y)}catch(c){let k=c instanceof Error?c:new Error(String(c));throw l(k),k}finally{e(!1)}},[n]),p=(0,j.useCallback)(async y=>{e(!0),l(null);try{await n.trackReward(y)}catch(c){let k=c instanceof Error?c:new Error(String(c));throw l(k),k}finally{e(!1)}},[n]);return{initAppUser:R,trackRewardEvent:p,showReferralDashboard:n.showDashboard,hideReferralDashboard:n.hideDashboard,getReferralTrackingId:n.getReferralTrackingId,getReferralLink:n.getReferralLink,isLoading:i,isInitialized:n.isInitialized,isUserReady:n.isUserReady,error:r,isDebugEnabled:n.isDebugEnabled}};0&&(module.exports={GrowthRailProvider,ReferralDashboard,TriggerButton,useGrowthRail});
package/dist/index.mjs CHANGED
@@ -1 +1 @@
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 ce=(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 we,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){ce(this,"baseUrl");ce(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"},P=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 de,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 B,Dimensions as ze}from"react-native";var{width:Te,height:fe}=ze.get("window"),ge=({visible:n,options:e,onClose:s})=>{let o=te(),[l,c]=de(null),[m,a]=de(!1),[g,p]=de(!1),d=ye(new B.Value(0)).current,b=ye(new B.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",O=e?.position||"bottom-right",q="#111827",j="#6b7280";De(()=>{n?(l||ae(),B.parallel([B.timing(b,{toValue:1,duration:300,useNativeDriver:!0}),B.spring(d,{toValue:1,useNativeDriver:!0,tension:50,friction:8})]).start()):(d.setValue(0),b.setValue(0))},[n]);let $=()=>{B.parallel([B.timing(b,{toValue:0,duration:250,useNativeDriver:!0}),B.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 S="",C=encodeURIComponent(l),H=encodeURIComponent("Check this out!");switch(G){case"twitter":S=`https://twitter.com/intent/tweet?url=${C}&text=${H}`;break;case"facebook":S=`https://www.facebook.com/sharer/sharer.php?u=${C}`;break;case"linkedin":S=`https://www.linkedin.com/sharing/share-offsite/?url=${C}`;break;case"whatsapp":S=`whatsapp://send?text=${H}%20${C}`;break;case"email":S=`mailto:?subject=Check this out&body=${H}%20${C}`;break}S&&Ce.openURL(S).catch(()=>{})},Y=()=>ie||"#000000",I=[];y?O.includes("right")?I=[{translateX:d.interpolate({inputRange:[0,1],outputRange:[Te,0]})}]:O.includes("left")?I=[{translateX:d.interpolate({inputRange:[0,1],outputRange:[-Te,0]})}]:I=[{translateY:d.interpolate({inputRange:[0,1],outputRange:[fe,0]})}]:I=[{scale:d.interpolate({inputRange:[0,1],outputRange:[.9,1]})},{translateY:d.interpolate({inputRange:[0,1],outputRange:[20,0]})}];let be=O.includes("top"),R=O.includes("right"),D=O.includes("left"),se=y?{position:"absolute",...be?{top:100}:{bottom:100},...R?{right:0}:D?{left:0}:{left:0,right:0},width:R||D?"85%":"100%",maxHeight:R||D?fe-200:"80%"}:{};return t.createElement(Ee,{visible:n,transparent:!0,animationType:"none",onRequestClose:$},t.createElement(u,{style:r.fullScreen},t.createElement(B.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(B.View,{style:[y?se:r.centeredModalContainer,{backgroundColor:M,transform:I},y&&R&&{borderTopLeftRadius:24,borderBottomLeftRadius:24},y&&D&&{borderTopRightRadius:24,borderBottomRightRadius:24},y&&!R&&!D&&O.includes("bottom")&&{borderTopLeftRadius:24,borderTopRightRadius:24},y&&!R&&!D&&O.includes("top")&&{borderBottomLeftRadius:24,borderBottomRightRadius:24},!y&&{borderRadius:24,opacity:d}]},t.createElement(u,{style:r.contentWrapper},y&&!R&&!D&&O.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:fe*.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 V,{useEffect as Fe,useRef as We}from"react";import{TouchableOpacity as Ne,View as A,StyleSheet as Me,Animated as ue,Easing as je}from"react-native";var pe=({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 ue.Value(-1)).current;Fe(()=>{let z=()=>{g.setValue(-1),ue.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=()=>V.createElement(A,{style:w.iconContainer},V.createElement(A,{style:w.bowContainer},V.createElement(A,{style:[w.bowLoop,w.bowLeft]}),V.createElement(A,{style:[w.bowLoop,w.bowRight]})),V.createElement(A,{style:w.giftLid}),V.createElement(A,{style:w.giftBody},V.createElement(A,{style:w.ribbonVertical})));return V.createElement(Ne,{style:[c?w.edgeButton:w.floatingButton,{backgroundColor:s},d[o],c&&(m?w.edgeRight:w.edgeLeft)],onPress:n,activeOpacity:.9},V.createElement(A,{style:w.content},b()),V.createElement(ue.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 he,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(he,{style:K.icon},"\u{1F381}"),W.createElement(he,{style:K.text},e.text),W.createElement(Ye,{onPress:s,style:K.closeBtn},W.createElement(he,{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=we(new J(s)),d=we(!1),b=we(null),[z,v]=E(!1),[M,ie]=E(),[ne,me]=E(!1),[y,O]=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 le=N.constants;T=le.Model,F=le.Brand||le.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 P.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]),I=U(async()=>{try{let f=X(),{referralTrackingId:i}=await p.current.checkDeferredDeepLink(f);i&&(console.log("GrowthRail: Found deferred referral via fingerprinting",i),await P.setTrackedReferral(i))}catch(f){console.warn("GrowthRail: Fingerprint check failed",f)}},[X]),be=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 P.setTrackedReferral(F),console.log("GrowthRail: Tracked referral via Install Referrer")}}catch(k){console.warn("GrowthRail: Failed to process install referrer",k)}else await I();f()})}),[L,I]),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&&me(!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 P.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]),se=U(async()=>await P.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 P.isFirstLaunch()&&(N.OS==="android"?await I():await I()),e&&await R(e);try{let T=await p.current.getNewUserExperience(),F=await P.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 S={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:se,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:S},n,oe.createElement(ge,{visible:z,options:H,onClose:()=>v(!1)}),ne&&oe.createElement(pe,{options:Be,onPress:()=>S.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,ge as ReferralDashboard,pe as TriggerButton,nt as useGrowthRail};
1
+ var Ve=Object.defineProperty;var Ue=(f,e,r)=>e in f?Ve(f,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):f[e]=r;var Z=(f,e,r)=>Ue(f,typeof e!="symbol"?e+"":e,r);import ae,{createContext as tr,useContext as or,useEffect as pe,useState as O,useRef as we,useCallback as V}from"react";import{Linking as ve,Platform as G,Dimensions as ir,PixelRatio as nr}from"react-native";import ar from"react-native-play-install-referrer";var Ee="[GrowthRail]",c={log(f,e,r,a){let n=`${Ee} [${e}] ${r}`;switch(f){case"error":console.error(n,a||"");break;case"warn":console.warn(n,a||"");break;default:console.log(n,a||"");break}}};var ee=class{constructor(e){Z(this,"baseUrl");Z(this,"projectSecretKey");Z(this,"_debug",!1);let r=typeof process<"u"&&process.env?.ENV_BASE_URL;this.baseUrl=r||"https://api.growthrail.dev",this.projectSecretKey=e.projectSecretKey}setDebug(e){this._debug=e}async request(e,r,a){let n={"Content-Type":"application/json","X-GrowthRail-ProjectSecret":this.projectSecretKey,Origin:this.baseUrl},b=Date.now();this._debug&&c.log("api","APIClient",`${r} ${e}`,{method:r,endpoint:e,body:a??null});try{let u=await fetch(`${this.baseUrl}${e}`,{method:r,headers:n,body:a?JSON.stringify(a):void 0}),w=Date.now()-b;if(!u.ok){let i="";try{i=await u.text()}catch{}let m=`GrowthRail API Error ${u.status} (${this.baseUrl}${e}): ${u.statusText} - ${i}`;throw this._debug&&c.log("api","APIClient",`\u2717 ${r} ${e}`,{method:r,endpoint:e,status:u.status,duration:w,error:i}),new Error(m)}return this._debug&&c.log("api","APIClient",`\u2713 ${r} ${e}`,{method:r,endpoint:e,status:u.status,duration:w}),u.json()}catch(u){let w=Date.now()-b;throw this._debug&&c.log("api","APIClient",`\u2717 ${r} ${e} \u2014 Network error`,{method:r,endpoint:e,duration:w,error:String(u)}),console.error("GrowthRail SDK Error:",u),u}}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,r){return this.request("/api/v1/sdk/track-referral","POST",{referralCode:e,rewardEventName:r})}async trackRewardEvent(e,r,a){return this.request("/api/v1/sdk/track-reward-event","POST",{refereeId:e,referralTrackingId:r,eventName:a})}async checkDeferredDeepLink(e){return this.request("/api/v1/sdk/match-link","POST",{fingerprint:e})}};import re from"@react-native-async-storage/async-storage";var te={TRACKED_REFERRAL:"growth-rail-tracked-referral",IS_FIRST_LAUNCH:"growth-rail-is-first-launch"},v=class{static async setTrackedReferral(e){await re.setItem(te.TRACKED_REFERRAL,e)}static async getTrackedReferral(){return await re.getItem(te.TRACKED_REFERRAL)}static async isFirstLaunch(){return await re.getItem(te.IS_FIRST_LAUNCH)===null?(await re.setItem(te.IS_FIRST_LAUNCH,"false"),!0):!1}};import t,{useEffect as Pe,useState as de,useRef as ye}from"react";import{Modal as ze,View as p,Text as T,StyleSheet as Re,TouchableOpacity as oe,Clipboard as Ae,ActivityIndicator as Fe,Linking as ke,ScrollView as Ge,Platform as Ce,Animated as L,Dimensions as $e,useColorScheme as We}from"react-native";var{width:Rr,height:xe}=$e.get("window"),fe=({visible:f,options:e,onClose:r})=>{let a=ie(),[n,b]=de(null),[u,w]=de(!1),[i,m]=de(!1),g=ye(new L.Value(0)).current,I=ye(new L.Value(0)).current,x=We(),R=(e?.appearance||x||"light")==="dark",_=e?.title||"Invite Friends & Earn",D=e?.theme?.primaryColor||"#2563eb",U=(e?.componentType||"modal")==="drawer",$=e?.position||"bottom-right",s={background:R?"#111827":"#ffffff",text:R?"#f9fafb":"#111827",textSecondary:R?"#9ca3af":"#6b7280",border:R?"#374151":"#e5e7eb",inputBg:R?"#1f2937":"#f9fafb",closeBtnBg:R?"#1f2937":"#f3f4f6",closeIcon:R?"#6b7280":"#9ca3af",drawerHandle:R?"#4b5563":"#e5e7eb",overlay:"#000000",overlayOpacity:.5};Pe(()=>{f?(n||J(),L.parallel([L.timing(I,{toValue:1,duration:300,useNativeDriver:!0}),L.spring(g,{toValue:1,useNativeDriver:!0,tension:50,friction:8})]).start()):(g.setValue(0),I.setValue(0))},[f]);let W=()=>{L.parallel([L.timing(I,{toValue:0,duration:250,useNativeDriver:!0}),L.timing(g,{toValue:0,duration:250,useNativeDriver:!0})]).start(()=>{r()})},J=async()=>{w(!0);try{if(a.isUserReady){let A=await a.getReferralLink();b(A||null)}}catch(A){console.error("GrowthRail: Failed to load referral link",A)}finally{w(!1)}},se=()=>{n&&(Ae.setString(n),m(!0),setTimeout(()=>m(!1),2e3))},z=A=>{if(!n)return;let B="",F=encodeURIComponent(n),M=encodeURIComponent("Check this out!");switch(A){case"twitter":B=`https://twitter.com/intent/tweet?url=${F}&text=${M}`;break;case"facebook":B=`https://www.facebook.com/sharer/sharer.php?u=${F}`;break;case"linkedin":B=`https://www.linkedin.com/sharing/share-offsite/?url=${F}`;break;case"whatsapp":B=`whatsapp://send?text=${M}%20${F}`;break;case"email":B=`mailto:?subject=Check this out&body=${M}%20${F}`;break}B&&ke.openURL(B).catch(()=>{})},Q=()=>s.overlay,E=[];U?E=[{translateY:g.interpolate({inputRange:[0,1],outputRange:[xe,0]})}]:E=[{scale:g.interpolate({inputRange:[0,1],outputRange:[.9,1]})},{translateY:g.interpolate({inputRange:[0,1],outputRange:[20,0]})}];let le=$.includes("top"),H=$.includes("right"),De=$.includes("left"),K=U?{position:"absolute",bottom:0,left:0,right:0,width:"100%",maxHeight:"90%"}:{};return t.createElement(ze,{visible:f,transparent:!0,animationType:"none",onRequestClose:W},t.createElement(p,{style:o.fullScreen},t.createElement(L.View,{style:[o.overlay,{backgroundColor:Q(),opacity:I.interpolate({inputRange:[0,1],outputRange:[0,s.overlayOpacity]})}]},t.createElement(oe,{style:o.fullScreen,activeOpacity:1,onPress:W})),t.createElement(L.View,{style:[U?K:o.centeredModalContainer,{backgroundColor:s.background,transform:E},U&&{borderTopLeftRadius:24,borderTopRightRadius:24,borderBottomLeftRadius:0,borderBottomRightRadius:0},!U&&{borderRadius:24,opacity:g,borderColor:s.border,borderWidth:R?1:0}]},t.createElement(p,{style:o.contentWrapper},U&&t.createElement(p,{style:[o.drawerHandle,{backgroundColor:s.drawerHandle}]}),t.createElement(oe,{style:[o.closeBtn,{backgroundColor:s.closeBtnBg}],onPress:W},t.createElement(T,{style:[o.closeIcon,{color:s.closeIcon}]},"\u2715")),t.createElement(Ge,{contentContainerStyle:o.scrollContent,showsVerticalScrollIndicator:!1},t.createElement(p,{style:o.header},t.createElement(p,{style:o.iconLgContainer},t.createElement(p,{style:o.bowContainerLg},t.createElement(p,{style:[o.bowLoopLg,o.bowLeftLg,{borderColor:D}]}),t.createElement(p,{style:[o.bowLoopLg,o.bowRightLg,{borderColor:D}]})),t.createElement(p,{style:[o.giftLidLg,{backgroundColor:D}]}),t.createElement(p,{style:[o.giftBodyLg,{borderColor:D}]},t.createElement(p,{style:[o.ribbonVerticalLg,{backgroundColor:"#fff",opacity:.3}]}))),t.createElement(T,{style:[o.title,{color:s.text}]},_),t.createElement(T,{style:[o.subtitle,{color:s.textSecondary}]},e?.description||"Share your unique link and earn rewards for every friend who signs up.")),a.isUserReady?u?t.createElement(Fe,{size:"large",color:D,style:o.loader}):t.createElement(p,{style:o.mainContent},t.createElement(T,{style:[o.label,{color:s.textSecondary}]},"YOUR UNIQUE LINK"),t.createElement(p,{style:[o.inputGroup,{backgroundColor:s.inputBg,borderColor:s.border}]},t.createElement(T,{numberOfLines:1,style:[o.input,{color:s.text}]},n||"Initializing..."),t.createElement(oe,{style:[o.copyBtn,{backgroundColor:i?"#10b981":D}],onPress:se},t.createElement(T,{style:o.copyBtnText},i?"Copied!":"Copy"))),t.createElement(p,{style:o.shareLabelContainer},t.createElement(p,{style:[o.divider,{backgroundColor:s.border}]}),t.createElement(T,{style:[o.shareLabel,{color:s.textSecondary}]},"Share via"),t.createElement(p,{style:[o.divider,{backgroundColor:s.border}]})),t.createElement(p,{style:o.socialContainer},t.createElement(Y,{platform:"twitter",color:R?"#FFFFFF":"#000000",onPress:()=>z("twitter"),icon:"\u{1D54F}",borderColor:s.border,bgColor:s.background}),t.createElement(Y,{platform:"facebook",color:"#1877F2",onPress:()=>z("facebook"),icon:"f",borderColor:s.border,bgColor:s.background}),t.createElement(Y,{platform:"linkedin",color:"#0A66C2",onPress:()=>z("linkedin"),icon:"in",borderColor:s.border,bgColor:s.background}),t.createElement(Y,{platform:"whatsapp",color:"#25D366",onPress:()=>z("whatsapp"),icon:"W",borderColor:s.border,bgColor:s.background}),t.createElement(Y,{platform:"email",color:s.textSecondary,onPress:()=>z("email"),icon:"\u2709",borderColor:s.border,bgColor:s.background}))):t.createElement(p,{style:[o.loadingBox,{backgroundColor:s.inputBg,borderColor:s.border}]},t.createElement(T,{style:{color:s.textSecondary,textAlign:"center"}},"Please log in to view your referral dashboard.")),t.createElement(p,{style:o.footer},t.createElement(T,{style:[o.poweredBy,{color:s.textSecondary}]},"Powered by ",t.createElement(T,{style:[o.brand,{color:D}],onPress:()=>ke.openURL("https://growthrail.com")},"Growth Rail"))))))))},Y=({color:f,onPress:e,icon:r,borderColor:a,bgColor:n})=>t.createElement(oe,{style:[o.socialBtn,{borderColor:a,backgroundColor:n}],onPress:e},t.createElement(T,{style:[o.socialIcon,{color:f}]},r)),o=Re.create({fullScreen:{flex:1},overlay:{...Re.absoluteFillObject},centeredModalContainer:{width:"90%",maxWidth:400,alignSelf:"center",marginTop:xe*.15,overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:20},shadowOpacity:.25,shadowRadius:30,elevation:20},contentWrapper:{paddingTop:Ce.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:Ce.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 S,{useEffect as Me,useRef as Ne}from"react";import{TouchableOpacity as je,View as P,StyleSheet as _e,Animated as ge,Easing as He}from"react-native";var ue=({onPress:f,options:e})=>{let r=e?.modal?.theme?.primaryColor||"#2563eb",a=e?.trigger?.position||"bottom-right",b=(e?.trigger?.displayMode||"floating")==="edge",u=a.includes("right"),w=a.includes("top"),i=Ne(new ge.Value(-1)).current;Me(()=>{let x=()=>{i.setValue(-1),ge.timing(i,{toValue:2,duration:3e3,easing:He.linear,useNativeDriver:!0}).start(()=>{setTimeout(x,1e3)})};x()},[]);let m=i.interpolate({inputRange:[-1,2],outputRange:b?[-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}};b||(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 I=()=>S.createElement(P,{style:y.iconContainer},S.createElement(P,{style:y.bowContainer},S.createElement(P,{style:[y.bowLoop,y.bowLeft]}),S.createElement(P,{style:[y.bowLoop,y.bowRight]})),S.createElement(P,{style:y.giftLid}),S.createElement(P,{style:y.giftBody},S.createElement(P,{style:y.ribbonVertical})));return S.createElement(je,{style:[b?y.edgeButton:y.floatingButton,{backgroundColor:r},g[a],b&&(u?y.edgeRight:y.edgeLeft)],onPress:f,activeOpacity:.9},S.createElement(P,{style:y.content},I()),S.createElement(ge.View,{style:[y.shimmer,{transform:[{translateX:m},{skewX:"-15deg"}]}]}))},y=_e.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 j,{useEffect as Ke,useRef as qe,useState as Ye}from"react";import{View as Xe,Text as he,StyleSheet as Je,Animated as ne,Dimensions as Qe,TouchableOpacity as Ze,Platform as er}from"react-native";var{width:rr}=Qe.get("window"),Te=({visible:f,options:e,onClose:r})=>{let a=qe(new ne.Value(0)).current,[n,b]=Ye(f),u=e.position.includes("bottom")?"bottom":"top",w=e.position.includes("left")?"left":e.position.includes("right")?"right":"center";if(Ke(()=>{f?(b(!0),ne.spring(a,{toValue:1,useNativeDriver:!0,tension:50,friction:8}).start()):ne.timing(a,{toValue:0,duration:250,useNativeDriver:!0}).start(()=>{b(!1)})},[f]),!n)return null;let i=a.interpolate({inputRange:[0,1],outputRange:[u==="top"?-100:100,0]}),m=a.interpolate({inputRange:[0,1],outputRange:[0,1]}),g={position:"absolute",[u]:er.OS==="ios"?60:40,zIndex:9999};return w==="center"?(g.left=20,g.right=20,g.alignItems="center"):g[w]=20,j.createElement(ne.View,{style:[g,{transform:[{translateY:i}],opacity:m}]},j.createElement(Xe,{style:[X.banner,{backgroundColor:e.themeColor||"#2563eb"}]},j.createElement(he,{style:X.icon},"\u{1F381}"),j.createElement(he,{style:X.text},e.text),j.createElement(Ze,{onPress:r,style:X.closeBtn},j.createElement(he,{style:X.closeIcon},"\u2715"))))},X=Je.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:rr-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 Le=tr(void 0),sr=({children:f,userId:e,debug:r=!1,...a})=>{let[n,b]=O(!1),[u,w]=O(!1),[i,m]=O(null),g=we(new ee(a)),I=we(!1),x=we(null),[be,R]=O(!1),[_,D]=O(),[me,U]=O(!1),[$,s]=O(),[W,J]=O(!1),[se,z]=O();pe(()=>{g.current.setDebug(r),r&&c.log("info","Provider","Debug mode enabled")},[r]);let Q=V(()=>{let{width:d,height:l}=ir.get("window"),h=Intl.DateTimeFormat().resolvedOptions().locale,C=nr.get(),k,N;if(G.OS==="android"){let ce=G.constants;k=ce.Model,N=ce.Brand||ce.Manufacturer}return{os:G.OS,platform:G.OS,osVersion:String(G.Version),screenWidth:d,screenHeight:l,timezoneOffsetInMinutes:String(new Date().getTimezoneOffset()),locale:h,language:h,deviceModel:k,deviceBrand:N,pixelRatio:C}},[]),E=V(async(d,l)=>{r&&c.log("info","Referral",`Tracking referral code: ${d}`,{referralCode:d,rewardEventName:l});let h=await g.current.trackReferral(d,l);return await v.setTrackedReferral(h.referralTrackingId),r&&c.log("success","Referral",`Referral tracked \u2192 ${h.referralTrackingId}`,h),h},[r]),le=V(async d=>{try{r&&c.log("info","DeepLink",`Received deep link: ${d}`);let l=d.match(/[?&]referralCode=([^&]+)/);l&&(console.log("GrowthRail: Tracking referral from deep link",l[1]),r&&c.log("info","DeepLink",`Found referral code in deep link: ${l[1]}`),await E(l[1]))}catch(l){console.warn("GrowthRail: Error handling deep link",l),r&&c.log("error","DeepLink","Deep link handling failed",{error:String(l)})}},[E,r]),H=V(async()=>{try{r&&c.log("info","Deferred","Checking deferred deep link via fingerprint");let d=Q(),{referralTrackingId:l}=await g.current.checkDeferredDeepLink(d);l?(console.log("GrowthRail: Found deferred referral via fingerprinting",l),r&&c.log("success","Deferred",`Deferred referral matched \u2192 ${l}`),await v.setTrackedReferral(l)):r&&c.log("info","Deferred","No deferred referral match found")}catch(d){console.warn("GrowthRail: Fingerprint check failed",d),r&&c.log("error","Deferred","Fingerprint check failed",{error:String(d)})}},[Q,r]),De=V(()=>new Promise(d=>{ar.getInstallReferrerInfo(async(l,h)=>{if(!h&&l&&l.installReferrer)try{let k=decodeURIComponent(l.installReferrer).match(/[?&]referralCode=([^&]+)/);if(k){let{referralTrackingId:N}=await E(k[1]);await v.setTrackedReferral(N),console.log("GrowthRail: Tracked referral via Install Referrer")}}catch(C){console.warn("GrowthRail: Failed to process install referrer",C)}else await H();d()})}),[E,H]),K=V(async d=>{if(i?.id===d&&u)return r&&c.log("info","User",`User ${d} already initialized, skipping`),i;r&&c.log("info","User",`Initializing user: ${d}`);let l=(async()=>{try{let h=await g.current.initAppUser(d),C={...h,id:d};return m(C),w(!0),r&&c.log("success","User",`User initialized: ${d}`,{referralCode:h.referralCode,referralLink:h.referralLink}),h.referrerExperience?.trigger?.displayMode!=="none"&&(U(!0),r&&c.log("info","UI","Trigger button shown (server-configured)")),C}catch(h){throw x.current=null,r&&c.log("error","User",`User init failed for ${d}`,{error:String(h)}),h}})();return x.current=l,l},[i,u,r]),A=V(async d=>{r&&c.log("info","Reward",`Tracking reward event: ${d||"(default)"}`);let l=i;!l&&x.current&&(l=await x.current);let h=l?.id||e;if(!h)throw r&&c.log("error","Reward","Cannot track reward \u2014 user not initialized"),new Error("GrowthRail: User must be initialized before tracking a reward event.");let C=await v.getTrackedReferral();if(!C){console.warn("GrowthRail: No referral tracking ID found. Reward event not attributed."),r&&c.log("warn","Reward","No referral tracking ID in storage \u2014 reward not attributed");return}let k=await g.current.trackRewardEvent(h,C,d);return r&&c.log("success","Reward",`Reward event tracked for user ${h}`),k},[i,e,r]),B=V(async()=>await v.getTrackedReferral(),[]),F=V(async()=>{if(i)return i.referralLink;if(x.current)return(await x.current).referralLink},[i]);pe(()=>{if(I.current)return;I.current=!0,r&&c.log("info","Provider","SDK initializing\u2026",{platform:G.OS}),(async()=>{let l=await ve.getInitialURL();r&&c.log("info","DeepLink",`Initial URL: ${l??"(none)"}`),l&&await le(l);let h=ve.addEventListener("url",({url:k})=>le(k)),C=await v.isFirstLaunch();r&&c.log("info","Provider",`First launch: ${C}`),C&&(G.OS==="android"?await H():await H()),e&&await K(e);try{let k=await g.current.getNewUserExperience(),N=await v.getTrackedReferral();k.banner?.show&&N&&(z(k.banner),J(!0),r&&c.log("info","UI","Banner shown for new user experience"))}catch(k){r&&c.log("warn","Provider","New user experience fetch failed",{error:String(k)})}return b(!0),r&&c.log("success","Provider","SDK initialization complete \u2713"),()=>h.remove()})()},[]),pe(()=>{n&&e&&i?.id!==e&&K(e)},[e,n]);let M={isInitialized:n,isUserReady:u,currentUser:i,referralCode:i?.referralCode,referralLink:i?.referralLink,showDashboard:d=>{D(d),R(!0)},hideDashboard:()=>R(!1),initUser:K,trackReward:A,getReferralTrackingId:B,getReferralLink:F,isDebugEnabled:r};if(!n)return null;let q=i?.referrerExperience,Be={...q?.modal,..._,appearance:_?.appearance||q?.modal?.appearance||a.appearance,theme:{...q?.modal?.theme||{},..._?.theme||{}}},Oe={...q,...$,trigger:{...q?.trigger||{},...$?.trigger||{}}};return ae.createElement(Le.Provider,{value:M},f,ae.createElement(fe,{visible:be,options:Be,onClose:()=>R(!1)}),me&&ae.createElement(ue,{options:Oe,onPress:()=>M.showDashboard()}),W&&ae.createElement(Te,{visible:W,options:se,onClose:()=>J(!1)}))},ie=()=>{let f=or(Le);if(!f)throw new Error("useGrowthRail must be used within a GrowthRailProvider");return f};import{useState as Se,useCallback as Ie}from"react";var lr=()=>{let[f,e]=Se(!1),[r,a]=Se(null),n=ie(),b=Ie(async w=>{e(!0),a(null);try{return await n.initUser(w)}catch(i){let m=i instanceof Error?i:new Error(String(i));throw a(m),m}finally{e(!1)}},[n]),u=Ie(async w=>{e(!0),a(null);try{await n.trackReward(w)}catch(i){let m=i instanceof Error?i:new Error(String(i));throw a(m),m}finally{e(!1)}},[n]);return{initAppUser:b,trackRewardEvent:u,showReferralDashboard:n.showDashboard,hideReferralDashboard:n.hideDashboard,getReferralTrackingId:n.getReferralTrackingId,getReferralLink:n.getReferralLink,isLoading:f,isInitialized:n.isInitialized,isUserReady:n.isUserReady,error:r,isDebugEnabled:n.isDebugEnabled}};export{sr as GrowthRailProvider,fe as ReferralDashboard,ue as TriggerButton,lr as useGrowthRail};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@growth-rail/react-native",
3
- "version": "2.0.1",
3
+ "version": "2.0.3",
4
4
  "description": "Growth Rail SDK for React Native",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",