feat(dashboard,core,medusa,promotion): add campaigns UI (#7269)

* feat(dashboard,core,medusa,promotion): add campaigns UI

* chore: add without campaign choice to promotion ui

* chore: fix builds and types

* chore: fix design issues

* chore: address pr reviews
This commit is contained in:
Riqwan Thamir
2024-05-09 10:00:28 +02:00
committed by GitHub
parent 5952fddad5
commit 6da2964998
48 changed files with 2027 additions and 100 deletions
@@ -1,3 +1,7 @@
import {
AdminCampaignListResponse,
AdminCampaignResponse,
} from "@medusajs/types"
import {
QueryKey,
UseMutationOptions,
@@ -9,25 +13,27 @@ import { client } from "../../lib/client"
import { queryClient } from "../../lib/medusa"
import { queryKeysFactory } from "../../lib/query-key-factory"
import { CreateCampaignReq, UpdateCampaignReq } from "../../types/api-payloads"
import {
CampaignDeleteRes,
CampaignListRes,
CampaignRes,
} from "../../types/api-responses"
import { CampaignDeleteRes } from "../../types/api-responses"
const REGIONS_QUERY_KEY = "campaigns" as const
const campaignsQueryKeys = queryKeysFactory(REGIONS_QUERY_KEY)
export const campaignsQueryKeys = queryKeysFactory(REGIONS_QUERY_KEY)
export const useCampaign = (
id: string,
query?: Record<string, any>,
options?: Omit<
UseQueryOptions<CampaignRes, Error, CampaignRes, QueryKey>,
UseQueryOptions<
AdminCampaignResponse,
Error,
AdminCampaignResponse,
QueryKey
>,
"queryFn" | "queryKey"
>
) => {
const { data, ...rest } = useQuery({
queryKey: campaignsQueryKeys.detail(id),
queryFn: async () => client.campaigns.retrieve(id),
queryFn: async () => client.campaigns.retrieve(id, query),
...options,
})
@@ -37,7 +43,12 @@ export const useCampaign = (
export const useCampaigns = (
query?: Record<string, any>,
options?: Omit<
UseQueryOptions<CampaignListRes, Error, CampaignListRes, QueryKey>,
UseQueryOptions<
AdminCampaignListResponse,
Error,
AdminCampaignListResponse,
QueryKey
>,
"queryFn" | "queryKey"
>
) => {
@@ -51,7 +62,7 @@ export const useCampaigns = (
}
export const useCreateCampaign = (
options?: UseMutationOptions<CampaignRes, Error, CreateCampaignReq>
options?: UseMutationOptions<AdminCampaignResponse, Error, CreateCampaignReq>
) => {
return useMutation({
mutationFn: (payload) => client.campaigns.create(payload),
@@ -65,7 +76,7 @@ export const useCreateCampaign = (
export const useUpdateCampaign = (
id: string,
options?: UseMutationOptions<CampaignRes, Error, UpdateCampaignReq>
options?: UseMutationOptions<AdminCampaignResponse, Error, UpdateCampaignReq>
) => {
return useMutation({
mutationFn: (payload) => client.campaigns.update(id, payload),
@@ -26,12 +26,6 @@ export const usePromotionTableColumns = () => {
cell: ({ row }) => <CodeCell code={row.original.code!} />,
}),
columnHelper.display({
id: "campaign",
header: () => <TextHeader text={t("promotions.fields.campaign")} />,
cell: ({ row }) => <TextCell text={row.original.campaign?.name} />,
}),
columnHelper.display({
id: "method",
header: () => <TextHeader text={t("promotions.fields.method")} />,
@@ -0,0 +1,73 @@
import { createColumnHelper } from "@tanstack/react-table"
import { CampaignResponse } from "@medusajs/types"
import { useMemo } from "react"
import { useTranslation } from "react-i18next"
import { DateCell } from "../../../components/table/table-cells/common/date-cell"
import {
TextCell,
TextHeader,
} from "../../../components/table/table-cells/common/text-cell"
import {
DescriptionCell,
DescriptionHeader,
} from "../../../components/table/table-cells/sales-channel/description-cell"
import {
NameCell,
NameHeader,
} from "../../../components/table/table-cells/sales-channel/name-cell"
const columnHelper = createColumnHelper<CampaignResponse>()
export const useCampaignTableColumns = () => {
const { t } = useTranslation()
return useMemo(
() => [
columnHelper.accessor("name", {
header: () => <NameHeader />,
cell: ({ getValue }) => <NameCell name={getValue()} />,
}),
columnHelper.accessor("description", {
header: () => <DescriptionHeader />,
cell: ({ getValue }) => <DescriptionCell description={getValue()} />,
}),
columnHelper.accessor("campaign_identifier", {
header: () => <TextHeader text={t("campaigns.fields.identifier")} />,
cell: ({ getValue }) => {
const value = getValue()
return <TextCell text={value} />
},
}),
columnHelper.accessor("starts_at", {
header: () => <TextHeader text={t("campaigns.fields.start_date")} />,
cell: ({ getValue }) => {
const value = getValue()
if (!value) {
return
}
const date = new Date(value)
return <DateCell date={date} />
},
}),
columnHelper.accessor("ends_at", {
header: () => <TextHeader text={t("campaigns.fields.end_date")} />,
cell: ({ getValue }) => {
const value = getValue()
if (!value) {
return
}
const date = new Date(value)
return <DateCell date={date} />
},
}),
],
[t]
)
}
@@ -0,0 +1,13 @@
import { useTranslation } from "react-i18next"
import { Filter } from "../../../components/table/data-table"
export const usePromotionTableFilters = () => {
const { t } = useTranslation()
let filters: Filter[] = [
{ label: t("fields.createdAt"), key: "created_at", type: "date" },
{ label: t("fields.updatedAt"), key: "updated_at", type: "date" },
]
return filters
}
@@ -0,0 +1,31 @@
import { useQueryParams } from "../../use-query-params"
type UseCampaignTableQueryProps = {
prefix?: string
pageSize?: number
}
export const useCampaignTableQuery = ({
prefix,
pageSize = 20,
}: UseCampaignTableQueryProps) => {
const queryObject = useQueryParams(
["offset", "q", "order", "created_at", "updated_at"],
prefix
)
const { offset, q, order, created_at, updated_at } = queryObject
const searchParams = {
limit: pageSize,
offset: offset ? Number(offset) : 0,
order,
created_at: created_at ? JSON.parse(created_at) : undefined,
updated_at: updated_at ? JSON.parse(updated_at) : undefined,
q,
}
return {
searchParams,
raw: queryObject,
}
}