mirror of
https://github.com/vercel/commerce.git
synced 2025-05-12 12:47:50 +00:00
add preloading to account's pages
This commit is contained in:
parent
19065c1d82
commit
aa29b3071d
@ -38,7 +38,7 @@ export default async function Page({ params }: { params: { page: string } }) {
|
|||||||
{page.title}
|
{page.title}
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<main>
|
<div>
|
||||||
<div className="mx-auto max-w-7xl py-6 sm:px-6 lg:px-8">
|
<div className="mx-auto max-w-7xl py-6 sm:px-6 lg:px-8">
|
||||||
<div className="flex flex-col space-y-16">
|
<div className="flex flex-col space-y-16">
|
||||||
{page.metaobjects?.map((content) => (
|
{page.metaobjects?.map((content) => (
|
||||||
@ -48,7 +48,7 @@ export default async function Page({ params }: { params: { page: string } }) {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
3
app/account/layout.tsx
Normal file
3
app/account/layout.tsx
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export default function Layout({ children }: { children: React.ReactNode }) {
|
||||||
|
return <div className="mx-auto max-w-screen-2xl">{children}</div>;
|
||||||
|
}
|
34
app/account/loading.tsx
Normal file
34
app/account/loading.tsx
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import Divider from 'components/divider';
|
||||||
|
import Heading from 'components/ui/heading';
|
||||||
|
import Skeleton from 'components/ui/skeleton';
|
||||||
|
|
||||||
|
export default function Loading() {
|
||||||
|
return (
|
||||||
|
<div className="p-6">
|
||||||
|
<Heading className="pb-4" as="h1">
|
||||||
|
Orders
|
||||||
|
</Heading>
|
||||||
|
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
|
||||||
|
<div className="flex w-full flex-col rounded border bg-white p-6">
|
||||||
|
<div className="flex flex-col gap-4">
|
||||||
|
<div>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<Skeleton className="h-20 w-20 flex-none" />
|
||||||
|
<Skeleton />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Divider />
|
||||||
|
<div className="flex flex-col gap-4">
|
||||||
|
<div>
|
||||||
|
<Skeleton className="mb-2 h-5 w-14" />
|
||||||
|
<Skeleton className="h-4 w-24" />
|
||||||
|
</div>
|
||||||
|
<Skeleton className="w-20" />
|
||||||
|
</div>
|
||||||
|
<Skeleton className="mt-4 h-11" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
29
app/account/orders/[id]/loading.tsx
Normal file
29
app/account/orders/[id]/loading.tsx
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import Skeleton from 'components/ui/skeleton';
|
||||||
|
|
||||||
|
export default function Loading() {
|
||||||
|
return (
|
||||||
|
<div className="mx-auto max-w-6xl p-6">
|
||||||
|
<div className="mb-6 flex justify-between">
|
||||||
|
<div className="flex items-start gap-2">
|
||||||
|
<Skeleton className="mt-1 h-6 w-6" />
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<Skeleton className="h-8 w-32" />
|
||||||
|
<Skeleton className="h-4 w-36" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Skeleton className="h-9 w-32" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-start gap-6">
|
||||||
|
<div className="flex flex-1 flex-col gap-6">
|
||||||
|
<Skeleton className="h-72" />
|
||||||
|
<Skeleton className="h-72" />
|
||||||
|
</div>
|
||||||
|
<div className="hidden md:block md:basis-5/12">
|
||||||
|
<Skeleton className="h-80" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -10,8 +10,9 @@ import Text from 'components/ui/text';
|
|||||||
import Price from 'components/price';
|
import Price from 'components/price';
|
||||||
import Badge from 'components/ui/badge';
|
import Badge from 'components/ui/badge';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
import OrderSummaryMobile from 'components/account/orders/order-summary-mobile';
|
||||||
import { Suspense } from 'react';
|
import { Suspense } from 'react';
|
||||||
import Skeleton from 'components/ui/skeleton';
|
import OrderSummary from 'components/account/orders/order-summary';
|
||||||
|
|
||||||
export const runtime = 'edge';
|
export const runtime = 'edge';
|
||||||
|
|
||||||
@ -236,86 +237,22 @@ function OrderDetails({ order }: { order: Order }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function OrderSummary({ order }: { order: Order }) {
|
|
||||||
return (
|
|
||||||
<div className="flex flex-col gap-6">
|
|
||||||
<Heading size="sm">Order Summary</Heading>
|
|
||||||
<div className="flex flex-col gap-6">
|
|
||||||
{order.lineItems.map((lineItem, index) => (
|
|
||||||
<div key={index} className="flex items-center gap-4">
|
|
||||||
<Badge content={lineItem.quantity!}>
|
|
||||||
<Image
|
|
||||||
src={lineItem.image.url}
|
|
||||||
alt={lineItem.image.altText}
|
|
||||||
width={lineItem.image.width}
|
|
||||||
height={lineItem.image.height}
|
|
||||||
className="rounded border"
|
|
||||||
/>
|
|
||||||
</Badge>
|
|
||||||
<div className="flex flex-col gap-2">
|
|
||||||
<Text>{lineItem.title}</Text>
|
|
||||||
<Label>{lineItem.sku}</Label>
|
|
||||||
</div>
|
|
||||||
<Price
|
|
||||||
className="text-sm"
|
|
||||||
amount={lineItem.price!.amount}
|
|
||||||
currencyCode={lineItem.price!.currencyCode}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col gap-4">
|
|
||||||
<div className="flex flex-col">
|
|
||||||
<div className="flex items-center justify-between">
|
|
||||||
<Text>Subtotal</Text>
|
|
||||||
<Price
|
|
||||||
className="text-sm font-semibold"
|
|
||||||
amount={order.totalPrice!.amount}
|
|
||||||
currencyCode={order.totalPrice!.currencyCode}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center justify-between">
|
|
||||||
<Text>Shipping</Text>
|
|
||||||
{order.shippingMethod?.price.amount !== '0.0' ? (
|
|
||||||
<Price
|
|
||||||
className="text-sm font-semibold"
|
|
||||||
amount={order.shippingMethod!.price.amount}
|
|
||||||
currencyCode={order.shippingMethod!.price.currencyCode}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<Text className="font-semibold">Free</Text>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center justify-between">
|
|
||||||
<Heading as="span" size="sm">
|
|
||||||
Total
|
|
||||||
</Heading>
|
|
||||||
<Price
|
|
||||||
className="font-semibold"
|
|
||||||
amount={order.totalPrice!.amount}
|
|
||||||
currencyCode={order.totalPrice!.currencyCode}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default async function OrderPage({ params }: { params: { id: string } }) {
|
export default async function OrderPage({ params }: { params: { id: string } }) {
|
||||||
const order = await getCustomerOrder(params.id);
|
const order = await getCustomerOrder(params.id);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className="mx-auto max-w-6xl p-6">
|
<>
|
||||||
|
<Suspense>
|
||||||
|
<OrderSummaryMobile order={order} />
|
||||||
|
</Suspense>
|
||||||
|
<div className="mx-auto max-w-6xl p-6">
|
||||||
<div className="mb-6 flex justify-between">
|
<div className="mb-6 flex justify-between">
|
||||||
<div className="flex items-start gap-2">
|
<div className="flex items-start gap-2">
|
||||||
<Link href="/account">
|
<Link href="/account">
|
||||||
<ArrowLeftIcon className="mt-1 h-6 w-6" />
|
<ArrowLeftIcon className="mt-1 h-6 w-6" />
|
||||||
</Link>
|
</Link>
|
||||||
<div>
|
<div>
|
||||||
<Suspense fallback={<Skeleton />}>
|
|
||||||
<Heading as="h1">Order {order.name}</Heading>
|
<Heading as="h1">Order {order.name}</Heading>
|
||||||
</Suspense>
|
|
||||||
<Label>Confirmed {toPrintDate(order.processedAt)}</Label>
|
<Label>Confirmed {toPrintDate(order.processedAt)}</Label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -325,16 +262,15 @@ export default async function OrderPage({ params }: { params: { id: string } })
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-start gap-6">
|
<div className="flex items-start gap-6">
|
||||||
<div className="flex flex-1 flex-col gap-6">
|
<div className="flex flex-1 flex-col gap-6">
|
||||||
<Suspense fallback={<Skeleton />}>
|
|
||||||
<Fulfillments order={order} />
|
<Fulfillments order={order} />
|
||||||
</Suspense>
|
|
||||||
<Unfulfilled order={order} />
|
<Unfulfilled order={order} />
|
||||||
<OrderDetails order={order} />
|
<OrderDetails order={order} />
|
||||||
</div>
|
</div>
|
||||||
<Card className="hidden md:block md:basis-5/12">
|
<Card className="hidden lg:block lg:basis-5/12">
|
||||||
<OrderSummary order={order} />
|
<OrderSummary order={order} />
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</div>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,104 +1,71 @@
|
|||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { getCustomerOrders } from 'lib/shopify';
|
import { getCustomerOrders } from 'lib/shopify';
|
||||||
|
import Text from 'components/ui/text';
|
||||||
import Price from 'components/price';
|
import Price from 'components/price';
|
||||||
import Divider from 'components/divider';
|
import Divider from 'components/divider';
|
||||||
import { Button } from 'components/button';
|
import { Button } from 'components/button';
|
||||||
|
import Heading from 'components/ui/heading';
|
||||||
|
import Label from 'components/ui/label';
|
||||||
|
import Badge from 'components/ui/badge';
|
||||||
|
import { Card } from 'components/ui/card';
|
||||||
|
|
||||||
export const runtime = 'edge';
|
export const runtime = 'edge';
|
||||||
|
|
||||||
export default async function AccountPage() {
|
export default async function AccountPage() {
|
||||||
// if (!access) {
|
|
||||||
// redirect('/logout');
|
|
||||||
// }
|
|
||||||
// if (access === 'denied') {
|
|
||||||
// redirect('/logout');
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// const customerAccessToken = access;
|
|
||||||
//
|
|
||||||
// //this is needed b/c of strange way server components handle redirects etc.
|
|
||||||
// //see https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#redirecting
|
|
||||||
// //can only redirect outside of try/catch!
|
|
||||||
// let success = true;
|
|
||||||
// let errorMessage;
|
|
||||||
// let customerData;
|
|
||||||
// let orders;
|
|
||||||
//
|
|
||||||
// try {
|
|
||||||
// const responseCustomerDetails = await shopifyCustomerFetch<CustomerDetailsData>({
|
|
||||||
// customerToken: customerAccessToken,
|
|
||||||
// query: CUSTOMER_DETAILS_QUERY,
|
|
||||||
// tags: [TAGS.customer]
|
|
||||||
// });
|
|
||||||
// const userDetails = responseCustomerDetails.body;
|
|
||||||
// if (!userDetails) {
|
|
||||||
// throw new Error('Error getting actual user data Account page.');
|
|
||||||
// }
|
|
||||||
// customerData = userDetails?.data?.customer;
|
|
||||||
// orders = customerData?.orders?.edges;
|
|
||||||
// //console.log ("Details",orders)
|
|
||||||
// } catch (e) {
|
|
||||||
// //they don't recognize this error in TS!
|
|
||||||
// //@ts-ignore
|
|
||||||
// errorMessage = e?.error?.toString() ?? 'Unknown Error';
|
|
||||||
// console.log('error customer fetch account', e);
|
|
||||||
// if (errorMessage !== 'unauthorized') {
|
|
||||||
// throw new Error('Error getting actual user data Account page.');
|
|
||||||
// } else {
|
|
||||||
// console.log('Unauthorized access. Set to false and redirect');
|
|
||||||
// success = false;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (!success && errorMessage === 'unauthorized') redirect('/logout');
|
|
||||||
// // revalidateTag('posts') // Update cached posts //FIX
|
|
||||||
const orders = await getCustomerOrders();
|
const orders = await getCustomerOrders();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx-auto mt-4 max-w-screen-2xl px-4">
|
<div className="p-6">
|
||||||
<h3 className="pb-4 text-2xl font-bold">Orders</h3>
|
<Heading className="pb-4" as="h1">
|
||||||
|
Orders
|
||||||
|
</Heading>
|
||||||
|
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
|
||||||
{orders.map((order, index) => (
|
{orders.map((order, index) => (
|
||||||
<div className="relative" key={index}>
|
<div className="relative" key={index}>
|
||||||
<Link
|
<Link
|
||||||
className="absolute left-0 top-0 h-full w-full"
|
className="peer absolute left-0 top-0 h-full w-full"
|
||||||
href={`/account/orders/${order.id}`}
|
href={`/account/orders/${order.id}`}
|
||||||
></Link>
|
/>
|
||||||
<div className="flex w-full flex-col rounded border bg-white p-6 md:w-fit">
|
<Card className="flex h-full flex-col transition-shadow peer-hover:shadow-lg peer-active:shadow-lg">
|
||||||
<div className="flex flex-col gap-2">
|
<div className="flex flex-col gap-4">
|
||||||
{order.lineItems.slice(0, 2).map((lineItem, index) => (
|
{order.lineItems.map((lineItem, index) => (
|
||||||
<div key={index}>
|
<div key={index}>
|
||||||
<div className="flex gap-2">
|
<div className="flex items-center gap-2">
|
||||||
|
<Badge content={lineItem.quantity!}>
|
||||||
<Image
|
<Image
|
||||||
src={lineItem?.image?.url}
|
src={lineItem?.image?.url}
|
||||||
alt={lineItem?.image?.altText}
|
alt={lineItem?.image?.altText}
|
||||||
width={80}
|
width={80}
|
||||||
height={80}
|
height={80}
|
||||||
|
className="rounded border"
|
||||||
/>
|
/>
|
||||||
<div>
|
</Badge>
|
||||||
<p>{lineItem.title}</p>
|
<Text>{lineItem.title}</Text>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Divider />
|
|
||||||
</div>
|
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-4">
|
<Divider />
|
||||||
|
<div className="flex flex-1 flex-col justify-end gap-4">
|
||||||
<div>
|
<div>
|
||||||
<p className="font-bold">
|
<Text>
|
||||||
{order.lineItems.length} item{order.lineItems.length > 1 && 's'}
|
{order.lineItems.length} item{order.lineItems.length > 1 && 's'}
|
||||||
</p>
|
</Text>
|
||||||
<p className="text-gray-500">Order {order.name}</p>
|
<Label>Order {order.name}</Label>
|
||||||
</div>
|
</div>
|
||||||
<Price
|
<Price
|
||||||
className="text-lg font-medium text-gray-900"
|
|
||||||
amount={order.totalPrice!.amount}
|
amount={order.totalPrice!.amount}
|
||||||
currencyCode={order.totalPrice!.currencyCode}
|
currencyCode={order.totalPrice!.currencyCode}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Button size="lg">Activate Warranty</Button>
|
<Button size="lg" className="mt-4">
|
||||||
</div>
|
Activate Warranty
|
||||||
|
</Button>
|
||||||
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -36,15 +36,17 @@ export const metadata = {
|
|||||||
export default async function RootLayout({ children }: { children: ReactNode }) {
|
export default async function RootLayout({ children }: { children: ReactNode }) {
|
||||||
return (
|
return (
|
||||||
<html lang="en" className={GeistSans.variable}>
|
<html lang="en" className={GeistSans.variable}>
|
||||||
<body className="bg-white text-black selection:bg-teal-300 dark:bg-neutral-900 dark:text-white dark:selection:bg-pink-500 dark:selection:text-white">
|
<body className="min-h-screen bg-white text-black selection:bg-primary-muted dark:bg-neutral-900 dark:text-white dark:selection:bg-primary-emphasis dark:selection:text-white">
|
||||||
<AuthProvider>
|
<AuthProvider>
|
||||||
<div>
|
{/* We need to have this wrapper div because the headless ui popover clickaway event is not working properly */}
|
||||||
|
{/* https://github.com/tailwindlabs/headlessui/issues/2752#issuecomment-1724096430 */}
|
||||||
|
<div className="flex h-screen flex-col">
|
||||||
<header>
|
<header>
|
||||||
<Banner />
|
<Banner />
|
||||||
<Navbar />
|
<Navbar />
|
||||||
</header>
|
</header>
|
||||||
<Suspense>
|
<Suspense>
|
||||||
<main>{children}</main>
|
<main className="main group flex-1">{children}</main>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</div>
|
</div>
|
||||||
</AuthProvider>
|
</AuthProvider>
|
||||||
|
46
components/account/orders/order-summary-mobile.tsx
Normal file
46
components/account/orders/order-summary-mobile.tsx
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
'use client';
|
||||||
|
import { ShoppingCartIcon, ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/24/outline';
|
||||||
|
import Text from 'components/ui/text';
|
||||||
|
import { Disclosure, DisclosureButton, DisclosurePanel, Transition } from '@headlessui/react';
|
||||||
|
import Divider from 'components/divider';
|
||||||
|
import Price from 'components/price';
|
||||||
|
import { Order } from 'lib/shopify/types';
|
||||||
|
import OrderSummary from './order-summary';
|
||||||
|
|
||||||
|
export default function OrderSummaryMobile({ order }: { order: Order }) {
|
||||||
|
return (
|
||||||
|
<div className="block lg:hidden">
|
||||||
|
<Disclosure>
|
||||||
|
{({ open }) => (
|
||||||
|
<>
|
||||||
|
<DisclosureButton className="flex w-full justify-between p-6">
|
||||||
|
<div className="flex items-center gap-2 text-primary">
|
||||||
|
<ShoppingCartIcon className="w-6" />
|
||||||
|
<Text>{open ? 'Hide order summary' : 'Show order summary'}</Text>
|
||||||
|
{open ? <ChevronUpIcon className="w-4" /> : <ChevronDownIcon className="w-4" />}
|
||||||
|
</div>
|
||||||
|
<Price
|
||||||
|
amount={order.totalPrice!.amount}
|
||||||
|
currencyCode={order.totalPrice!.currencyCode}
|
||||||
|
/>
|
||||||
|
</DisclosureButton>
|
||||||
|
|
||||||
|
<Transition
|
||||||
|
enter="duration-200 ease-out"
|
||||||
|
enterFrom="opacity-0 -translate-y-6"
|
||||||
|
enterTo="opacity-100 translate-y-0"
|
||||||
|
leave="duration-300 ease-out"
|
||||||
|
leaveFrom="opacity-100 translate-y-0"
|
||||||
|
leaveTo="opacity-0 -translate-y-6"
|
||||||
|
>
|
||||||
|
<DisclosurePanel className="origin-top p-6 text-gray-500 transition">
|
||||||
|
<OrderSummary order={order} />
|
||||||
|
</DisclosurePanel>
|
||||||
|
</Transition>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Disclosure>
|
||||||
|
<Divider hasSpacing={false} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
73
components/account/orders/order-summary.tsx
Normal file
73
components/account/orders/order-summary.tsx
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import Image from 'next/image';
|
||||||
|
import Price from 'components/price';
|
||||||
|
import Badge from 'components/ui/badge';
|
||||||
|
import Heading from 'components/ui/heading';
|
||||||
|
import Label from 'components/ui/label';
|
||||||
|
import Text from 'components/ui/text';
|
||||||
|
import { Order } from 'lib/shopify/types';
|
||||||
|
|
||||||
|
export default function OrderSummary({ order }: { order: Order }) {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col gap-6">
|
||||||
|
<Heading size="sm">Order Summary</Heading>
|
||||||
|
<div className="flex flex-col gap-6">
|
||||||
|
{order.lineItems.map((lineItem, index) => (
|
||||||
|
<div key={index} className="flex items-center gap-4">
|
||||||
|
<Badge content={lineItem.quantity!}>
|
||||||
|
<Image
|
||||||
|
src={lineItem.image.url}
|
||||||
|
alt={lineItem.image.altText}
|
||||||
|
width={lineItem.image.width}
|
||||||
|
height={lineItem.image.height}
|
||||||
|
className="rounded border"
|
||||||
|
/>
|
||||||
|
</Badge>
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<Text>{lineItem.title}</Text>
|
||||||
|
<Label>{lineItem.sku}</Label>
|
||||||
|
</div>
|
||||||
|
<Price
|
||||||
|
className="text-sm"
|
||||||
|
amount={lineItem.price!.amount}
|
||||||
|
currencyCode={lineItem.price!.currencyCode}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col gap-4">
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<Text>Subtotal</Text>
|
||||||
|
<Price
|
||||||
|
className="text-sm font-semibold"
|
||||||
|
amount={order.totalPrice!.amount}
|
||||||
|
currencyCode={order.totalPrice!.currencyCode}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<Text>Shipping</Text>
|
||||||
|
{order.shippingMethod?.price.amount !== '0.0' ? (
|
||||||
|
<Price
|
||||||
|
className="text-sm font-semibold"
|
||||||
|
amount={order.shippingMethod!.price.amount}
|
||||||
|
currencyCode={order.shippingMethod!.price.currencyCode}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Text className="font-semibold">Free</Text>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<Heading as="span" size="sm">
|
||||||
|
Total
|
||||||
|
</Heading>
|
||||||
|
<Price
|
||||||
|
className="font-semibold"
|
||||||
|
amount={order.totalPrice!.amount}
|
||||||
|
currencyCode={order.totalPrice!.currencyCode}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -43,7 +43,9 @@ const buttonVariants = tv({
|
|||||||
// hover color
|
// hover color
|
||||||
'hover:bg-primary-empahsis',
|
'hover:bg-primary-empahsis',
|
||||||
// disabled
|
// disabled
|
||||||
'disabled:bg-primary-muted'
|
'disabled:bg-primary-muted',
|
||||||
|
'hover:bg-primary-emphasis',
|
||||||
|
'pressed:bg-primary-emphasis/80'
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
secondary: {
|
secondary: {
|
||||||
|
@ -8,15 +8,16 @@ const cardStyles = tv({
|
|||||||
variants: {
|
variants: {
|
||||||
outlined: {
|
outlined: {
|
||||||
true: 'border bg-white',
|
true: 'border bg-white',
|
||||||
false: {}
|
false: ''
|
||||||
},
|
},
|
||||||
elevated: {
|
elevated: {
|
||||||
true: 'shadow-lg shadow-content/10 bg-white',
|
true: 'shadow-lg bg-white',
|
||||||
false: {}
|
false: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
defaultVariants: {
|
defaultVariants: {
|
||||||
outlined: true
|
outlined: true,
|
||||||
|
elevated: false
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -27,8 +28,13 @@ interface CardProps extends React.ComponentPropsWithoutRef<'div'>, VariantProps<
|
|||||||
const Card = React.forwardRef<HTMLDivElement, CardProps>(
|
const Card = React.forwardRef<HTMLDivElement, CardProps>(
|
||||||
({ className, asChild, outlined, elevated, ...props }, forwardedRef) => {
|
({ className, asChild, outlined, elevated, ...props }, forwardedRef) => {
|
||||||
const Component = asChild ? Slot : 'div';
|
const Component = asChild ? Slot : 'div';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Component ref={forwardedRef} className={cardStyles({ outlined, className })} {...props} />
|
<Component
|
||||||
|
ref={forwardedRef}
|
||||||
|
className={cardStyles({ outlined, elevated, className })}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -20,6 +20,7 @@ const orderCard = /* GraphQL */ `
|
|||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
title
|
title
|
||||||
|
quantity
|
||||||
image {
|
image {
|
||||||
altText
|
altText
|
||||||
height
|
height
|
||||||
|
Loading…
x
Reference in New Issue
Block a user