Skip to content

Commit f839149

Browse files
committed
Add Commerce component and route: implement Commerce component with purchase tracking, define Commerce route in navigation, and create associated constants and styles
1 parent 4bdb860 commit f839149

File tree

9 files changed

+175
-1
lines changed

9 files changed

+175
-1
lines changed

example/src/components/App/Main.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ import type { MainScreenParamList } from '../../types';
88
import { routeIcon } from './App.constants';
99
import { getIcon } from './App.utils';
1010
import { User } from '../User';
11-
import Inbox from '../Inbox';
11+
import { Inbox } from '../Inbox';
1212
import { useIterableApp } from '../../hooks';
13+
import { Commerce } from '../Commerce';
1314

1415
const Tab = createBottomTabNavigator<MainScreenParamList>();
1516

@@ -65,6 +66,13 @@ export const Main = () => {
6566
},
6667
})}
6768
/>
69+
<Tab.Screen
70+
name={Route.Commerce}
71+
component={Commerce}
72+
listeners={() => ({
73+
tabPress: () => setIsInboxTab(false),
74+
})}
75+
/>
6876
<Tab.Screen
6977
name={Route.User}
7078
component={User}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
export type CommerceItem = {
2+
id: string;
3+
name: string;
4+
icon: any;
5+
subtitle: string;
6+
price: number;
7+
};
8+
9+
export const items: CommerceItem[] = [
10+
{
11+
id: 'black',
12+
name: 'Black Coffee',
13+
icon: require('./img/black-coffee.png'),
14+
subtitle: 'Maximize health benefits',
15+
price: 2.53,
16+
},
17+
{
18+
id: 'cappuccino',
19+
name: 'Cappuccino',
20+
icon: require('./img/cappuccino.png'),
21+
subtitle: 'Tasty and creamy',
22+
price: 3.56,
23+
},
24+
{
25+
id: 'mocha',
26+
name: 'Mocha',
27+
icon: require('./img/mocha.png'),
28+
subtitle: 'Indulge yourself',
29+
price: 4.98,
30+
},
31+
];
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { StyleSheet } from 'react-native';
2+
import {
3+
button,
4+
buttonText,
5+
colors,
6+
container,
7+
title,
8+
subtitle,
9+
} from '../../constants';
10+
11+
const styles = StyleSheet.create({
12+
container,
13+
title: { ...title, textAlign: 'center' },
14+
subtitle: { ...subtitle, textAlign: 'center' },
15+
cardContainer: {
16+
backgroundColor: colors?.white,
17+
borderWidth: 1,
18+
padding: 15,
19+
borderColor: colors?.grey5,
20+
shadowColor: 'rgba(0,0,0, .2)',
21+
shadowOffset: { height: 0, width: 0 },
22+
shadowOpacity: 1,
23+
shadowRadius: 1,
24+
elevation: 10, // Required for Android
25+
width: '100%',
26+
height: 150,
27+
marginBottom: 10,
28+
},
29+
infoContainer: {
30+
display: 'flex',
31+
flexDirection: 'row',
32+
gap: 10,
33+
alignItems: 'center',
34+
},
35+
imageContainer: {
36+
width: 120,
37+
height: 100,
38+
flex: 0,
39+
},
40+
textContainer: {
41+
paddingTop: 10,
42+
flex: 1,
43+
marginLeft: 10,
44+
},
45+
cardImage: {
46+
height: '100%',
47+
width: '100%',
48+
resizeMode: 'contain',
49+
},
50+
cardTitle: {
51+
fontSize: 18,
52+
fontWeight: 'bold',
53+
},
54+
cardSubtitle: {
55+
fontSize: 14,
56+
color: colors.textSecondary,
57+
},
58+
price: {
59+
marginVertical: 5,
60+
fontWeight: 'bold',
61+
color: colors.salmon50,
62+
},
63+
button: { ...button, width: 100, marginTop: 10, paddingVertical: 5 },
64+
buttonText,
65+
});
66+
67+
export default styles;
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { Alert, Image, Pressable, ScrollView, Text, View } from 'react-native';
2+
3+
import { Iterable, IterableCommerceItem } from '@iterable/react-native-sdk';
4+
5+
import { items, type CommerceItem } from './Commerce.constants';
6+
import styles from './Commerce.styles';
7+
8+
export const Commerce = () => {
9+
const handleClick = (item: CommerceItem) => {
10+
const purchasedItem = new IterableCommerceItem(
11+
item.id,
12+
item.name,
13+
item.price,
14+
1
15+
);
16+
const totalPrice = item.price;
17+
const purchaseItems = [purchasedItem];
18+
const dataFields = null;
19+
20+
Iterable.trackPurchase(totalPrice, purchaseItems, dataFields);
21+
22+
console.group('Purchase tracked with the following arguments:');
23+
console.log('Total price:', totalPrice);
24+
console.log('Purchase items:', [...purchaseItems]);
25+
console.log('Data fields:', dataFields);
26+
console.groupEnd();
27+
28+
Alert.alert(
29+
`Tracked purchase: ${item.name}, $${item.price}`,
30+
'Check logs for output'
31+
);
32+
};
33+
34+
return (
35+
<ScrollView>
36+
<View style={styles.container}>
37+
<Text style={styles.title}>Commerce</Text>
38+
<Text style={styles.subtitle}>
39+
Purchase will be tracked when "Buy" is clicked. See logs for output.
40+
</Text>
41+
{items.map((item) => (
42+
<View key={item.id} style={styles.cardContainer}>
43+
<View style={styles.infoContainer}>
44+
<View style={styles.imageContainer}>
45+
<Image source={item.icon} style={styles.cardImage} />
46+
</View>
47+
<View style={styles.textContainer}>
48+
<Text style={styles.cardTitle}>{item.name}</Text>
49+
<Text style={styles.cardSubtitle}>{item.subtitle}</Text>
50+
<Text style={styles.price}>${item.price}</Text>
51+
<Pressable
52+
style={styles.button}
53+
onPress={() => handleClick(item)}
54+
>
55+
<Text style={styles.buttonText}>Buy</Text>
56+
</Pressable>
57+
</View>
58+
</View>
59+
</View>
60+
))}
61+
</View>
62+
</ScrollView>
63+
);
64+
};
65+
66+
export default Commerce;
823 KB
Loading
116 KB
Loading
15 KB
Loading
317 KB
Loading
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './Commerce';
2+
export { default } from './Commerce';

0 commit comments

Comments
 (0)