feat(dashboard,ui,types,admin-shared): Add more extension zones + pass data to widgets (#7465)

This commit is contained in:
Kasper Fabricius Kristensen
2024-05-27 12:47:12 +02:00
committed by GitHub
parent 0b0e210f67
commit ab2e8fcd45
19 changed files with 220 additions and 109 deletions

View File

@@ -1,5 +1,7 @@
declare module "virtual:medusa/widgets/*" {
const widgets: { Component: () => JSX.Element }[]
import type { ComponentType } from "react"
const widgets: { Component: ComponentType<any> }[]
export default {
widgets,

View File

@@ -95,7 +95,6 @@ export const CreateCampaignForm = () => {
{t("actions.cancel")}
</Button>
</RouteFocusModal.Close>
<Button
size="small"
variant="primary"

View File

@@ -1,5 +1,4 @@
import {
clx,
CurrencyInput,
DatePicker,
Heading,
@@ -7,10 +6,12 @@ import {
RadioGroup,
Select,
Text,
Textarea,
} from "@medusajs/ui"
import { useEffect } from "react"
import { useWatch } from "react-hook-form"
import { useTranslation } from "react-i18next"
import { Form } from "../../../../../components/common/form"
import { useStore } from "../../../../../hooks/api/store"
import { currencies, getCurrencySymbol } from "../../../../../lib/currencies"
@@ -70,24 +71,44 @@ export const CreateCampaignFormFields = ({ form, fieldScope = "" }) => {
</Text>
</div>
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
<Form.Field
control={form.control}
name={`${fieldScope}name`}
render={({ field }) => {
return (
<Form.Item>
<Form.Label>{t("fields.name")}</Form.Label>
<div className="flex flex-col gap-y-4">
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
<Form.Field
control={form.control}
name={`${fieldScope}name`}
render={({ field }) => {
return (
<Form.Item>
<Form.Label>{t("fields.name")}</Form.Label>
<Form.Control>
<Input {...field} />
</Form.Control>
<Form.Control>
<Input {...field} />
</Form.Control>
<Form.ErrorMessage />
</Form.Item>
)
}}
/>
<Form.ErrorMessage />
</Form.Item>
)
}}
/>
<Form.Field
control={form.control}
name={`${fieldScope}campaign_identifier`}
render={({ field }) => {
return (
<Form.Item>
<Form.Label>{t("campaigns.fields.identifier")}</Form.Label>
<Form.Control>
<Input {...field} />
</Form.Control>
<Form.ErrorMessage />
</Form.Item>
)
}}
/>
</div>
<Form.Field
control={form.control}
@@ -98,7 +119,7 @@ export const CreateCampaignFormFields = ({ form, fieldScope = "" }) => {
<Form.Label>{t("fields.description")}</Form.Label>
<Form.Control>
<Input {...field} />
<Textarea {...field} />
</Form.Control>
<Form.ErrorMessage />
@@ -106,27 +127,9 @@ export const CreateCampaignFormFields = ({ form, fieldScope = "" }) => {
)
}}
/>
</div>
<Form.Field
control={form.control}
name={`${fieldScope}campaign_identifier`}
render={({ field }) => {
return (
<Form.Item>
<Form.Label>{t("campaigns.fields.identifier")}</Form.Label>
<Form.Control>
<Input {...field} />
</Form.Control>
<Form.ErrorMessage />
</Form.Item>
)
}}
/>
<div></div>
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
<Form.Field
control={form.control}
name={`${fieldScope}starts_at`}
@@ -198,20 +201,12 @@ export const CreateCampaignFormFields = ({ form, fieldScope = "" }) => {
onValueChange={field.onChange}
>
<RadioGroup.ChoiceBox
className={clx("basis-1/2 border", {
"border border-ui-border-interactive":
"spend" === field.value,
})}
value={"spend"}
label={t("campaigns.budget.type.spend.title")}
description={t("campaigns.budget.type.spend.description")}
/>
<RadioGroup.ChoiceBox
className={clx("basis-1/2 border", {
"border border-ui-border-interactive":
"usage" === field.value,
})}
value={"usage"}
label={t("campaigns.budget.type.usage.title")}
description={t("campaigns.budget.type.usage.description")}

View File

@@ -39,7 +39,7 @@ export const CategoryDetail = () => {
{before.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component />
<w.Component data={product_category} />
</div>
)
})}
@@ -50,7 +50,7 @@ export const CategoryDetail = () => {
{after.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component />
<w.Component data={product_category} />
</div>
)
})}
@@ -62,7 +62,7 @@ export const CategoryDetail = () => {
{sideBefore.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component />
<w.Component data={product_category} />
</div>
)
})}
@@ -70,7 +70,7 @@ export const CategoryDetail = () => {
{sideAfter.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component />
<w.Component data={product_category} />
</div>
)
})}

View File

@@ -36,7 +36,7 @@ export const CollectionDetail = () => {
{before.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component />
<w.Component data={collection} />
</div>
)
})}
@@ -45,7 +45,7 @@ export const CollectionDetail = () => {
{after.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component />
<w.Component data={collection} />
</div>
)
})}

View File

@@ -36,7 +36,7 @@ export const CustomerGroupDetail = () => {
{before.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component />
<w.Component data={customer_group} />
</div>
)
})}
@@ -45,7 +45,7 @@ export const CustomerGroupDetail = () => {
{after.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component />
<w.Component data={customer_group} />
</div>
)
})}

View File

@@ -32,7 +32,7 @@ export const CustomerDetail = () => {
{before.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component />
<w.Component data={customer} />
</div>
)
})}
@@ -44,7 +44,7 @@ export const CustomerDetail = () => {
{after.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component />
<w.Component data={customer} />
</div>
)
})}

View File

@@ -43,7 +43,7 @@ export const OrderDetail = () => {
{before.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component />
<w.Component data={order} />
</div>
)
})}
@@ -56,7 +56,7 @@ export const OrderDetail = () => {
{after.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component />
<w.Component data={order} />
</div>
)
})}
@@ -68,7 +68,7 @@ export const OrderDetail = () => {
{sideBefore.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component />
<w.Component data={order} />
</div>
)
})}
@@ -77,7 +77,7 @@ export const OrderDetail = () => {
{sideAfter.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component />
<w.Component data={order} />
</div>
)
})}

View File

@@ -1,10 +1,16 @@
import { Outlet, useParams } from "react-router-dom"
import { JsonViewSection } from "../../../components/common/json-view-section"
import { usePriceList } from "../../../hooks/api/price-lists"
import { PricingConfigurationSection } from "./components/pricing-configuration-section"
import { PricingGeneralSection } from "./components/pricing-general-section"
import { PricingProductSection } from "./components/pricing-product-section"
import after from "virtual:medusa/widgets/price_list/details/after"
import before from "virtual:medusa/widgets/price_list/details/before"
import sideAfter from "virtual:medusa/widgets/price_list/details/side/after"
import sideBefore from "virtual:medusa/widgets/price_list/details/side/before"
export const PricingDetail = () => {
const { id } = useParams()
@@ -19,19 +25,51 @@ export const PricingDetail = () => {
}
return (
<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 className="flex flex-col gap-y-2">
{before.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component data={price_list} />
</div>
)
})}
<div className="flex flex-col gap-x-4 lg:flex-row xl:items-start">
<div className="flex w-full flex-col gap-y-2">
<PricingGeneralSection priceList={price_list} />
<PricingProductSection priceList={price_list} />
{after.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component data={price_list} />
</div>
)
})}
<div className="hidden xl:block">
<JsonViewSection data={price_list} />
</div>
</div>
<JsonViewSection data={price_list} />
<div className="mt-2 flex w-full max-w-[100%] flex-col gap-y-2 xl:mt-0 xl:max-w-[400px]">
{sideBefore.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component data={price_list} />
</div>
)
})}
<PricingConfigurationSection priceList={price_list} />
{sideAfter.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component data={price_list} />
</div>
)
})}
<div className="xl:hidden">
<JsonViewSection data={price_list} />
</div>
</div>
<Outlet />
</div>
<div className="hidden w-full max-w-[400px] flex-col gap-y-2 xl:flex">
<PricingConfigurationSection priceList={price_list} />
</div>
<Outlet />
</div>
)
}

View File

@@ -1,10 +1,28 @@
import { Outlet } from "react-router-dom"
import { PricingListTable } from "./components/pricing-list-table"
import after from "virtual:medusa/widgets/price_list/list/after"
import before from "virtual:medusa/widgets/price_list/list/before"
export const PricingList = () => {
return (
<div className="flex flex-col gap-y-2">
{before.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component />
</div>
)
})}
<PricingListTable />
{after.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component />
</div>
)
})}
<Outlet />
</div>
)

View File

@@ -40,7 +40,7 @@ export const ProductDetail = () => {
{before.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component />
<w.Component data={product} />
</div>
)
})}
@@ -53,7 +53,7 @@ export const ProductDetail = () => {
{after.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component />
<w.Component data={product} />
</div>
)
})}
@@ -65,7 +65,7 @@ export const ProductDetail = () => {
{sideBefore.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component />
<w.Component data={product} />
</div>
)
})}
@@ -75,7 +75,7 @@ export const ProductDetail = () => {
{sideAfter.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component />
<w.Component data={product} />
</div>
)
})}

View File

@@ -7,6 +7,9 @@ import { PromotionConditionsSection } from "./components/promotion-conditions-se
import { PromotionGeneralSection } from "./components/promotion-general-section"
import { promotionLoader } from "./loader"
import after from "virtual:medusa/widgets/promotion/details/after"
import before from "virtual:medusa/widgets/promotion/details/before"
export const PromotionDetail = () => {
const initialData = useLoaderData() as Awaited<
ReturnType<typeof promotionLoader>
@@ -24,33 +27,43 @@ export const PromotionDetail = () => {
return (
<div className="flex flex-col gap-y-2">
{before.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component data={promotion} />
</div>
)
})}
<div className="flex flex-col gap-x-4 xl:flex-row xl:items-start">
<div className="flex w-full flex-col gap-y-2">
<PromotionGeneralSection promotion={promotion} />
<PromotionConditionsSection rules={rules || []} ruleType={"rules"} />
<PromotionConditionsSection
rules={targetRules || []}
ruleType={"target-rules"}
/>
{promotion.type === "buyget" && (
<PromotionConditionsSection
rules={buyRules || []}
ruleType={"buy-rules"}
/>
)}
<div className="flex w-full flex-col gap-y-2 xl:hidden">
<CampaignSection campaign={promotion.campaign!} />
{after.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component data={promotion} />
</div>
)
})}
<div className="hidden xl:block">
<JsonViewSection data={promotion} />
</div>
<JsonViewSection data={promotion as any} />
</div>
<div className="hidden w-full max-w-[400px] flex-col gap-y-2 xl:flex">
<div className="mt-2 flex w-full max-w-[100%] flex-col gap-y-2 xl:mt-0 xl:max-w-[400px]">
<CampaignSection campaign={promotion.campaign!} />
<div className="xl:hidden">
<JsonViewSection data={promotion} />
</div>
</div>
</div>
<Outlet />

View File

@@ -1,9 +1,26 @@
import { PromotionListTable } from "./components/promotion-list-table"
import after from "virtual:medusa/widgets/promotion/list/after"
import before from "virtual:medusa/widgets/promotion/list/before"
export const PromotionsList = () => {
return (
<div className="flex flex-col gap-y-2">
{before.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component />
</div>
)
})}
<PromotionListTable />
{after.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component />
</div>
)
})}
</div>
)
}