fix(dashboard,ui): ConditionBlock styling (#10481)
**What** - Resolves CMRC-58 - Also fixes some other issues, TS errors, Eslint warnings etc. in the Promotion domain. There are still several TS errors as the return types from `@medusajs/types` don't seem to match how they are used here, but I have left that as is, as I am not super familiar with the Promotion module.
This commit is contained in:
1 parent
3409953c4f
commit
c9a66b19af
8 files changed
+171
-92
No files matched your search
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/ui": patch
|
||||||
|
"@medusajs/dashboard": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix(dashboard,ui): Bring ConditionBlock in line with design
|
||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
Separator as PrimitiveSeparator,
|
Separator as PrimitiveSeparator,
|
||||||
} from "@ariakit/react"
|
} from "@ariakit/react"
|
||||||
import {
|
import {
|
||||||
|
CheckMini,
|
||||||
EllipseMiniSolid,
|
EllipseMiniSolid,
|
||||||
PlusMini,
|
PlusMini,
|
||||||
TrianglesMini,
|
TrianglesMini,
|
||||||
@@ -290,7 +291,7 @@ const ComboboxImpl = <T extends Value = string>(
|
|||||||
ref={comboboxRef}
|
ref={comboboxRef}
|
||||||
onFocus={() => setOpen(true)}
|
onFocus={() => setOpen(true)}
|
||||||
className={clx(
|
className={clx(
|
||||||
"txt-compact-small text-ui-fg-base placeholder:text-ui-fg-subtle transition-fg size-full cursor-pointer bg-transparent pl-2 pr-8 outline-none focus:cursor-text",
|
"txt-compact-small text-ui-fg-base !placeholder:text-ui-fg-muted transition-fg size-full cursor-pointer bg-transparent pl-2 pr-8 outline-none focus:cursor-text",
|
||||||
"hover:bg-ui-bg-field-hover",
|
"hover:bg-ui-bg-field-hover",
|
||||||
{
|
{
|
||||||
"opacity-0": hideInput,
|
"opacity-0": hideInput,
|
||||||
@@ -349,7 +350,7 @@ const ComboboxImpl = <T extends Value = string>(
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<PrimitiveComboboxItemCheck className="flex !size-5 items-center justify-center">
|
<PrimitiveComboboxItemCheck className="flex !size-5 items-center justify-center">
|
||||||
<EllipseMiniSolid />
|
{isArrayValue ? <CheckMini /> : <EllipseMiniSolid />}
|
||||||
</PrimitiveComboboxItemCheck>
|
</PrimitiveComboboxItemCheck>
|
||||||
<PrimitiveComboboxItemValue className="txt-compact-small">
|
<PrimitiveComboboxItemValue className="txt-compact-small">
|
||||||
{label}
|
{label}
|
||||||
|
|||||||
+11
-11
@@ -1,6 +1,6 @@
|
|||||||
import { RuleAttributeOptionsResponse, StoreDTO } from "@medusajs/types"
|
import { RuleAttributeOptionsResponse, StoreDTO } from "@medusajs/types"
|
||||||
import { Input, Select } from "@medusajs/ui"
|
import { Input, Select } from "@medusajs/ui"
|
||||||
import { RefCallBack, useWatch } from "react-hook-form"
|
import { useWatch } from "react-hook-form"
|
||||||
import { Form } from "../../../../../../components/common/form"
|
import { Form } from "../../../../../../components/common/form"
|
||||||
import { Combobox } from "../../../../../../components/inputs/combobox"
|
import { Combobox } from "../../../../../../components/inputs/combobox"
|
||||||
import { usePromotionRuleValues } from "../../../../../../hooks/api/promotions"
|
import { usePromotionRuleValues } from "../../../../../../hooks/api/promotions"
|
||||||
@@ -13,9 +13,8 @@ type RuleValueFormFieldType = {
|
|||||||
| "application_method.buy_rules"
|
| "application_method.buy_rules"
|
||||||
| "rules"
|
| "rules"
|
||||||
| "application_method.target_rules"
|
| "application_method.target_rules"
|
||||||
valuesField: any
|
name: string
|
||||||
operatorsField: any
|
operator: string
|
||||||
valuesRef: RefCallBack
|
|
||||||
fieldRule: any
|
fieldRule: any
|
||||||
attributes: RuleAttributeOptionsResponse[]
|
attributes: RuleAttributeOptionsResponse[]
|
||||||
ruleType: "rules" | "target-rules" | "buy-rules"
|
ruleType: "rules" | "target-rules" | "buy-rules"
|
||||||
@@ -39,9 +38,8 @@ export const RuleValueFormField = ({
|
|||||||
form,
|
form,
|
||||||
identifier,
|
identifier,
|
||||||
scope,
|
scope,
|
||||||
valuesField,
|
name,
|
||||||
operatorsField,
|
operator,
|
||||||
valuesRef,
|
|
||||||
fieldRule,
|
fieldRule,
|
||||||
attributes,
|
attributes,
|
||||||
ruleType,
|
ruleType,
|
||||||
@@ -65,13 +63,13 @@ export const RuleValueFormField = ({
|
|||||||
|
|
||||||
const watchOperator = useWatch({
|
const watchOperator = useWatch({
|
||||||
control: form.control,
|
control: form.control,
|
||||||
name: operatorsField.name,
|
name: operator,
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form.Field
|
<Form.Field
|
||||||
key={`${identifier}.${scope}.${valuesField.name}-${fieldRule.attribute}`}
|
key={`${identifier}.${scope}.${name}-${fieldRule.attribute}`}
|
||||||
{...valuesField}
|
name={name}
|
||||||
render={({ field: { onChange, ref, ...field } }) => {
|
render={({ field: { onChange, ref, ...field } }) => {
|
||||||
if (attribute?.field_type === "number") {
|
if (attribute?.field_type === "number") {
|
||||||
return (
|
return (
|
||||||
@@ -82,7 +80,7 @@ export const RuleValueFormField = ({
|
|||||||
type="number"
|
type="number"
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
className="bg-ui-bg-base"
|
className="bg-ui-bg-base"
|
||||||
ref={valuesRef}
|
ref={ref}
|
||||||
min={1}
|
min={1}
|
||||||
disabled={!fieldRule.attribute}
|
disabled={!fieldRule.attribute}
|
||||||
/>
|
/>
|
||||||
@@ -96,6 +94,7 @@ export const RuleValueFormField = ({
|
|||||||
<Form.Control>
|
<Form.Control>
|
||||||
<Input
|
<Input
|
||||||
{...field}
|
{...field}
|
||||||
|
ref={ref}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
className="bg-ui-bg-base"
|
className="bg-ui-bg-base"
|
||||||
disabled={!fieldRule.attribute}
|
disabled={!fieldRule.attribute}
|
||||||
@@ -143,6 +142,7 @@ export const RuleValueFormField = ({
|
|||||||
<Form.Control>
|
<Form.Control>
|
||||||
<Combobox
|
<Combobox
|
||||||
{...field}
|
{...field}
|
||||||
|
ref={ref}
|
||||||
placeholder="Select Values"
|
placeholder="Select Values"
|
||||||
options={options}
|
options={options}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
|
|||||||
+125
-58
@@ -1,8 +1,13 @@
|
|||||||
import { XMarkMini } from "@medusajs/icons"
|
import { XMarkMini } from "@medusajs/icons"
|
||||||
import { PromotionDTO } from "@medusajs/types"
|
import { PromotionDTO } from "@medusajs/types"
|
||||||
import { Badge, Button, Heading, Select, Text } from "@medusajs/ui"
|
import { Badge, Button, Heading, IconButton, Select, Text } from "@medusajs/ui"
|
||||||
import { Fragment, useEffect } from "react"
|
import { forwardRef, Fragment, useEffect } from "react"
|
||||||
import { useFieldArray, UseFormReturn, useWatch } from "react-hook-form"
|
import {
|
||||||
|
ControllerRenderProps,
|
||||||
|
useFieldArray,
|
||||||
|
UseFormReturn,
|
||||||
|
useWatch,
|
||||||
|
} from "react-hook-form"
|
||||||
import { useTranslation } from "react-i18next"
|
import { useTranslation } from "react-i18next"
|
||||||
import { Form } from "../../../../../../components/common/form"
|
import { Form } from "../../../../../../components/common/form"
|
||||||
import {
|
import {
|
||||||
@@ -102,7 +107,16 @@ export const RulesFormField = ({
|
|||||||
|
|
||||||
replace(generateRuleAttributes(rulesToAppend) as any)
|
replace(generateRuleAttributes(rulesToAppend) as any)
|
||||||
}
|
}
|
||||||
}, [promotionType, isLoading])
|
}, [
|
||||||
|
promotionType,
|
||||||
|
isLoading,
|
||||||
|
ruleType,
|
||||||
|
fields.length,
|
||||||
|
form,
|
||||||
|
replace,
|
||||||
|
rules,
|
||||||
|
promotion?.id,
|
||||||
|
])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
@@ -116,24 +130,16 @@ export const RulesFormField = ({
|
|||||||
|
|
||||||
{fields.map((fieldRule: any, index) => {
|
{fields.map((fieldRule: any, index) => {
|
||||||
const identifier = fieldRule.id
|
const identifier = fieldRule.id
|
||||||
const { ref: attributeRef, ...attributeField } = form.register(
|
|
||||||
`${scope}.${index}.attribute`
|
|
||||||
)
|
|
||||||
const { ref: operatorRef, ...operatorsField } = form.register(
|
|
||||||
`${scope}.${index}.operator`
|
|
||||||
)
|
|
||||||
const { ref: valuesRef, ...valuesField } = form.register(
|
|
||||||
`${scope}.${index}.values`
|
|
||||||
)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment key={`${fieldRule.id}.${index}.${fieldRule.attribute}`}>
|
<Fragment key={`${fieldRule.id}.${index}.${fieldRule.attribute}`}>
|
||||||
<div className="bg-ui-bg-subtle border-ui-border-base flex flex-row gap-2 rounded-xl border px-2 py-2">
|
<div className="bg-ui-bg-subtle border-ui-border-base flex flex-row gap-2 rounded-xl border px-2 py-2">
|
||||||
<div className="grow">
|
<div className="grow">
|
||||||
<Form.Field
|
<Form.Field
|
||||||
key={`${identifier}.${scope}.${attributeField.name}`}
|
name={`${scope}.${index}.attribute`}
|
||||||
{...attributeField}
|
render={({ field }) => {
|
||||||
render={({ field: { onChange, ref, ...field } }) => {
|
const { onChange, ref, ...fieldProps } = field
|
||||||
|
|
||||||
const existingAttributes =
|
const existingAttributes =
|
||||||
fields?.map((field: any) => field.attribute) || []
|
fields?.map((field: any) => field.attribute) || []
|
||||||
const attributeOptions =
|
const attributeOptions =
|
||||||
@@ -145,33 +151,39 @@ export const RulesFormField = ({
|
|||||||
return !existingAttributes.includes(attr.value)
|
return !existingAttributes.includes(attr.value)
|
||||||
}) || []
|
}) || []
|
||||||
|
|
||||||
return (
|
const disabled = !!fieldRule.required
|
||||||
<Form.Item className="mb-2">
|
const onValueChange = (e: string) => {
|
||||||
{fieldRule.required && (
|
const currentAttributeOption = attributeOptions.find(
|
||||||
<p className="text text-ui-fg-muted txt-small">
|
(ao) => ao.id === e
|
||||||
{t("promotions.form.required")}
|
)
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Form.Control>
|
|
||||||
<Select
|
|
||||||
{...field}
|
|
||||||
onValueChange={(e) => {
|
|
||||||
const currentAttributeOption =
|
|
||||||
attributeOptions.find((ao) => ao.id === e)
|
|
||||||
|
|
||||||
update(index, {
|
update(index, {
|
||||||
...fieldRule,
|
...fieldRule,
|
||||||
values: [],
|
values: [],
|
||||||
disguised:
|
disguised: currentAttributeOption?.disguised || false,
|
||||||
currentAttributeOption?.disguised || false,
|
|
||||||
})
|
})
|
||||||
onChange(e)
|
onChange(e)
|
||||||
}}
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Form.Item className="mb-2">
|
||||||
|
{fieldRule.required && (
|
||||||
|
<div className="flex items-center px-2">
|
||||||
|
<p className="text text-ui-fg-muted txt-small">
|
||||||
|
{t("promotions.form.required")}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Form.Control>
|
||||||
|
{!disabled ? (
|
||||||
|
<Select
|
||||||
|
{...fieldProps}
|
||||||
|
onValueChange={onValueChange}
|
||||||
disabled={fieldRule.required}
|
disabled={fieldRule.required}
|
||||||
>
|
>
|
||||||
<Select.Trigger
|
<Select.Trigger
|
||||||
ref={attributeRef}
|
ref={ref}
|
||||||
className="bg-ui-bg-base"
|
className="bg-ui-bg-base"
|
||||||
>
|
>
|
||||||
<Select.Value
|
<Select.Value
|
||||||
@@ -194,6 +206,16 @@ export const RulesFormField = ({
|
|||||||
))}
|
))}
|
||||||
</Select.Content>
|
</Select.Content>
|
||||||
</Select>
|
</Select>
|
||||||
|
) : (
|
||||||
|
<DisabledField
|
||||||
|
label={
|
||||||
|
attributeOptions?.find(
|
||||||
|
(ao) => ao.value === fieldRule.attribute
|
||||||
|
)?.label || ""
|
||||||
|
}
|
||||||
|
field={field}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</Form.Control>
|
</Form.Control>
|
||||||
<Form.ErrorMessage />
|
<Form.ErrorMessage />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
@@ -203,43 +225,60 @@ export const RulesFormField = ({
|
|||||||
|
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<Form.Field
|
<Form.Field
|
||||||
key={`${identifier}.${scope}.${operatorsField.name}`}
|
name={`${scope}.${index}.operator`}
|
||||||
{...operatorsField}
|
render={({ field }) => {
|
||||||
render={({ field: { onChange, ref, ...field } }) => {
|
const { onChange, ref, ...fieldProps } = field
|
||||||
const currentAttributeOption = attributes.find(
|
|
||||||
|
const currentAttributeOption = attributes?.find(
|
||||||
(attr) => attr.value === fieldRule.attribute
|
(attr) => attr.value === fieldRule.attribute
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const options =
|
||||||
|
currentAttributeOption?.operators?.map((o, idx) => ({
|
||||||
|
label: o.label,
|
||||||
|
value: o.value,
|
||||||
|
key: `${identifier}-operator-option-${idx}`,
|
||||||
|
})) || []
|
||||||
|
|
||||||
|
const disabled =
|
||||||
|
!!fieldRule.attribute && options?.length <= 1
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form.Item className="basis-1/2">
|
<Form.Item className="basis-1/2">
|
||||||
<Form.Control>
|
<Form.Control>
|
||||||
|
{!disabled ? (
|
||||||
<Select
|
<Select
|
||||||
{...field}
|
{...fieldProps}
|
||||||
disabled={!fieldRule.attribute}
|
disabled={!fieldRule.attribute}
|
||||||
onValueChange={onChange}
|
onValueChange={onChange}
|
||||||
>
|
>
|
||||||
<Select.Trigger
|
<Select.Trigger
|
||||||
ref={operatorRef}
|
ref={ref}
|
||||||
className="bg-ui-bg-base"
|
className="bg-ui-bg-base"
|
||||||
>
|
>
|
||||||
<Select.Value placeholder="Select Operator" />
|
<Select.Value placeholder="Select Operator" />
|
||||||
</Select.Trigger>
|
</Select.Trigger>
|
||||||
|
|
||||||
<Select.Content>
|
<Select.Content>
|
||||||
{currentAttributeOption?.operators?.map(
|
{options?.map((c) => (
|
||||||
(c, i) => (
|
<Select.Item key={c.key} value={c.value}>
|
||||||
<Select.Item
|
|
||||||
key={`${identifier}-operator-option-${i}`}
|
|
||||||
value={c.value}
|
|
||||||
>
|
|
||||||
<span className="text-ui-fg-subtle">
|
<span className="text-ui-fg-subtle">
|
||||||
{c.label}
|
{c.label}
|
||||||
</span>
|
</span>
|
||||||
</Select.Item>
|
</Select.Item>
|
||||||
)
|
))}
|
||||||
)}
|
|
||||||
</Select.Content>
|
</Select.Content>
|
||||||
</Select>
|
</Select>
|
||||||
|
) : (
|
||||||
|
<DisabledField
|
||||||
|
label={
|
||||||
|
options.find(
|
||||||
|
(o) => o.value === fieldProps.value
|
||||||
|
)?.label || ""
|
||||||
|
}
|
||||||
|
field={field}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</Form.Control>
|
</Form.Control>
|
||||||
<Form.ErrorMessage />
|
<Form.ErrorMessage />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
@@ -251,9 +290,8 @@ export const RulesFormField = ({
|
|||||||
form={form}
|
form={form}
|
||||||
identifier={identifier}
|
identifier={identifier}
|
||||||
scope={scope}
|
scope={scope}
|
||||||
valuesField={valuesField}
|
name={`${scope}.${index}.values`}
|
||||||
operatorsField={operatorsField}
|
operator={`${scope}.${index}.operator`}
|
||||||
valuesRef={valuesRef}
|
|
||||||
fieldRule={fieldRule}
|
fieldRule={fieldRule}
|
||||||
attributes={attributes}
|
attributes={attributes}
|
||||||
ruleType={ruleType}
|
ruleType={ruleType}
|
||||||
@@ -261,11 +299,13 @@ export const RulesFormField = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex-none self-center px-1">
|
<div className="size-7 flex-none self-center">
|
||||||
<XMarkMini
|
{!fieldRule.required && (
|
||||||
className={`text-ui-fg-muted cursor-pointer ${
|
<IconButton
|
||||||
fieldRule.required ? "invisible" : "visible"
|
size="small"
|
||||||
}`}
|
variant="transparent"
|
||||||
|
className="text-ui-fg-muted"
|
||||||
|
type="button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (!fieldRule.required) {
|
if (!fieldRule.required) {
|
||||||
setRulesToRemove &&
|
setRulesToRemove &&
|
||||||
@@ -274,7 +314,10 @@ export const RulesFormField = ({
|
|||||||
remove(index)
|
remove(index)
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
>
|
||||||
|
<XMarkMini />
|
||||||
|
</IconButton>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -291,7 +334,7 @@ export const RulesFormField = ({
|
|||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|
||||||
<div className={!!fields.length ? "mt-6" : ""}>
|
<div className={fields.length ? "mt-6" : ""}>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
@@ -330,3 +373,27 @@ export const RulesFormField = ({
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DisabledAttributeProps = {
|
||||||
|
label: string
|
||||||
|
field: ControllerRenderProps
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render this if an attribute is disabled, or
|
||||||
|
* if there is only one option available.
|
||||||
|
*/
|
||||||
|
const DisabledField = forwardRef<HTMLInputElement, DisabledAttributeProps>(
|
||||||
|
({ label, field }, ref) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="txt-compact-small bg-ui-bg-component shadow-borders-base text-ui-fg-base h-8 rounded-md px-2 py-1.5">
|
||||||
|
{label}
|
||||||
|
</div>
|
||||||
|
<input {...field} ref={ref} disabled hidden />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
DisabledField.displayName = "DisabledField"
|
||||||
+13
-12
@@ -79,6 +79,7 @@ export const CreatePromotionForm = () => {
|
|||||||
defaultValues,
|
defaultValues,
|
||||||
resolver: zodResolver(CreatePromotionSchema),
|
resolver: zodResolver(CreatePromotionSchema),
|
||||||
})
|
})
|
||||||
|
const { setValue, reset, getValues } = form
|
||||||
|
|
||||||
const { mutateAsync: createPromotion } = useCreatePromotion()
|
const { mutateAsync: createPromotion } = useCreatePromotion()
|
||||||
|
|
||||||
@@ -150,7 +151,7 @@ export const CreatePromotionForm = () => {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
handleSuccess()
|
handleSuccess(`/promotions/${promotion.id}`)
|
||||||
},
|
},
|
||||||
onError: (e) => {
|
onError: (e) => {
|
||||||
toast.error(e.message)
|
toast.error(e.message)
|
||||||
@@ -244,20 +245,20 @@ export const CreatePromotionForm = () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
form.reset({ ...defaultValues, template_id: watchTemplateId })
|
reset({ ...defaultValues, template_id: watchTemplateId })
|
||||||
|
|
||||||
for (const [key, value] of Object.entries(currentTemplate.defaults)) {
|
for (const [key, value] of Object.entries(currentTemplate.defaults)) {
|
||||||
if (typeof value === "object") {
|
if (typeof value === "object") {
|
||||||
for (const [subKey, subValue] of Object.entries(value)) {
|
for (const [subKey, subValue] of Object.entries(value)) {
|
||||||
form.setValue(`application_method.${subKey}`, subValue)
|
setValue(`application_method.${subKey}`, subValue)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
form.setValue(key, value)
|
setValue(key, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return currentTemplate
|
return currentTemplate
|
||||||
}, [watchTemplateId])
|
}, [watchTemplateId, setValue, reset])
|
||||||
|
|
||||||
const watchValueType = useWatch({
|
const watchValueType = useWatch({
|
||||||
control: form.control,
|
control: form.control,
|
||||||
@@ -272,9 +273,9 @@ export const CreatePromotionForm = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (watchAllocation === "across") {
|
if (watchAllocation === "across") {
|
||||||
form.setValue("application_method.max_quantity", null)
|
setValue("application_method.max_quantity", null)
|
||||||
}
|
}
|
||||||
}, [watchAllocation])
|
}, [watchAllocation, setValue])
|
||||||
|
|
||||||
const watchType = useWatch({
|
const watchType = useWatch({
|
||||||
control: form.control,
|
control: form.control,
|
||||||
@@ -307,19 +308,19 @@ export const CreatePromotionForm = () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const formData = form.getValues()
|
const formData = getValues()
|
||||||
|
|
||||||
if (watchCampaignChoice !== "existing") {
|
if (watchCampaignChoice !== "existing") {
|
||||||
form.setValue("campaign_id", undefined)
|
setValue("campaign_id", undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (watchCampaignChoice !== "new") {
|
if (watchCampaignChoice !== "new") {
|
||||||
form.setValue("campaign", undefined)
|
setValue("campaign", undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (watchCampaignChoice === "new") {
|
if (watchCampaignChoice === "new") {
|
||||||
if (!formData.campaign || !formData.campaign?.budget?.type) {
|
if (!formData.campaign || !formData.campaign?.budget?.type) {
|
||||||
form.setValue("campaign", {
|
setValue("campaign", {
|
||||||
...DEFAULT_CAMPAIGN_VALUES,
|
...DEFAULT_CAMPAIGN_VALUES,
|
||||||
budget: {
|
budget: {
|
||||||
...DEFAULT_CAMPAIGN_VALUES.budget,
|
...DEFAULT_CAMPAIGN_VALUES.budget,
|
||||||
@@ -328,7 +329,7 @@ export const CreatePromotionForm = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [watchCampaignChoice])
|
}, [watchCampaignChoice, getValues, setValue])
|
||||||
|
|
||||||
const watchRules = useWatch({
|
const watchRules = useWatch({
|
||||||
control: form.control,
|
control: form.control,
|
||||||
|
|||||||
+6
-2
@@ -85,7 +85,7 @@ export const PromotionGeneralSection = ({
|
|||||||
[PromotionStatus.EXPIRED]: ["red", t("statuses.expired")],
|
[PromotionStatus.EXPIRED]: ["red", t("statuses.expired")],
|
||||||
}[getPromotionStatus(promotion)] as [
|
}[getPromotionStatus(promotion)] as [
|
||||||
"grey" | "orange" | "green" | "red",
|
"grey" | "orange" | "green" | "red",
|
||||||
string,
|
string
|
||||||
]
|
]
|
||||||
|
|
||||||
const displayValue = getDisplayValue(promotion)
|
const displayValue = getDisplayValue(promotion)
|
||||||
@@ -141,7 +141,11 @@ export const PromotionGeneralSection = ({
|
|||||||
{t("fields.code")}
|
{t("fields.code")}
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
<Copy content={promotion.code!} asChild>
|
<Copy
|
||||||
|
content={promotion.code!}
|
||||||
|
className="text-ui-tag-neutral-text"
|
||||||
|
asChild
|
||||||
|
>
|
||||||
<Badge
|
<Badge
|
||||||
size="2xsmall"
|
size="2xsmall"
|
||||||
rounded="full"
|
rounded="full"
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ const Copy = React.forwardRef<HTMLButtonElement, CopyProps>(
|
|||||||
aria-label="Copy code snippet"
|
aria-label="Copy code snippet"
|
||||||
type="button"
|
type="button"
|
||||||
className={clx(
|
className={clx(
|
||||||
"text-ui-contrast-fg-secondary h-fit w-fit",
|
"h-fit w-fit",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
onClick={copyToClipboard}
|
onClick={copyToClipboard}
|
||||||
@@ -100,14 +100,14 @@ const Copy = React.forwardRef<HTMLButtonElement, CopyProps>(
|
|||||||
children
|
children
|
||||||
) : done ? (
|
) : done ? (
|
||||||
isDefault ? (
|
isDefault ? (
|
||||||
<CheckCircleSolid />
|
<CheckCircleSolid className="text-ui-fg-subtle" />
|
||||||
) : (
|
) : (
|
||||||
<CheckCircleMiniSolid />
|
<CheckCircleMiniSolid className="text-ui-fg-subtle" />
|
||||||
)
|
)
|
||||||
) : isDefault ? (
|
) : isDefault ? (
|
||||||
<SquareTwoStack />
|
<SquareTwoStack className="text-ui-fg-subtle" />
|
||||||
) : (
|
) : (
|
||||||
<SquareTwoStackMini />
|
<SquareTwoStackMini className="text-ui-fg-subtle" />
|
||||||
)}
|
)}
|
||||||
</Component>
|
</Component>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { EllipseMiniSolid, TrianglesMini } from "@medusajs/icons"
|
import { Check, TrianglesMini } from "@medusajs/icons"
|
||||||
import * as SelectPrimitive from "@radix-ui/react-select"
|
import * as SelectPrimitive from "@radix-ui/react-select"
|
||||||
import { cva } from "cva"
|
import { cva } from "cva"
|
||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
@@ -194,7 +194,7 @@ const Item = React.forwardRef<
|
|||||||
>
|
>
|
||||||
<span className="flex h-[15px] w-[15px] items-center justify-center">
|
<span className="flex h-[15px] w-[15px] items-center justify-center">
|
||||||
<SelectPrimitive.ItemIndicator className="flex items-center justify-center">
|
<SelectPrimitive.ItemIndicator className="flex items-center justify-center">
|
||||||
<EllipseMiniSolid />
|
<Check />
|
||||||
</SelectPrimitive.ItemIndicator>
|
</SelectPrimitive.ItemIndicator>
|
||||||
</span>
|
</span>
|
||||||
<SelectPrimitive.ItemText className="flex-1 truncate">
|
<SelectPrimitive.ItemText className="flex-1 truncate">
|
||||||
|
|||||||
Reference in new issue
Block a user