feat(dashboard,types,js-sdk,ui): Add missing Price List features (#7856)
**What** - Adds missing features to Price List domain - Adds `StackedFocusModal` and `StackedDrawer` components that should replace SplitView across the project. - Add Footer to FocusModal - Adds missing js-sdk functions and types **Note** The DatePickers in the PriceLists forms do not work as intended atm. The component is broken, and needs to be fixed. I am working on a fix, but choose to move that work into a separate branch, to prevent this PR from getting bigger then it already is. Will update once the fixes have been merged.
This commit is contained in:
committed by
GitHub
parent
9f3998393b
commit
c1740218e9
+59
@@ -0,0 +1,59 @@
|
||||
import { PropsWithChildren, createContext } from "react"
|
||||
|
||||
type ConditionOperator =
|
||||
| "eq"
|
||||
| "ne"
|
||||
| "gt"
|
||||
| "lt"
|
||||
| "gte"
|
||||
| "lte"
|
||||
| "in"
|
||||
| "nin"
|
||||
|
||||
type ConditionBlockValue<TValue> = {
|
||||
attribute: string
|
||||
operator: ConditionOperator
|
||||
value: TValue
|
||||
}
|
||||
|
||||
type ConditionBlockState<TValue> = {
|
||||
defaultValue?: ConditionBlockValue<TValue>
|
||||
value?: ConditionBlockValue<TValue>
|
||||
onChange: (value: ConditionBlockValue<TValue>) => void
|
||||
}
|
||||
|
||||
const ConditionBlockContext = createContext<ConditionBlockState<any> | null>(
|
||||
null
|
||||
)
|
||||
|
||||
const useConditionBlock = () => {
|
||||
const context = ConditionBlockContext
|
||||
|
||||
if (!context) {
|
||||
throw new Error("useConditionBlock must be used within a ConditionBlock")
|
||||
}
|
||||
|
||||
return context
|
||||
}
|
||||
|
||||
type ConditionBlockProps<TValue> = PropsWithChildren<
|
||||
ConditionBlockState<TValue>
|
||||
>
|
||||
|
||||
const Root = <TValue,>({ children, ...props }: ConditionBlockProps<TValue>) => {
|
||||
return (
|
||||
<ConditionBlockContext.Provider value={props}>
|
||||
{children}
|
||||
</ConditionBlockContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
const Divider = () => {}
|
||||
|
||||
const Operator = () => {}
|
||||
|
||||
const Item = () => {}
|
||||
|
||||
export const ConditionBlock = Object.assign(Root, {
|
||||
Divider,
|
||||
})
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
import { Text, clx } from "@medusajs/ui"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { useDate } from "../../../hooks/use-date"
|
||||
|
||||
type DateRangeDisplayProps = {
|
||||
startsAt?: Date | string | null
|
||||
endsAt?: Date | string | null
|
||||
showTime?: boolean
|
||||
}
|
||||
|
||||
export const DateRangeDisplay = ({
|
||||
startsAt,
|
||||
endsAt,
|
||||
showTime = false,
|
||||
}: DateRangeDisplayProps) => {
|
||||
const startDate = startsAt ? new Date(startsAt) : null
|
||||
const endDate = endsAt ? new Date(endsAt) : null
|
||||
|
||||
const { t } = useTranslation()
|
||||
const { getFullDate } = useDate()
|
||||
|
||||
return (
|
||||
<div className="grid gap-3 md:grid-cols-2">
|
||||
<div className="shadow-elevation-card-rest bg-ui-bg-component text-ui-fg-subtle flex items-center gap-x-3 rounded-md px-3 py-1.5">
|
||||
<Bar date={startDate} />
|
||||
<div>
|
||||
<Text weight="plus" size="small">
|
||||
{t("fields.startDate")}
|
||||
</Text>
|
||||
<Text size="small">
|
||||
{startDate
|
||||
? getFullDate({
|
||||
date: startDate,
|
||||
includeTime: showTime,
|
||||
})
|
||||
: "-"}
|
||||
</Text>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="shadow-elevation-card-rest bg-ui-bg-component text-ui-fg-subtle flex items-center gap-x-3 rounded-md px-3 py-1.5">
|
||||
<Bar date={endDate} />
|
||||
<div>
|
||||
<Text size="small" weight="plus">
|
||||
{t("fields.endDate")}
|
||||
</Text>
|
||||
<Text size="small">
|
||||
{endDate
|
||||
? getFullDate({
|
||||
date: endDate,
|
||||
includeTime: showTime,
|
||||
})
|
||||
: "-"}
|
||||
</Text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const Bar = ({ date }: { date: Date | null }) => {
|
||||
const now = new Date()
|
||||
|
||||
const isDateInFuture = date && date > now
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clx("bg-ui-tag-neutral-icon h-8 w-1 rounded-full", {
|
||||
"bg-ui-tag-orange-icon": isDateInFuture,
|
||||
})}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from "./date-range-display"
|
||||
+5
-10
@@ -7,11 +7,11 @@ import {
|
||||
useState,
|
||||
} from "react"
|
||||
|
||||
import { Adjustments } from "@medusajs/icons"
|
||||
import { Button, DropdownMenu, clx } from "@medusajs/ui"
|
||||
import {
|
||||
CellContext,
|
||||
ColumnDef,
|
||||
OnChangeFn,
|
||||
Row,
|
||||
VisibilityState,
|
||||
flexRender,
|
||||
@@ -41,7 +41,7 @@ interface DataGridRootProps<
|
||||
data?: TData[]
|
||||
columns: ColumnDef<TData>[]
|
||||
state: UseFormReturn<TFieldValues>
|
||||
getSubRows?: (row: TData) => TData[]
|
||||
getSubRows?: (row: TData) => TData[] | undefined
|
||||
}
|
||||
|
||||
const ARROW_KEYS = ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"]
|
||||
@@ -93,13 +93,6 @@ export const DataGridRoot = <
|
||||
|
||||
const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({})
|
||||
|
||||
const onColumnVisibilityChange: OnChangeFn<VisibilityState> = useCallback(
|
||||
(next) => {
|
||||
const update = typeof next === "function" ? next(columnVisibility) : next
|
||||
},
|
||||
[columnVisibility]
|
||||
)
|
||||
|
||||
const grid = useReactTable({
|
||||
data: data,
|
||||
columns,
|
||||
@@ -663,7 +656,8 @@ export const DataGridRoot = <
|
||||
<DropdownMenu>
|
||||
<DropdownMenu.Trigger asChild>
|
||||
<Button size="small" variant="secondary">
|
||||
Columns
|
||||
<Adjustments />
|
||||
Edit columns
|
||||
</Button>
|
||||
</DropdownMenu.Trigger>
|
||||
<DropdownMenu.Content>
|
||||
@@ -799,6 +793,7 @@ export const DataGridRoot = <
|
||||
{flexRender(cell.column.columnDef.cell, {
|
||||
...cell.getContext(),
|
||||
columnIndex,
|
||||
rowIndex: virtualRow.index,
|
||||
} as CellContext<TData, any>)}
|
||||
{isAnchor && (
|
||||
<div
|
||||
|
||||
@@ -29,11 +29,14 @@ export const useDataGridCell = <TData, TValue>({
|
||||
field,
|
||||
context,
|
||||
}: UseDataGridCellProps<TData, TValue>) => {
|
||||
const { row, columnIndex } = context as DataGridCellContext<TData, TValue>
|
||||
const { rowIndex, columnIndex } = context as DataGridCellContext<
|
||||
TData,
|
||||
TValue
|
||||
>
|
||||
|
||||
const coords: CellCoords = useMemo(
|
||||
() => ({ row: row.index, col: columnIndex }),
|
||||
[row, columnIndex]
|
||||
() => ({ row: rowIndex, col: columnIndex }),
|
||||
[rowIndex, columnIndex]
|
||||
)
|
||||
const id = generateCellId(coords)
|
||||
|
||||
|
||||
@@ -22,6 +22,10 @@ export interface DataGridCellContext<TData = unknown, TValue = any>
|
||||
* The index of the column in the grid.
|
||||
*/
|
||||
columnIndex: number
|
||||
/**
|
||||
* The index of the row in the grid.
|
||||
*/
|
||||
rowIndex: number
|
||||
}
|
||||
|
||||
export interface DataGridCellContainerProps {
|
||||
|
||||
@@ -150,8 +150,8 @@ const useCoreRoutes = (): Omit<NavItemProps, "pathname">[] => {
|
||||
},
|
||||
{
|
||||
icon: <CurrencyDollar />,
|
||||
label: t("pricing.domain"),
|
||||
to: "/pricing",
|
||||
label: t("priceLists.domain"),
|
||||
to: "/price-lists",
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
export { RouteDrawer } from "./route-drawer"
|
||||
export { RouteFocusModal } from "./route-focus-modal"
|
||||
export { useRouteModal } from "./route-modal-provider"
|
||||
|
||||
export { StackedDrawer } from "./stacked-drawer"
|
||||
export { StackedFocusModal } from "./stacked-focus-modal"
|
||||
export { useStackedModal } from "./stacked-modal-provider"
|
||||
+23
-4
@@ -1,8 +1,9 @@
|
||||
import { Drawer } from "@medusajs/ui"
|
||||
import { Drawer, clx } from "@medusajs/ui"
|
||||
import { PropsWithChildren, useEffect, useState } from "react"
|
||||
import { useNavigate } from "react-router-dom"
|
||||
import { RouteForm } from "../route-form"
|
||||
import { RouteModalForm } from "../route-modal-form"
|
||||
import { RouteModalProvider } from "../route-modal-provider/route-provider"
|
||||
import { StackedModalProvider } from "../stacked-modal-provider"
|
||||
|
||||
type RouteDrawerProps = PropsWithChildren<{
|
||||
prev?: string
|
||||
@@ -11,6 +12,7 @@ type RouteDrawerProps = PropsWithChildren<{
|
||||
const Root = ({ prev = "..", children }: RouteDrawerProps) => {
|
||||
const navigate = useNavigate()
|
||||
const [open, setOpen] = useState(false)
|
||||
const [stackedModalOpen, onStackedModalOpen] = useState(false)
|
||||
|
||||
/**
|
||||
* Open the modal when the component mounts. This
|
||||
@@ -18,6 +20,11 @@ const Root = ({ prev = "..", children }: RouteDrawerProps) => {
|
||||
*/
|
||||
useEffect(() => {
|
||||
setOpen(true)
|
||||
|
||||
return () => {
|
||||
setOpen(false)
|
||||
onStackedModalOpen(false)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const handleOpenChange = (open: boolean) => {
|
||||
@@ -33,17 +40,27 @@ const Root = ({ prev = "..", children }: RouteDrawerProps) => {
|
||||
return (
|
||||
<Drawer open={open} onOpenChange={handleOpenChange}>
|
||||
<RouteModalProvider prev={prev}>
|
||||
<Drawer.Content>{children}</Drawer.Content>
|
||||
<StackedModalProvider onOpenChange={onStackedModalOpen}>
|
||||
<Drawer.Content
|
||||
className={clx({
|
||||
"!bg-ui-bg-disabled !inset-y-5 !right-5": stackedModalOpen,
|
||||
})}
|
||||
>
|
||||
{children}
|
||||
</Drawer.Content>
|
||||
</StackedModalProvider>
|
||||
</RouteModalProvider>
|
||||
</Drawer>
|
||||
)
|
||||
}
|
||||
|
||||
const Header = Drawer.Header
|
||||
const Title = Drawer.Title
|
||||
const Description = Drawer.Description
|
||||
const Body = Drawer.Body
|
||||
const Footer = Drawer.Footer
|
||||
const Close = Drawer.Close
|
||||
const Form = RouteForm
|
||||
const Form = RouteModalForm
|
||||
|
||||
/**
|
||||
* Drawer that is used to render a form on a separate route.
|
||||
@@ -52,7 +69,9 @@ const Form = RouteForm
|
||||
*/
|
||||
export const RouteDrawer = Object.assign(Root, {
|
||||
Header,
|
||||
Title,
|
||||
Body,
|
||||
Description,
|
||||
Footer,
|
||||
Close,
|
||||
Form,
|
||||
+25
-4
@@ -1,8 +1,9 @@
|
||||
import { FocusModal } from "@medusajs/ui"
|
||||
import { FocusModal, clx } from "@medusajs/ui"
|
||||
import { PropsWithChildren, useEffect, useState } from "react"
|
||||
import { useNavigate } from "react-router-dom"
|
||||
import { RouteForm } from "../route-form"
|
||||
import { RouteModalForm } from "../route-modal-form"
|
||||
import { RouteModalProvider } from "../route-modal-provider/route-provider"
|
||||
import { StackedModalProvider } from "../stacked-modal-provider"
|
||||
|
||||
type RouteFocusModalProps = PropsWithChildren<{
|
||||
prev?: string
|
||||
@@ -11,6 +12,7 @@ type RouteFocusModalProps = PropsWithChildren<{
|
||||
const Root = ({ prev = "..", children }: RouteFocusModalProps) => {
|
||||
const navigate = useNavigate()
|
||||
const [open, setOpen] = useState(false)
|
||||
const [stackedModalOpen, onStackedModalOpen] = useState(false)
|
||||
|
||||
/**
|
||||
* Open the modal when the component mounts. This
|
||||
@@ -18,6 +20,11 @@ const Root = ({ prev = "..", children }: RouteFocusModalProps) => {
|
||||
*/
|
||||
useEffect(() => {
|
||||
setOpen(true)
|
||||
|
||||
return () => {
|
||||
setOpen(false)
|
||||
onStackedModalOpen(false)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const handleOpenChange = (open: boolean) => {
|
||||
@@ -33,16 +40,27 @@ const Root = ({ prev = "..", children }: RouteFocusModalProps) => {
|
||||
return (
|
||||
<FocusModal open={open} onOpenChange={handleOpenChange}>
|
||||
<RouteModalProvider prev={prev}>
|
||||
<FocusModal.Content>{children}</FocusModal.Content>
|
||||
<StackedModalProvider onOpenChange={onStackedModalOpen}>
|
||||
<FocusModal.Content
|
||||
className={clx({
|
||||
"!bg-ui-bg-disabled !inset-x-5 !inset-y-3": stackedModalOpen,
|
||||
})}
|
||||
>
|
||||
{children}
|
||||
</FocusModal.Content>
|
||||
</StackedModalProvider>
|
||||
</RouteModalProvider>
|
||||
</FocusModal>
|
||||
)
|
||||
}
|
||||
|
||||
const Header = FocusModal.Header
|
||||
const Title = FocusModal.Title
|
||||
const Description = FocusModal.Description
|
||||
const Footer = FocusModal.Footer
|
||||
const Body = FocusModal.Body
|
||||
const Close = FocusModal.Close
|
||||
const Form = RouteForm
|
||||
const Form = RouteModalForm
|
||||
|
||||
/**
|
||||
* FocusModal that is used to render a form on a separate route.
|
||||
@@ -52,7 +70,10 @@ const Form = RouteForm
|
||||
*/
|
||||
export const RouteFocusModal = Object.assign(Root, {
|
||||
Header,
|
||||
Title,
|
||||
Body,
|
||||
Description,
|
||||
Footer,
|
||||
Close,
|
||||
Form,
|
||||
})
|
||||
@@ -0,0 +1 @@
|
||||
export * from "./route-modal-form"
|
||||
+3
-3
@@ -5,16 +5,16 @@ import { useTranslation } from "react-i18next"
|
||||
import { useBlocker } from "react-router-dom"
|
||||
import { Form } from "../../common/form"
|
||||
|
||||
type RouteFormProps<TFieldValues extends FieldValues> = PropsWithChildren<{
|
||||
type RouteModalFormProps<TFieldValues extends FieldValues> = PropsWithChildren<{
|
||||
form: UseFormReturn<TFieldValues>
|
||||
blockSearch?: boolean
|
||||
}>
|
||||
|
||||
export const RouteForm = <TFieldValues extends FieldValues = any>({
|
||||
export const RouteModalForm = <TFieldValues extends FieldValues = any>({
|
||||
form,
|
||||
blockSearch = false,
|
||||
children,
|
||||
}: RouteFormProps<TFieldValues>) => {
|
||||
}: RouteModalFormProps<TFieldValues>) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const {
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from "./route-provider"
|
||||
export * from "./use-route-modal"
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import { createContext } from "react"
|
||||
|
||||
type RouteModalProviderState = {
|
||||
handleSuccess: (path?: string) => void
|
||||
}
|
||||
|
||||
export const RouteModalProviderContext =
|
||||
createContext<RouteModalProviderState | null>(null)
|
||||
+2
-18
@@ -1,22 +1,6 @@
|
||||
import { PropsWithChildren, createContext, useContext } from "react"
|
||||
import { PropsWithChildren } from "react"
|
||||
import { useNavigate } from "react-router-dom"
|
||||
|
||||
type RouteModalProviderContextType = {
|
||||
handleSuccess: (path?: string) => void
|
||||
}
|
||||
|
||||
const RouteModalProviderContext =
|
||||
createContext<RouteModalProviderContextType | null>(null)
|
||||
|
||||
export const useRouteModal = () => {
|
||||
const context = useContext(RouteModalProviderContext)
|
||||
|
||||
if (!context) {
|
||||
throw new Error("useRouteModal must be used within a RouteModalProvider")
|
||||
}
|
||||
|
||||
return context
|
||||
}
|
||||
import { RouteModalProviderContext } from "./route-modal-context"
|
||||
|
||||
type RouteModalProviderProps = PropsWithChildren<{
|
||||
prev: string
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
import { useContext } from "react"
|
||||
import { RouteModalProviderContext } from "./route-modal-context"
|
||||
|
||||
export const useRouteModal = () => {
|
||||
const context = useContext(RouteModalProviderContext)
|
||||
|
||||
if (!context) {
|
||||
throw new Error("useRouteModal must be used within a RouteModalProvider")
|
||||
}
|
||||
|
||||
return context
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from "./stacked-drawer"
|
||||
@@ -0,0 +1,85 @@
|
||||
import { Drawer, clx } from "@medusajs/ui"
|
||||
import {
|
||||
ComponentPropsWithoutRef,
|
||||
PropsWithChildren,
|
||||
forwardRef,
|
||||
useEffect,
|
||||
} from "react"
|
||||
import { useStackedModal } from "../stacked-modal-provider"
|
||||
|
||||
type StackedDrawerProps = PropsWithChildren<{
|
||||
/**
|
||||
* A unique identifier for the modal. This is used to differentiate stacked modals,
|
||||
* when multiple stacked modals are registered to the same parent modal.
|
||||
*/
|
||||
id: string
|
||||
}>
|
||||
|
||||
/**
|
||||
* A stacked modal that can be rendered above a parent modal.
|
||||
*/
|
||||
export const Root = ({ id, children }: StackedDrawerProps) => {
|
||||
const { register, unregister, getIsOpen, setIsOpen } = useStackedModal()
|
||||
|
||||
useEffect(() => {
|
||||
register(id)
|
||||
|
||||
return () => unregister(id)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<Drawer open={getIsOpen(id)} onOpenChange={(open) => setIsOpen(id, open)}>
|
||||
{children}
|
||||
</Drawer>
|
||||
)
|
||||
}
|
||||
|
||||
const Close = Drawer.Close
|
||||
Close.displayName = "StackedDrawer.Close"
|
||||
|
||||
const Header = Drawer.Header
|
||||
Header.displayName = "StackedDrawer.Header"
|
||||
|
||||
const Body = Drawer.Body
|
||||
Body.displayName = "StackedDrawer.Body"
|
||||
|
||||
const Trigger = Drawer.Trigger
|
||||
Trigger.displayName = "StackedDrawer.Trigger"
|
||||
|
||||
const Footer = Drawer.Footer
|
||||
Footer.displayName = "StackedDrawer.Footer"
|
||||
|
||||
const Title = Drawer.Title
|
||||
Title.displayName = "StackedDrawer.Title"
|
||||
|
||||
const Description = Drawer.Description
|
||||
Description.displayName = "StackedDrawer.Description"
|
||||
|
||||
const Content = forwardRef<
|
||||
HTMLDivElement,
|
||||
ComponentPropsWithoutRef<typeof Drawer.Content>
|
||||
>(({ className, ...props }, ref) => {
|
||||
return (
|
||||
<Drawer.Content
|
||||
ref={ref}
|
||||
className={clx(className)}
|
||||
overlayProps={{
|
||||
className: "bg-transparent",
|
||||
}}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
})
|
||||
Content.displayName = "StackedDrawer.Content"
|
||||
|
||||
export const StackedDrawer = Object.assign(Root, {
|
||||
Close,
|
||||
Header,
|
||||
Body,
|
||||
Content,
|
||||
Trigger,
|
||||
Footer,
|
||||
Description,
|
||||
Title,
|
||||
})
|
||||
@@ -0,0 +1 @@
|
||||
export * from "./stacked-foucs-modal"
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
import { FocusModal, clx } from "@medusajs/ui"
|
||||
import {
|
||||
ComponentPropsWithoutRef,
|
||||
PropsWithChildren,
|
||||
forwardRef,
|
||||
useEffect,
|
||||
} from "react"
|
||||
import { useStackedModal } from "../stacked-modal-provider"
|
||||
|
||||
type StackedFocusModalProps = PropsWithChildren<{
|
||||
/**
|
||||
* A unique identifier for the modal. This is used to differentiate stacked modals,
|
||||
* when multiple stacked modals are registered to the same parent modal.
|
||||
*/
|
||||
id: string
|
||||
}>
|
||||
|
||||
/**
|
||||
* A stacked modal that can be rendered above a parent modal.
|
||||
*/
|
||||
export const Root = ({ id, children }: StackedFocusModalProps) => {
|
||||
const { register, unregister, getIsOpen, setIsOpen } = useStackedModal()
|
||||
|
||||
useEffect(() => {
|
||||
register(id)
|
||||
|
||||
return () => unregister(id)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<FocusModal
|
||||
open={getIsOpen(id)}
|
||||
onOpenChange={(open) => setIsOpen(id, open)}
|
||||
>
|
||||
{children}
|
||||
</FocusModal>
|
||||
)
|
||||
}
|
||||
|
||||
const Close = FocusModal.Close
|
||||
Close.displayName = "StackedFocusModal.Close"
|
||||
|
||||
const Header = FocusModal.Header
|
||||
Header.displayName = "StackedFocusModal.Header"
|
||||
|
||||
const Body = FocusModal.Body
|
||||
Body.displayName = "StackedFocusModal.Body"
|
||||
|
||||
const Trigger = FocusModal.Trigger
|
||||
Trigger.displayName = "StackedFocusModal.Trigger"
|
||||
|
||||
const Footer = FocusModal.Footer
|
||||
Footer.displayName = "StackedFocusModal.Footer"
|
||||
|
||||
const Title = FocusModal.Title
|
||||
Title.displayName = "StackedFocusModal.Title"
|
||||
|
||||
const Description = FocusModal.Description
|
||||
Description.displayName = "StackedFocusModal.Description"
|
||||
|
||||
const Content = forwardRef<
|
||||
HTMLDivElement,
|
||||
ComponentPropsWithoutRef<typeof FocusModal.Content>
|
||||
>(({ className, ...props }, ref) => {
|
||||
return (
|
||||
<FocusModal.Content
|
||||
ref={ref}
|
||||
className={clx("top-6", className)}
|
||||
overlayProps={{
|
||||
className: "bg-transparent",
|
||||
}}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
})
|
||||
Content.displayName = "StackedFocusModal.Content"
|
||||
|
||||
export const StackedFocusModal = Object.assign(Root, {
|
||||
Close,
|
||||
Header,
|
||||
Body,
|
||||
Content,
|
||||
Trigger,
|
||||
Footer,
|
||||
Description,
|
||||
Title,
|
||||
})
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from "./stacked-modal-provider"
|
||||
export * from "./use-stacked-modal"
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import { createContext } from "react"
|
||||
|
||||
type StackedModalState = {
|
||||
getIsOpen: (id: string) => boolean
|
||||
setIsOpen: (id: string, open: boolean) => void
|
||||
register: (id: string) => void
|
||||
unregister: (id: string) => void
|
||||
}
|
||||
|
||||
export const StackedModalContext = createContext<StackedModalState | null>(null)
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
import { PropsWithChildren, useState } from "react"
|
||||
import { StackedModalContext } from "./stacked-modal-context"
|
||||
|
||||
type StackedModalProviderProps = PropsWithChildren<{
|
||||
onOpenChange: (open: boolean) => void
|
||||
}>
|
||||
|
||||
export const StackedModalProvider = ({
|
||||
children,
|
||||
onOpenChange,
|
||||
}: StackedModalProviderProps) => {
|
||||
const [state, setState] = useState<Record<string, boolean>>({})
|
||||
|
||||
const getIsOpen = (id: string) => {
|
||||
return state[id] || false
|
||||
}
|
||||
|
||||
const setIsOpen = (id: string, open: boolean) => {
|
||||
setState((prevState) => ({
|
||||
...prevState,
|
||||
[id]: open,
|
||||
}))
|
||||
|
||||
onOpenChange(open)
|
||||
}
|
||||
|
||||
const register = (id: string) => {
|
||||
setState((prevState) => ({
|
||||
...prevState,
|
||||
[id]: false,
|
||||
}))
|
||||
}
|
||||
|
||||
const unregister = (id: string) => {
|
||||
setState((prevState) => {
|
||||
const newState = { ...prevState }
|
||||
delete newState[id]
|
||||
return newState
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<StackedModalContext.Provider
|
||||
value={{
|
||||
getIsOpen,
|
||||
setIsOpen,
|
||||
register,
|
||||
unregister,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</StackedModalContext.Provider>
|
||||
)
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
import { useContext } from "react"
|
||||
import { StackedModalContext } from "./stacked-modal-context"
|
||||
|
||||
export const useStackedModal = () => {
|
||||
const context = useContext(StackedModalContext)
|
||||
|
||||
if (!context) {
|
||||
throw new Error(
|
||||
"useStackedModal must be used within a StackedModalProvider"
|
||||
)
|
||||
}
|
||||
|
||||
return context
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
export { RouteDrawer } from "./route-drawer"
|
||||
export { RouteFocusModal } from "./route-focus-modal"
|
||||
export { useRouteModal } from "./route-modal-provider"
|
||||
@@ -1 +0,0 @@
|
||||
export * from "./route-form"
|
||||
@@ -1 +0,0 @@
|
||||
export * from "./route-provider"
|
||||
+1
@@ -46,6 +46,7 @@ export const DataTableSearch = ({
|
||||
|
||||
return (
|
||||
<Input
|
||||
autoComplete="off"
|
||||
name="q"
|
||||
type="search"
|
||||
size="small"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { HttpTypes, PaginatedResponse } from "@medusajs/types"
|
||||
import {
|
||||
QueryKey,
|
||||
UseMutationOptions,
|
||||
@@ -12,7 +13,6 @@ import { queryKeysFactory } from "../../lib/query-key-factory"
|
||||
import { CreateCustomerGroupSchema } from "../../routes/customer-groups/customer-group-create/components/create-customer-group-form"
|
||||
import { EditCustomerGroupSchema } from "../../routes/customer-groups/customer-group-edit/components/edit-customer-group-form"
|
||||
import { customersQueryKeys } from "./customers"
|
||||
import { HttpTypes, PaginatedResponse } from "@medusajs/types"
|
||||
|
||||
const CUSTOMER_GROUPS_QUERY_KEY = "customer_groups" as const
|
||||
export const customerGroupsQueryKeys = queryKeysFactory(
|
||||
@@ -45,9 +45,9 @@ export const useCustomerGroups = (
|
||||
query?: Record<string, any>,
|
||||
options?: Omit<
|
||||
UseQueryOptions<
|
||||
PaginatedResponse<HttpTypes.AdminCustomerGroup[]>,
|
||||
PaginatedResponse<{ customer_groups: HttpTypes.AdminCustomerGroup[] }>,
|
||||
Error,
|
||||
PaginatedResponse<HttpTypes.AdminCustomerGroup[]>,
|
||||
PaginatedResponse<{ customer_groups: HttpTypes.AdminCustomerGroup[] }>,
|
||||
QueryKey
|
||||
>,
|
||||
"queryFn" | "queryKey"
|
||||
|
||||
@@ -7,20 +7,10 @@ import {
|
||||
useMutation,
|
||||
useQuery,
|
||||
} from "@tanstack/react-query"
|
||||
import { client, sdk } from "../../lib/client"
|
||||
import { sdk } from "../../lib/client"
|
||||
import { queryClient } from "../../lib/query-client"
|
||||
import { queryKeysFactory } from "../../lib/query-key-factory"
|
||||
import {
|
||||
AddPriceListPricesReq,
|
||||
CreatePriceListReq,
|
||||
DeletePriceListPricesReq,
|
||||
UpdatePriceListReq,
|
||||
} from "../../types/api-payloads"
|
||||
import {
|
||||
PriceListDeleteRes,
|
||||
PriceListListRes,
|
||||
PriceListRes,
|
||||
} from "../../types/api-responses"
|
||||
import { customerGroupsQueryKeys } from "./customer-groups"
|
||||
import { productsQueryKeys } from "./products"
|
||||
|
||||
const PRICE_LISTS_QUERY_KEY = "price-lists" as const
|
||||
@@ -28,14 +18,19 @@ export const priceListsQueryKeys = queryKeysFactory(PRICE_LISTS_QUERY_KEY)
|
||||
|
||||
export const usePriceList = (
|
||||
id: string,
|
||||
query?: Record<string, any>,
|
||||
query?: HttpTypes.AdminPriceListListParams,
|
||||
options?: Omit<
|
||||
UseQueryOptions<PriceListRes, Error, PriceListRes, QueryKey>,
|
||||
UseQueryOptions<
|
||||
HttpTypes.AdminPriceListResponse,
|
||||
FetchError,
|
||||
HttpTypes.AdminPriceListResponse,
|
||||
QueryKey
|
||||
>,
|
||||
"queryKey" | "queryFn"
|
||||
>
|
||||
) => {
|
||||
const { data, ...rest } = useQuery({
|
||||
queryFn: () => client.priceLists.retrieve(id, query),
|
||||
queryFn: () => sdk.admin.priceList.retrieve(id, query),
|
||||
queryKey: priceListsQueryKeys.detail(id),
|
||||
...options,
|
||||
})
|
||||
@@ -44,14 +39,19 @@ export const usePriceList = (
|
||||
}
|
||||
|
||||
export const usePriceLists = (
|
||||
query?: Record<string, any>,
|
||||
query?: HttpTypes.AdminPriceListListParams,
|
||||
options?: Omit<
|
||||
UseQueryOptions<PriceListListRes, Error, PriceListListRes, QueryKey>,
|
||||
UseQueryOptions<
|
||||
HttpTypes.AdminPriceListListResponse,
|
||||
FetchError,
|
||||
HttpTypes.AdminPriceListListResponse,
|
||||
QueryKey
|
||||
>,
|
||||
"queryKey" | "queryFn"
|
||||
>
|
||||
) => {
|
||||
const { data, ...rest } = useQuery({
|
||||
queryFn: () => client.priceLists.list(query),
|
||||
queryFn: () => sdk.admin.priceList.list(query),
|
||||
queryKey: priceListsQueryKeys.list(query),
|
||||
...options,
|
||||
})
|
||||
@@ -60,13 +60,20 @@ export const usePriceLists = (
|
||||
}
|
||||
|
||||
export const useCreatePriceList = (
|
||||
options?: UseMutationOptions<PriceListRes, Error, CreatePriceListReq>
|
||||
query?: HttpTypes.AdminPriceListParams,
|
||||
options?: UseMutationOptions<
|
||||
HttpTypes.AdminPriceListResponse,
|
||||
FetchError,
|
||||
HttpTypes.AdminCreatePriceList
|
||||
>
|
||||
) => {
|
||||
return useMutation({
|
||||
mutationFn: (payload) => client.priceLists.create(payload),
|
||||
mutationFn: (payload) => sdk.admin.priceList.create(payload, query),
|
||||
onSuccess: (data, variables, context) => {
|
||||
queryClient.invalidateQueries({ queryKey: priceListsQueryKeys.list() })
|
||||
|
||||
queryClient.invalidateQueries({ queryKey: customerGroupsQueryKeys.all })
|
||||
|
||||
options?.onSuccess?.(data, variables, context)
|
||||
},
|
||||
...options,
|
||||
@@ -75,16 +82,23 @@ export const useCreatePriceList = (
|
||||
|
||||
export const useUpdatePriceList = (
|
||||
id: string,
|
||||
options?: UseMutationOptions<PriceListRes, Error, UpdatePriceListReq>
|
||||
query?: HttpTypes.AdminPriceListParams,
|
||||
options?: UseMutationOptions<
|
||||
HttpTypes.AdminPriceListResponse,
|
||||
FetchError,
|
||||
HttpTypes.AdminUpdatePriceList
|
||||
>
|
||||
) => {
|
||||
return useMutation({
|
||||
mutationFn: (payload) => client.priceLists.update(id, payload),
|
||||
mutationFn: (payload) => sdk.admin.priceList.update(id, payload, query),
|
||||
onSuccess: (data, variables, context) => {
|
||||
queryClient.invalidateQueries({ queryKey: priceListsQueryKeys.list() })
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: priceListsQueryKeys.detail(id),
|
||||
})
|
||||
|
||||
queryClient.invalidateQueries({ queryKey: customerGroupsQueryKeys.all })
|
||||
|
||||
options?.onSuccess?.(data, variables, context)
|
||||
},
|
||||
...options,
|
||||
@@ -93,10 +107,14 @@ export const useUpdatePriceList = (
|
||||
|
||||
export const useDeletePriceList = (
|
||||
id: string,
|
||||
options?: UseMutationOptions<PriceListDeleteRes, Error, void>
|
||||
options?: UseMutationOptions<
|
||||
HttpTypes.AdminPriceListDeleteResponse,
|
||||
FetchError,
|
||||
void
|
||||
>
|
||||
) => {
|
||||
return useMutation({
|
||||
mutationFn: () => client.priceLists.delete(id),
|
||||
mutationFn: () => sdk.admin.priceList.delete(id),
|
||||
onSuccess: (data, variables, context) => {
|
||||
queryClient.invalidateQueries({ queryKey: priceListsQueryKeys.list() })
|
||||
|
||||
@@ -106,17 +124,22 @@ export const useDeletePriceList = (
|
||||
})
|
||||
}
|
||||
|
||||
export const usePriceListAddPrices = (
|
||||
export const useBatchPriceListPrices = (
|
||||
id: string,
|
||||
options?: UseMutationOptions<PriceListRes, Error, AddPriceListPricesReq>
|
||||
query?: HttpTypes.AdminPriceListParams,
|
||||
options?: UseMutationOptions<
|
||||
HttpTypes.AdminPriceListResponse,
|
||||
FetchError,
|
||||
HttpTypes.AdminBatchPriceListPrice
|
||||
>
|
||||
) => {
|
||||
return useMutation({
|
||||
mutationFn: (payload) => client.priceLists.addPrices(id, payload),
|
||||
mutationFn: (payload) =>
|
||||
sdk.admin.priceList.batchPrices(id, payload, query),
|
||||
onSuccess: (data, variables, context) => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: priceListsQueryKeys.detail(id),
|
||||
})
|
||||
queryClient.invalidateQueries({ queryKey: priceListsQueryKeys.lists() })
|
||||
queryClient.invalidateQueries({ queryKey: productsQueryKeys.lists() })
|
||||
|
||||
options?.onSuccess?.(data, variables, context)
|
||||
@@ -125,24 +148,6 @@ export const usePriceListAddPrices = (
|
||||
})
|
||||
}
|
||||
|
||||
export const usePriceListRemovePrices = (
|
||||
id: string,
|
||||
options?: UseMutationOptions<PriceListRes, Error, DeletePriceListPricesReq>
|
||||
) => {
|
||||
return useMutation({
|
||||
mutationFn: (payload) => client.priceLists.removePrices(id, payload),
|
||||
onSuccess: (data, variables, context) => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: priceListsQueryKeys.detail(id),
|
||||
})
|
||||
queryClient.invalidateQueries({ queryKey: priceListsQueryKeys.lists() })
|
||||
|
||||
options?.onSuccess?.(data, variables, context)
|
||||
},
|
||||
...options,
|
||||
})
|
||||
}
|
||||
|
||||
export const usePriceListLinkProducts = (
|
||||
id: string,
|
||||
options?: UseMutationOptions<
|
||||
|
||||
@@ -6,23 +6,46 @@ import {
|
||||
useQuery,
|
||||
} from "@tanstack/react-query"
|
||||
|
||||
import { client } from "../../lib/client"
|
||||
import { FetchError } from "@medusajs/js-sdk"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import { sdk } from "../../lib/client"
|
||||
import { queryClient } from "../../lib/query-client"
|
||||
import { queryKeysFactory } from "../../lib/query-key-factory"
|
||||
import { UpdateStoreReq } from "../../types/api-payloads"
|
||||
import { StoreRes } from "../../types/api-responses"
|
||||
|
||||
const STORE_QUERY_KEY = "store" as const
|
||||
export const storeQueryKeys = queryKeysFactory(STORE_QUERY_KEY)
|
||||
|
||||
/**
|
||||
* Workaround to keep the V1 version of retrieving the store.
|
||||
*/
|
||||
async function retrieveActiveStore(
|
||||
query?: HttpTypes.AdminStoreParams
|
||||
): Promise<HttpTypes.AdminStoreResponse> {
|
||||
const response = await sdk.admin.store.list(query)
|
||||
|
||||
const activeStore = response.stores?.[0]
|
||||
|
||||
if (!activeStore) {
|
||||
throw new FetchError("No active store found", "Not Found", 404)
|
||||
}
|
||||
|
||||
return { store: activeStore }
|
||||
}
|
||||
|
||||
export const useStore = (
|
||||
query?: Record<string, any>,
|
||||
options?: Omit<
|
||||
UseQueryOptions<StoreRes, Error, StoreRes, QueryKey>,
|
||||
UseQueryOptions<
|
||||
HttpTypes.AdminStoreResponse,
|
||||
FetchError,
|
||||
HttpTypes.AdminStoreResponse,
|
||||
QueryKey
|
||||
>,
|
||||
"queryFn" | "queryKey"
|
||||
>
|
||||
) => {
|
||||
const { data, ...rest } = useQuery({
|
||||
queryFn: () => client.stores.retrieve(),
|
||||
queryFn: () => retrieveActiveStore(query),
|
||||
queryKey: storeQueryKeys.details(),
|
||||
...options,
|
||||
})
|
||||
@@ -35,10 +58,14 @@ export const useStore = (
|
||||
|
||||
export const useUpdateStore = (
|
||||
id: string,
|
||||
options?: MutationOptions<StoreRes, Error, UpdateStoreReq>
|
||||
options?: MutationOptions<
|
||||
HttpTypes.AdminStoreResponse,
|
||||
FetchError,
|
||||
HttpTypes.AdminUpdateStore
|
||||
>
|
||||
) => {
|
||||
return useMutation({
|
||||
mutationFn: (payload) => client.stores.update(id, payload),
|
||||
mutationFn: (payload) => sdk.admin.store.update(id, payload),
|
||||
onSuccess: (data, variables, context) => {
|
||||
queryClient.invalidateQueries({ queryKey: storeQueryKeys.details() })
|
||||
options?.onSuccess?.(data, variables, context)
|
||||
|
||||
@@ -86,8 +86,12 @@
|
||||
"apply": "Apply",
|
||||
"add": "Add",
|
||||
"select": "Select",
|
||||
"browse": "Browse",
|
||||
"logout": "Logout"
|
||||
},
|
||||
"operators": {
|
||||
"in": "In"
|
||||
},
|
||||
"app": {
|
||||
"search": {
|
||||
"allAreas": "All areas",
|
||||
@@ -1295,61 +1299,96 @@
|
||||
"deleteCampaignWarning": "You are about to delete the campaign {{name}}. This action cannot be undone.",
|
||||
"totalSpend": "<0>{{amount}}</0> <1>{{currency}}</1>"
|
||||
},
|
||||
"pricing": {
|
||||
"domain": "Pricing",
|
||||
"priceLists": {
|
||||
"domain": "Price Lists",
|
||||
"delete": {
|
||||
"confirmation": "You are about to delete the price list {{title}}. This action cannot be undone.",
|
||||
"successToast": "Price list {{title}} was successfully deleted."
|
||||
},
|
||||
"create": {
|
||||
"header": "Create Price List",
|
||||
"hint": "Create a new price list to manage the prices of your products."
|
||||
"subheader": "Create a new price list to manage the prices of your products.",
|
||||
"tabs": {
|
||||
"details": "Details",
|
||||
"products": "Products",
|
||||
"prices": "Prices"
|
||||
},
|
||||
"successToast": "Price list {{title}} was successfully created."
|
||||
},
|
||||
"edit": {
|
||||
"header": "Edit Price List"
|
||||
"header": "Edit Price List",
|
||||
"successToast": "Price list {{title}} was successfully updated."
|
||||
},
|
||||
"configuration": {
|
||||
"header": "Configuration",
|
||||
"editHeader": "Edit Price List Configuration"
|
||||
},
|
||||
"warnings": {
|
||||
"delete": "You are about to delete the price list {{name}}. This action cannot be undone."
|
||||
},
|
||||
"status": {
|
||||
"draft": "Draft",
|
||||
"expired": "Expired",
|
||||
"active": "Active",
|
||||
"scheduled": "Scheduled"
|
||||
},
|
||||
"type": {
|
||||
"sale": "Sale",
|
||||
"override": "Override"
|
||||
"edit": {
|
||||
"header": "Edit Price List Configuration",
|
||||
"description": "Edit the configuration of the price list.",
|
||||
"successToast": "Price list configuration was successfully updated."
|
||||
}
|
||||
},
|
||||
"products": {
|
||||
"deleteProductsPricesWarning": "You are about to delete all prices of {{count}} product(s). This action cannot be undone."
|
||||
},
|
||||
"prices": {
|
||||
"addPrices": "Add prices",
|
||||
"editPrices": "Edit prices"
|
||||
},
|
||||
"table": {
|
||||
"pricesHeader": "Prices"
|
||||
"header": "Products",
|
||||
"actions": {
|
||||
"addProducts": "Add products",
|
||||
"editPrices": "Edit prices"
|
||||
},
|
||||
"delete": {
|
||||
"confirmation_one": "You are about to delete the prices for {{count}} product in the price list. This action cannot be undone.",
|
||||
"confirmation_other": "You are about to delete the prices for {{count}} products in the price list. This action cannot be undone.",
|
||||
"successToast_one": "Successfully deleted prices for {{count}} product.",
|
||||
"successToast_other": "Successfully deleted prices for {{count}} products."
|
||||
},
|
||||
"add": {
|
||||
"successToast": "Prices were successfully added to the price list."
|
||||
},
|
||||
"edit": {
|
||||
"successToast": "Prices were successfully updated."
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"statusTooltip": "Status can also be expired or scheduled depending on the start and end date.",
|
||||
"typeHint": "Choose the type of price you want to create.",
|
||||
"statusHint": "Choose if price should be published to users",
|
||||
"draftTypeHint": "Prices will not be visible to users in a draft state",
|
||||
"activeTypeHint": "Prices are visibile to users in an active state",
|
||||
"saleTypeHint": "Sale prices are temporary price changes for products.",
|
||||
"overrideTypeHint": "Overrides are usually used to create customer-specific prices.",
|
||||
"startDateLabel": "Price list has a start date?",
|
||||
"startDateHint": "Schedule the price list to activate in the future.",
|
||||
"endDateLabel": "Price list has an expiry date?",
|
||||
"endDateHint": "Schedule the price list to deactivate in the future.",
|
||||
"customerAvailabilityLabel": "Customer availability",
|
||||
"customerAvailabilityHint": "Choose which customer groups the price list should be applied to.",
|
||||
"customerAvailabilityNoSelectionLabel": "No customer groups selected",
|
||||
"priceOverridesLabel": "Price overrides"
|
||||
},
|
||||
"actions": {
|
||||
"addCustomerGroups": "Add customer groups"
|
||||
"priceOverrides": {
|
||||
"label": "Price overrides",
|
||||
"header": "Price Overrides"
|
||||
},
|
||||
"status": {
|
||||
"label": "Status",
|
||||
"options": {
|
||||
"active": "Active",
|
||||
"draft": "Draft",
|
||||
"expired": "Expired",
|
||||
"scheduled": "Scheduled"
|
||||
}
|
||||
},
|
||||
"type": {
|
||||
"label": "Type",
|
||||
"hint": "Choose the type of price list you want to create.",
|
||||
"options": {
|
||||
"sale": {
|
||||
"label": "Sale",
|
||||
"description": "Sale prices are temporary price changes for products."
|
||||
},
|
||||
"override": {
|
||||
"label": "Override",
|
||||
"description": "Overrides are usually used to create customer-specific prices."
|
||||
}
|
||||
}
|
||||
},
|
||||
"startsAt": {
|
||||
"label": "Price list has a start date?",
|
||||
"hint": "Schedule the price list to activate in the future."
|
||||
},
|
||||
"endsAt": {
|
||||
"label": "Price list has an expiry date?",
|
||||
"hint": "Schedule the price list to deactivate in the future."
|
||||
},
|
||||
"customerAvailability": {
|
||||
"header": "Choose customer groups",
|
||||
"label": "Customer availability",
|
||||
"hint": "Choose which customer groups the price list should be applied to.",
|
||||
"placeholder": "Search for customer groups",
|
||||
"attribute": "Customer groups"
|
||||
}
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
|
||||
@@ -171,7 +171,7 @@ export const useGlobalShortcuts = () => {
|
||||
},
|
||||
label: t("app.keyboardShortcuts.goToPriceLists"),
|
||||
type: "pageShortcut",
|
||||
callback: () => navigate("/pricing"),
|
||||
callback: () => navigate("/price-lists"),
|
||||
},
|
||||
{
|
||||
keys: {
|
||||
|
||||
@@ -332,45 +332,51 @@ export const RouteMap: RouteObject[] = [
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/pricing",
|
||||
path: "/price-lists",
|
||||
handle: {
|
||||
crumb: () => "Pricing",
|
||||
crumb: () => "Price Lists",
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
lazy: () => import("../../routes/pricing/pricing-list"),
|
||||
lazy: () => import("../../routes/price-lists/price-list-list"),
|
||||
children: [
|
||||
{
|
||||
path: "create",
|
||||
lazy: () => import("../../routes/pricing/pricing-create"),
|
||||
lazy: () =>
|
||||
import("../../routes/price-lists/price-list-create"),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: ":id",
|
||||
lazy: () => import("../../routes/pricing/pricing-detail"),
|
||||
lazy: () =>
|
||||
import("../../routes/price-lists/price-list-detail"),
|
||||
handle: {
|
||||
crumb: (data: PriceListRes) => data.price_list.title,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "edit",
|
||||
lazy: () => import("../../routes/pricing/pricing-edit"),
|
||||
lazy: () =>
|
||||
import("../../routes/price-lists/price-list-edit"),
|
||||
},
|
||||
{
|
||||
path: "configuration",
|
||||
lazy: () =>
|
||||
import("../../routes/pricing/pricing-configuration"),
|
||||
import(
|
||||
"../../routes/price-lists/price-list-configuration"
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "products/add",
|
||||
lazy: () => import("../../routes/pricing/pricing-products"),
|
||||
lazy: () =>
|
||||
import("../../routes/price-lists/price-list-prices-add"),
|
||||
},
|
||||
{
|
||||
path: "products/edit",
|
||||
lazy: () =>
|
||||
import("../../routes/pricing/pricing-products-prices"),
|
||||
import("../../routes/price-lists/price-list-prices-edit"),
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -780,7 +786,8 @@ export const RouteMap: RouteObject[] = [
|
||||
{
|
||||
path: ":id",
|
||||
handle: {
|
||||
crumb: (data) => data.shipping_profile.name,
|
||||
crumb: (data: HttpTypes.AdminShippingProfileResponse) =>
|
||||
data.shipping_profile.name,
|
||||
},
|
||||
lazy: () =>
|
||||
import(
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export type { Theme } from "./theme-context";
|
||||
export * from "./theme-provider";
|
||||
export * from "./use-theme";
|
||||
export type { Theme } from "./theme-context"
|
||||
export * from "./theme-provider"
|
||||
export * from "./use-theme"
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
import { PropsWithChildren, useEffect, useState } from "react";
|
||||
import { Theme, ThemeContext } from "./theme-context";
|
||||
import { PropsWithChildren, useEffect, useState } from "react"
|
||||
import { Theme, ThemeContext } from "./theme-context"
|
||||
|
||||
const THEME_KEY = "medusa_admin_theme";
|
||||
const THEME_KEY = "medusa_admin_theme"
|
||||
|
||||
export const ThemeProvider = ({ children }: PropsWithChildren) => {
|
||||
const [state, setState] = useState<Theme>(
|
||||
(localStorage?.getItem(THEME_KEY) as Theme) || "light"
|
||||
);
|
||||
)
|
||||
|
||||
const setTheme = (theme: Theme) => {
|
||||
localStorage.setItem(THEME_KEY, theme);
|
||||
setState(theme);
|
||||
};
|
||||
localStorage.setItem(THEME_KEY, theme)
|
||||
setState(theme)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const html = document.querySelector("html");
|
||||
const html = document.querySelector("html")
|
||||
if (html) {
|
||||
/**
|
||||
* Temporarily disable transitions to prevent
|
||||
* the theme change from flashing.
|
||||
*/
|
||||
const css = document.createElement("style");
|
||||
const css = document.createElement("style")
|
||||
css.appendChild(
|
||||
document.createTextNode(
|
||||
`* {
|
||||
@@ -31,24 +31,24 @@ export const ThemeProvider = ({ children }: PropsWithChildren) => {
|
||||
transition: none !important;
|
||||
}`
|
||||
)
|
||||
);
|
||||
document.head.appendChild(css);
|
||||
)
|
||||
document.head.appendChild(css)
|
||||
|
||||
html.classList.remove(state === "light" ? "dark" : "light");
|
||||
html.classList.add(state);
|
||||
html.classList.remove(state === "light" ? "dark" : "light")
|
||||
html.classList.add(state)
|
||||
|
||||
/**
|
||||
* Re-enable transitions after the theme has been set,
|
||||
* and force the browser to repaint.
|
||||
*/
|
||||
window.getComputedStyle(css).opacity;
|
||||
document.head.removeChild(css);
|
||||
window.getComputedStyle(css).opacity
|
||||
document.head.removeChild(css)
|
||||
}
|
||||
}, [state]);
|
||||
}, [state])
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={{ theme: state, setTheme }}>
|
||||
{children}
|
||||
</ThemeContext.Provider>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { useContext } from "react";
|
||||
import { ThemeContext } from "./theme-context";
|
||||
import { useContext } from "react"
|
||||
import { ThemeContext } from "./theme-context"
|
||||
|
||||
export const useTheme = () => {
|
||||
const context = useContext(ThemeContext);
|
||||
const context = useContext(ThemeContext)
|
||||
if (!context) {
|
||||
throw new Error("useTheme must be used within a ThemeProvider");
|
||||
throw new Error("useTheme must be used within a ThemeProvider")
|
||||
}
|
||||
return context;
|
||||
};
|
||||
return context
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { useLocation } from "react-router-dom"
|
||||
import { RouteFocusModal } from "../../../components/route-modal"
|
||||
import { RouteFocusModal } from "../../../components/modals"
|
||||
import { getApiKeyTypeFromPathname } from "../common/utils"
|
||||
import { ApiKeyCreateForm } from "./components/api-key-create-form"
|
||||
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ import { Form } from "../../../../../components/common/form"
|
||||
import {
|
||||
RouteFocusModal,
|
||||
useRouteModal,
|
||||
} from "../../../../../components/route-modal"
|
||||
} from "../../../../../components/modals"
|
||||
import { useCreateApiKey } from "../../../../../hooks/api/api-keys"
|
||||
import { ApiKeyType } from "../../../common/constants"
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import { Heading } from "@medusajs/ui"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { useParams } from "react-router-dom"
|
||||
import { RouteDrawer } from "../../../components/route-modal"
|
||||
import { RouteDrawer } from "../../../components/modals"
|
||||
import { useApiKey } from "../../../hooks/api/api-keys"
|
||||
import { EditApiKeyForm } from "./components/edit-api-key-form"
|
||||
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ import { Form } from "../../../../../components/common/form"
|
||||
import {
|
||||
RouteDrawer,
|
||||
useRouteModal,
|
||||
} from "../../../../../components/route-modal"
|
||||
} from "../../../../../components/modals"
|
||||
import { useUpdateApiKey } from "../../../../../hooks/api/api-keys"
|
||||
|
||||
type EditApiKeyFormProps = {
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import { useParams } from "react-router-dom"
|
||||
|
||||
import { AdminApiKeyResponse, AdminSalesChannelResponse } from "@medusajs/types"
|
||||
import { RouteFocusModal } from "../../../components/route-modal"
|
||||
import { RouteFocusModal } from "../../../components/modals"
|
||||
import { useApiKey } from "../../../hooks/api/api-keys"
|
||||
import { ApiKeySalesChannelsForm } from "./components/api-key-sales-channels-form"
|
||||
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ import * as zod from "zod"
|
||||
import {
|
||||
RouteFocusModal,
|
||||
useRouteModal,
|
||||
} from "../../../../../components/route-modal"
|
||||
} from "../../../../../components/modals"
|
||||
import { DataTable } from "../../../../../components/table/data-table"
|
||||
import { useBatchAddSalesChannelsToApiKey } from "../../../../../hooks/api/api-keys"
|
||||
import { useSalesChannels } from "../../../../../hooks/api/sales-channels"
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { useParams } from "react-router-dom"
|
||||
import { RouteFocusModal } from "../../../components/route-modal"
|
||||
import { RouteFocusModal } from "../../../components/modals"
|
||||
import { useCampaign } from "../../../hooks/api/campaigns"
|
||||
import { AddCampaignPromotionsForm } from "./components"
|
||||
|
||||
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { CampaignResponse, PromotionDTO } from "@medusajs/types"
|
||||
import { Button, Checkbox, Hint, toast, Tooltip } from "@medusajs/ui"
|
||||
import { Button, Checkbox, Hint, Tooltip, toast } from "@medusajs/ui"
|
||||
import { keepPreviousData } from "@tanstack/react-query"
|
||||
import {
|
||||
createColumnHelper,
|
||||
OnChangeFn,
|
||||
RowSelectionState,
|
||||
createColumnHelper,
|
||||
} from "@tanstack/react-table"
|
||||
import { useMemo, useState } from "react"
|
||||
import { useForm } from "react-hook-form"
|
||||
@@ -14,7 +14,7 @@ import * as zod from "zod"
|
||||
import {
|
||||
RouteFocusModal,
|
||||
useRouteModal,
|
||||
} from "../../../../components/route-modal"
|
||||
} from "../../../../components/modals"
|
||||
import { DataTable } from "../../../../components/table/data-table"
|
||||
import { useAddOrRemoveCampaignPromotions } from "../../../../hooks/api/campaigns"
|
||||
import { usePromotions } from "../../../../hooks/api/promotions"
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import { Heading } from "@medusajs/ui"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { useParams } from "react-router-dom"
|
||||
import { RouteDrawer } from "../../../components/route-modal"
|
||||
import { RouteDrawer } from "../../../components/modals"
|
||||
import { useCampaign } from "../../../hooks/api/campaigns"
|
||||
import { EditCampaignBudgetForm } from "./components/edit-campaign-budget-form"
|
||||
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ import { Form } from "../../../../../components/common/form"
|
||||
import {
|
||||
RouteDrawer,
|
||||
useRouteModal,
|
||||
} from "../../../../../components/route-modal"
|
||||
} from "../../../../../components/modals"
|
||||
import { useUpdateCampaign } from "../../../../../hooks/api/campaigns"
|
||||
import { getCurrencySymbol } from "../../../../../lib/currencies"
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { RouteFocusModal } from "../../../components/route-modal"
|
||||
import { RouteFocusModal } from "../../../components/modals"
|
||||
import { CreateCampaignForm } from "./components/create-campaign-form"
|
||||
|
||||
export const CampaignCreate = () => {
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ import { CampaignBudgetTypeValues } from "@medusajs/types"
|
||||
import {
|
||||
RouteFocusModal,
|
||||
useRouteModal,
|
||||
} from "../../../../../components/route-modal"
|
||||
} from "../../../../../components/modals"
|
||||
import { useCreateCampaign } from "../../../../../hooks/api/campaigns"
|
||||
import { CreateCampaignFormFields } from "../../../common/components/create-campaign-form-fields"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Heading } from "@medusajs/ui"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { useParams } from "react-router-dom"
|
||||
import { RouteDrawer } from "../../../components/route-modal"
|
||||
import { RouteDrawer } from "../../../components/modals"
|
||||
import { useCampaign } from "../../../hooks/api/campaigns"
|
||||
import { EditCampaignForm } from "./components/edit-campaign-form"
|
||||
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ import { Form } from "../../../../../components/common/form"
|
||||
import {
|
||||
RouteDrawer,
|
||||
useRouteModal,
|
||||
} from "../../../../../components/route-modal"
|
||||
} from "../../../../../components/modals"
|
||||
import { useUpdateCampaign } from "../../../../../hooks/api/campaigns"
|
||||
|
||||
type EditCampaignFormProps = {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { useSearchParams } from "react-router-dom"
|
||||
|
||||
import { RouteFocusModal } from "../../../components/route-modal"
|
||||
import { RouteFocusModal } from "../../../components/modals"
|
||||
import { CreateCategoryForm } from "./components/create-category-form/create-category-form"
|
||||
|
||||
export const CategoryCreate = () => {
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import { useState } from "react"
|
||||
import {
|
||||
RouteFocusModal,
|
||||
useRouteModal,
|
||||
} from "../../../../../components/route-modal"
|
||||
} from "../../../../../components/modals"
|
||||
import { useCreateProductCategory } from "../../../../../hooks/api/categories"
|
||||
import { CreateCategoryDetails } from "./create-category-details"
|
||||
import { CreateCategoryNesting } from "./create-category-nesting"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Heading } from "@medusajs/ui"
|
||||
|
||||
import { useParams } from "react-router-dom"
|
||||
import { RouteDrawer } from "../../../components/route-modal"
|
||||
import { RouteDrawer } from "../../../components/modals"
|
||||
import { useProductCategory } from "../../../hooks/api/categories"
|
||||
import { EditCategoryForm } from "./components/edit-category-form"
|
||||
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import { z } from "zod"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import { Form } from "../../../../../components/common/form"
|
||||
import { HandleInput } from "../../../../../components/inputs/handle-input"
|
||||
import { RouteDrawer } from "../../../../../components/route-modal"
|
||||
import { RouteDrawer } from "../../../../../components/modals"
|
||||
|
||||
const EditCategorySchema = z.object({
|
||||
name: z.string().min(1),
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { RouteFocusModal } from "../../../components/route-modal"
|
||||
import { RouteFocusModal } from "../../../components/modals"
|
||||
import { OrganizeCategoryForm } from "./components/organize-category-form/organize-category-form"
|
||||
|
||||
export const CategoryOrganize = () => {
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ import { FetchError } from "@medusajs/js-sdk"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import { toast } from "@medusajs/ui"
|
||||
import { t } from "i18next"
|
||||
import { RouteFocusModal } from "../../../../../components/route-modal"
|
||||
import { RouteFocusModal } from "../../../../../components/modals"
|
||||
import {
|
||||
categoriesQueryKeys,
|
||||
useProductCategories,
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { useParams } from "react-router-dom"
|
||||
import { RouteFocusModal } from "../../../components/route-modal"
|
||||
import { RouteFocusModal } from "../../../components/modals"
|
||||
import { useProductCategory } from "../../../hooks/api/categories"
|
||||
import { EditCategoryProductsForm } from "./components/edit-category-products-form"
|
||||
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ import { useTranslation } from "react-i18next"
|
||||
import {
|
||||
RouteFocusModal,
|
||||
useRouteModal,
|
||||
} from "../../../../../components/route-modal"
|
||||
} from "../../../../../components/modals"
|
||||
import { DataTable } from "../../../../../components/table/data-table"
|
||||
import { useUpdateProductCategoryProducts } from "../../../../../hooks/api/categories"
|
||||
import { useProducts } from "../../../../../hooks/api/products"
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { useParams } from "react-router-dom"
|
||||
|
||||
import { RouteFocusModal } from "../../../components/route-modal"
|
||||
import { RouteFocusModal } from "../../../components/modals"
|
||||
import { useCollection } from "../../../hooks/api/collections"
|
||||
import { AddProductsToCollectionForm } from "./components/add-products-to-collection-form"
|
||||
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ import * as zod from "zod"
|
||||
import {
|
||||
RouteFocusModal,
|
||||
useRouteModal,
|
||||
} from "../../../../../components/route-modal/index.ts"
|
||||
} from "../../../../../components/modals/index.ts"
|
||||
import { DataTable } from "../../../../../components/table/data-table/data-table.tsx"
|
||||
import { useUpdateCollectionProducts } from "../../../../../hooks/api/collections.tsx"
|
||||
import { useProducts } from "../../../../../hooks/api/products.tsx"
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { RouteFocusModal } from "../../../components/route-modal"
|
||||
import { RouteFocusModal } from "../../../components/modals"
|
||||
import { CreateCollectionForm } from "./components/create-collection-form"
|
||||
|
||||
export const CollectionCreate = () => {
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ import { HandleInput } from "../../../../../components/inputs/handle-input"
|
||||
import {
|
||||
RouteFocusModal,
|
||||
useRouteModal,
|
||||
} from "../../../../../components/route-modal"
|
||||
} from "../../../../../components/modals"
|
||||
import { useCreateCollection } from "../../../../../hooks/api/collections"
|
||||
|
||||
const CreateCollectionSchema = zod.object({
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import { Heading } from "@medusajs/ui"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { useParams } from "react-router-dom"
|
||||
import { RouteDrawer } from "../../../components/route-modal"
|
||||
import { RouteDrawer } from "../../../components/modals"
|
||||
import { useCollection } from "../../../hooks/api/collections"
|
||||
import { EditCollectionForm } from "./components/edit-collection-form"
|
||||
|
||||
|
||||
+2
-2
@@ -4,13 +4,13 @@ import { useForm } from "react-hook-form"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import * as zod from "zod"
|
||||
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import { Form } from "../../../../../components/common/form"
|
||||
import {
|
||||
RouteDrawer,
|
||||
useRouteModal,
|
||||
} from "../../../../../components/route-modal"
|
||||
} from "../../../../../components/modals"
|
||||
import { useUpdateCollection } from "../../../../../hooks/api/collections"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
type EditCollectionFormProps = {
|
||||
collection: HttpTypes.AdminCollection
|
||||
|
||||
+2
-2
@@ -10,10 +10,11 @@ import { useForm } from "react-hook-form"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import * as zod from "zod"
|
||||
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import {
|
||||
RouteFocusModal,
|
||||
useRouteModal,
|
||||
} from "../../../../../components/route-modal"
|
||||
} from "../../../../../components/modals"
|
||||
import { DataTable } from "../../../../../components/table/data-table"
|
||||
import { useAddCustomersToGroup } from "../../../../../hooks/api/customer-groups"
|
||||
import { useCustomers } from "../../../../../hooks/api/customers"
|
||||
@@ -21,7 +22,6 @@ import { useCustomerTableColumns } from "../../../../../hooks/table/columns/use-
|
||||
import { useCustomerTableFilters } from "../../../../../hooks/table/filters/use-customer-table-filters"
|
||||
import { useCustomerTableQuery } from "../../../../../hooks/table/query/use-customer-table-query"
|
||||
import { useDataTable } from "../../../../../hooks/use-data-table"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
type AddCustomersFormProps = {
|
||||
customerGroupId: string
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { useParams } from "react-router-dom"
|
||||
import { RouteFocusModal } from "../../../components/route-modal"
|
||||
import { RouteFocusModal } from "../../../components/modals"
|
||||
import { AddCustomersForm } from "./components/add-customers-form"
|
||||
|
||||
export const CustomerGroupAddCustomers = () => {
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ import { Form } from "../../../../../components/common/form"
|
||||
import {
|
||||
RouteFocusModal,
|
||||
useRouteModal,
|
||||
} from "../../../../../components/route-modal"
|
||||
} from "../../../../../components/modals"
|
||||
import { useCreateCustomerGroup } from "../../../../../hooks/api/customer-groups"
|
||||
|
||||
export const CreateCustomerGroupSchema = zod.object({
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { RouteFocusModal } from "../../../components/route-modal"
|
||||
import { RouteFocusModal } from "../../../components/modals"
|
||||
import { CreateCustomerGroupForm } from "./components/create-customer-group-form"
|
||||
|
||||
export const CustomerGroupCreate = () => {
|
||||
|
||||
+2
-2
@@ -1,4 +1,5 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import { Button, Input, toast } from "@medusajs/ui"
|
||||
import { useForm } from "react-hook-form"
|
||||
import { useTranslation } from "react-i18next"
|
||||
@@ -7,9 +8,8 @@ import { Form } from "../../../../../components/common/form"
|
||||
import {
|
||||
RouteDrawer,
|
||||
useRouteModal,
|
||||
} from "../../../../../components/route-modal"
|
||||
} from "../../../../../components/modals"
|
||||
import { useUpdateCustomerGroup } from "../../../../../hooks/api/customer-groups"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
type EditCustomerGroupFormProps = {
|
||||
group: HttpTypes.AdminCustomerGroup
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import { Heading } from "@medusajs/ui"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { useParams } from "react-router-dom"
|
||||
import { RouteDrawer } from "../../../components/route-modal"
|
||||
import { RouteDrawer } from "../../../components/modals"
|
||||
import { useCustomerGroup } from "../../../hooks/api/customer-groups"
|
||||
import { EditCustomerGroupForm } from "./components/edit-customer-group-form"
|
||||
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ import { Form } from "../../../../../components/common/form"
|
||||
import {
|
||||
RouteFocusModal,
|
||||
useRouteModal,
|
||||
} from "../../../../../components/route-modal"
|
||||
} from "../../../../../components/modals"
|
||||
import { useCreateCustomer } from "../../../../../hooks/api/customers"
|
||||
|
||||
const CreateCustomerSchema = zod.object({
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { RouteFocusModal } from "../../../components/route-modal"
|
||||
import { RouteFocusModal } from "../../../components/modals"
|
||||
import { CreateCustomerForm } from "./components/create-customer-form"
|
||||
|
||||
export const CustomerCreate = () => {
|
||||
|
||||
+2
-2
@@ -1,4 +1,5 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import { Button, Input, toast } from "@medusajs/ui"
|
||||
import { useForm } from "react-hook-form"
|
||||
import { useTranslation } from "react-i18next"
|
||||
@@ -9,14 +10,13 @@ import { Metadata } from "../../../../../components/forms/metadata/index.ts"
|
||||
import {
|
||||
RouteDrawer,
|
||||
useRouteModal,
|
||||
} from "../../../../../components/route-modal/index.ts"
|
||||
} from "../../../../../components/modals/index.ts"
|
||||
import { useUpdateCustomer } from "../../../../../hooks/api/customers.tsx"
|
||||
import {
|
||||
formValuesToMetadata,
|
||||
metadataToFormValues,
|
||||
} from "../../../../../lib/metadata.ts"
|
||||
import { metadataFormSchema } from "../../../../../lib/validation.ts"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
type EditCustomerFormProps = {
|
||||
customer: HttpTypes.AdminCustomer
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Heading } from "@medusajs/ui"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { useParams } from "react-router-dom"
|
||||
import { RouteDrawer } from "../../../components/route-modal"
|
||||
import { RouteDrawer } from "../../../components/modals"
|
||||
import { useCustomer } from "../../../hooks/api/customers"
|
||||
import { EditCustomerForm } from "./components/edit-customer-form"
|
||||
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ import { TransferOwnerShipForm } from "../../../../../components/forms/transfer-
|
||||
import {
|
||||
RouteDrawer,
|
||||
useRouteModal,
|
||||
} from "../../../../../components/route-modal"
|
||||
} from "../../../../../components/modals"
|
||||
import { TransferOwnershipSchema } from "../../../../../lib/schemas"
|
||||
|
||||
type TransferCustomerOrderOwnershipFormProps = {
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ import { Heading } from "@medusajs/ui"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { useParams } from "react-router-dom"
|
||||
|
||||
import { RouteDrawer } from "../../../components/route-modal"
|
||||
import { RouteDrawer } from "../../../components/modals"
|
||||
import { useOrder } from "../../../hooks/api/orders"
|
||||
import { TransferCustomerOrderOwnershipForm } from "./components/transfer-customer-order-ownership-form"
|
||||
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ import * as zod from "zod"
|
||||
import {
|
||||
RouteFocusModal,
|
||||
useRouteModal,
|
||||
} from "../../../../../components/route-modal"
|
||||
} from "../../../../../components/modals"
|
||||
import { DataTable } from "../../../../../components/table/data-table"
|
||||
import {
|
||||
customerGroupsQueryKeys,
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { useParams } from "react-router-dom"
|
||||
import { RouteFocusModal } from "../../../components/route-modal"
|
||||
import { RouteFocusModal } from "../../../components/modals"
|
||||
import { AddCustomerGroupsForm } from "./components/add-customers-form"
|
||||
|
||||
export const CustomerAddCustomerGroups = () => {
|
||||
|
||||
+8
-8
@@ -6,30 +6,30 @@ import * as zod from "zod"
|
||||
import {
|
||||
Button,
|
||||
Heading,
|
||||
Input,
|
||||
ProgressStatus,
|
||||
ProgressTabs,
|
||||
clx,
|
||||
Input,
|
||||
Textarea,
|
||||
Switch,
|
||||
Textarea,
|
||||
clx,
|
||||
toast,
|
||||
} from "@medusajs/ui"
|
||||
import { useTranslation } from "react-i18next"
|
||||
|
||||
import { Form } from "../../../../../components/common/form"
|
||||
import { CountrySelect } from "../../../../../components/inputs/country-select"
|
||||
import {
|
||||
RouteFocusModal,
|
||||
useRouteModal,
|
||||
} from "../../../../../components/route-modal"
|
||||
import { CreateInventoryAvailabilityForm } from "./create-inventory-availability-form"
|
||||
import { CountrySelect } from "../../../../../components/inputs/country-select"
|
||||
import { Form } from "../../../../../components/common/form"
|
||||
} from "../../../../../components/modals"
|
||||
import {
|
||||
inventoryItemsQueryKeys,
|
||||
useCreateInventoryItem,
|
||||
} from "../../../../../hooks/api/inventory"
|
||||
import { sdk } from "../../../../../lib/client"
|
||||
import { optionalInt } from "../../../../../lib/validation"
|
||||
import { queryClient } from "../../../../../lib/query-client"
|
||||
import { optionalInt } from "../../../../../lib/validation"
|
||||
import { CreateInventoryAvailabilityForm } from "./create-inventory-availability-form"
|
||||
|
||||
enum Tab {
|
||||
DETAILS = "details",
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { RouteFocusModal } from "../../../components/route-modal"
|
||||
import { RouteFocusModal } from "../../../components/modals"
|
||||
import { CreateInventoryItemForm } from "./components/create-inventory-item-form"
|
||||
|
||||
export function InventoryCreate() {
|
||||
|
||||
+6
-6
@@ -1,11 +1,11 @@
|
||||
import { AdjustInventoryForm } from "./components/adjust-inventory-form"
|
||||
import { Heading } from "@medusajs/ui"
|
||||
import { InventoryTypes } from "@medusajs/types"
|
||||
import { RouteDrawer } from "../../../../../components/route-modal"
|
||||
import { useInventoryItem } from "../../../../../hooks/api/inventory"
|
||||
import { useParams } from "react-router-dom"
|
||||
import { useStockLocation } from "../../../../../hooks/api/stock-locations"
|
||||
import { Heading } from "@medusajs/ui"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { useParams } from "react-router-dom"
|
||||
import { RouteDrawer } from "../../../../../components/modals"
|
||||
import { useInventoryItem } from "../../../../../hooks/api/inventory"
|
||||
import { useStockLocation } from "../../../../../hooks/api/stock-locations"
|
||||
import { AdjustInventoryForm } from "./components/adjust-inventory-form"
|
||||
|
||||
export const AdjustInventoryDrawer = () => {
|
||||
const { id, location_id } = useParams()
|
||||
|
||||
+4
-4
@@ -1,16 +1,16 @@
|
||||
import * as zod from "zod"
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import * as zod from "zod"
|
||||
|
||||
import { HttpTypes, InventoryLevelDTO, StockLocationDTO } from "@medusajs/types"
|
||||
import { Button, Input, Text, toast } from "@medusajs/ui"
|
||||
import { InventoryLevelDTO, StockLocationDTO, HttpTypes } from "@medusajs/types"
|
||||
import {
|
||||
RouteDrawer,
|
||||
useRouteModal,
|
||||
} from "../../../../../../components/route-modal"
|
||||
} from "../../../../../../components/modals"
|
||||
|
||||
import { Form } from "../../../../../../components/common/form"
|
||||
import { useForm } from "react-hook-form"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { Form } from "../../../../../../components/common/form"
|
||||
import { useUpdateInventoryLevel } from "../../../../../../hooks/api/inventory"
|
||||
|
||||
type AdjustInventoryFormProps = {
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ import { Button, Input, toast } from "@medusajs/ui"
|
||||
import {
|
||||
RouteDrawer,
|
||||
useRouteModal,
|
||||
} from "../../../../../../components/route-modal"
|
||||
} from "../../../../../../components/modals"
|
||||
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { InventoryTypes } from "@medusajs/types"
|
||||
|
||||
+4
-4
@@ -1,9 +1,9 @@
|
||||
import { EditInventoryItemAttributesForm } from "./components/edit-item-attributes-form"
|
||||
import { Heading } from "@medusajs/ui"
|
||||
import { RouteDrawer } from "../../../../../components/route-modal"
|
||||
import { useInventoryItem } from "../../../../../hooks/api/inventory"
|
||||
import { useParams } from "react-router-dom"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { useParams } from "react-router-dom"
|
||||
import { RouteDrawer } from "../../../../../components/modals"
|
||||
import { useInventoryItem } from "../../../../../hooks/api/inventory"
|
||||
import { EditInventoryItemAttributesForm } from "./components/edit-item-attributes-form"
|
||||
|
||||
export const InventoryItemAttributesEdit = () => {
|
||||
const { id } = useParams()
|
||||
|
||||
+4
-4
@@ -4,15 +4,15 @@ import { Button, Input, toast } from "@medusajs/ui"
|
||||
import {
|
||||
RouteDrawer,
|
||||
useRouteModal,
|
||||
} from "../../../../../../components/route-modal"
|
||||
} from "../../../../../../components/modals"
|
||||
|
||||
import { Form } from "../../../../../../components/common/form"
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { InventoryTypes } from "@medusajs/types"
|
||||
import { useForm } from "react-hook-form"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { useUpdateInventoryItem } from "../../../../../../hooks/api/inventory"
|
||||
import { z } from "zod"
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { Form } from "../../../../../../components/common/form"
|
||||
import { useUpdateInventoryItem } from "../../../../../../hooks/api/inventory"
|
||||
|
||||
type EditInventoryItemFormProps = {
|
||||
item: InventoryTypes.InventoryItemDTO
|
||||
|
||||
+4
-4
@@ -1,9 +1,9 @@
|
||||
import { EditInventoryItemForm } from "./components/edit-item-form"
|
||||
import { Heading } from "@medusajs/ui"
|
||||
import { RouteDrawer } from "../../../../../components/route-modal"
|
||||
import { useInventoryItem } from "../../../../../hooks/api/inventory"
|
||||
import { useParams } from "react-router-dom"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { useParams } from "react-router-dom"
|
||||
import { RouteDrawer } from "../../../../../components/modals"
|
||||
import { useInventoryItem } from "../../../../../hooks/api/inventory"
|
||||
import { EditInventoryItemForm } from "./components/edit-item-form"
|
||||
|
||||
export const InventoryItemEdit = () => {
|
||||
const { id } = useParams()
|
||||
|
||||
+4
-4
@@ -1,16 +1,16 @@
|
||||
import * as zod from "zod"
|
||||
|
||||
import { Button, Text, toast } from "@medusajs/ui"
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { AdminInventoryItem, AdminStockLocation } from "@medusajs/types"
|
||||
import { Button, Text, toast } from "@medusajs/ui"
|
||||
import { useFieldArray, useForm } from "react-hook-form"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { z } from "zod"
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import {
|
||||
RouteDrawer,
|
||||
useRouteModal,
|
||||
} from "../../../../../../components/route-modal"
|
||||
} from "../../../../../../components/modals"
|
||||
import { useBatchUpdateInventoryLevels } from "../../../../../../hooks/api/inventory"
|
||||
import { useFieldArray, useForm } from "react-hook-form"
|
||||
|
||||
import { LocationItem } from "./location-item"
|
||||
import { useEffect, useMemo } from "react"
|
||||
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
import { Heading } from "@medusajs/ui"
|
||||
import { useTranslation } from "react-i18next"
|
||||
|
||||
import { ManageLocationsForm } from "./components/manage-locations-form"
|
||||
import { RouteDrawer } from "../../../../../components/route-modal"
|
||||
import { useInventoryItem } from "../../../../../hooks/api/inventory"
|
||||
import { useParams } from "react-router-dom"
|
||||
import { RouteDrawer } from "../../../../../components/modals"
|
||||
import { useInventoryItem } from "../../../../../hooks/api/inventory"
|
||||
import { useStockLocations } from "../../../../../hooks/api/stock-locations"
|
||||
import { ManageLocationsForm } from "./components/manage-locations-form"
|
||||
|
||||
export const ManageLocationsDrawer = () => {
|
||||
const { id } = useParams()
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ import { CountrySelect } from "../../../../../components/inputs/country-select"
|
||||
import {
|
||||
RouteFocusModal,
|
||||
useRouteModal,
|
||||
} from "../../../../../components/route-modal"
|
||||
} from "../../../../../components/modals"
|
||||
import { useCreateStockLocation } from "../../../../../hooks/api/stock-locations"
|
||||
|
||||
const CreateLocationSchema = zod.object({
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { RouteFocusModal } from "../../../components/route-modal"
|
||||
import { RouteFocusModal } from "../../../components/modals"
|
||||
import { CreateLocationForm } from "./components/create-location-form"
|
||||
|
||||
export const LocationCreate = () => {
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ import { CountrySelect } from "../../../../../components/inputs/country-select"
|
||||
import {
|
||||
RouteDrawer,
|
||||
useRouteModal,
|
||||
} from "../../../../../components/route-modal"
|
||||
} from "../../../../../components/modals"
|
||||
import { useUpdateStockLocation } from "../../../../../hooks/api/stock-locations"
|
||||
|
||||
type EditLocationFormProps = {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Heading } from "@medusajs/ui"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { useParams } from "react-router-dom"
|
||||
import { RouteDrawer } from "../../../components/route-modal"
|
||||
import { RouteDrawer } from "../../../components/modals"
|
||||
import { useStockLocation } from "../../../hooks/api/stock-locations"
|
||||
import { EditLocationForm } from "./components/edit-location-form"
|
||||
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ import { useForm } from "react-hook-form"
|
||||
import {
|
||||
RouteFocusModal,
|
||||
useRouteModal,
|
||||
} from "../../../../../components/route-modal"
|
||||
} from "../../../../../components/modals"
|
||||
import { DataTable } from "../../../../../components/table/data-table"
|
||||
import { useSalesChannels } from "../../../../../hooks/api/sales-channels"
|
||||
import { useUpdateStockLocationSalesChannels } from "../../../../../hooks/api/stock-locations"
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { useParams } from "react-router-dom"
|
||||
|
||||
import { RouteFocusModal } from "../../../components/route-modal"
|
||||
import { RouteFocusModal } from "../../../components/modals"
|
||||
import { useStockLocation } from "../../../hooks/api/stock-locations"
|
||||
import { LocationEditSalesChannelsForm } from "./components/edit-sales-channels-form"
|
||||
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ import { SplitView } from "../../../../../components/layout/split-view"
|
||||
import {
|
||||
RouteFocusModal,
|
||||
useRouteModal,
|
||||
} from "../../../../../components/route-modal"
|
||||
} from "../../../../../components/modals"
|
||||
import { useCreateFulfillmentSetServiceZone } from "../../../../../hooks/api/fulfillment-sets"
|
||||
import { GeoZoneForm } from "../../../common/components/geo-zone-form"
|
||||
import { FulfillmentSetType } from "../../../common/constants"
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { json, useLoaderData, useParams } from "react-router-dom"
|
||||
|
||||
import { RouteFocusModal } from "../../../components/route-modal"
|
||||
import { RouteFocusModal } from "../../../components/modals"
|
||||
import { useStockLocation } from "../../../hooks/api/stock-locations"
|
||||
import { FulfillmentSetType } from "../common/constants"
|
||||
import { CreateServiceZoneForm } from "./components/create-service-zone-form"
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ import { InlineTip } from "../../../../../components/common/inline-tip"
|
||||
import {
|
||||
RouteDrawer,
|
||||
useRouteModal,
|
||||
} from "../../../../../components/route-modal"
|
||||
} from "../../../../../components/modals"
|
||||
import { useUpdateFulfillmentSetServiceZone } from "../../../../../hooks/api/fulfillment-sets"
|
||||
|
||||
type EditServiceZoneFormProps = {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user