Skip to content

Commit

Permalink
show checkout is better
Browse files Browse the repository at this point in the history
  • Loading branch information
hdcola committed Nov 4, 2024
1 parent 1ab4c79 commit fdc5818
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 92 deletions.
38 changes: 38 additions & 0 deletions src/components/CartItemList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Box, Typography, Stack, Divider } from '@mui/material';
import { IItem } from '../api/useGetCartItems';

interface CartItemListProps {
items: IItem[];
}

export const CartItemList = ({ items }: CartItemListProps) => {
return (
<Box sx={{ mb: 2 }}>
<Typography variant="h6" gutterBottom>
Order Summary
</Typography>
<Stack divider={<Divider />} spacing={2}>
{items.map((item) => (
<Box
key={item.name}
sx={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
}}
>
<Box>
<Typography variant="body1">{item.name}</Typography>
<Typography variant="body2" color="text.secondary">
Quantity: {item.quantity}
</Typography>
</Box>
<Typography variant="body1">
${(Number(item.price) * item.quantity).toFixed(2)}
</Typography>
</Box>
))}
</Stack>
</Box>
);
};
60 changes: 44 additions & 16 deletions src/components/CheckoutForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ import {
useStripe,
useElements,
} from '@stripe/react-stripe-js';
import {
Box,
Button,
Stack,
Alert,
Typography,
CircularProgress,
Paper,
} from '@mui/material';

export const CheckoutForm = () => {
const stripe = useStripe();
Expand Down Expand Up @@ -51,27 +60,46 @@ export const CheckoutForm = () => {
};

return (
<>
<Paper elevation={3} sx={{ p: 3, maxWidth: 600, mx: 'auto' }}>
<form id="payment-form" onSubmit={handleSubmit}>
<PaymentElement
id="payment-element"
options={paymentElementOptions}
/>
<button
disabled={isLoading || !stripe || !elements}
id="submit"
>
<span id="button-text">
<Stack spacing={3}>
<Typography variant="h5" component="h2" gutterBottom>
Payment Details
</Typography>

<Box sx={{ mb: 2 }}>
<PaymentElement
id="payment-element"
options={paymentElementOptions}
/>
</Box>

<Button
variant="contained"
size="large"
disabled={isLoading || !stripe || !elements}
type="submit"
fullWidth
sx={{ mt: 2 }}
>
{isLoading ? (
<div className="spinner" id="spinner"></div>
<CircularProgress size={24} color="inherit" />
) : (
'Pay now'
)}
</span>
</button>
{/* Show any error or success messages */}
{message && <div id="payment-message">{message}</div>}
</Button>

{message && (
<Alert
severity={
message.includes('error') ? 'error' : 'info'
}
>
{message}
</Alert>
)}
</Stack>
</form>
</>
</Paper>
);
};
50 changes: 50 additions & 0 deletions src/components/CheckoutInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Stack, Typography, Divider } from '@mui/material';
import { ICheckout } from '../api/useGetCartItems';

export const CheckoutInfo = ({
checkout,
itemsCount,
}: {
checkout: ICheckout | undefined;
itemsCount: number;
}) => {
return (
<Stack spacing={1}>
{/* Items total */}
<Stack direction="row" justifyContent="space-between">
<Typography variant="body1">Item(s) total</Typography>
<Typography variant="body1">
CA${checkout?.itemsTotal}
</Typography>
</Stack>
{/* Shop discount */}
<Stack direction="row" justifyContent="space-between">
<Typography variant="body1">Shop discount</Typography>
<Typography variant="body1">
- CA${checkout?.shopDiscount}
</Typography>
</Stack>
<Divider />
{/* Subtotal */}
<Stack direction="row" justifyContent="space-between">
<Typography variant="body1">Subtotal</Typography>
<Typography variant="body1">CA${checkout?.subtotal}</Typography>
</Stack>
{/* Shipping */}
<Stack direction="row" justifyContent="space-between">
<Typography variant="body1">Shipping</Typography>
<Typography variant="body1">CA${checkout?.shipping}</Typography>
</Stack>
<Divider />
{/* Total */}
<Stack direction="row" justifyContent="space-between">
<Typography fontWeight={'bold'}>
Total ({itemsCount} items)
</Typography>
<Typography variant="body1" fontWeight={'bold'}>
CA${checkout?.total}
</Typography>
</Stack>
</Stack>
);
};
68 changes: 5 additions & 63 deletions src/pages/Cart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
Avatar,
Box,
Button,
Divider,
} from '@mui/material';
import Grid from '@mui/material/Grid2';
import { useQuery } from '@tanstack/react-query';
Expand All @@ -19,6 +18,7 @@ import useCartCount from '../hooks/useCartCount';
import { useNavigate } from 'react-router-dom';
import useGetCartItems from '../api/useGetCartItems';
import type { IItem } from '../api/useGetCartItems';
import { CheckoutInfo } from '../components/CheckoutInfo';

const CartItem = ({ refreshCart, removeItem, itemData }: Props) => {
const { server } = useAppContext();
Expand Down Expand Up @@ -170,68 +170,10 @@ const Cart = () => {
<Grid size={{ xs: 12, md: 4 }}>
<Box padding={3} mx={1}>
<Stack spacing={1} mb={3}>
{/* Items total */}
<Stack
direction="row"
justifyContent="space-between"
>
<Typography variant="body1">
Item(s) total
</Typography>
<Typography variant="body1">
CA${checkout?.itemsTotal}
</Typography>
</Stack>
{/* Shop discount */}
<Stack
direction="row"
justifyContent="space-between"
>
<Typography variant="body1">
Shop discount
</Typography>
<Typography variant="body1">
- CA${checkout?.shopDiscount}
</Typography>
</Stack>
<Divider />
{/* Subtotal */}
<Stack
direction="row"
justifyContent="space-between"
>
<Typography variant="body1">
Subtotal
</Typography>
<Typography variant="body1">
CA${checkout?.subtotal}
</Typography>
</Stack>
{/* Shipping */}
<Stack
direction="row"
justifyContent="space-between"
>
<Typography variant="body1">
Shipping
</Typography>
<Typography variant="body1">
CA${checkout?.shipping}
</Typography>
</Stack>
<Divider />
{/* Total */}
<Stack
direction="row"
justifyContent="space-between"
>
<Typography fontWeight={'bold'}>
Total ({items?.length} items)
</Typography>
<Typography variant="body1" fontWeight={'bold'}>
CA${checkout?.total}
</Typography>
</Stack>
<CheckoutInfo
checkout={checkout}
itemsCount={items?.length ?? 0}
/>
</Stack>
<Button
variant="contained"
Expand Down
37 changes: 24 additions & 13 deletions src/pages/CheckoutPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { Elements, useStripe } from '@stripe/react-stripe-js';
import { useStripeClientSecret } from '../api/useStripeClientSecret';
import { CheckoutForm } from '../components/CheckoutForm';
import useGetCartItems from '../api/useGetCartItems';
import { CheckoutInfo } from '../components/CheckoutInfo';
import { Box, Stack } from '@mui/material';
import Grid from '@mui/material/Grid';
import { CartItemList } from '../components/CartItemList';

export const CheckoutPage = () => {
const { data: { items: cartItem, checkout } = {} } = useGetCartItems(true);
Expand All @@ -26,18 +30,25 @@ export const CheckoutPage = () => {
if (error) return <p>Error: {error.message}</p>;

return (
<>
{items.map((item) => (
<div key={item.id}>
<h2>{item.id}</h2>
<p>{item.amount / 100}</p>
</div>
))}
{clientSecret && (
<Elements options={{ clientSecret }} stripe={stripe}>
<CheckoutForm />
</Elements>
)}
</>
<Grid container spacing={2}>
<Grid item xs={12} md={4}>
<Box padding={3}>
<Stack spacing={3}>
{cartItem && <CartItemList items={cartItem} />}
<CheckoutInfo
checkout={checkout}
itemsCount={cartItem?.length ?? 0}
/>
</Stack>
</Box>
</Grid>
<Grid item xs={12} md={8}>
{clientSecret && (
<Elements options={{ clientSecret }} stripe={stripe}>
<CheckoutForm />
</Elements>
)}
</Grid>
</Grid>
);
};

0 comments on commit fdc5818

Please sign in to comment.