Skip to content

Commit

Permalink
Fix show multiple gift cards in order details (#4814)
Browse files Browse the repository at this point in the history
* Show multiple order gift cards

* Extract ThemeWrapper

* Write tests

* Rename to OrderUsedGiftCards, add this to order summary

* Add changeset

* Fix for comma

* Update tests
  • Loading branch information
poulch committed Apr 23, 2024
1 parent b4798b7 commit c957d9c
Show file tree
Hide file tree
Showing 13 changed files with 154 additions and 50 deletions.
5 changes: 5 additions & 0 deletions .changeset/warm-taxis-mate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"saleor-dashboard": patch
---

Show all gift card used in order details
20 changes: 5 additions & 15 deletions src/orders/components/OrderPayment/OrderPayment.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { Button } from "@dashboard/components/Button";
import CardTitle from "@dashboard/components/CardTitle";
import HorizontalSpacer from "@dashboard/components/HorizontalSpacer";
import Link from "@dashboard/components/Link";
import Money from "@dashboard/components/Money";
import { Pill } from "@dashboard/components/Pill";
import Skeleton from "@dashboard/components/Skeleton";
import { giftCardPath } from "@dashboard/giftCards/urls";
import {
OrderAction,
OrderDetailsFragment,
Expand All @@ -19,12 +17,13 @@ import React from "react";
import { FormattedMessage, useIntl } from "react-intl";

import { transformPaymentStatus } from "../../../misc";
import { OrderUsedGiftCards } from "../OrderUsedGiftCards";
import { orderPaymentMessages, paymentButtonMessages } from "./messages";
import { useStyles } from "./styles";
import {
extractOrderGiftCardUsedAmount,
extractRefundedAmount,
obtainUsedGifrcard,
obtainUsedGifrcards,
} from "./utils";

interface OrderPaymentProps {
Expand All @@ -50,7 +49,7 @@ const OrderPayment: React.FC<OrderPaymentProps> = props => {
const payment = transformPaymentStatus(order?.paymentStatus, intl);
const refundedAmount = extractRefundedAmount(order);
const usedGiftCardAmount = extractOrderGiftCardUsedAmount(order);
const usedGiftcard = obtainUsedGifrcard(order);
const usedGiftcards = obtainUsedGifrcards(order);

const getDeliveryMethodName = (order: OrderDetailsFragment) => {
if (
Expand Down Expand Up @@ -212,18 +211,9 @@ const OrderPayment: React.FC<OrderPaymentProps> = props => {
<Divider />
<CardContent className={classes.payments}>
<div className={classes.root}>
{!!usedGiftCardAmount && usedGiftcard && (
{!!usedGiftCardAmount && usedGiftcards && (
<div>
<FormattedMessage
{...orderPaymentMessages.paidWithGiftCard}
values={{
link: (
<Link href={giftCardPath(usedGiftcard.id)}>
{usedGiftcard.last4CodeChars}
</Link>
),
}}
/>
<OrderUsedGiftCards giftCards={usedGiftcards} />
<div className={classes.leftmostRightAlignedElement}>
<Money
money={{
Expand Down
5 changes: 0 additions & 5 deletions src/orders/components/OrderPayment/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,6 @@ export const orderPaymentMessages = defineMessages({
defaultMessage: "Outstanding Balance",
description: "order payment",
},
paidWithGiftCard: {
id: "yivxZJ",
defaultMessage: "Paid with Gift Card: ({link})",
description: "order payment",
},
includedInSubtotal: {
id: "pPef6L",
defaultMessage: "Included in subtotal",
Expand Down
4 changes: 2 additions & 2 deletions src/orders/components/OrderPayment/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ import {
import { IMoney } from "@dashboard/utils/intl";
import compact from "lodash/compact";

export const obtainUsedGifrcard = (order?: OrderDetailsFragment) => {
export const obtainUsedGifrcards = (order?: OrderDetailsFragment) => {
if (!order) return null;

const { giftCards } = order;

if (giftCards.length > 0) {
return giftCards[0];
return giftCards;
}

return null;
Expand Down
21 changes: 4 additions & 17 deletions src/orders/components/OrderSummaryCard/OrderSummaryCard.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
// @ts-strict-ignore
import CardTitle from "@dashboard/components/CardTitle";
import Link from "@dashboard/components/Link";
import { giftCardPath } from "@dashboard/giftCards/urls";
import { OrderDetailsFragment } from "@dashboard/graphql";
import { getDiscountTypeLabel } from "@dashboard/orders/utils/data";
import { Card, CardContent } from "@material-ui/core";
import { makeStyles } from "@saleor/macaw-ui";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";

import { obtainUsedGifrcard } from "../OrderPayment/utils";
import { obtainUsedGifrcards } from "../OrderPayment/utils";
import { OrderUsedGiftCards } from "../OrderUsedGiftCards";
import { orderSummaryMessages } from "./messages";
import SummaryLine from "./SummaryLine";
import { SummaryList } from "./SummaryList";
Expand Down Expand Up @@ -45,7 +44,7 @@ const OrderSummaryCard: React.FC<OrderPaymentProps> = ({ order }) => {
const intl = useIntl();

const giftCardAmount = extractOrderGiftCardUsedAmount(order);
const usedGiftcard = obtainUsedGifrcard(order);
const usedGiftcards = obtainUsedGifrcards(order);

return (
<Card data-test-id="OrderSummaryCard">
Expand Down Expand Up @@ -79,19 +78,7 @@ const OrderSummaryCard: React.FC<OrderPaymentProps> = ({ order }) => {
{/* TODO: Remove when gift cards are not treated as discounts */}
{giftCardAmount > 0 && (
<SummaryLine
text={
<FormattedMessage
{...orderSummaryMessages.paidWithGiftCard}
values={{
link: (
<Link href={giftCardPath(usedGiftcard.id)}>
{" "}
{usedGiftcard.last4CodeChars}
</Link>
),
}}
/>
}
text={<OrderUsedGiftCards giftCards={usedGiftcards} />}
negative
money={{
amount: giftCardAmount,
Expand Down
5 changes: 0 additions & 5 deletions src/orders/components/OrderSummaryCard/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,6 @@ export const orderSummaryMessages = defineMessages({
defaultMessage: "Outstanding Balance",
description: "order payment",
},
paidWithGiftCard: {
id: "yivxZJ",
defaultMessage: "Paid with Gift Card: ({link})",
description: "order payment",
},
negative: {
defaultMessage: "minus",
id: "GcbFa9",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { OrderDetailsFragment } from "@dashboard/graphql";
import { ThemeWrapper } from "@test/themeWrapper";
import { render, screen } from "@testing-library/react";
import React, { ReactNode } from "react";
import { IntlProvider } from "react-intl";
import { BrowserRouter } from "react-router-dom";

import { messages } from "./messages";
import { OrderUsedGiftCards } from "./OrderUsedGiftCards";

const mockGiftCards = [
{
id: "1",
last4CodeChars: "LTD2",
},
{
id: "2",
last4CodeChars: "FRTG",
},
] as OrderDetailsFragment["giftCards"];

const Wrapper = ({ children }: { children: ReactNode }) => {
return (
<BrowserRouter>
<ThemeWrapper>
<IntlProvider
locale="EN"
messages={{
paidWithGiftCard: messages.usedGiftCard.defaultMessage,
}}
>
{children}
</IntlProvider>
</ThemeWrapper>
</BrowserRouter>
);
};

describe("OrderUsedGiftCards", () => {
it("should render single gift card", () => {
// Arrange & Act
render(<OrderUsedGiftCards giftCards={[mockGiftCards[0]]} />, {
wrapper: Wrapper,
});

// Assert
expect(screen.getByText(/paid with gift card/i)).toBeInTheDocument();
expect(screen.getByRole("link", { name: "LTD2" })).toHaveAttribute(
"href",
"/gift-cards/1",
);
expect(screen.getByText(/LTD2/)).toBeInTheDocument();
});

it("should render multipe gift cards", () => {
// Arrange & Act
render(
<OrderUsedGiftCards giftCards={[mockGiftCards[0], mockGiftCards[1]]} />,
{ wrapper: Wrapper },
);

// Assert
expect(screen.getByText(/paid with gift card/i)).toBeInTheDocument();
expect(screen.getByText(/LTD2/)).toBeInTheDocument();
expect(screen.getByRole("link", { name: "LTD2," })).toHaveAttribute(
"href",
"/gift-cards/1",
);
expect(screen.getByText(/FRTG/)).toBeInTheDocument();
expect(screen.getByRole("link", { name: "FRTG" })).toHaveAttribute(
"href",
"/gift-cards/2",
);
});
});
35 changes: 35 additions & 0 deletions src/orders/components/OrderUsedGiftCards/OrderUsedGiftCards.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import Link from "@dashboard/components/Link";
import { giftCardPath } from "@dashboard/giftCards/urls";
import { OrderDetailsFragment } from "@dashboard/graphql";
import { Box } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage } from "react-intl";

import { messages } from "./messages";
import { showComma } from "./utils";

interface OrderUsedGiftCardsProps {
giftCards: OrderDetailsFragment["giftCards"];
}

export const OrderUsedGiftCards = ({ giftCards }: OrderUsedGiftCardsProps) => {
return (
<FormattedMessage
{...messages.usedGiftCard}
values={{
link: giftCards.map(({ id, last4CodeChars }, index) => {
const hasComma = showComma(giftCards.length, index);

return (
<Link key={id} href={giftCardPath(id)}>
<Box as="span" marginRight={hasComma ? 1 : 0}>
{last4CodeChars}
{hasComma && ", "}
</Box>
</Link>
);
}),
}}
/>
);
};
1 change: 1 addition & 0 deletions src/orders/components/OrderUsedGiftCards/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./OrderUsedGiftCards";
9 changes: 9 additions & 0 deletions src/orders/components/OrderUsedGiftCards/messages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { defineMessages } from "react-intl";

export const messages = defineMessages({
usedGiftCard: {
id: "yivxZJ",
defaultMessage: "Paid with Gift Card: ({link})",
description: "order payment",
},
});
3 changes: 3 additions & 0 deletions src/orders/components/OrderUsedGiftCards/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const showComma = (totalLength: number, currentIndex: number) => {
return totalLength - 1 !== currentIndex;
};
11 changes: 11 additions & 0 deletions testUtils/themeWrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React, { ReactNode } from 'react'
import { ThemeProvider as LegacyThemeProvider } from "@saleor/macaw-ui";
import { ThemeProvider } from "@saleor/macaw-ui-next";

export const ThemeWrapper = ({ children }: {children: ReactNode}) => (
<LegacyThemeProvider>
<ThemeProvider>
{children}
</ThemeProvider>
</LegacyThemeProvider>
)
10 changes: 4 additions & 6 deletions testUtils/wrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import { ExternalAppProvider } from "@dashboard/apps/components/ExternalAppConte
import { Provider as DateProvider } from "@dashboard/components/Date/DateContext";
import { Locale, RawLocaleProvider } from "@dashboard/components/Locale";
import { TimezoneProvider } from "@dashboard/components/Timezone";
import { ThemeProvider as LegacyThemeProvider } from "@saleor/macaw-ui";
import { ThemeProvider } from "@saleor/macaw-ui-next";

import React from "react";
import { IntlProvider } from "react-intl";

import { ApolloMockedProvider } from "./ApolloMockedProvider";
import { ThemeWrapper } from "./themeWrapper";

const Wrapper: React.FC = ({ children }) => (
<ApolloMockedProvider>
Expand All @@ -20,11 +20,9 @@ const Wrapper: React.FC = ({ children }) => (
>
<DateProvider value={+new Date("2018-08-07T14:30:44+00:00")}>
<TimezoneProvider value="America/New_York">
<LegacyThemeProvider>
<ThemeProvider>
<ThemeWrapper>
<ExternalAppProvider>{children}</ExternalAppProvider>
</ThemeProvider>
</LegacyThemeProvider>
</ThemeWrapper>
</TimezoneProvider>
</DateProvider>
</RawLocaleProvider>
Expand Down

0 comments on commit c957d9c

Please sign in to comment.