Skip to content

Commit

Permalink
Implement refund add modal (#4745)
Browse files Browse the repository at this point in the history
* Implement refund add modal

* Add changeset

* Add translations

* Refactor & tests

* Remove package.json comment

* Better handling of empty state

* Remove radix from package.json

* Rename getHoverState

* Export indicator to separate component

* Handle empty state

* Make RadioTiles compound component

* Add translation

* Handle empty state with datagrid
  • Loading branch information
Droniu authored Mar 22, 2024
1 parent ca4d4d4 commit b3a87cd
Show file tree
Hide file tree
Showing 19 changed files with 471 additions and 11 deletions.
5 changes: 5 additions & 0 deletions .changeset/many-vans-itch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"saleor-dashboard": minor
---

Implement refund add modal
36 changes: 32 additions & 4 deletions locale/defaultMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
"context": "order, button",
"string": "Mark as paid"
},
"+6liDh": {
"context": "radio button label",
"string": "The purchased product list will be sent and used to suggest amount to refund."
},
"+7OsyM": {
"context": "button",
"string": "Set as default shipping address"
Expand Down Expand Up @@ -2213,6 +2217,10 @@
"context": "section title",
"string": "Checkout Configuration"
},
"DAgLzp": {
"context": "radio button label",
"string": "Do not use information about the products and rely on amount provided manually."
},
"DDYrvn": {
"string": "Rule reward value must be less than 100"
},
Expand Down Expand Up @@ -3822,6 +3830,10 @@
"context": "window title",
"string": "Fulfill Order"
},
"O+w1k0": {
"context": "dialog subtitle",
"string": "How do you want to make a refund?"
},
"O22NIZ": {
"context": "deletion error message",
"string": "Cant's delete group which is out of your permission scope"
Expand Down Expand Up @@ -4277,6 +4289,10 @@
"context": "use attribute in filtering",
"string": "Use in Filtering"
},
"RK6l3Z": {
"context": "radio button label",
"string": "Refund with manual amount"
},
"RLBLPQ": {
"context": "no warehouses info",
"string": "There are no warehouses set up for your store. To add stock quantity to the product please <a>configure a warehouse</a>"
Expand Down Expand Up @@ -5549,6 +5565,10 @@
"ZTG+Dv": {
"string": "Draft order will be automatically created for replaced products"
},
"ZU1Kz8": {
"context": "empty state message",
"string": "No refunds made for this order."
},
"ZWIjvr": {
"context": "dialog header",
"string": "Delete Sales"
Expand Down Expand Up @@ -5994,6 +6014,10 @@
"context": "error message",
"string": "Error loading apps marketplace"
},
"cN8pa0": {
"context": "radio button label",
"string": "Refund with line items"
},
"cNSLLO": {
"context": "button",
"string": "Unassign and save"
Expand Down Expand Up @@ -6912,6 +6936,10 @@
"jHJmjf": {
"string": "No results"
},
"jIVn80": {
"context": "dialog title",
"string": "Create a new refund"
},
"jMzyU8": {
"context": "tax classes card header",
"string": "Tax classes"
Expand Down Expand Up @@ -8339,10 +8367,6 @@
"context": "balance curreny missing error message",
"string": "Balance currency is missing"
},
"tZmVfa": {
"context": "refund section header",
"string": "Refund"
},
"tZnV8L": {
"context": "Header row stock label",
"string": "Stock"
Expand Down Expand Up @@ -8755,6 +8779,10 @@
"context": "button",
"string": "Edit Address"
},
"w067gF": {
"context": "refund section header",
"string": "Refunds"
},
"w2Cewo": {
"string": "Search engine title"
},
Expand Down
28 changes: 28 additions & 0 deletions src/components/RadioTiles/RadioTile.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import * as RadixRadioGroup from "@radix-ui/react-radio-group";
import { render, screen } from "@testing-library/react";
import React from "react";

import { RadioTile } from "./RadioTile";

describe("RadioTile", () => {
it("renders the title and description", () => {
// Arrange
const props = {
checked: false,
title: "Test Title",
description: "Test Description",
value: "test",
};

// Act
render(
<RadixRadioGroup.Root>
<RadioTile {...props} />
</RadixRadioGroup.Root>,
);

// Assert
expect(screen.getByText(props.title)).toBeInTheDocument();
expect(screen.getByText(props.description)).toBeInTheDocument();
});
});
75 changes: 75 additions & 0 deletions src/components/RadioTiles/RadioTile.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import * as RadixRadioGroup from "@radix-ui/react-radio-group";
import { Box, Text } from "@saleor/macaw-ui-next";
import React from "react";

import { RadioTileIndicator } from "./RadioTileIndicator";
import { getBgColor, getBorderColor, getHoverStateBgColor } from "./utils";

export interface RadioTileProps {
checked: boolean;
title: string;
description: string;
value: string;
}

export const RadioTile = ({
checked,
title,
description,
value,
}: RadioTileProps) => {
const [isHoverState, setHoverState] = React.useState(false);

return (
<RadixRadioGroup.Item value={value} asChild>
<Box
position="relative"
as="label"
gap={2}
display="grid"
__gridTemplateColumns="auto 1fr"
alignItems="center"
borderColor={getBorderColor({ checked, isHoverState })}
borderWidth={1}
borderStyle="solid"
borderRadius={2}
padding={3}
cursor="pointer"
onMouseEnter={() => setHoverState(true)}
onMouseLeave={() => setHoverState(false)}
>
<Box
width={5}
height={5}
borderRadius="100%"
display="flex"
justifyContent="center"
alignItems="center"
backgroundColor={getHoverStateBgColor({ checked, isHoverState })}
>
<Box
width={3}
height={3}
boxShadow={checked || isHoverState ? "none" : "defaultFocused"}
borderColor="default1"
borderWidth={1}
borderStyle={checked ? "none" : "solid"}
borderRadius="100%"
padding={0}
backgroundColor={getBgColor({ checked, isHoverState })}
display="flex"
justifyContent="center"
alignItems="center"
>
<RadioTileIndicator />
</Box>
</Box>
<Text size={5}>{title}</Text>
<Box />
<Text size={1} color="default2">
{description}
</Text>
</Box>
</RadixRadioGroup.Item>
);
};
24 changes: 24 additions & 0 deletions src/components/RadioTiles/RadioTileIndicator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import * as RadixRadioGroup from "@radix-ui/react-radio-group";
import { sprinkles } from "@saleor/macaw-ui-next";
import React from "react";

export const RadioTileIndicator = () => {
return (
<RadixRadioGroup.Indicator
className={sprinkles({
position: "relative",
display: "flex",
justifyContent: "center",
alignItems: "center",
color: "buttonDefaultPrimary",
height: "100%",
width: "100%",
borderRadius: "100%",
})}
>
<svg xmlns="http://www.w3.org/2000/svg" width="6" height="6" fill="white">
<circle cx="3" cy="3" r="3" fill="currentColor" />
</svg>
</RadixRadioGroup.Indicator>
);
};
30 changes: 30 additions & 0 deletions src/components/RadioTiles/RadioTiles.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import * as RadixRadioGroup from "@radix-ui/react-radio-group";
import React from "react";

import { RadioTile } from "./RadioTile";

export interface RadioTilesProps {
children: React.ReactNode;
asChild: boolean;
value: string;
onValueChange: (value: string) => void;
}

const RadioTilesBase = ({
children,
asChild,
value,
onValueChange,
}: RadioTilesProps) => {
return (
<RadixRadioGroup.Root
asChild={asChild}
value={value}
onValueChange={onValueChange}
>
{children}
</RadixRadioGroup.Root>
);
};

export const RadioTiles = Object.assign(RadioTilesBase, { RadioTile });
37 changes: 37 additions & 0 deletions src/components/RadioTiles/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
interface RadioTileState {
checked: boolean;
isHoverState: boolean;
}

export const getHoverStateBgColor = ({
checked,
isHoverState,
}: RadioTileState) => {
if (checked && isHoverState) {
return "accent1Hovered";
}
if (isHoverState) {
return "default1Hovered";
}
return "transparent";
};

export const getBorderColor = ({ checked, isHoverState }: RadioTileState) => {
if (checked) {
return "accent1";
}
if (isHoverState) {
return "default1Hovered";
}
return "default1";
};

export const getBgColor = ({ checked, isHoverState }: RadioTileState) => {
if (checked) {
return "accent1";
}
if (isHoverState) {
return "default1Hovered";
}
return "transparent";
};
3 changes: 3 additions & 0 deletions src/orders/components/OrderDetailsPage/OrderDetailsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export interface OrderDetailsPageProps {
actionType: TransactionActionEnum,
) => any;
onAddManualTransaction: () => any;
onRefundAdd: () => void;
onSubmit: (data: MetadataIdSchema) => SubmitPromise;
}

Expand Down Expand Up @@ -122,6 +123,7 @@ const OrderDetailsPage: React.FC<OrderDetailsPageProps> = props => {
onAddManualTransaction,
onShowMetadata,
onMarkAsPaid,
onRefundAdd,
onSubmit,
} = props;
const navigate = useNavigator();
Expand Down Expand Up @@ -282,6 +284,7 @@ const OrderDetailsPage: React.FC<OrderDetailsPageProps> = props => {
onPaymentRefund={onPaymentRefund}
onMarkAsPaid={onMarkAsPaid}
onAddManualTransaction={onAddManualTransaction}
onRefundAdd={onRefundAdd}
/>
<Metadata
isLoading={loading}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ describe("OrderPaymentOrTransaction", () => {
onPaymentCapture: () => undefined,
onTransactionAction: () => undefined,
onPaymentVoid: () => undefined,
onRefundAdd: () => undefined,
} as OrderPaymentOrTransactionProps;

it("renders OrderPayment when transactions are disabled in channel", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export interface OrderPaymentOrTransactionProps {
onPaymentRefund: () => any;
onMarkAsPaid: () => any;
onAddManualTransaction: () => any;
onRefundAdd: () => void;
}

export const OrderPaymentOrTransaction: React.FC<
Expand All @@ -36,6 +37,7 @@ export const OrderPaymentOrTransaction: React.FC<
onPaymentRefund,
onMarkAsPaid,
onAddManualTransaction,
onRefundAdd,
}) => {
if (orderShouldUseTransactions(order)) {
return (
Expand All @@ -47,6 +49,7 @@ export const OrderPaymentOrTransaction: React.FC<
onMarkAsPaid={onMarkAsPaid}
onPaymentVoid={onPaymentVoid}
onAddManualTransaction={onAddManualTransaction}
onRefundAdd={onRefundAdd}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ interface OrderTransactionsWrapper {
onMarkAsPaid: () => any;
onPaymentVoid: () => any;
onAddManualTransaction: () => any;
onRefundAdd: () => void;
}

export const OrderTransactionsWrapper: React.FC<OrderTransactionsWrapper> = ({
Expand All @@ -40,6 +41,7 @@ export const OrderTransactionsWrapper: React.FC<OrderTransactionsWrapper> = ({
onMarkAsPaid,
onPaymentVoid,
onAddManualTransaction,
onRefundAdd,
}) => {
const classes = useStyles();

Expand All @@ -63,6 +65,7 @@ export const OrderTransactionsWrapper: React.FC<OrderTransactionsWrapper> = ({
<OrderRefundDatagrid
orderId={order?.id}
grantedRefunds={order?.grantedRefunds}
onRefundAdd={onRefundAdd}
/>
<CardSpacer />
</>
Expand Down
Loading

0 comments on commit b3a87cd

Please sign in to comment.