From 53428a92a1d8c811ff303416dc80bcccd310392e Mon Sep 17 00:00:00 2001 From: Daniel Almaguer Date: Tue, 30 Apr 2024 10:28:11 -0500 Subject: [PATCH] refactor(core): cart page fragment colocation (#830) --- .../cart/_components/checkout-summary.tsx | 84 +++++++++----- .../coupon-code}/apply-coupon-code.ts | 0 .../cart/_components/coupon-code/fragment.ts | 16 +++ .../index.tsx} | 20 ++-- .../coupon-code}/remove-coupon-code.ts | 0 .../index.tsx} | 4 +- .../item-quantity}/update-item-quantity.ts | 2 +- .../shipping-estimator/fragment.ts | 31 +++++ .../get-shipping-countries.ts | 4 +- .../index.tsx} | 30 ++--- .../_components/shipping-info/fragment.ts | 27 +++++ .../shipping-info}/get-shipping-states.ts | 0 .../index.tsx} | 13 ++- .../shipping-info}/submit-shipping-info.ts | 0 .../_components/shipping-options/fragment.ts | 15 +++ .../index.tsx} | 57 +++------ .../shipping-options/submit-button.tsx | 22 ++++ .../submit-shipping-costs.ts | 0 .../core/app/[locale]/(default)/cart/page.tsx | 12 +- apps/core/client/queries/get-checkout.ts | 108 ------------------ 20 files changed, 225 insertions(+), 220 deletions(-) rename apps/core/app/[locale]/(default)/cart/{_actions => _components/coupon-code}/apply-coupon-code.ts (100%) create mode 100644 apps/core/app/[locale]/(default)/cart/_components/coupon-code/fragment.ts rename apps/core/app/[locale]/(default)/cart/_components/{coupon-code.tsx => coupon-code/index.tsx} (88%) rename apps/core/app/[locale]/(default)/cart/{_actions => _components/coupon-code}/remove-coupon-code.ts (100%) rename apps/core/app/[locale]/(default)/cart/_components/{item-quantity.tsx => item-quantity/index.tsx} (98%) rename apps/core/app/[locale]/(default)/cart/{_actions => _components/item-quantity}/update-item-quantity.ts (96%) create mode 100644 apps/core/app/[locale]/(default)/cart/_components/shipping-estimator/fragment.ts rename apps/core/app/[locale]/(default)/cart/{_actions => _components/shipping-estimator}/get-shipping-countries.ts (91%) rename apps/core/app/[locale]/(default)/cart/_components/{shipping-estimator.tsx => shipping-estimator/index.tsx} (83%) create mode 100644 apps/core/app/[locale]/(default)/cart/_components/shipping-info/fragment.ts rename apps/core/app/[locale]/(default)/cart/{_actions => _components/shipping-info}/get-shipping-states.ts (100%) rename apps/core/app/[locale]/(default)/cart/_components/{shipping-info.tsx => shipping-info/index.tsx} (95%) rename apps/core/app/[locale]/(default)/cart/{_actions => _components/shipping-info}/submit-shipping-info.ts (100%) create mode 100644 apps/core/app/[locale]/(default)/cart/_components/shipping-options/fragment.ts rename apps/core/app/[locale]/(default)/cart/_components/{shipping-options.tsx => shipping-options/index.tsx} (67%) create mode 100644 apps/core/app/[locale]/(default)/cart/_components/shipping-options/submit-button.tsx rename apps/core/app/[locale]/(default)/cart/{_actions => _components/shipping-options}/submit-shipping-costs.ts (100%) delete mode 100644 apps/core/client/queries/get-checkout.ts diff --git a/apps/core/app/[locale]/(default)/cart/_components/checkout-summary.tsx b/apps/core/app/[locale]/(default)/cart/_components/checkout-summary.tsx index 72fbac37b..c32def948 100644 --- a/apps/core/app/[locale]/(default)/cart/_components/checkout-summary.tsx +++ b/apps/core/app/[locale]/(default)/cart/_components/checkout-summary.tsx @@ -1,74 +1,100 @@ -import { AlertCircle } from 'lucide-react'; import { NextIntlClientProvider } from 'next-intl'; import { getFormatter, getLocale, getMessages, getTranslations } from 'next-intl/server'; -import { toast } from 'react-hot-toast'; -import { getCheckout } from '~/client/queries/get-checkout'; - -import { getShippingCountries } from '../_actions/get-shipping-countries'; +import { FragmentOf, graphql } from '~/client/graphql'; import { CouponCode } from './coupon-code'; +import { CouponCodeFragment } from './coupon-code/fragment'; import { ShippingEstimator } from './shipping-estimator'; +import { ShippingEstimatorFragment } from './shipping-estimator/fragment'; +import { getShippingCountries } from './shipping-estimator/get-shipping-countries'; + +const MoneyFieldsFragment = graphql(` + fragment MoneyFields on Money { + currencyCode + value + } +`); + +export const CheckoutSummaryFragment = graphql( + ` + fragment CheckoutSummaryFragment on Checkout { + ...ShippingEstimatorFragment + ...CouponCodeFragment + subtotal { + ...MoneyFields + } + grandTotal { + ...MoneyFields + } + taxTotal { + ...MoneyFields + } + cart { + currencyCode + discountedAmount { + ...MoneyFields + } + } + } + `, + [MoneyFieldsFragment, ShippingEstimatorFragment, CouponCodeFragment], +); -export const CheckoutSummary = async ({ cartId }: { cartId: string }) => { +interface Props { + data: FragmentOf; +} + +export const CheckoutSummary = async ({ data }: Props) => { const locale = await getLocale(); const t = await getTranslations({ locale, namespace: 'Cart.CheckoutSummary' }); const format = await getFormatter({ locale }); const messages = await getMessages({ locale }); - const [checkout, shippingCountries] = await Promise.all([ - getCheckout(cartId), - getShippingCountries(), - ]); - - if (!checkout) { - toast.error(t('errorMessage'), { - icon: , - }); + const shippingCountries = await getShippingCountries(); - return null; - } + const { cart, grandTotal, subtotal, taxTotal } = data; return ( <>
{t('subTotal')} - {format.number(checkout.subtotal?.value || 0, { + {format.number(subtotal?.value || 0, { style: 'currency', - currency: checkout.cart?.currencyCode, + currency: cart?.currencyCode, })}
- + - {checkout.cart?.discountedAmount && ( + {cart?.discountedAmount && (
{t('discounts')} - - {format.number(checkout.cart.discountedAmount.value, { + {format.number(cart.discountedAmount.value, { style: 'currency', - currency: checkout.cart.currencyCode, + currency: cart.currencyCode, })}
)} - + - {checkout.taxTotal && ( + {taxTotal && (
{t('tax')} - {format.number(checkout.taxTotal.value, { + {format.number(taxTotal.value, { style: 'currency', - currency: checkout.cart?.currencyCode, + currency: cart?.currencyCode, })}
@@ -77,9 +103,9 @@ export const CheckoutSummary = async ({ cartId }: { cartId: string }) => {
{t('grandTotal')} - {format.number(checkout.grandTotal?.value || 0, { + {format.number(grandTotal?.value || 0, { style: 'currency', - currency: checkout.cart?.currencyCode, + currency: cart?.currencyCode, })}
diff --git a/apps/core/app/[locale]/(default)/cart/_actions/apply-coupon-code.ts b/apps/core/app/[locale]/(default)/cart/_components/coupon-code/apply-coupon-code.ts similarity index 100% rename from apps/core/app/[locale]/(default)/cart/_actions/apply-coupon-code.ts rename to apps/core/app/[locale]/(default)/cart/_components/coupon-code/apply-coupon-code.ts diff --git a/apps/core/app/[locale]/(default)/cart/_components/coupon-code/fragment.ts b/apps/core/app/[locale]/(default)/cart/_components/coupon-code/fragment.ts new file mode 100644 index 000000000..a5b45bda0 --- /dev/null +++ b/apps/core/app/[locale]/(default)/cart/_components/coupon-code/fragment.ts @@ -0,0 +1,16 @@ +import { graphql } from '~/client/graphql'; + +export const CouponCodeFragment = graphql(` + fragment CouponCodeFragment on Checkout { + entityId + coupons { + code + discountedAmount { + value + } + } + cart { + currencyCode + } + } +`); diff --git a/apps/core/app/[locale]/(default)/cart/_components/coupon-code.tsx b/apps/core/app/[locale]/(default)/cart/_components/coupon-code/index.tsx similarity index 88% rename from apps/core/app/[locale]/(default)/cart/_components/coupon-code.tsx rename to apps/core/app/[locale]/(default)/cart/_components/coupon-code/index.tsx index 5f71e6b9a..5bcc5e28c 100644 --- a/apps/core/app/[locale]/(default)/cart/_components/coupon-code.tsx +++ b/apps/core/app/[locale]/(default)/cart/_components/coupon-code/index.tsx @@ -9,13 +9,11 @@ import { useEffect, useState } from 'react'; import { useFormStatus } from 'react-dom'; import { toast } from 'react-hot-toast'; -import { getCheckout } from '~/client/queries/get-checkout'; -import { ExistingResultType } from '~/client/util'; +import { FragmentOf } from '~/client/graphql'; -import { applyCouponCode } from '../_actions/apply-coupon-code'; -import { removeCouponCode } from '../_actions/remove-coupon-code'; - -type Checkout = ExistingResultType; +import { applyCouponCode } from './apply-coupon-code'; +import { CouponCodeFragment } from './fragment'; +import { removeCouponCode } from './remove-coupon-code'; const SubmitButton = () => { const t = useTranslations('Cart.SubmitCouponCode'); @@ -35,14 +33,16 @@ const SubmitButton = () => { ); }; -export const CouponCode = ({ checkout }: { checkout: ExistingResultType }) => { +interface Props { + checkout: FragmentOf; +} + +export const CouponCode = ({ checkout }: Props) => { const t = useTranslations('Cart.CheckoutSummary'); const format = useFormatter(); const [showAddCoupon, setShowAddCoupon] = useState(false); - const [selectedCoupon, setSelectedCoupon] = useState( - checkout.coupons.at(0) || null, - ); + const [selectedCoupon, setSelectedCoupon] = useState(checkout.coupons.at(0) || null); useEffect(() => { if (checkout.coupons[0]) { diff --git a/apps/core/app/[locale]/(default)/cart/_actions/remove-coupon-code.ts b/apps/core/app/[locale]/(default)/cart/_components/coupon-code/remove-coupon-code.ts similarity index 100% rename from apps/core/app/[locale]/(default)/cart/_actions/remove-coupon-code.ts rename to apps/core/app/[locale]/(default)/cart/_components/coupon-code/remove-coupon-code.ts diff --git a/apps/core/app/[locale]/(default)/cart/_components/item-quantity.tsx b/apps/core/app/[locale]/(default)/cart/_components/item-quantity/index.tsx similarity index 98% rename from apps/core/app/[locale]/(default)/cart/_components/item-quantity.tsx rename to apps/core/app/[locale]/(default)/cart/_components/item-quantity/index.tsx index bd2b3ee3c..4b61cf3b4 100644 --- a/apps/core/app/[locale]/(default)/cart/_components/item-quantity.tsx +++ b/apps/core/app/[locale]/(default)/cart/_components/item-quantity/index.tsx @@ -8,9 +8,9 @@ import { toast } from 'react-hot-toast'; import { graphql } from '~/client/graphql'; -import { updateItemQuantity } from '../_actions/update-item-quantity'; +import { Product } from '../cart-item'; -import { Product } from './cart-item'; +import { updateItemQuantity } from './update-item-quantity'; type CartSelectedOptionsInput = ReturnType>; diff --git a/apps/core/app/[locale]/(default)/cart/_actions/update-item-quantity.ts b/apps/core/app/[locale]/(default)/cart/_components/item-quantity/update-item-quantity.ts similarity index 96% rename from apps/core/app/[locale]/(default)/cart/_actions/update-item-quantity.ts rename to apps/core/app/[locale]/(default)/cart/_components/item-quantity/update-item-quantity.ts index fc6871c86..7e062f4c6 100644 --- a/apps/core/app/[locale]/(default)/cart/_actions/update-item-quantity.ts +++ b/apps/core/app/[locale]/(default)/cart/_components/item-quantity/update-item-quantity.ts @@ -6,7 +6,7 @@ import { cookies } from 'next/headers'; import { graphql } from '~/client/graphql'; import { updateCartLineItem } from '~/client/mutations/update-cart-line-item'; -import { removeItem } from './remove-item'; +import { removeItem } from '../../_actions/remove-item'; type CartLineItemInput = ReturnType>; type UpdateCartLineItemInput = ReturnType>; diff --git a/apps/core/app/[locale]/(default)/cart/_components/shipping-estimator/fragment.ts b/apps/core/app/[locale]/(default)/cart/_components/shipping-estimator/fragment.ts new file mode 100644 index 000000000..53474742a --- /dev/null +++ b/apps/core/app/[locale]/(default)/cart/_components/shipping-estimator/fragment.ts @@ -0,0 +1,31 @@ +import { graphql } from '~/client/graphql'; + +import { ShippingInfoFragment } from '../shipping-info/fragment'; +import { ShippingOptionsFragment } from '../shipping-options/fragment'; + +export const ShippingEstimatorFragment = graphql( + ` + fragment ShippingEstimatorFragment on Checkout { + ...ShippingInfoFragment + entityId + shippingConsignments { + ...ShippingOptionsFragment + selectedShippingOption { + entityId + description + } + } + handlingCostTotal { + value + } + shippingCostTotal { + currencyCode + value + } + cart { + currencyCode + } + } + `, + [ShippingOptionsFragment, ShippingInfoFragment], +); diff --git a/apps/core/app/[locale]/(default)/cart/_actions/get-shipping-countries.ts b/apps/core/app/[locale]/(default)/cart/_components/shipping-estimator/get-shipping-countries.ts similarity index 91% rename from apps/core/app/[locale]/(default)/cart/_actions/get-shipping-countries.ts rename to apps/core/app/[locale]/(default)/cart/_components/shipping-estimator/get-shipping-countries.ts index 94fb55353..f7a67a481 100644 --- a/apps/core/app/[locale]/(default)/cart/_actions/get-shipping-countries.ts +++ b/apps/core/app/[locale]/(default)/cart/_components/shipping-estimator/get-shipping-countries.ts @@ -2,7 +2,8 @@ import { getCountries } from '~/client/management/get-countries'; import { getShippingZones } from '~/client/management/get-shipping-zones'; export const getShippingCountries = async () => { - const shippingZones = await getShippingZones(); + const [shippingZones, allCountries] = await Promise.all([getShippingZones(), getCountries()]); + const uniqueCountryZones = shippingZones.reduce((zones, item) => { item.locations.forEach(({ country_iso2 }) => { if (zones.length === 0) { @@ -23,7 +24,6 @@ export const getShippingCountries = async () => { return zones; }, []); - const allCountries = await getCountries(); const shippingCountries = allCountries.flatMap((countryDetails) => { const isCountryInTheList = uniqueCountryZones.includes(countryDetails.country_iso2); diff --git a/apps/core/app/[locale]/(default)/cart/_components/shipping-estimator.tsx b/apps/core/app/[locale]/(default)/cart/_components/shipping-estimator/index.tsx similarity index 83% rename from apps/core/app/[locale]/(default)/cart/_components/shipping-estimator.tsx rename to apps/core/app/[locale]/(default)/cart/_components/shipping-estimator/index.tsx index f62ab4523..97cefcd5c 100644 --- a/apps/core/app/[locale]/(default)/cart/_components/shipping-estimator.tsx +++ b/apps/core/app/[locale]/(default)/cart/_components/shipping-estimator/index.tsx @@ -4,21 +4,21 @@ import { Button } from '@bigcommerce/components/button'; import { useFormatter, useTranslations } from 'next-intl'; import { useEffect, useRef, useState } from 'react'; -import { getCheckout } from '~/client/queries/get-checkout'; +import { FragmentOf } from '~/client/graphql'; import { ExistingResultType } from '~/client/util'; -import { getShippingCountries } from '../_actions/get-shipping-countries'; +import { ShippingInfo } from '../shipping-info'; +import { ShippingOptions } from '../shipping-options'; -import { ShippingInfo } from './shipping-info'; -import { ShippingOptions } from './shipping-options'; +import { ShippingEstimatorFragment } from './fragment'; +import { getShippingCountries } from './get-shipping-countries'; -export const ShippingEstimator = ({ - checkout, - shippingCountries, -}: { - checkout: ExistingResultType; +interface Props { + checkout: FragmentOf; shippingCountries: ExistingResultType; -}) => { +} + +export const ShippingEstimator = ({ checkout, shippingCountries }: Props) => { const t = useTranslations('Cart.CheckoutSummary'); const format = useFormatter(); @@ -97,13 +97,13 @@ export const ShippingEstimator = ({ {showShippingOptions && checkout.shippingConsignments && (
- {checkout.shippingConsignments.map(({ entityId, availableShippingOptions }) => { + {checkout.shippingConsignments.map((consignment) => { return ( ); })} diff --git a/apps/core/app/[locale]/(default)/cart/_components/shipping-info/fragment.ts b/apps/core/app/[locale]/(default)/cart/_components/shipping-info/fragment.ts new file mode 100644 index 000000000..239a8ed25 --- /dev/null +++ b/apps/core/app/[locale]/(default)/cart/_components/shipping-info/fragment.ts @@ -0,0 +1,27 @@ +import { graphql } from '~/client/graphql'; + +export const ShippingInfoFragment = graphql(` + fragment ShippingInfoFragment on Checkout { + entityId + shippingConsignments { + entityId + selectedShippingOption { + entityId + } + address { + city + countryCode + stateOrProvince + postalCode + } + } + cart { + lineItems { + physicalItems { + entityId + quantity + } + } + } + } +`); diff --git a/apps/core/app/[locale]/(default)/cart/_actions/get-shipping-states.ts b/apps/core/app/[locale]/(default)/cart/_components/shipping-info/get-shipping-states.ts similarity index 100% rename from apps/core/app/[locale]/(default)/cart/_actions/get-shipping-states.ts rename to apps/core/app/[locale]/(default)/cart/_components/shipping-info/get-shipping-states.ts diff --git a/apps/core/app/[locale]/(default)/cart/_components/shipping-info.tsx b/apps/core/app/[locale]/(default)/cart/_components/shipping-info/index.tsx similarity index 95% rename from apps/core/app/[locale]/(default)/cart/_components/shipping-info.tsx rename to apps/core/app/[locale]/(default)/cart/_components/shipping-info/index.tsx index d9942d139..2a31645de 100644 --- a/apps/core/app/[locale]/(default)/cart/_components/shipping-info.tsx +++ b/apps/core/app/[locale]/(default)/cart/_components/shipping-info/index.tsx @@ -4,17 +4,18 @@ import { Input } from '@bigcommerce/components/input'; import { Select, SelectContent, SelectItem } from '@bigcommerce/components/select'; import { AlertCircle, Loader2 as Spinner } from 'lucide-react'; import { useTranslations } from 'next-intl'; -import React, { useEffect, useReducer } from 'react'; +import { useEffect, useReducer } from 'react'; import { useFormStatus } from 'react-dom'; import { toast } from 'react-hot-toast'; -import { getShippingCountries } from '~/app/[locale]/(default)/cart/_actions/get-shipping-countries'; -import { getCheckout } from '~/client/queries/get-checkout'; +import { getShippingCountries } from '~/app/[locale]/(default)/cart/_components/shipping-estimator/get-shipping-countries'; +import { FragmentOf } from '~/client/graphql'; import { ExistingResultType } from '~/client/util'; import { cn } from '~/lib/utils'; -import { getShippingStates } from '../_actions/get-shipping-states'; -import { submitShippingInfo } from '../_actions/submit-shipping-info'; +import { ShippingInfoFragment } from './fragment'; +import { getShippingStates } from './get-shipping-states'; +import { submitShippingInfo } from './submit-shipping-info'; type StatesList = Array<{ id: number; @@ -55,7 +56,7 @@ export const ShippingInfo = ({ isVisible, hideShippingOptions, }: { - checkout: ExistingResultType; + checkout: FragmentOf; shippingCountries: ExistingResultType; isVisible: boolean; hideShippingOptions: () => void; diff --git a/apps/core/app/[locale]/(default)/cart/_actions/submit-shipping-info.ts b/apps/core/app/[locale]/(default)/cart/_components/shipping-info/submit-shipping-info.ts similarity index 100% rename from apps/core/app/[locale]/(default)/cart/_actions/submit-shipping-info.ts rename to apps/core/app/[locale]/(default)/cart/_components/shipping-info/submit-shipping-info.ts diff --git a/apps/core/app/[locale]/(default)/cart/_components/shipping-options/fragment.ts b/apps/core/app/[locale]/(default)/cart/_components/shipping-options/fragment.ts new file mode 100644 index 000000000..87d864219 --- /dev/null +++ b/apps/core/app/[locale]/(default)/cart/_components/shipping-options/fragment.ts @@ -0,0 +1,15 @@ +import { graphql } from '~/client/graphql'; + +export const ShippingOptionsFragment = graphql(` + fragment ShippingOptionsFragment on CheckoutShippingConsignment { + entityId + availableShippingOptions { + cost { + value + } + description + entityId + isRecommended + } + } +`); diff --git a/apps/core/app/[locale]/(default)/cart/_components/shipping-options.tsx b/apps/core/app/[locale]/(default)/cart/_components/shipping-options/index.tsx similarity index 67% rename from apps/core/app/[locale]/(default)/cart/_components/shipping-options.tsx rename to apps/core/app/[locale]/(default)/cart/_components/shipping-options/index.tsx index b9448d175..129818a76 100644 --- a/apps/core/app/[locale]/(default)/cart/_components/shipping-options.tsx +++ b/apps/core/app/[locale]/(default)/cart/_components/shipping-options/index.tsx @@ -1,56 +1,27 @@ -import { Button } from '@bigcommerce/components/button'; import { Field, FieldLabel, Form, FormSubmit } from '@bigcommerce/components/form'; import { Label } from '@bigcommerce/components/label'; import { Message } from '@bigcommerce/components/message'; import { RadioGroup, RadioItem } from '@bigcommerce/components/radio-group'; -import { AlertCircle, Loader2 as Spinner } from 'lucide-react'; +import { AlertCircle } from 'lucide-react'; import { useFormatter, useTranslations } from 'next-intl'; -import { useFormStatus } from 'react-dom'; import { toast } from 'react-hot-toast'; -import { getCheckout } from '~/client/queries/get-checkout'; -import { ExistingResultType } from '~/client/util'; +import { FragmentOf } from '~/client/graphql'; -interface AvailableShippingOptions { - cost: { - value: number; - }; - description: string; - entityId: string; - isRecommended: boolean; -} - -import { submitShippingCosts } from '../_actions/submit-shipping-costs'; - -const SubmitButton = () => { - const t = useTranslations('Cart.SubmitShippingCost'); - const { pending } = useFormStatus(); +import { ShippingOptionsFragment } from './fragment'; +import { SubmitButton } from './submit-button'; +import { submitShippingCosts } from './submit-shipping-costs'; - return ( - - ); -}; +interface Props { + data: FragmentOf; + checkoutEntityId: string; + currencyCode?: string; +} -export const ShippingOptions = ({ - checkout, - consignmentEntityId, - availableShippingOptions, -}: { - checkout: ExistingResultType; - consignmentEntityId: string; - availableShippingOptions: AvailableShippingOptions[] | null; -}) => { +export const ShippingOptions = ({ data, checkoutEntityId, currencyCode }: Props) => { const t = useTranslations('Cart.ShippingCost'); const format = useFormatter(); + const { availableShippingOptions, entityId } = data; const shippingOptions = availableShippingOptions?.map( ({ cost, description, entityId: shippingOptionEntityId, isRecommended }) => ({ @@ -62,7 +33,7 @@ export const ShippingOptions = ({ ); const onSubmit = async (formData: FormData) => { - const { status } = await submitShippingCosts(formData, checkout.entityId, consignmentEntityId); + const { status } = await submitShippingCosts(formData, checkoutEntityId, entityId); if (status === 'failed') { toast.error(t('errorMessage'), { @@ -97,7 +68,7 @@ export const ShippingOptions = ({ {format.number(option.cost, { style: 'currency', - currency: checkout.cart?.currencyCode, + currency: currencyCode, })}

diff --git a/apps/core/app/[locale]/(default)/cart/_components/shipping-options/submit-button.tsx b/apps/core/app/[locale]/(default)/cart/_components/shipping-options/submit-button.tsx new file mode 100644 index 000000000..571c3900a --- /dev/null +++ b/apps/core/app/[locale]/(default)/cart/_components/shipping-options/submit-button.tsx @@ -0,0 +1,22 @@ +import { Button } from '@bigcommerce/components/button'; +import { Loader2 as Spinner } from 'lucide-react'; +import { useTranslations } from 'next-intl'; +import { useFormStatus } from 'react-dom'; + +export const SubmitButton = () => { + const t = useTranslations('Cart.SubmitShippingCost'); + const { pending } = useFormStatus(); + + return ( + + ); +}; diff --git a/apps/core/app/[locale]/(default)/cart/_actions/submit-shipping-costs.ts b/apps/core/app/[locale]/(default)/cart/_components/shipping-options/submit-shipping-costs.ts similarity index 100% rename from apps/core/app/[locale]/(default)/cart/_actions/submit-shipping-costs.ts rename to apps/core/app/[locale]/(default)/cart/_components/shipping-options/submit-shipping-costs.ts diff --git a/apps/core/app/[locale]/(default)/cart/page.tsx b/apps/core/app/[locale]/(default)/cart/page.tsx index f470cf636..3e7276ec7 100644 --- a/apps/core/app/[locale]/(default)/cart/page.tsx +++ b/apps/core/app/[locale]/(default)/cart/page.tsx @@ -9,7 +9,7 @@ import { LocaleType } from '~/i18n'; import { CartItem, CartItemFragment } from './_components/cart-item'; import { CheckoutButton } from './_components/checkout-button'; -import { CheckoutSummary } from './_components/checkout-summary'; +import { CheckoutSummary, CheckoutSummaryFragment } from './_components/checkout-summary'; import { EmptyCart } from './_components/empty-cart'; export const metadata = { @@ -33,10 +33,13 @@ const CartPageQuery = graphql( ...CartItemFragment } } + checkout(entityId: $cartId) { + ...CheckoutSummaryFragment + } } } `, - [CartItemFragment], + [CartItemFragment, CheckoutSummaryFragment], ); export default async function CartPage({ params: { locale } }: Props) { @@ -56,12 +59,13 @@ export default async function CartPage({ params: { locale } }: Props) { fetchOptions: { cache: 'no-store', next: { - tags: ['cart'], + tags: ['cart', 'checkout'], }, }, }); const cart = data.site.cart; + const checkout = data.site.checkout; if (!cart) { return ; @@ -80,7 +84,7 @@ export default async function CartPage({ params: { locale } }: Props) {
- + {checkout && } diff --git a/apps/core/client/queries/get-checkout.ts b/apps/core/client/queries/get-checkout.ts deleted file mode 100644 index 32752bb07..000000000 --- a/apps/core/client/queries/get-checkout.ts +++ /dev/null @@ -1,108 +0,0 @@ -import { cache } from 'react'; - -import { getSessionCustomerId } from '~/auth'; - -import { client } from '..'; -import { graphql } from '../graphql'; - -const MONEY_FIELDS_FRAGMENT = graphql(` - fragment MoneyFields on Money { - currencyCode - value - } -`); - -const GET_CHECKOUT_QUERY = graphql( - ` - query getCheckout($checkoutId: String) { - site { - checkout(entityId: $checkoutId) { - entityId - subtotal { - ...MoneyFields - } - grandTotal { - ...MoneyFields - } - handlingCostTotal { - ...MoneyFields - } - shippingCostTotal { - ...MoneyFields - } - taxTotal { - ...MoneyFields - } - shippingConsignments { - entityId - lineItemIds - address { - countryCode - city - stateOrProvince - postalCode - } - selectedShippingOption { - description - entityId - } - availableShippingOptions { - entityId - description - cost { - value - currencyCode - } - isRecommended - type - } - } - coupons { - code - entityId - discountedAmount { - ...MoneyFields - } - } - cart { - currencyCode - discountedAmount { - ...MoneyFields - } - lineItems { - physicalItems { - entityId - quantity - } - } - } - } - } - } - `, - [MONEY_FIELDS_FRAGMENT], -); - -export const getCheckout = cache(async (checkoutId?: string) => { - const customerId = await getSessionCustomerId(); - - const response = await client.fetch({ - document: GET_CHECKOUT_QUERY, - variables: { checkoutId }, - customerId, - fetchOptions: { - cache: 'no-store', - next: { - tags: ['checkout'], - }, - }, - }); - - const checkout = response.data.site.checkout; - - if (!checkout) { - return; - } - - return checkout; -});