@@ -19,6 +19,11 @@ import { SectionHeader } from './components/SectionHeader';
1919import { ProfileTextField } from './components/ProfileTextField' ;
2020import { ActionButton } from './components/ActionButton' ;
2121import { ToggleButtons } from './components/ToggleButtons' ;
22+ import {
23+ requestLocationPermission ,
24+ checkLocationPermissionState ,
25+ type LocationPermissionState ,
26+ } from './PermissionHelper' ;
2227
2328export default function App ( ) {
2429 // Profile state
@@ -29,11 +34,20 @@ export default function App() {
2934 // Feature state
3035 const [ pushToken , setPushToken ] = useState ( '' ) ;
3136 const [ formsRegistered , setFormsRegistered ] = useState ( false ) ;
37+ const [ geofencingRegistered , setGeofencingRegistered ] = useState ( false ) ;
38+ const [ locationPermission , setLocationPermission ] =
39+ useState < LocationPermissionState > ( 'none' ) ;
40+
41+ // Helper to refresh location permission state
42+ const refreshLocationPermission = async ( ) => {
43+ const state = await checkLocationPermissionState ( ) ;
44+ setLocationPermission ( state ) ;
45+ } ;
3246
3347 // Initialize SDK and load current state on mount
3448 useEffect ( ( ) => {
3549 // Initialize the SDK with public key
36- Klaviyo . initialize ( 'YOUR_KLAVIYO_PUBLIC_API_KEY ' ) ;
50+ Klaviyo . initialize ( 'TRJ3wp ' ) ;
3751
3852 // Load current profile values from SDK
3953 Klaviyo . getEmail ( ( value : string ) => {
@@ -52,6 +66,11 @@ export default function App() {
5266 if ( value ) setPushToken ( value ) ;
5367 } ) ;
5468
69+ // Check initial location permission state
70+ refreshLocationPermission ( ) . then ( ( ) => {
71+ console . log ( 'Fetched initial location permission state' ) ;
72+ } ) ;
73+
5574 // Set up deep linking handler
5675 const handleUrl = ( url : string ) => {
5776 if ( Klaviyo . handleUniversalTrackingLink ( url ) ) {
@@ -172,7 +191,70 @@ export default function App() {
172191 console . log ( 'Unregistered from in-app forms' ) ;
173192 } ;
174193
175- // Push notifications handler
194+ // Geofencing handlers
195+ const handleRegisterGeofencing = ( ) => {
196+ Klaviyo . registerGeofencing ( ) ;
197+ setGeofencingRegistered ( true ) ;
198+ console . log ( 'Registered for geofencing' ) ;
199+ } ;
200+
201+ const handleUnregisterGeofencing = ( ) => {
202+ Klaviyo . unregisterGeofencing ( ) ;
203+ setGeofencingRegistered ( false ) ;
204+ console . log ( 'Unregistered from geofencing' ) ;
205+ } ;
206+
207+ const handleGetCurrentGeofences = ( ) => {
208+ // Note: this @internal method is intended only for demonstration and debugging purposes
209+ Klaviyo . getCurrentGeofences ( ( result : { geofences : Array < {
210+ identifier : string ;
211+ latitude : number ;
212+ longitude : number ;
213+ radius : number ;
214+ } > } ) => {
215+ const { geofences } = result ;
216+ console . log ( 'Current geofences:' , JSON . stringify ( geofences , null , 2 ) ) ;
217+
218+ if ( geofences . length === 0 ) {
219+ Alert . alert (
220+ 'Current Geofences' ,
221+ 'No geofences are currently being monitored.' ,
222+ [ { text : 'OK' } ]
223+ ) ;
224+ } else {
225+ const geofencesList = geofences
226+ . map (
227+ ( g , index ) =>
228+ `${ index + 1 } . ${ g . identifier } \n Center: (${ g . latitude . toFixed ( 6 ) } , ${ g . longitude . toFixed ( 6 ) } )\n Radius: ${ g . radius . toFixed ( 2 ) } m`
229+ )
230+ . join ( '\n\n' ) ;
231+
232+ Alert . alert ( `Current Geofences (${ geofences . length } )` , geofencesList , [
233+ { text : 'OK' } ,
234+ ] ) ;
235+ }
236+ } ) ;
237+ } ;
238+
239+ const handleRequestLocationPermission = async ( ) => {
240+ await requestLocationPermission ( ) ;
241+ // Refresh permission state after requesting
242+ await refreshLocationPermission ( ) ;
243+ } ;
244+
245+ // Push notifications handlers
246+ const handleRequestPushPermission = ( ) => {
247+ // Note: This is a placeholder. In a real app, you would use a push notification
248+ // library like @react -native-firebase/messaging or react-native-push-notification
249+ // to request push permissions. The Klaviyo SDK will handle the token registration
250+ // when you call setPushToken.
251+ Alert . alert (
252+ 'Push Notifications' ,
253+ 'Push notification permission requests should be handled by your push notification library (e.g., Firebase). The SDK will automatically register the token when available.' ,
254+ [ { text : 'OK' } ]
255+ ) ;
256+ } ;
257+
176258 const handleSetBadgeCount = ( ) => {
177259 const randomBadgeCount = Math . floor ( Math . random ( ) * 10 ) ;
178260 Klaviyo . setBadgeCount ( randomBadgeCount ) ;
@@ -211,28 +293,39 @@ export default function App() {
211293 placeholder = "+1234567890"
212294 keyboardType = "phone-pad"
213295 />
214- < ActionButton
215- title = "Set Profile"
216- onPress = { handleSetProfile }
217- disabled = {
218- ! email . trim ( ) && ! phoneNumber . trim ( ) && ! externalId . trim ( )
219- }
220- />
221- < ActionButton
222- title = "Reset Profile"
223- onPress = { handleResetProfile }
224- destructive
225- />
296+ < View style = { styles . actionButtonRow } >
297+ < ActionButton
298+ title = "Set Profile"
299+ onPress = { handleSetProfile }
300+ disabled = {
301+ ! email . trim ( ) && ! phoneNumber . trim ( ) && ! externalId . trim ( )
302+ }
303+ inRow
304+ />
305+ < ActionButton
306+ title = "Reset Profile"
307+ onPress = { handleResetProfile }
308+ destructive
309+ inRow
310+ />
311+ </ View >
226312 </ View >
227313
228314 { /* Events Section */ }
229315 < View style = { styles . section } >
230316 < SectionHeader title = "Events" />
231- < ActionButton
232- title = "Create Test Event"
233- onPress = { handleCreateTestEvent }
234- />
235- < ActionButton title = "Viewed Product" onPress = { handleViewedProduct } />
317+ < View style = { styles . actionButtonRow } >
318+ < ActionButton
319+ title = "Test Event"
320+ onPress = { handleCreateTestEvent }
321+ inRow
322+ />
323+ < ActionButton
324+ title = "Viewed Product"
325+ onPress = { handleViewedProduct }
326+ inRow
327+ />
328+ </ View >
236329 </ View >
237330
238331 { /* In-App Forms Section */ }
@@ -244,12 +337,57 @@ export default function App() {
244337 isLeftActive = { formsRegistered }
245338 onLeftPress = { handleRegisterForms }
246339 onRightPress = { handleUnregisterForms }
340+ leftDisabled = { formsRegistered }
341+ rightDisabled = { ! formsRegistered }
342+ />
343+ </ View >
344+
345+ { /* Geofencing & Location Section */ }
346+ < View style = { styles . section } >
347+ < SectionHeader title = "Geofencing & Location" />
348+ { locationPermission === 'none' && (
349+ < ActionButton
350+ title = "Request Location Permission"
351+ onPress = { handleRequestLocationPermission }
352+ />
353+ ) }
354+ { locationPermission === 'inUse' && (
355+ < ActionButton
356+ title = "Request Background Permission"
357+ onPress = { handleRequestLocationPermission }
358+ />
359+ ) }
360+ { locationPermission === 'background' && (
361+ < View style = { styles . permissionGrantedContainer } >
362+ < Text style = { styles . permissionGrantedText } >
363+ Background Permission Granted
364+ </ Text >
365+ </ View >
366+ ) }
367+ < ToggleButtons
368+ leftLabel = "Register"
369+ rightLabel = "Unregister"
370+ isLeftActive = { geofencingRegistered }
371+ onLeftPress = { handleRegisterGeofencing }
372+ onRightPress = { handleUnregisterGeofencing }
373+ leftDisabled = { geofencingRegistered }
374+ rightDisabled = { ! geofencingRegistered }
247375 />
376+ { geofencingRegistered && (
377+ < ActionButton
378+ title = "Get Current Geofences"
379+ onPress = { handleGetCurrentGeofences }
380+ />
381+ ) }
248382 </ View >
249383
250384 { /* Push Notifications Section */ }
251385 < View style = { styles . section } >
252386 < SectionHeader title = "Push Notifications" />
387+ < ActionButton
388+ title = "Request Push Permission"
389+ onPress = { handleRequestPushPermission }
390+ />
253391 < View style = { styles . pushTokenContainer } >
254392 < Text style = { styles . pushTokenLabel } > Push Token</ Text >
255393 < Text
0 commit comments