feat(dashboard): Price List configurations section (#6663)
**What** - Adds section for displaying price list configurations. Closes CORE-1857
This commit is contained in:
@@ -848,6 +848,8 @@
|
||||
"label": "Label",
|
||||
"rate": "Rate",
|
||||
"requiresShipping": "Requires shipping",
|
||||
"startDate": "Start date",
|
||||
"endDate": "End date",
|
||||
"draft": "Draft"
|
||||
},
|
||||
"dateTime": {
|
||||
|
||||
+4
-4
@@ -40,12 +40,12 @@ export const DiscountDetail = () => {
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
<div className="grid grid-cols-1 gap-x-4 lg:grid-cols-[1fr,400px]">
|
||||
<div className="flex flex-col gap-y-2">
|
||||
<div className="flex flex-col gap-x-4 xl:flex-row xl:items-start">
|
||||
<div className="flex w-full flex-col gap-y-2">
|
||||
<DiscountGeneralSection discount={discount} />
|
||||
<DiscountConfigurationSection discount={discount} />
|
||||
<DiscountConditionsSection discount={discount} />
|
||||
<div className="flex flex-col gap-y-2 lg:hidden">
|
||||
<div className="flex w-full flex-col gap-y-2 xl:hidden">
|
||||
<RedemptionsSection redemptions={discount.usage_count} />
|
||||
<DetailsSection discount={discount} />
|
||||
</div>
|
||||
@@ -58,7 +58,7 @@ export const DiscountDetail = () => {
|
||||
})}
|
||||
<JsonViewSection data={discount} />
|
||||
</div>
|
||||
<div className="hidden flex-col gap-y-2 lg:flex">
|
||||
<div className="hidden w-full max-w-[400px] flex-col gap-y-2 xl:flex">
|
||||
<RedemptionsSection redemptions={discount.usage_count} />
|
||||
<DetailsSection discount={discount} />
|
||||
</div>
|
||||
|
||||
@@ -33,18 +33,18 @@ export const OrderDetail = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-1 gap-x-4 xl:grid-cols-[1fr,400px]">
|
||||
<div className="flex flex-col gap-y-2">
|
||||
<div className="flex flex-col gap-x-4 xl:flex-row xl:items-start">
|
||||
<div className="flex w-full flex-col gap-y-2">
|
||||
<OrderGeneralSection order={order} />
|
||||
<OrderSummarySection order={order} />
|
||||
<OrderPaymentSection order={order} />
|
||||
<OrderFulfillmentSection order={order} />
|
||||
<div className="flex flex-col gap-y-2 lg:hidden">
|
||||
<div className="flex flex-col gap-y-2 xl:hidden">
|
||||
<OrderCustomerSection order={order} />
|
||||
</div>
|
||||
<JsonViewSection data={order} />
|
||||
</div>
|
||||
<div className="hidden flex-col gap-y-2 lg:flex">
|
||||
<div className="hidden w-full max-w-[400px] flex-col gap-y-2 xl:flex">
|
||||
<OrderCustomerSection order={order} />
|
||||
</div>
|
||||
<Outlet />
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
export * from "./pricing-configuration-section"
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
import { PencilSquare } from "@medusajs/icons"
|
||||
import { PriceList } from "@medusajs/medusa"
|
||||
import { Container, Heading, Text, Tooltip } from "@medusajs/ui"
|
||||
import { format } from "date-fns"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { ActionMenu } from "../../../../../components/common/action-menu"
|
||||
|
||||
type PricingConfigurationSectionProps = {
|
||||
priceList: PriceList
|
||||
}
|
||||
|
||||
export const PricingConfigurationSection = ({
|
||||
priceList,
|
||||
}: PricingConfigurationSectionProps) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const firstCustomerGroups = priceList.customer_groups?.slice(0, 3)
|
||||
const remainingCustomerGroups = priceList.customer_groups?.slice(3)
|
||||
|
||||
return (
|
||||
<Container className="divide-y p-0">
|
||||
<div className="flex items-center justify-between px-6 py-4">
|
||||
<Heading level="h2">{t("fields.configurations")}</Heading>
|
||||
<ActionMenu
|
||||
groups={[
|
||||
{
|
||||
actions: [
|
||||
{
|
||||
label: t("actions.edit"),
|
||||
to: "configurations/edit",
|
||||
icon: <PencilSquare />,
|
||||
},
|
||||
],
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
<div className="text-ui-fg-subtle grid grid-cols-2 items-center px-6 py-4">
|
||||
<Text leading="compact" size="small" weight="plus">
|
||||
{t("fields.startDate")}
|
||||
</Text>
|
||||
<Text size="small" className="text-pretty">
|
||||
{priceList.starts_at
|
||||
? format(new Date(priceList.starts_at), "dd MMM yyyy")
|
||||
: "-"}
|
||||
</Text>
|
||||
</div>
|
||||
<div className="text-ui-fg-subtle grid grid-cols-2 items-center px-6 py-4">
|
||||
<Text leading="compact" size="small" weight="plus">
|
||||
{t("fields.endDate")}
|
||||
</Text>
|
||||
<Text size="small" className="text-pretty">
|
||||
{priceList.ends_at
|
||||
? format(new Date(priceList.ends_at), "dd MMM yyyy")
|
||||
: "-"}
|
||||
</Text>
|
||||
</div>
|
||||
<div className="text-ui-fg-subtle grid grid-cols-2 items-center px-6 py-4">
|
||||
<Text leading="compact" size="small" weight="plus">
|
||||
{t("pricing.settings.customerGroupsLabel")}
|
||||
</Text>
|
||||
<Text size="small" className="text-pretty">
|
||||
<span>
|
||||
{firstCustomerGroups.length > 0
|
||||
? firstCustomerGroups.join(", ")
|
||||
: "-"}
|
||||
</span>
|
||||
{remainingCustomerGroups.length > 0 && (
|
||||
<Tooltip
|
||||
content={
|
||||
<ul>
|
||||
{remainingCustomerGroups.map((cg) => (
|
||||
<li key={cg.id}>{cg.name}</li>
|
||||
))}
|
||||
</ul>
|
||||
}
|
||||
>
|
||||
<span className="text-ui-fg-muted">
|
||||
{" "}
|
||||
{t("general.plusCountMore", {
|
||||
count: remainingCustomerGroups.length,
|
||||
})}
|
||||
</span>
|
||||
</Tooltip>
|
||||
)}
|
||||
</Text>
|
||||
</div>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
+1
-40
@@ -1,13 +1,6 @@
|
||||
import { PencilSquare, Trash } from "@medusajs/icons"
|
||||
import { PriceList } from "@medusajs/medusa"
|
||||
import {
|
||||
Container,
|
||||
Heading,
|
||||
StatusBadge,
|
||||
Text,
|
||||
Tooltip,
|
||||
usePrompt,
|
||||
} from "@medusajs/ui"
|
||||
import { Container, Heading, StatusBadge, Text, usePrompt } from "@medusajs/ui"
|
||||
import { useAdminDeletePriceList } from "medusa-react"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { useNavigate } from "react-router-dom"
|
||||
@@ -28,8 +21,6 @@ export const PricingGeneralSection = ({
|
||||
const { mutateAsync } = useAdminDeletePriceList(priceList.id)
|
||||
|
||||
const overrideCount = priceList.prices?.length || 0
|
||||
const firstCustomerGroups = priceList.customer_groups?.slice(0, 3)
|
||||
const remainingCustomerGroups = priceList.customer_groups?.slice(3)
|
||||
|
||||
const { color, text } = getPriceListStatus(t, priceList)
|
||||
|
||||
@@ -105,36 +96,6 @@ export const PricingGeneralSection = ({
|
||||
{priceList.description}
|
||||
</Text>
|
||||
</div>
|
||||
<div className="text-ui-fg-subtle grid grid-cols-2 items-center px-6 py-4">
|
||||
<Text leading="compact" size="small" weight="plus">
|
||||
{t("pricing.settings.customerGroupsLabel")}
|
||||
</Text>
|
||||
<Text size="small" className="text-pretty">
|
||||
<span>
|
||||
{firstCustomerGroups.length > 0
|
||||
? firstCustomerGroups.join(", ")
|
||||
: "-"}
|
||||
</span>
|
||||
{remainingCustomerGroups.length > 0 && (
|
||||
<Tooltip
|
||||
content={
|
||||
<ul>
|
||||
{remainingCustomerGroups.map((cg) => (
|
||||
<li key={cg.id}>{cg.name}</li>
|
||||
))}
|
||||
</ul>
|
||||
}
|
||||
>
|
||||
<span className="text-ui-fg-muted">
|
||||
{" "}
|
||||
{t("general.plusCountMore", {
|
||||
count: remainingCustomerGroups.length,
|
||||
})}
|
||||
</span>
|
||||
</Tooltip>
|
||||
)}
|
||||
</Text>
|
||||
</div>
|
||||
<div className="text-ui-fg-subtle grid grid-cols-2 items-center px-6 py-4">
|
||||
<Text leading="compact" size="small" weight="plus">
|
||||
{t("pricing.settings.priceOverridesLabel")}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useAdminPriceList } from "medusa-react"
|
||||
import { Outlet, useParams } from "react-router-dom"
|
||||
import { JsonViewSection } from "../../../components/common/json-view-section"
|
||||
import { PricingConfigurationSection } from "./components/pricing-configuration-section"
|
||||
import { PricingGeneralSection } from "./components/pricing-general-section"
|
||||
import { PricingProductSection } from "./components/pricing-product-section"
|
||||
|
||||
@@ -18,10 +19,18 @@ export const PricingDetail = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-y-2">
|
||||
<PricingGeneralSection priceList={price_list} />
|
||||
<PricingProductSection priceList={price_list} />
|
||||
<JsonViewSection data={price_list} />
|
||||
<div className="flex flex-col gap-x-4 xl:flex-row xl:items-start">
|
||||
<div className="flex w-full flex-col gap-y-2">
|
||||
<PricingGeneralSection priceList={price_list} />
|
||||
<PricingProductSection priceList={price_list} />
|
||||
<div className="flex w-full flex-col gap-y-2 xl:hidden">
|
||||
<PricingConfigurationSection priceList={price_list} />
|
||||
</div>
|
||||
<JsonViewSection data={price_list} />
|
||||
</div>
|
||||
<div className="hidden w-full max-w-[400px] flex-col gap-y-2 xl:flex">
|
||||
<PricingConfigurationSection priceList={price_list} />
|
||||
</div>
|
||||
<Outlet />
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -47,7 +47,7 @@ export const ProductDetail = () => {
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
<div className="grid grid-cols-1 gap-x-4 xl:grid-cols-[1fr,400px]">
|
||||
<div className="flex flex-col gap-x-4 xl:flex-row xl:items-start">
|
||||
<div className="flex flex-col gap-y-2">
|
||||
<ProductGeneralSection product={product} />
|
||||
<ProductMediaSection product={product} />
|
||||
@@ -81,7 +81,7 @@ export const ProductDetail = () => {
|
||||
})}
|
||||
<JsonViewSection data={product} root="product" />
|
||||
</div>
|
||||
<div className="hidden flex-col gap-y-2 xl:flex">
|
||||
<div className="hidden w-full max-w-[400px] flex-col gap-y-2 xl:flex">
|
||||
{sideBefore.widgets.map((w, i) => {
|
||||
return (
|
||||
<div key={i}>
|
||||
|
||||
Reference in New Issue
Block a user