Skip to content

Commit 81fcf95

Browse files
authored
Prefill buyer information (#43)
* Add setting to prefill buyer information * No daemon
1 parent 60c3c79 commit 81fcf95

File tree

9 files changed

+145
-18
lines changed

9 files changed

+145
-18
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ jobs:
7070
- name: Run Android tests
7171
run: |
7272
yarn module build
73-
yarn sample test:android
73+
yarn sample test:android --no-daemon
7474
7575
test-ios:
7676
name: Run iOS Tests

sample/.env.example

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,16 @@
1-
STOREFRONT_DOMAIN="YOUR_STORE.myshopify.com"
2-
STOREFRONT_ACCESS_TOKEN="YOUR_PUBLIC_STOREFRONT_ACCESS_TOKEN"
1+
# Storefront Details
2+
STOREFRONT_DOMAIN="YOUR_STORE.myshopify.com"
3+
STOREFRONT_ACCESS_TOKEN="YOUR_PUBLIC_STOREFRONT_ACCESS_TOKEN"
4+
5+
# Prefilled buyer information
6+
7+
ADDRESS_1="650 King Street"
8+
ADDRESS_2="Shopify HQ"
9+
CITY="Toronto"
10+
COMPANY="Shopify"
11+
COUNTRY="CA"
12+
FIRST_NAME="Evelyn"
13+
LAST_NAME="Hartley"
14+
PROVINCE="ON"
15+
ZIP="M5V 1M7"
16+
PHONE="1-888-746-7439"

sample/@types/env.d.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
11
declare module '@env' {
22
export const STOREFRONT_DOMAIN: string;
33
export const STOREFRONT_ACCESS_TOKEN: string;
4+
5+
export const EMAIL: string;
6+
export const ADDRESS_1: string;
7+
export const ADDRESS_2: string;
8+
export const CITY: string;
9+
export const COMPANY: string;
10+
export const COUNTRY: string;
11+
export const FIRST_NAME: string;
12+
export const LAST_NAME: string;
13+
export const PROVINCE: string;
14+
export const ZIP: string;
15+
export const PHONE: string;
416
}

sample/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "sample",
3-
"version": "0.0.1",
3+
"version": "0.6.0",
44
"private": true,
55
"scripts": {
66
"android": "react-native run-android",

sample/src/context/Cart.tsx

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,15 @@ import React, {
99
import {atom, useAtom} from 'jotai';
1010
import {useShopifyCheckoutKit} from 'react-native-shopify-checkout-kit';
1111
import useShopify from '../hooks/useShopify';
12+
import {useConfig} from './Config';
13+
import {createBuyerIdentityCartInput} from '../utils';
1214

1315
interface Context {
1416
cartId: string | undefined;
1517
checkoutURL: string | undefined;
1618
totalQuantity: number;
1719
addingToCart: Set<string>;
20+
clearCart: () => void;
1821
addToCart: (variantId: string) => Promise<void>;
1922
removeFromCart: (variantId: string) => Promise<void>;
2023
}
@@ -28,6 +31,7 @@ const CartContext = createContext<Context>({
2831
addingToCart: new Set(),
2932
addToCart: async () => {},
3033
removeFromCart: async () => {},
34+
clearCart: () => {},
3135
});
3236

3337
type AddingToCartAction =
@@ -63,26 +67,37 @@ export const CartProvider: React.FC<PropsWithChildren> = ({children}) => {
6367
// Maintain a loading state for items being added to the cart
6468
const defaultSet: Set<string> = new Set();
6569
const [addingToCart, dispatch] = useReducer(addingToCartReducer, defaultSet);
70+
const {appConfig} = useConfig();
6671

6772
const {mutations, queries} = useShopify();
6873
const [createCart] = mutations.cartCreate;
6974
const [addLineItems] = mutations.cartLinesAdd;
7075
const [removeLineItems] = mutations.cartLinesRemove;
7176
const [fetchCart] = queries.cart;
7277

78+
const clearCart = useCallback(() => {
79+
setCartId(defaultCartId);
80+
setCheckoutURL(undefined);
81+
setTotalQuantity(0);
82+
}, [setCartId, setCheckoutURL, setTotalQuantity]);
83+
7384
useEffect(() => {
7485
const subscription = ShopifyCheckoutKit.addEventListener(
7586
'completed',
7687
() => {
7788
// Clear the cart ID and checkout URL when the checkout is completed
78-
setCartId(defaultCartId);
79-
setCheckoutURL(undefined);
80-
setTotalQuantity(0);
89+
clearCart();
8190
},
8291
);
8392

8493
return subscription?.remove;
85-
}, [ShopifyCheckoutKit, setCartId, setCheckoutURL, setTotalQuantity]);
94+
}, [
95+
ShopifyCheckoutKit,
96+
clearCart,
97+
setCartId,
98+
setCheckoutURL,
99+
setTotalQuantity,
100+
]);
86101

87102
useEffect(() => {
88103
async function getCart() {
@@ -110,7 +125,8 @@ export const CartProvider: React.FC<PropsWithChildren> = ({children}) => {
110125
dispatch({type: 'add', variantId});
111126

112127
if (!id) {
113-
const cart = await createCart();
128+
const cartInput = createBuyerIdentityCartInput(appConfig);
129+
const cart = await createCart({variables: {input: cartInput}});
114130
id = cart.data.cartCreate.cart.id;
115131

116132
if (id) {
@@ -147,6 +163,7 @@ export const CartProvider: React.FC<PropsWithChildren> = ({children}) => {
147163
addLineItems,
148164
setCheckoutURL,
149165
setTotalQuantity,
166+
appConfig,
150167
createCart,
151168
setCartId,
152169
ShopifyCheckoutKit,
@@ -205,6 +222,7 @@ export const CartProvider: React.FC<PropsWithChildren> = ({children}) => {
205222
removeFromCart,
206223
totalQuantity,
207224
addingToCart,
225+
clearCart,
208226
}),
209227
[
210228
cartId,
@@ -213,6 +231,7 @@ export const CartProvider: React.FC<PropsWithChildren> = ({children}) => {
213231
removeFromCart,
214232
totalQuantity,
215233
addingToCart,
234+
clearCart,
216235
],
217236
);
218237

sample/src/context/Config.tsx

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,36 @@ import {
1313
} from 'react-native-shopify-checkout-kit';
1414
import {useTheme} from './Theme';
1515

16+
export interface AppConfig {
17+
prefillBuyerInformation: boolean;
18+
}
19+
1620
interface Context {
21+
appConfig: AppConfig;
1722
config: Configuration | undefined;
1823
setConfig: (config: Configuration) => void;
24+
setAppConfig: (config: AppConfig) => void;
1925
}
2026

27+
const defaultAppConfig: AppConfig = {
28+
prefillBuyerInformation: false,
29+
};
30+
2131
const ConfigContext = createContext<Context>({
32+
appConfig: defaultAppConfig,
2233
config: {
2334
colorScheme: ColorScheme.automatic,
2435
preloading: false,
2536
},
2637
setConfig: () => undefined,
38+
setAppConfig: () => undefined,
2739
});
2840

2941
export const ConfigProvider: React.FC<PropsWithChildren> = ({children}) => {
3042
const ShopifyCheckoutKit = useShopifyCheckoutKit();
3143
const [config, setInternalConfig] = useState<Context['config']>(undefined);
44+
const [appConfig, setInternalAppConfig] =
45+
useState<AppConfig>(defaultAppConfig);
3246
const {setColorScheme} = useTheme();
3347

3448
useEffect(() => {
@@ -74,12 +88,18 @@ export const ConfigProvider: React.FC<PropsWithChildren> = ({children}) => {
7488
[setColorScheme, ShopifyCheckoutKit],
7589
);
7690

91+
const setAppConfig = useCallback((config: AppConfig) => {
92+
setInternalAppConfig(config);
93+
}, []);
94+
7795
const value = useMemo(
7896
() => ({
7997
config,
98+
appConfig,
8099
setConfig,
100+
setAppConfig,
81101
}),
82-
[config, setConfig],
102+
[appConfig, config, setAppConfig, setConfig],
83103
);
84104

85105
return (

sample/src/hooks/useShopify.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,8 @@ const CART_QUERY = gql`
134134
`;
135135

136136
const CREATE_CART_MUTATION = gql`
137-
mutation CreateCart {
138-
cartCreate(input: {}) {
137+
mutation CreateCart($input: CartInput) {
138+
cartCreate(input: $input) {
139139
cart {
140140
id
141141
checkoutUrl

sample/src/screens/SettingsScreen.tsx

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import {
4545
lightColors,
4646
useTheme,
4747
} from '../context/Theme';
48+
import {useCart} from '../context/Cart';
4849

4950
enum SectionType {
5051
Switch = 'switch',
@@ -91,7 +92,8 @@ interface SectionData {
9192

9293
function SettingsScreen() {
9394
const ShopifyCheckoutKit = useShopifyCheckoutKit();
94-
const {config, setConfig} = useConfig();
95+
const {clearCart} = useCart();
96+
const {config, appConfig, setConfig, setAppConfig} = useConfig();
9597
const {colors} = useTheme();
9698
const styles = createStyles(colors);
9799

@@ -147,6 +149,13 @@ function SettingsScreen() {
147149
});
148150
}, [config?.preloading, setConfig]);
149151

152+
const handleTogglePrefill = useCallback(() => {
153+
clearCart();
154+
setAppConfig({
155+
prefillBuyerInformation: !appConfig.prefillBuyerInformation,
156+
});
157+
}, [appConfig.prefillBuyerInformation, clearCart, setAppConfig]);
158+
150159
const configurationOptions: readonly SwitchItem[] = useMemo(
151160
() => [
152161
{
@@ -155,8 +164,19 @@ function SettingsScreen() {
155164
value: config?.preloading ?? false,
156165
handler: handleTogglePreloading,
157166
},
167+
{
168+
title: 'Prefill buyer information',
169+
type: SectionType.Switch,
170+
value: appConfig.prefillBuyerInformation ?? false,
171+
handler: handleTogglePrefill,
172+
},
173+
],
174+
[
175+
appConfig.prefillBuyerInformation,
176+
config?.preloading,
177+
handleTogglePrefill,
178+
handleTogglePreloading,
158179
],
159-
[config?.preloading, handleTogglePreloading],
160180
);
161181

162182
const themeOptions: readonly SingleSelectItem[] = useMemo(
@@ -208,15 +228,15 @@ function SettingsScreen() {
208228
const sections: SectionData[] = useMemo(
209229
() => [
210230
{
211-
title: 'Configuration',
231+
title: 'Features',
212232
data: configurationOptions,
213233
},
214234
{
215235
title: 'Theme',
216236
data: themeOptions,
217237
},
218238
{
219-
title: 'About',
239+
title: 'Versions',
220240
data: informationalItems,
221241
},
222242
],
@@ -315,6 +335,10 @@ function TextItem({item, styles}: TextItemProps) {
315335

316336
function createStyles(colors: Colors) {
317337
return StyleSheet.create({
338+
list: {
339+
borderColor: colors.border,
340+
borderTopWidth: 1,
341+
},
318342
listItem: {
319343
flex: 1,
320344
flexDirection: 'row',
@@ -326,8 +350,6 @@ function createStyles(colors: Colors) {
326350
backgroundColor: colors.backgroundSubdued,
327351
borderColor: colors.border,
328352
borderBottomWidth: 1,
329-
borderTopWidth: 1,
330-
marginBottom: -1,
331353
},
332354
listItemText: {
333355
flex: 1,

sample/src/utils.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import {
2+
EMAIL,
3+
ADDRESS_1,
4+
ADDRESS_2,
5+
CITY,
6+
COMPANY,
7+
COUNTRY,
8+
FIRST_NAME,
9+
LAST_NAME,
10+
PROVINCE,
11+
ZIP,
12+
PHONE,
13+
} from '@env';
14+
import {AppConfig} from './context/Config';
15+
16+
export function createBuyerIdentityCartInput(appConfig: AppConfig) {
17+
if (!appConfig.prefillBuyerInformation) {
18+
return {};
19+
}
20+
21+
return {
22+
buyerIdentity: {
23+
email: EMAIL,
24+
deliveryAddressPreferences: {
25+
deliveryAddress: {
26+
address1: ADDRESS_1,
27+
address2: ADDRESS_2,
28+
city: CITY,
29+
company: COMPANY,
30+
country: COUNTRY,
31+
firstName: FIRST_NAME,
32+
lastName: LAST_NAME,
33+
phone: PHONE,
34+
province: PROVINCE,
35+
zip: ZIP,
36+
},
37+
},
38+
},
39+
};
40+
}

0 commit comments

Comments
 (0)