Skip to content

Commit

Permalink
patches for checkout flows and grid
Browse files Browse the repository at this point in the history
  • Loading branch information
roncodes committed Jan 3, 2025
1 parent 0afe60b commit 28492a4
Show file tree
Hide file tree
Showing 15 changed files with 2,118 additions and 786 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,5 @@ android/app/google-services.json
# Storefront assets/configurations
#
storefront.config.js
.tamagui
vendor
17 changes: 16 additions & 1 deletion babel.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
module.exports = {
presets: ['module:@react-native/babel-preset'],
plugins: ['preval', 'react-native-reanimated/plugin', '@babel/plugin-proposal-export-namespace-from'],
plugins: [
'preval',
'react-native-reanimated/plugin',
'@babel/plugin-proposal-export-namespace-from',
[
'@tamagui/babel-plugin',
{
components: ['tamagui'],
config: './tamagui.config.ts',
importsWhitelist: ['constants.js', 'colors.js'],
logTimings: true,
disableExtraction: process.env.NODE_ENV === 'development',
experimentalFlattenThemesOnNative: false,
},
],
],
};
10 changes: 8 additions & 2 deletions ios/StorefrontApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,10 @@
"-DFOLLY_CFG_NO_COROUTINES=1",
"-DFOLLY_HAVE_CLOCK_GETTIME=1",
);
OTHER_LDFLAGS = "$(inherited) ";
OTHER_LDFLAGS = (
"$(inherited)",
" ",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG";
Expand Down Expand Up @@ -671,7 +674,10 @@
"-DFOLLY_CFG_NO_COROUTINES=1",
"-DFOLLY_HAVE_CLOCK_GETTIME=1",
);
OTHER_LDFLAGS = "$(inherited) ";
OTHER_LDFLAGS = (
"$(inherited)",
" ",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
USE_HERMES = true;
Expand Down
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
"test": "jest",
"lint": "eslint .",
"format": "prettier --write .",
"tamagui:build": "./node_modules/.bin/tamagui-build",
"tamagui:clean": "./node_modules/.bin/tamagui-build clean",
"clean:android": "cd android && ./gradlew clean && cd ../",
"adb-reverse": "adb reverse tcp:8081 tcp:8081",
"generate-app-icon": "npx app-icon generate -i ./assets/app-icon.png",
Expand Down Expand Up @@ -40,6 +42,7 @@
"@react-navigation/native-stack": "^7.0.0",
"@shopify/flash-list": "^1.7.2",
"@stripe/stripe-react-native": "0.39.0",
"@tamagui/babel-plugin": "^1.121.5",
"@tamagui/config": "^1.116.14",
"add": "^2.0.6",
"countries-list": "^3.0.6",
Expand Down Expand Up @@ -75,13 +78,14 @@
"react-native-safe-area-context": "^5.0.0",
"react-native-screens": "^4.3.0",
"react-native-snap-carousel": "^3.9.1",
"react-native-super-grid": "^6.0.1",
"react-native-svg": "^15.10.1",
"react-native-web": "^0.19.13",
"react-native-webview": "^13.12.3",
"react-native-youtube": "^2.0.2",
"react-redux": "^9.0.4",
"socketcluster-client": "^19.2.3",
"tamagui": "^1.116.14",
"tamagui": "^1.121.5",
"yarn": "^1.22.22"
},
"devDependencies": {
Expand Down
4 changes: 2 additions & 2 deletions src/components/CartContents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,14 +123,14 @@ const CartContents = ({}) => {
</Text>
)}
<YStack>
{cartItem.variants.map((variant) => (
{cartItem.variants.filter(Boolean).map((variant) => (
<XStack key={variant.id} alignItems='center' space='$2'>
<Text flex={1} fontSize='$3' color='$textSecondary' numberOfLines={1}>
{variant.name}
</Text>
</XStack>
))}
{cartItem.addons.map((addon) => (
{cartItem.addons.filter(Boolean).map((addon) => (
<XStack key={addon.id} alignItems='center' space='$2'>
<Text flex={1} fontSize='$3' color='$textSecondary' numberOfLines={1}>
{addon.name}
Expand Down
3 changes: 2 additions & 1 deletion src/components/OrderTotal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const OrderTotal = ({ order }) => {
const tip = order.getAttribute('meta.tip');
const deliveryTip = order.getAttribute('meta.delivery_tip');
const total = order.getAttribute('meta.total');
const isPickup = order.getAttribute('meta.is_pickup');

const lineItems = useMemo(() => {
const items = [
Expand All @@ -38,7 +39,7 @@ const OrderTotal = ({ order }) => {
},
];

if (deliveryFee) {
if (deliveryFee && !isPickup) {
items.push({
name: 'Delivery Fee',
value: deliveryFee,
Expand Down
2 changes: 1 addition & 1 deletion src/components/QPayPaymentSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ const QPayPaymentSheet = forwardRef<QPayPaymentSheetRef, QPayPaymentSheetProps>(
({ item: bank }: { item: Bank }) => (
<Pressable onPress={() => openLink(bank)}>
<YStack py='$3' borderBottomWidth={1} borderColor='$borderColor'>
<XStack px='$5' style={styles.row}>
<XStack space='$2' px='$4' style={styles.row}>
<YStack style={styles.logoContainer}>
<Image source={{ uri: bank.logo }} width={40} height={40} borderRadius='$5' />
</YStack>
Expand Down
85 changes: 18 additions & 67 deletions src/components/StoreCategoriesGrid.tsx
Original file line number Diff line number Diff line change
@@ -1,80 +1,31 @@
import React from 'react';
import { Dimensions, Pressable } from 'react-native';
import { Pressable } from 'react-native';
import { YStack, XStack, Image, Text } from 'tamagui';
import { SimpleGrid } from 'react-native-super-grid';

const calculateCategoriesPerRow = (numCategories) => {
if (numCategories <= 2) return numCategories;
if (numCategories <= 4) return 2;
if (numCategories <= 6) return 3;
if (numCategories <= 8) return 4;
if (numCategories <= 10) return 5;
return 6;
};

const organizeCategoriesIntoRows = (categories, categoriesPerRow) => {
const rows = [];
for (let i = 0; i < categories.length; i += categoriesPerRow) {
rows.push(categories.slice(i, i + categoriesPerRow));
}
return rows;
};

const StoreCategoriesGrid = ({
categories = [],
categoriesPerRow = null,
wrapperStyle = {},
wrapperProps = {},
justifyContent = 'space-between',
rowStyle = {},
rowProps = {},
itemStyle = {},
itemContainerProps = {},
itemContainerWidth = null,
onPressCategory = null,
}) => {
const adjustedCategoriesPerRow = categoriesPerRow || calculateCategoriesPerRow(categories.length);

// Calculate item width with fixed padding
const screenWidth = Dimensions.get('window').width;
const sidePadding = 16;
const itemSpacing = 8;
const totalItemWidth = screenWidth - sidePadding * 2 - itemSpacing * (adjustedCategoriesPerRow - 1);
const itemWidth = itemContainerWidth ? itemContainerWidth : totalItemWidth / adjustedCategoriesPerRow;
const rows = organizeCategoriesIntoRows(categories, adjustedCategoriesPerRow);

const StoreCategoriesGrid = ({ categories = [], onPressCategory = null }) => {
const handleCategoryPress = (category) => {
if (typeof onPressCategory === 'function') {
onPressCategory(category);
}
};

const renderCategory = ({ item: category, index }) => {
return (
<Pressable key={index} onPress={() => handleCategoryPress(category)}>
<YStack alignItems='center' justifyContent='center' py='$2' space='$2'>
<Image source={{ uri: category.getAttribute('icon_url') }} width={50} height={50} borderRadius={25} />
<Text fontSize='$5' fontWeight='bold' textAlign='center' color='$textPrimary' numberOfLines={1}>
{category.getAttribute('name')}
</Text>
</YStack>
</Pressable>
);
};

return (
<YStack
paddingHorizontal={sidePadding}
bg='$surface'
borderWidth={1}
borderColor='$borderColorWithShadow'
borderRadius='$4'
paddingVertical='$2'
space='$2'
flex={1}
style={wrapperStyle}
{...wrapperProps}
>
{rows.map((row, rowIndex) => (
<XStack key={rowIndex} justifyContent={justifyContent} space={itemSpacing} style={rowStyle} {...rowProps}>
{row.map((category, index) => (
<Pressable key={index} onPress={() => handleCategoryPress(category)}>
<YStack alignItems='center' justifyContent='center' paddingVertical='$2' space='$2' width={itemWidth} style={itemStyle} {...itemContainerProps}>
<Image source={{ uri: category.getAttribute('icon_url') }} width={50} height={50} borderRadius={25} />
<Text fontSize='$5' fontWeight='bold' textAlign='center' color='$color'>
{category.getAttribute('name')}
</Text>
</YStack>
</Pressable>
))}
</XStack>
))}
<YStack bg='$surface' borderWidth={1} borderColor='$borderColorWithShadow' borderRadius='$4' paddingVertical='$2' space='$2' flex={1}>
<SimpleGrid maxItemsPerRow={4} itemDimension={50} data={categories} renderItem={renderCategory} />
</YStack>
);
};
Expand Down
6 changes: 4 additions & 2 deletions src/hooks/use-qpay-checkout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useAuth } from '../contexts/AuthContext';
import { getServiceQuote } from '../utils/checkout';
import { numbersOnly } from '../utils/format';
import { percentage, calculateTip } from '../utils/math';
import { getCoordinates } from '../utils/location';
import { get } from '../utils';
import useStorefront from '../hooks/use-storefront';
import useCurrentLocation from '../hooks/use-current-location';
Expand Down Expand Up @@ -176,15 +177,16 @@ export default function useQPayCheckout({ onOrderComplete }) {
}, [setupGateway, customer, cart, serviceQuote]);

useEffect(() => {
if (!deliveryLocation?.id || !cart) {
if (checkoutOptions.pickup || !cart) {
return;
}

let destination = deliveryLocation.isSaved ? deliveryLocation : getCoordinates(deliveryLocation);
let isMounted = true;
const fetchServiceQuote = async () => {
setServiceQuote(null);
try {
const quote = await getServiceQuote(currentStoreLocation, deliveryLocation, cart);
const quote = await getServiceQuote(currentStoreLocation, destination, cart);
if (isMounted) {
setServiceQuote(quote);
}
Expand Down
11 changes: 6 additions & 5 deletions src/hooks/use-stripe-checkout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { useAuth } from '../contexts/AuthContext';
import { getServiceQuote } from '../utils/checkout';
import { numbersOnly } from '../utils/format';
import { percentage, calculateTip } from '../utils/math';
import { get } from '../utils';
import { config, storefrontConfig } from '../utils';
import { getCoordinates } from '../utils/location';
import { config, storefrontConfig, get } from '../utils';
import useStorefront from '../hooks/use-storefront';
import useCart from '../hooks/use-cart';
import useCurrentLocation from '../hooks/use-current-location';
Expand Down Expand Up @@ -48,7 +48,7 @@ export default function useStripeCheckout({ onOrderComplete }) {
const totalItem = lineItems.find((item) => item.name === 'Total');
return totalItem ? totalItem.value : 0;
}, [checkoutOptions, subtotal, serviceQuote]);
const isReady = serviceQuote && !isLoading && !stripeLoading;
const isReady = serviceQuote && paymentMethod && !isLoading && !stripeLoading;
const isPickupEnabled = get(info, 'options.pickup_enabled') === true;

function computeLineItems() {
Expand Down Expand Up @@ -345,15 +345,16 @@ export default function useStripeCheckout({ onOrderComplete }) {

// Fetch service quote whenever location or cart contents change
useEffect(() => {
if (checkoutOptions.pickup) {
if (checkoutOptions.pickup || !cart) {
return;
}

let destination = deliveryLocation.isSaved ? deliveryLocation : getCoordinates(deliveryLocation);
let isMounted = true;
const fetchServiceQuote = async () => {
setServiceQuote(null);
try {
const quote = await getServiceQuote(currentStoreLocation, deliveryLocation, cart);
const quote = await getServiceQuote(currentStoreLocation, destination, cart);
if (isMounted) {
setServiceQuote(quote);
}
Expand Down
4 changes: 2 additions & 2 deletions src/screens/CartScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -221,14 +221,14 @@ const CartScreen = () => {
)}
</YStack>
<YStack>
{cartItem.variants.map((variant) => (
{cartItem.variants.filter(Boolean).map((variant) => (
<XStack key={variant.id} alignItems='center' space='$2'>
<Text flex={1} fontSize='$3' color='$textSecondary' numberOfLines={1}>
{variant.name}
</Text>
</XStack>
))}
{cartItem.addons.map((addon) => (
{cartItem.addons.filter(Boolean).map((addon) => (
<XStack key={addon.id} alignItems='center' space='$2'>
<Text flex={1} fontSize='$3' color='$textSecondary' numberOfLines={1}>
{addon.name}
Expand Down
1 change: 0 additions & 1 deletion src/screens/PhoneLoginScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ const PhoneLoginScreen = () => {
return;
}

console.log('[phone]', phone);
if (!isValidPhoneNumber(phone)) {
return toast.error('Invalid phone number provided.');
}
Expand Down
3 changes: 2 additions & 1 deletion src/screens/StripeCustomerScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@ const StripeCustomerScreen = () => {

if (error) {
console.error('Error initializing stripe customer sheet:', error);
return;
return navigation.goBack();
}

setCustomerSheetReady(true);
} catch (err) {
console.error('Error initializing stripe customer sheet:', err);
return navigation.goBack();
}
};

Expand Down
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"*": ["*", "*.native", "*.web"]
}
Expand Down
Loading

0 comments on commit 28492a4

Please sign in to comment.