Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(dashboard): added details page for promotions + edit sliders #6882

Merged
merged 14 commits into from
Apr 6, 2024
Merged
6 changes: 6 additions & 0 deletions .changeset/quick-jeans-push.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"medusa-react": patch
"@medusajs/medusa": patch
---

feat(dashboard): added details page for promotions
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ medusaIntegrationTestRunner({
`/admin/pricing/rule-types/${ruleType.id}`,
adminHeaders
)
console.log("response.data -- ", response.data)

expect(response.status).toEqual(200)
expect(response.data).toEqual({
id: ruleType.id,
Expand Down
9 changes: 9 additions & 0 deletions packages/admin-next/dashboard/public/locales/$schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,15 @@
},
"required": ["domain"]
},
"campaigns": {
"type": "object",
"properties": {
"domain": {
"type": "string"
}
},
"required": ["domain"]
},
"giftCards": {
"type": "object",
"properties": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"items_one": "{{count}} item",
"items_other": "{{count}} items",
"countSelected": "{{count}} selected",
"plusCount": "+ {{count}}",
"plusCountMore": "+ {{count}} more",
"areYouSure": "Are you sure?",
"noRecordsFound": "No records found",
Expand Down Expand Up @@ -595,12 +596,116 @@
"domain": "Promotions",
"fields": {
"method": "Method",
"campaign": "Campaign"
"type": "Type",
"value_type": "Value Type",
"value": "Value",
"campaign": "Campaign",
"allocation": "Allocation",
"conditions": {
"rules": {
"title": "Who can use this code?",
"description": "Is the customer allowed to add the promotion code? Discount code can be used by all customers if left untouched. Choose between attributes, operators, and values to set up the conditions."
},
"target-rules": {
"title": "What needs to be in the cart to unlock the promotion?",
"description": "If these conditions match, we enable a promotion action on the target items. Choose between attributes, operators, and values to set up the conditions."
},
"buy-rules": {
"title": "What will the promotion be applied to?",
"description": "The promotion will be applied to items that match these conditions"
}
}
},
"edit": {
"title": "Edit Promotion Details",
"rules": {
"title": "Edit rules"
},
"target-rules": {
"title": "Edit target rules"
},
"buy-rules": {
"title": "Edit buy rules"
}
},
"addToCampaign": {
"title": "Add Promotion To Campaign"
},
"form": {
"campaign": {
"existing": {
"title": "Existing Campaign",
"description": "Would you like to add promotion to an existing campaign?"
},
"new": {
"title": "New Campaign",
"description": "Would you like to create a new campaign with this promotion?"
}
},
"status": {
"title": "Status"
},
"method": {
"code": {
"title": "Promotion code",
"description": "Customers must enter this at checkout"
},
"automatic": {
"title": "Automatic",
"description": "Customers will automatically see this during checkout"
}
},
"allocation": {
"each": {
"title": "Each",
"description": "Applies value on each product"
},
"across": {
"title": "Across",
"description": "Applies value proportionally across products"
}
},
"code": {
"title": "Code",
"description": "The code your customers will enter during checkout."
},
"value": {
"title": "Value"
},
"value_type": {
"fixed": {
"title": "Fixed amount",
"description": "eg. 100"
},
"percentage": {
"title": "Percentage",
"description": "eg. 8%"
}
}
},
"deleteWarning": "You are about to delete the promotion {{code}}. This action cannot be undone.",
"createPromotionTitle": "Create Promotion",
"type": "Promotion type"
},
"campaigns": {
"domain": "Campaigns",
"details": "Campaign details",
"fields": {
"name": "Name",
"identifier": "Identifier",
"start_date": "Start date",
"end_date": "End date"
},
"budget": {
"details": "Campaign budget",
"fields": {
"type": "Type",
"currency": "Currency",
"limit": "Limit",
"used": "Used"
}
}
},
"pricing": {
"domain": "Pricing",
"deletePriceListWarning": "You are about to delete the price list {{name}}. This action cannot be undone.",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { Badge, Tooltip, clx } from "@medusajs/ui"
import { useTranslation } from "react-i18next"

type BadgeListSummaryProps = {
/**
* Number of initial items to display
* @default 2
*/
n?: number
/**
* List of strings to display as abbreviated list
*/
list: string[]
/**
* Is the summary displayed inline.
* Determines whether the center text is truncated if there is no space in the container
*/
inline?: boolean

className?: string
}

export const BadgeListSummary = ({
list,
className,
inline,
n = 2,
}: BadgeListSummaryProps) => {
const { t } = useTranslation()

const title = t("general.plusCount", {
count: list.length - n,
})

return (
<div
className={clx(
"ml-2 text-ui-fg-subtle txt-compact-small gap-x-2 overflow-hidden",
{
"inline-flex": inline,
flex: !inline,
},
className
)}
>
{list.slice(0, n).map((item) => {
return (
<Badge key={item} size="2xsmall">
{item}
</Badge>
)
})}

{list.length > n && (
<div className="whitespace-nowrap">
<Tooltip
content={
<ul>
{list.slice(n).map((c) => (
<li key={c}>{c}</li>
))}
</ul>
}
>
<Badge size="2xsmall" className="cursor-default whitespace-nowrap">
{title}
</Badge>
</Tooltip>
</div>
)}
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./badge-list-summary"
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ExclamationCircle, MagnifyingGlass } from "@medusajs/icons"
import { ExclamationCircle, MagnifyingGlass, PlusMini } from "@medusajs/icons"
import { Button, Text, clx } from "@medusajs/ui"
import { useTranslation } from "react-i18next"
import { Link } from "react-router-dom"
Expand Down Expand Up @@ -32,21 +32,44 @@ export const NoResults = ({ title, message, className }: NoResultsProps) => {
)
}

type NoRecordsProps = {
title?: string
message?: string
type ActionProps = {
action?: {
to: string
label: string
}
className?: string
}

type NoRecordsProps = {
title?: string
message?: string
className?: string
buttonVariant?: string
} & ActionProps

const DefaultButton = ({ action }: ActionProps) =>
action && (
<Link to={action.to}>
<Button variant="secondary" size="small">
{action.label}
</Button>
</Link>
)

const TransparentIconLeftButton = ({ action }: ActionProps) =>
action && (
<Link to={action.to}>
<Button variant="transparent" className="text-ui-fg-interactive">
<PlusMini /> {action.label}
</Button>
</Link>
)

export const NoRecords = ({
title,
message,
action,
className,
buttonVariant = "default",
}: NoRecordsProps) => {
const { t } = useTranslation()

Expand All @@ -59,19 +82,19 @@ export const NoRecords = ({
>
<div className="flex flex-col items-center gap-y-2">
<ExclamationCircle />

<Text size="small" leading="compact" weight="plus">
{title ?? t("general.noRecordsTitle")}
</Text>

<Text size="small" className="text-ui-fg-muted">
{message ?? t("general.noRecordsMessage")}
</Text>
</div>
{action && (
<Link to={action.to}>
<Button variant="secondary" size="small">
{action.label}
</Button>
</Link>

{buttonVariant === "default" && <DefaultButton action={action} />}
{buttonVariant === "transparentIconLeft" && (
<TransparentIconLeftButton action={action} />
)}
</div>
)
Expand Down
Loading