diff --git a/app/[page]/page.tsx b/app/[page]/page.tsx index 0781a6edc..35ac63867 100644 --- a/app/[page]/page.tsx +++ b/app/[page]/page.tsx @@ -38,7 +38,7 @@ export default async function Page({ params }: { params: { page: string } }) { {page.title} -
+
{page.metaobjects?.map((content) => ( @@ -48,7 +48,7 @@ export default async function Page({ params }: { params: { page: string } }) { ))}
-
+ ); } diff --git a/app/account/layout.tsx b/app/account/layout.tsx new file mode 100644 index 000000000..db15d4d52 --- /dev/null +++ b/app/account/layout.tsx @@ -0,0 +1,3 @@ +export default function Layout({ children }: { children: React.ReactNode }) { + return
{children}
; +} diff --git a/app/account/loading.tsx b/app/account/loading.tsx new file mode 100644 index 000000000..c932332d5 --- /dev/null +++ b/app/account/loading.tsx @@ -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 ( +
+ + Orders + +
+
+
+
+
+ + +
+
+
+ +
+
+ + +
+ +
+ +
+
+
+ ); +} diff --git a/app/account/orders/[id]/loading.tsx b/app/account/orders/[id]/loading.tsx new file mode 100644 index 000000000..da845d7d3 --- /dev/null +++ b/app/account/orders/[id]/loading.tsx @@ -0,0 +1,29 @@ +import Skeleton from 'components/ui/skeleton'; + +export default function Loading() { + return ( +
+
+
+ +
+ + +
+
+
+ +
+
+
+
+ + +
+
+ +
+
+
+ ); +} diff --git a/app/account/orders/[id]/page.tsx b/app/account/orders/[id]/page.tsx index ccf2938e8..51fb47237 100644 --- a/app/account/orders/[id]/page.tsx +++ b/app/account/orders/[id]/page.tsx @@ -10,8 +10,9 @@ import Text from 'components/ui/text'; import Price from 'components/price'; import Badge from 'components/ui/badge'; import Link from 'next/link'; +import OrderSummaryMobile from 'components/account/orders/order-summary-mobile'; import { Suspense } from 'react'; -import Skeleton from 'components/ui/skeleton'; +import OrderSummary from 'components/account/orders/order-summary'; export const runtime = 'edge'; @@ -236,105 +237,40 @@ function OrderDetails({ order }: { order: Order }) { ); } -function OrderSummary({ order }: { order: Order }) { - return ( -
- Order Summary -
- {order.lineItems.map((lineItem, index) => ( -
- - {lineItem.image.altText} - -
- {lineItem.title} - -
- -
- ))} -
-
-
-
- Subtotal - -
-
- Shipping - {order.shippingMethod?.price.amount !== '0.0' ? ( - - ) : ( - Free - )} -
-
-
- - Total - - -
-
-
- ); -} - export default async function OrderPage({ params }: { params: { id: string } }) { const order = await getCustomerOrder(params.id); return ( -
-
-
- - - -
- }> + <> + + + +
+
+
+ + + +
Order {order.name} - - + +
+
+
+
-
- -
-
-
-
- }> +
+
- - - + + +
+ + +
- - -
-
+ ); } diff --git a/app/account/page.tsx b/app/account/page.tsx index 1484c432d..c26ed1650 100644 --- a/app/account/page.tsx +++ b/app/account/page.tsx @@ -1,104 +1,71 @@ import Image from 'next/image'; import Link from 'next/link'; import { getCustomerOrders } from 'lib/shopify'; +import Text from 'components/ui/text'; import Price from 'components/price'; import Divider from 'components/divider'; 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 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({ - // 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(); return ( -
-

Orders

- {orders.map((order, index) => ( -
- -
-
- {order.lineItems.slice(0, 2).map((lineItem, index) => ( -
-
- {lineItem?.image?.altText} -
-

{lineItem.title}

+
+ + Orders + +
+ {orders.map((order, index) => ( +
+ + +
+ {order.lineItems.map((lineItem, index) => ( +
+
+ + {lineItem?.image?.altText} + + {lineItem.title}
- -
- ))} -
-
-
-

- {order.lineItems.length} item{order.lineItems.length > 1 && 's'} -

-

Order {order.name}

+ ))}
- -
- + +
+
+ + {order.lineItems.length} item{order.lineItems.length > 1 && 's'} + + +
+ +
+ +
-
- ))} + ))} +
); } diff --git a/app/layout.tsx b/app/layout.tsx index 468672c3d..1080eebcc 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -36,15 +36,17 @@ export const metadata = { export default async function RootLayout({ children }: { children: ReactNode }) { return ( - + -
+ {/* 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 */} +
-
{children}
+
{children}
diff --git a/components/account/orders/order-summary-mobile.tsx b/components/account/orders/order-summary-mobile.tsx new file mode 100644 index 000000000..1b81d2a5c --- /dev/null +++ b/components/account/orders/order-summary-mobile.tsx @@ -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 ( +
+ + {({ open }) => ( + <> + +
+ + {open ? 'Hide order summary' : 'Show order summary'} + {open ? : } +
+ +
+ + + + + + + + )} +
+ +
+ ); +} diff --git a/components/account/orders/order-summary.tsx b/components/account/orders/order-summary.tsx new file mode 100644 index 000000000..25aa81a51 --- /dev/null +++ b/components/account/orders/order-summary.tsx @@ -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 ( +
+ Order Summary +
+ {order.lineItems.map((lineItem, index) => ( +
+ + {lineItem.image.altText} + +
+ {lineItem.title} + +
+ +
+ ))} +
+
+
+
+ Subtotal + +
+
+ Shipping + {order.shippingMethod?.price.amount !== '0.0' ? ( + + ) : ( + Free + )} +
+
+
+ + Total + + +
+
+
+ ); +} diff --git a/components/button.tsx b/components/button.tsx index ed7c860ae..27fe38708 100644 --- a/components/button.tsx +++ b/components/button.tsx @@ -43,7 +43,9 @@ const buttonVariants = tv({ // hover color 'hover:bg-primary-empahsis', // disabled - 'disabled:bg-primary-muted' + 'disabled:bg-primary-muted', + 'hover:bg-primary-emphasis', + 'pressed:bg-primary-emphasis/80' ] }, secondary: { diff --git a/components/ui/card.tsx b/components/ui/card.tsx index 67a852431..31d263482 100644 --- a/components/ui/card.tsx +++ b/components/ui/card.tsx @@ -8,15 +8,16 @@ const cardStyles = tv({ variants: { outlined: { true: 'border bg-white', - false: {} + false: '' }, elevated: { - true: 'shadow-lg shadow-content/10 bg-white', - false: {} + true: 'shadow-lg bg-white', + false: '' } }, defaultVariants: { - outlined: true + outlined: true, + elevated: false } }); @@ -27,8 +28,13 @@ interface CardProps extends React.ComponentPropsWithoutRef<'div'>, VariantProps< const Card = React.forwardRef( ({ className, asChild, outlined, elevated, ...props }, forwardedRef) => { const Component = asChild ? Slot : 'div'; + return ( - + ); } ); diff --git a/lib/shopify/fragments/order-card.ts b/lib/shopify/fragments/order-card.ts index 98352add9..a7e87671b 100644 --- a/lib/shopify/fragments/order-card.ts +++ b/lib/shopify/fragments/order-card.ts @@ -20,6 +20,7 @@ const orderCard = /* GraphQL */ ` edges { node { title + quantity image { altText height