Skip to content

Commit

Permalink
Added support for viewing Invoices/Shipments and Credit Memo's
Browse files Browse the repository at this point in the history
  • Loading branch information
paales committed Feb 17, 2025
1 parent 0124e3e commit 6d2420c
Show file tree
Hide file tree
Showing 84 changed files with 2,319 additions and 212 deletions.
5 changes: 5 additions & 0 deletions .changeset/popular-suns-exercise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphcommerce/magento-customer': minor
---

Added support for viewing Invoices/Shipments and Credit Memo's
1 change: 0 additions & 1 deletion examples/magento-graphcms/pages/account/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
AddressSingleLine,
getCustomerAccountIsDisabled,
OrderStateLabel,
OrderStateLabelInline,
SignOutForm,
useCustomerQuery,
WaitForCustomer,
Expand Down
117 changes: 117 additions & 0 deletions examples/magento-graphcms/pages/account/orders/credit-memo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import type { PageOptions } from '@graphcommerce/framer-next-pages'
import {
CreditMemoDetailPageDocument,
CreditMemoItems,
CreditMemoTotals,
getCustomerAccountIsDisabled,
OrderDetails,
SalesComments,
useCustomerQuery,
WaitForCustomer,
} from '@graphcommerce/magento-customer'
import { CountryRegionsDocument, PageMeta, StoreConfigDocument } from '@graphcommerce/magento-store'
import type { GetStaticProps } from '@graphcommerce/next-ui'
import {
FullPageMessage,
iconInvoice,
IconSvg,
LayoutOverlayHeader,
LayoutTitle,
} from '@graphcommerce/next-ui'
import { i18n } from '@lingui/core'
import { Trans } from '@lingui/macro'
import { Container } from '@mui/material'
import { useRouter } from 'next/router'
import type { LayoutOverlayProps } from '../../../components'
import { LayoutOverlay } from '../../../components'
import { graphqlSharedClient, graphqlSsrClient } from '../../../lib/graphql/graphqlSsrClient'

type GetPageStaticProps = GetStaticProps<LayoutOverlayProps>

function CreditMemoDetailPage() {
const router = useRouter()
const { orderNumber, creditMemoNumber } = router.query

const creditMemos = useCustomerQuery(CreditMemoDetailPageDocument, {
fetchPolicy: 'cache-and-network',
variables: { orderNumber: orderNumber as string },
skip: !orderNumber || !creditMemoNumber,
})
const order = creditMemos.data?.customer?.orders?.items?.[0]
const creditMemo = order?.credit_memos?.find((c) => c?.number === creditMemoNumber)

return (
<>
<LayoutOverlayHeader hideBackButton>
<LayoutTitle size='small' component='span' icon={iconInvoice}>
<Trans>Credit Memo #{creditMemoNumber}</Trans>
</LayoutTitle>
</LayoutOverlayHeader>
<WaitForCustomer waitFor={[creditMemos, router.isReady]} sx={{ height: '100%' }}>
<Container maxWidth='md'>
{(!creditMemoNumber || !creditMemo || !order) && (
<FullPageMessage
title={<Trans>Credit Memo not found</Trans>}
icon={<IconSvg src={iconInvoice} size='xxl' />}
/>
)}

{creditMemoNumber && creditMemo && order && (
<>
<LayoutTitle
icon={iconInvoice}
gutterBottom={false}
sx={(theme) => ({ mb: theme.spacings.xxs })}
>
<Trans>Credit Memo #{creditMemoNumber}</Trans>
</LayoutTitle>

<PageMeta
title={i18n._(/* i18n */ 'Credit Memo #{creditMemoNumber}', { creditMemoNumber })}
metaRobots={['noindex']}
/>

<OrderDetails order={order} />
{/* <CreditMemoDetails creditMemo={creditMemo} /> */}
<CreditMemoItems creditMemo={creditMemo} />
<CreditMemoTotals creditMemo={creditMemo} />
<SalesComments
comments={creditMemo.comments}
sx={(theme) => ({ mb: theme.spacings.lg })}
/>
</>
)}
</Container>
</WaitForCustomer>
</>
)
}

const pageOptions: PageOptions<LayoutOverlayProps> = {
overlayGroup: 'account',
Layout: LayoutOverlay,
}
CreditMemoDetailPage.pageOptions = pageOptions

export default CreditMemoDetailPage

export const getStaticProps: GetPageStaticProps = async (context) => {
if (getCustomerAccountIsDisabled(context.locale)) return { notFound: true }

const client = graphqlSharedClient(context)
const staticClient = graphqlSsrClient(context)
const config = client.query({ query: StoreConfigDocument })

const countryRegions = staticClient.query({
query: CountryRegionsDocument,
})

return {
props: {
...(await countryRegions).data,
apolloState: await config.then(() => client.cache.extract()),
variantMd: 'bottom',
up: { href: '/account/orders', title: i18n._(/* i18n */ 'Orders') },
},
}
}
3 changes: 2 additions & 1 deletion examples/magento-graphcms/pages/account/orders/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ function AccountOrdersPage() {
pageSize: 5,
currentPage: Number(query?.page ?? 1),
},
errorPolicy: 'all',
})
const { data } = orders
const customer = data?.customer
Expand All @@ -47,7 +48,7 @@ function AccountOrdersPage() {
</LayoutOverlayHeader>
<Container maxWidth='md'>
<PageMeta title={i18n._(/* i18n */ 'Orders')} metaRobots={['noindex']} />
<WaitForCustomer waitFor={orders}>
<WaitForCustomer waitFor={orders} allowError>
{customer?.orders && customer.orders.items.length > 0 && (
<>
<LayoutTitle icon={iconBox}>
Expand Down
117 changes: 117 additions & 0 deletions examples/magento-graphcms/pages/account/orders/invoice.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import type { PageOptions } from '@graphcommerce/framer-next-pages'
import {
getCustomerAccountIsDisabled,
InvoiceDetailPageDocument,
InvoiceItems,
InvoiceTotals,
OrderDetails,
SalesComments,
useCustomerQuery,
WaitForCustomer,
} from '@graphcommerce/magento-customer'
import { CountryRegionsDocument, PageMeta, StoreConfigDocument } from '@graphcommerce/magento-store'
import type { GetStaticProps } from '@graphcommerce/next-ui'
import {
FullPageMessage,
iconInvoice,
IconSvg,
LayoutOverlayHeader,
LayoutTitle,
} from '@graphcommerce/next-ui'
import { i18n } from '@lingui/core'
import { Trans } from '@lingui/macro'
import { Container } from '@mui/material'
import { useRouter } from 'next/router'
import type { LayoutOverlayProps } from '../../../components'
import { LayoutOverlay } from '../../../components'
import { graphqlSharedClient, graphqlSsrClient } from '../../../lib/graphql/graphqlSsrClient'

type GetPageStaticProps = GetStaticProps<LayoutOverlayProps>

function InvoiceDetailPage() {
const router = useRouter()
const { invoiceNumber, orderNumber } = router.query

const invoices = useCustomerQuery(InvoiceDetailPageDocument, {
fetchPolicy: 'cache-and-network',
variables: { orderNumber: orderNumber as string },
skip: !invoiceNumber || !orderNumber,
})

const order = invoices.data?.customer?.orders?.items?.[0]
const invoice = order?.invoices.find((i) => i?.number === invoiceNumber)

return (
<>
<LayoutOverlayHeader hideBackButton>
<LayoutTitle size='small' component='span' icon={iconInvoice}>
<Trans>Invoice #{invoiceNumber}</Trans>
</LayoutTitle>
</LayoutOverlayHeader>
<WaitForCustomer waitFor={[invoices, router.isReady]} sx={{ height: '100%' }}>
<Container maxWidth='md'>
{(!invoiceNumber || !invoice || !order) && (
<FullPageMessage
title={<Trans>Invoice not found</Trans>}
icon={<IconSvg src={iconInvoice} size='xxl' />}
/>
)}

{invoiceNumber && invoice && order && (
<>
<LayoutTitle
icon={iconInvoice}
gutterBottom={false}
sx={(theme) => ({ mb: theme.spacings.xxs })}
>
<Trans>Invoice #{invoiceNumber}</Trans>
</LayoutTitle>

<PageMeta
title={i18n._(/* i18n */ 'Invoice #{invoiceNumber}', { invoiceNumber })}
metaRobots={['noindex']}
/>

<OrderDetails order={order} />
<InvoiceItems invoice={invoice} />
<InvoiceTotals invoice={invoice} />
<SalesComments
comments={invoice.comments}
sx={(theme) => ({ mb: theme.spacings.lg })}
/>
</>
)}
</Container>
</WaitForCustomer>
</>
)
}

const pageOptions: PageOptions<LayoutOverlayProps> = {
overlayGroup: 'account',
Layout: LayoutOverlay,
}
InvoiceDetailPage.pageOptions = pageOptions

export default InvoiceDetailPage

export const getStaticProps: GetPageStaticProps = async (context) => {
if (getCustomerAccountIsDisabled(context.locale)) return { notFound: true }

const client = graphqlSharedClient(context)
const staticClient = graphqlSsrClient(context)
const config = client.query({ query: StoreConfigDocument })

const countryRegions = staticClient.query({
query: CountryRegionsDocument,
})

return {
props: {
...(await countryRegions).data,
apolloState: await config.then(() => client.cache.extract()),
variantMd: 'bottom',
up: { href: '/account/orders', title: i18n._(/* i18n */ 'Orders') },
},
}
}
116 changes: 116 additions & 0 deletions examples/magento-graphcms/pages/account/orders/shipment.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import type { PageOptions } from '@graphcommerce/framer-next-pages'
import {
getCustomerAccountIsDisabled,
OrderDetails,
SalesComments,
ShipmentDetailPageDocument,
ShipmentDetails,
ShipmentItems,
useCustomerQuery,
WaitForCustomer,
} from '@graphcommerce/magento-customer'
import { CountryRegionsDocument, PageMeta, StoreConfigDocument } from '@graphcommerce/magento-store'
import type { GetStaticProps } from '@graphcommerce/next-ui'
import {
FullPageMessage,
iconBox,
IconSvg,
LayoutOverlayHeader,
LayoutTitle,
} from '@graphcommerce/next-ui'
import { i18n } from '@lingui/core'
import { Trans } from '@lingui/macro'
import { Container } from '@mui/material'
import { useRouter } from 'next/router'
import type { LayoutOverlayProps } from '../../../components'
import { LayoutOverlay } from '../../../components'
import { graphqlSharedClient, graphqlSsrClient } from '../../../lib/graphql/graphqlSsrClient'

type GetPageStaticProps = GetStaticProps<LayoutOverlayProps>

function ShipmentDetailPage() {
const router = useRouter()
const { orderNumber, shipmentNumber } = router.query

const shipments = useCustomerQuery(ShipmentDetailPageDocument, {
fetchPolicy: 'cache-and-network',
variables: { orderNumber: orderNumber as string },
skip: !orderNumber || !shipmentNumber,
})
const order = shipments.data?.customer?.orders?.items?.[0]
const shipment = order?.shipments?.find((s) => s?.number === shipmentNumber)

return (
<>
<LayoutOverlayHeader hideBackButton>
<LayoutTitle size='small' component='span' icon={iconBox}>
<Trans>Shipment #{shipmentNumber}</Trans>
</LayoutTitle>
</LayoutOverlayHeader>
<WaitForCustomer waitFor={[shipments, router.isReady]} sx={{ height: '100%' }}>
<Container maxWidth='md'>
{(!shipmentNumber || !shipment || !order) && (
<FullPageMessage
title={<Trans>Shipment not found</Trans>}
icon={<IconSvg src={iconBox} size='xxl' />}
/>
)}

{shipmentNumber && shipment && order && (
<>
<LayoutTitle
icon={iconBox}
gutterBottom={false}
sx={(theme) => ({ mb: theme.spacings.xxs })}
>
<Trans>Shipment #{shipmentNumber}</Trans>
</LayoutTitle>

<PageMeta
title={i18n._(/* i18n */ 'Shipment #{shipmentNumber}', { shipmentNumber })}
metaRobots={['noindex']}
/>

{/* <OrderDetails order={order} /> */}
<ShipmentDetails shipment={shipment} />
<ShipmentItems shipment={shipment} />
<SalesComments
comments={shipment.comments}
sx={(theme) => ({ mb: theme.spacings.lg })}
/>
</>
)}
</Container>
</WaitForCustomer>
</>
)
}

const pageOptions: PageOptions<LayoutOverlayProps> = {
overlayGroup: 'account',
Layout: LayoutOverlay,
}
ShipmentDetailPage.pageOptions = pageOptions

export default ShipmentDetailPage

export const getStaticProps: GetPageStaticProps = async (context) => {
if (getCustomerAccountIsDisabled(context.locale)) return { notFound: true }

const client = graphqlSharedClient(context)
const staticClient = graphqlSsrClient(context)
const config = client.query({ query: StoreConfigDocument })

const countryRegions = staticClient.query({
query: CountryRegionsDocument,
})

return {
props: {
...(await countryRegions).data,
apolloState: await config.then(() => client.cache.extract()),
variantMd: 'bottom',
up: { href: '/account/orders', title: i18n._(/* i18n */ 'Orders') },
},
}
}
Loading

0 comments on commit 6d2420c

Please sign in to comment.