feat(admin-next) discounts list page (#6490)

This commit is contained in:
Frane Polić
2024-02-27 12:33:19 +01:00
committed by GitHub
parent a223566d96
commit 608c10383a
23 changed files with 683 additions and 10 deletions
@@ -0,0 +1,28 @@
import type { Discount } from "@medusajs/medusa"
import { useTranslation } from "react-i18next"
type DiscountCellProps = {
discount: Discount
}
export const CodeCell = ({ discount }: DiscountCellProps) => {
return (
<div className="flex h-full w-full items-center gap-x-3 overflow-hidden">
{/*// TODO: border color inversion*/}
<span className="bg-ui-tag-neutral-bg truncate rounded-md border border-neutral-200 p-1 text-xs">
{discount.code}
</span>
</div>
)
}
export const CodeHeader = () => {
const { t } = useTranslation()
return (
<div className=" flex h-full w-full items-center ">
<span>{t("fields.description")}</span>
</div>
)
}
@@ -0,0 +1 @@
export * from "./code-cell"
@@ -0,0 +1,25 @@
import type { Discount } from "@medusajs/medusa"
import { useTranslation } from "react-i18next"
type DiscountCellProps = {
discount: Discount
}
export const DescriptionCell = ({ discount }: DiscountCellProps) => {
return (
<div className="flex h-full w-full items-center gap-x-3 overflow-hidden">
<span className="truncate">{discount.rule.description}</span>
</div>
)
}
export const DescriptionHeader = () => {
const { t } = useTranslation()
return (
<div className=" flex h-full w-full items-center ">
<span>{t("fields.description")}</span>
</div>
)
}
@@ -0,0 +1 @@
export * from "./description-cell"
@@ -0,0 +1 @@
export * from "./redemption-cell.tsx"
@@ -0,0 +1,23 @@
import { useTranslation } from "react-i18next"
type DiscountCellProps = {
redemptions: number
}
export const RedemptionCell = ({ redemptions }: DiscountCellProps) => {
return (
<div className="flex h-full w-full items-center justify-end gap-x-3 text-right">
<span>{redemptions}</span>
</div>
)
}
export const RedemptionHeader = () => {
const { t } = useTranslation()
return (
<div className="flex h-full w-full items-center justify-end text-right">
<span className="truncate">{t("fields.totalRedemptions")}</span>
</div>
)
}
@@ -0,0 +1 @@
export * from "./status-cell"
@@ -0,0 +1,72 @@
import { Discount } from "@medusajs/medusa"
import { end, parse } from "iso8601-duration"
import { StatusCell as StatusCell_ } from "../../common/status-cell"
import { useTranslation } from "react-i18next"
type DiscountCellProps = {
discount: Discount
}
enum PromotionStatus {
SCHEDULED = "SCHEDULED",
EXPIRED = "EXPIRED",
ACTIVE = "ACTIVE",
DISABLED = "DISABLED",
}
const getDiscountStatus = (discount: Discount) => {
if (discount.is_disabled) {
return PromotionStatus.DISABLED
}
const date = new Date()
if (new Date(discount.starts_at) > date) {
return PromotionStatus.SCHEDULED
}
if (
(discount.ends_at && new Date(discount.ends_at) < date) ||
(discount.valid_duration &&
date >
end(parse(discount.valid_duration), new Date(discount.starts_at))) ||
discount.usage_count === discount.usage_limit
) {
return PromotionStatus.EXPIRED
}
return PromotionStatus.ACTIVE
}
export const StatusCell = ({ discount }: DiscountCellProps) => {
const { t } = useTranslation()
const [color, text] = {
[PromotionStatus.DISABLED]: [
"grey",
t("discounts.discountStatus.disabled"),
],
[PromotionStatus.ACTIVE]: ["green", t("discounts.discountStatus.active")],
[PromotionStatus.SCHEDULED]: [
"orange",
t("discounts.discountStatus.scheduled"),
],
[PromotionStatus.EXPIRED]: ["red", t("discounts.discountStatus.expired")],
}[getDiscountStatus(discount)] as [
"grey" | "orange" | "green" | "red",
string
]
return <StatusCell_ color={color}>{text}</StatusCell_>
}
export const StatusHeader = () => {
const { t } = useTranslation()
return (
<div className=" flex h-full w-full items-center ">
<span>{t("fields.status")}</span>
</div>
)
}
@@ -0,0 +1 @@
export * from "./value-cell.tsx"
@@ -0,0 +1,35 @@
import { DiscountRule } from "@medusajs/medusa"
import { useTranslation } from "react-i18next"
import { MoneyAmountCell } from "../../common/money-amount-cell"
type DiscountCellProps = {
rule: DiscountRule
currencyCode: string
}
export const ValueCell = ({ currencyCode, rule }: DiscountCellProps) => {
const isFixed = rule.type === "fixed"
const isPercentage = rule.type === "percentage"
const isFreeShipping = rule.type === "free_shipping"
return (
<div className="flex h-full w-full items-center gap-x-3 overflow-hidden">
{isFreeShipping && <span>Free shipping</span>}
{isPercentage && <span className="">{rule.value}%</span>}
{isFixed && (
<MoneyAmountCell currencyCode={currencyCode} amount={rule.value} />
)}
</div>
)
}
export const ValueHeader = () => {
const { t } = useTranslation()
return (
<div className=" flex h-full w-full items-center ">
<span>{t("fields.value")}</span>
</div>
)
}