Skip to content

Commit

Permalink
Move carts to REST data
Browse files Browse the repository at this point in the history
  • Loading branch information
koredefashokun committed Jan 6, 2025
1 parent ad209ef commit b62053a
Show file tree
Hide file tree
Showing 12 changed files with 112 additions and 89 deletions.
13 changes: 11 additions & 2 deletions api/src/controllers/carts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,23 @@ export default class CartController {
}

const cart = await prismaClient.cart.findUnique({
where: { id: req.params.id, userId: req.auth.id }
where: { id: req.params.id, userId: req.auth.id },
include: {
user: { include: { cards: true } },
store: { include: { image: true } },
products: { include: { product: { include: { images: true } } } }
}
});

if (!cart) {
return res.status(404).json({ error: 'Cart not found' });
}

return res.json({ cart });
const computedTotal = cart.products.reduce((acc, p) => {
return acc + p.product.unitPrice * p.quantity;
}, 0);

return res.json({ cart: { ...cart, total: computedTotal } });
}

// POST /carts/products
Expand Down
2 changes: 2 additions & 0 deletions api/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { createServer } from 'http';
import prismaClient from './config/prisma';
import redisClient from './config/redis';
import { initSentry } from './config/sentry';
import carts from './routes/carts';
import health from './routes/health';
import payments from './routes/payments';
import stores from './routes/stores';
Expand Down Expand Up @@ -65,6 +66,7 @@ const main = async () => {
app.use('/payments', payments);
app.use('/health', health);
app.use('/users', users);
app.use('/carts', carts);
app.use('/stores', stores);

const PORT = Number(process.env.PORT || 3000);
Expand Down
2 changes: 1 addition & 1 deletion apps/app/src/components/cart/CartSummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const CartSummary: React.FC<CartSummaryProps> = ({ products }) => {

{products.map(cartProduct => (
<CartProduct
key={cartProduct.id}
key={`${cartProduct.cartId}-${cartProduct.productId}`}
cartProduct={cartProduct}
onPress={handleCartProductPress(cartProduct.productId)}
/>
Expand Down
9 changes: 3 additions & 6 deletions apps/app/src/components/explore/SearchResults.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,14 @@ import ProductResultRow from './ProductResultRow';
import RecentSearches from './RecentSearches';
import { SearchProvider, useSearchContext } from './SearchContext';
import StoreResultRow from './StoreResultRow';
import {
AppStackParamList,
ExploreStackParamList
} from '../../types/navigation';
import { AppStackParamList, HomeStackParamList } from '../../types/navigation';

const StoresView: React.FC = () => {
const { navigate } = useNavigation<NavigationProp<ExploreStackParamList>>();
const { navigate } = useNavigation<NavigationProp<HomeStackParamList>>();
const { stores } = useSearchContext();

const handleStorePress = (storeId: string) => () => {
navigate('Explore.Store', {
navigate('Home.Store', {
screen: 'Store.Main',
params: { storeId }
});
Expand Down
32 changes: 11 additions & 21 deletions apps/app/src/components/home/RecentOrders.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ListEmpty, Typography } from '@habiti/components';
import { Typography } from '@habiti/components';
import { useNavigation, NavigationProp } from '@react-navigation/native';
import React from 'react';
import { View, StyleSheet } from 'react-native';
Expand All @@ -11,10 +11,6 @@ interface RecentOrdersProps {
orders: HomeQuery['currentUser']['orders'];
}

// This should only query the last three orders.
// We should have a "view all" button that navigates to a more in-depth view
// (infinite scrolling and filters) of all previous orders.

const RecentOrders: React.FC<RecentOrdersProps> = ({ orders }) => {
const { navigate } =
useNavigation<NavigationProp<MainTabParamList & HomeStackParamList>>();
Expand All @@ -26,6 +22,10 @@ const RecentOrders: React.FC<RecentOrdersProps> = ({ orders }) => {
[]
);

if (!orders || orders.length === 0) {
return null;
}

return (
<View style={styles.container}>
<Typography
Expand All @@ -34,23 +34,13 @@ const RecentOrders: React.FC<RecentOrdersProps> = ({ orders }) => {
>
Recent orders
</Typography>
{!orders || orders?.length === 0 ? (
<ListEmpty
description='Pending orders will be displayed here.'
cta={{
text: 'View your carts',
action: () => navigate('Main.Carts')
}}
{orders.map(order => (
<RecentOrder
key={order.id}
order={order}
onPress={handleOrderPress(order.id)}
/>
) : (
orders.map(order => (
<RecentOrder
key={order.id}
order={order}
onPress={handleOrderPress(order.id)}
/>
))
)}
))}
</View>
);
};
Expand Down
21 changes: 9 additions & 12 deletions apps/app/src/screens/Cart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ import CartTotal from '../components/cart/CartTotal';
// import DeliveryInfo from '../components/cart/DeliveryInfo';
import SelectCard from '../components/cart/SelectCard';
import StoreInfo from '../components/cart/StoreInfo';
import { useCartQuery } from '../data/queries';
import useGoBack from '../hooks/useGoBack';
import useRefreshing from '../hooks/useRefreshing';
import useStore from '../state';
import { useCreateOrderMutation, useCartQuery } from '../types/api';
import { useCreateOrderMutation } from '../types/api';
import { AppStackParamList } from '../types/navigation';
import { calculateFees } from '../utils/fees';

Expand All @@ -37,8 +39,8 @@ const Cart: React.FC = () => {
const { goBack } = useNavigation<NavigationProp<AppStackParamList>>();
useGoBack();

const [{ data, fetching }, refetch] = useCartQuery({ variables: { cartId } });
const [refreshing, setRefreshing] = React.useState(false);
const { data, error, refetch } = useCartQuery(cartId);
const { refreshing, handleRefresh } = useRefreshing(refetch);
const [, createOrder] = useCreateOrderMutation();

const { defaultCardId, setPreference } = useStore(state => ({
Expand All @@ -50,20 +52,15 @@ const Cart: React.FC = () => {

const [selectedCard, setSelectedCard] = React.useState(defaultCardId);

const handleRefresh = React.useCallback(() => {
setRefreshing(true);
refetch();
}, [refetch]);

React.useEffect(() => {
if (!fetching && refreshing) setRefreshing(false);
}, [fetching, refreshing]);

const fees = React.useMemo(
() => calculateFees(data?.cart.total ?? 0),
[data?.cart.total]
);

React.useEffect(() => {
console.log({ data: JSON.stringify(data, null, 2), error });
}, [data, error]);

// TODO: Process the fee amount on the server, to make sure we don't have to
// update client code to reflect new fee changes.

Expand Down
4 changes: 1 addition & 3 deletions apps/app/src/screens/Carts.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ListEmpty, Screen, ScreenHeader, useTheme } from '@habiti/components';
import { NavigationProp, useNavigation } from '@react-navigation/native';
// import { FlashList } from '@shopify/flash-list';
import React from 'react';
import { FlatList, RefreshControl } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
Expand Down Expand Up @@ -35,7 +34,6 @@ const Carts: React.FC = () => {
renderItem={({ item }) => (
<CartsListItem cart={item} onPress={handleCartPress(item.id)} />
)}
// estimatedItemSize={66}
data={data?.carts}
contentContainerStyle={{ flexGrow: 1 }}
ListEmptyComponent={() => (
Expand All @@ -44,7 +42,7 @@ const Carts: React.FC = () => {
description={`Looks like your cart is empty. Let's change that.`}
cta={{
text: 'Discover new stores',
action: () => navigate('Main.Explore')
action: () => {}
}}
viewStyle={{ flex: 1 }}
/>
Expand Down
30 changes: 26 additions & 4 deletions apps/app/src/screens/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import {
Screen,
ScreenHeader,
ScrollableScreen,
Spacer
Spacer,
useTheme
} from '@habiti/components';
import { NavigationProp, useNavigation } from '@react-navigation/native';
import React from 'react';
import { ActivityIndicator, View } from 'react-native';
import { ActivityIndicator, RefreshControl, View } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';

import FollowedStores from '../components/home/FollowedStores';
Expand All @@ -15,9 +16,22 @@ import { useHomeQuery } from '../types/api';
import { HomeStackParamList } from '../types/navigation';

const Home: React.FC = () => {
const [{ fetching, data }] = useHomeQuery();
const [{ fetching, data }, refetch] = useHomeQuery();
const { top } = useSafeAreaInsets();
const { navigate } = useNavigation<NavigationProp<HomeStackParamList>>();
const [refreshing, setRefreshing] = React.useState(false);
const { theme } = useTheme();

React.useEffect(() => {
if (!fetching && refreshing) {
setRefreshing(false);
}
}, [fetching, refreshing]);

const handleRefresh = () => {
setRefreshing(true);
refetch();
};

if (fetching || !data) {
return (
Expand All @@ -36,7 +50,15 @@ const Home: React.FC = () => {
onPress: () => navigate('Home.Search')
}}
/>
<ScrollableScreen>
<ScrollableScreen
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={handleRefresh}
tintColor={theme.text.secondary}
/>
}
>
<Spacer y={16} />
<FollowedStores followed={data.currentUser.followed} />
<Spacer y={8} />
Expand Down
63 changes: 34 additions & 29 deletions apps/app/src/screens/PaymentMethods.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@ import {
ListEmpty,
Screen,
Separator,
Spacer,
Typography,
useTheme
} from '@habiti/components';
import { useNavigation, NavigationProp } from '@react-navigation/native';
import React from 'react';
import { View, StyleSheet, ActivityIndicator, Pressable } from 'react-native';
import {
View,
StyleSheet,
ActivityIndicator,
Pressable,
FlatList
} from 'react-native';

import { MastercardIcon } from '../components/cart/CardIcons';
import { useCardsQuery } from '../data/queries';
Expand Down Expand Up @@ -45,41 +50,41 @@ const PaymentMethods: React.FC = () => {

return (
<Screen>
{cards.length === 0 ? (
<View>
<Spacer y={16} />
{/* <Typography
weight='medium'
variant='label'
style={styles.sectionHeader}
>
Cards
</Typography>
<Separator /> */}
<FlatList
style={{ flex: 1 }}
contentContainerStyle={{ flexGrow: 1 }}
data={cards}
keyExtractor={c => c.id}
renderItem={({ item: card }) => (
<Pressable
style={[styles.card, { borderBottomColor: theme.border.color }]}
>
<MastercardIcon />
<Typography
style={styles.capitalize}
>{`${card.cardType} \u2022\u2022\u2022\u2022${card.last4}`}</Typography>
</Pressable>
)}
ListEmptyComponent={() => (
<ListEmpty
title='No cards added'
description='When you add your cards, they will be displayed here.'
cta={{
text: 'Add card',
action: () => navigate('Add Card')
}}
viewStyle={{ flex: 1 }}
/>
</View>
) : (
<View>
<Typography
weight='medium'
variant='label'
style={styles.sectionHeader}
>
Cards
</Typography>
<Separator />
{cards.map(card => (
<Pressable
key={card.id}
style={[styles.card, { borderBottomColor: theme.border.color }]}
>
<MastercardIcon />
<Typography
style={styles.capitalize}
>{`${card.cardType} \u2022\u2022\u2022\u2022${card.last4}`}</Typography>
</Pressable>
))}
</View>
)}
)}
/>
</Screen>
);
};
Expand Down
8 changes: 4 additions & 4 deletions apps/app/src/screens/SearchStore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ const SearchStore = () => {
<ActivityIndicator />
) : (
<FlashList
data={data.store.products}
keyExtractor={({ id }) => id}
data={data.store.products.edges}
keyExtractor={({ node }) => node.id}
showsVerticalScrollIndicator={false}
estimatedItemSize={240}
renderItem={({ item, index }) => (
<StoreListItem
item={item}
onPress={handleProductPress(item.id)}
item={item.node}
onPress={handleProductPress(item.node.id)}
side={index % 2 === 0 ? 'left' : 'right'}
/>
)}
Expand Down
1 change: 0 additions & 1 deletion apps/app/src/types/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ export type StoreStackParamList = {

export type MainTabParamList = {
'Main.ForYou': undefined;
'Main.Explore': undefined;
'Main.Carts': undefined;
'Main.Profile': undefined;
};
Loading

0 comments on commit b62053a

Please sign in to comment.