feat(dashboard,types,js-sdk,ui): Tax Regions UI (#7935)
This commit is contained in:
@@ -107,10 +107,7 @@ export const NavItem = ({
|
||||
<ul>
|
||||
{items.map((item) => {
|
||||
return (
|
||||
<li
|
||||
key={item.to}
|
||||
className="flex h-[32px] items-center gap-x-1 pl-2"
|
||||
>
|
||||
<li key={item.to} className="flex h-[32px] items-center pl-1">
|
||||
<div
|
||||
role="presentation"
|
||||
className="flex h-full w-5 items-center justify-center"
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from "./single-column-page"
|
||||
export * from "./two-column-page"
|
||||
@@ -0,0 +1 @@
|
||||
export * from "./single-column-page"
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
import { Outlet } from "react-router-dom"
|
||||
import { JsonViewSection } from "../../../common/json-view-section"
|
||||
import { PageProps } from "../types"
|
||||
|
||||
export const SingleColumnPage = <TData,>({
|
||||
children,
|
||||
widgets,
|
||||
data,
|
||||
hasOutlet,
|
||||
showJSON,
|
||||
}: PageProps<TData>) => {
|
||||
const { before, after } = widgets
|
||||
const widgetProps = { data }
|
||||
|
||||
if (showJSON && !data) {
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
console.warn(
|
||||
"`showJSON` is true but no data is provided. To display JSON, provide data prop."
|
||||
)
|
||||
}
|
||||
|
||||
showJSON = false
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-y-3">
|
||||
{before.widgets.map((w, i) => {
|
||||
return <w.Component {...widgetProps} key={i} />
|
||||
})}
|
||||
{children}
|
||||
{after.widgets.map((w, i) => {
|
||||
return <w.Component {...widgetProps} key={i} />
|
||||
})}
|
||||
{showJSON && <JsonViewSection data={data!} />}
|
||||
{hasOutlet && <Outlet />}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from "./two-column-page"
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
import { clx } from "@medusajs/ui"
|
||||
import { Children, ComponentPropsWithoutRef } from "react"
|
||||
import { Outlet } from "react-router-dom"
|
||||
import { JsonViewSection } from "../../../common/json-view-section"
|
||||
import { PageProps, WidgetImport, WidgetProps } from "../types"
|
||||
|
||||
interface TwoColumnWidgetProps extends WidgetProps {
|
||||
sideBefore: WidgetImport
|
||||
sideAfter: WidgetImport
|
||||
}
|
||||
|
||||
interface TwoColumnPageProps<TData> extends PageProps<TData> {
|
||||
widgets: TwoColumnWidgetProps
|
||||
}
|
||||
|
||||
const Root = <TData,>({
|
||||
children,
|
||||
/**
|
||||
* Widgets to be rendered in the main content area and sidebar.
|
||||
*/
|
||||
widgets,
|
||||
/**
|
||||
* Data to be passed to widgets and the JSON view.
|
||||
*/
|
||||
data,
|
||||
/**
|
||||
* Whether to show JSON view of the data. Defaults to true.
|
||||
*/
|
||||
showJSON = false,
|
||||
/**
|
||||
* Whether to render an outlet for children routes. Defaults to true.
|
||||
*/
|
||||
hasOutlet = true,
|
||||
}: TwoColumnPageProps<TData>) => {
|
||||
const widgetProps = { data }
|
||||
const { before, after, sideBefore, sideAfter } = widgets
|
||||
|
||||
if (showJSON && !data) {
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
console.warn(
|
||||
"`showJSON` is true but no data is provided. To display JSON, provide data prop."
|
||||
)
|
||||
}
|
||||
|
||||
showJSON = false
|
||||
}
|
||||
|
||||
const childrenArray = Children.toArray(children)
|
||||
|
||||
if (childrenArray.length !== 2) {
|
||||
throw new Error("TwoColumnPage expects exactly two children")
|
||||
}
|
||||
|
||||
const [main, sidebar] = childrenArray
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-y-2">
|
||||
{before.widgets.map((w, i) => {
|
||||
return <w.Component {...widgetProps} key={i} />
|
||||
})}
|
||||
<div className="flex flex-col gap-x-4 gap-y-3 xl:flex-row xl:items-start">
|
||||
<div className="flex w-full flex-col gap-y-3">
|
||||
{main}
|
||||
{after.widgets.map((w, i) => {
|
||||
return <w.Component {...widgetProps} key={i} />
|
||||
})}
|
||||
{showJSON && (
|
||||
<div className="hidden xl:block">
|
||||
<JsonViewSection data={data!} root="product" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex w-full max-w-[100%] flex-col gap-y-3 xl:mt-0 xl:max-w-[440px]">
|
||||
{sideBefore.widgets.map((w, i) => {
|
||||
return <w.Component {...widgetProps} key={i} />
|
||||
})}
|
||||
{sidebar}
|
||||
{sideAfter.widgets.map((w, i) => {
|
||||
return <w.Component {...widgetProps} key={i} />
|
||||
})}
|
||||
{showJSON && (
|
||||
<div className="xl:hidden">
|
||||
<JsonViewSection data={data!} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{hasOutlet && <Outlet />}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const Main = ({
|
||||
children,
|
||||
className,
|
||||
...props
|
||||
}: ComponentPropsWithoutRef<"div">) => {
|
||||
return (
|
||||
<div className={clx("flex w-full flex-col gap-y-3", className)} {...props}>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const Sidebar = ({
|
||||
children,
|
||||
className,
|
||||
...props
|
||||
}: ComponentPropsWithoutRef<"div">) => {
|
||||
return (
|
||||
<div
|
||||
className={clx(
|
||||
"flex w-full max-w-[100%] flex-col gap-y-3 xl:mt-0 xl:max-w-[400px]",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export const TwoColumnPage = Object.assign(Root, { Main, Sidebar })
|
||||
@@ -0,0 +1,22 @@
|
||||
import { ReactNode } from "react"
|
||||
|
||||
export type Widget = {
|
||||
Component: React.ComponentType<any>
|
||||
}
|
||||
|
||||
export type WidgetImport = {
|
||||
widgets: Widget[]
|
||||
}
|
||||
|
||||
export interface WidgetProps {
|
||||
before: WidgetImport
|
||||
after: WidgetImport
|
||||
}
|
||||
|
||||
export interface PageProps<TData> {
|
||||
children: ReactNode
|
||||
widgets: WidgetProps
|
||||
data?: TData
|
||||
showJSON?: boolean
|
||||
hasOutlet?: boolean
|
||||
}
|
||||
+2
-2
@@ -42,8 +42,8 @@ const useSettingRoutes = (): NavItemProps[] => {
|
||||
to: "/settings/regions",
|
||||
},
|
||||
{
|
||||
label: "Taxes",
|
||||
to: "/settings/taxes",
|
||||
label: t("taxRegions.domain"),
|
||||
to: "/settings/tax-regions",
|
||||
},
|
||||
{
|
||||
label: t("salesChannels.domain"),
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
Keyboard,
|
||||
MagnifyingGlass,
|
||||
SidebarLeft,
|
||||
TriangleRightMini,
|
||||
User as UserIcon,
|
||||
} from "@medusajs/icons"
|
||||
import {
|
||||
@@ -92,18 +93,17 @@ const Breadcrumbs = () => {
|
||||
})
|
||||
|
||||
return (
|
||||
<ol className={clx("text-ui-fg-muted flex select-none items-center")}>
|
||||
<ol
|
||||
className={clx(
|
||||
"text-ui-fg-muted txt-compact-small-plus flex select-none items-center"
|
||||
)}
|
||||
>
|
||||
{crumbs.map((crumb, index) => {
|
||||
const isLast = index === crumbs.length - 1
|
||||
const isSingle = crumbs.length === 1
|
||||
|
||||
return (
|
||||
<li
|
||||
key={index}
|
||||
className={clx("txt-compact-small-plus flex items-center", {
|
||||
"text-ui-fg-subtle": isLast,
|
||||
})}
|
||||
>
|
||||
<li key={index} className={clx("flex items-center")}>
|
||||
{!isLast ? (
|
||||
<Link
|
||||
className="transition-fg hover:text-ui-fg-subtle"
|
||||
@@ -124,7 +124,11 @@ const Breadcrumbs = () => {
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{!isLast && <span className="mx-2 -mt-0.5">›</span>}
|
||||
{!isLast && (
|
||||
<span className="mx-2">
|
||||
<TriangleRightMini />
|
||||
</span>
|
||||
)}
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
|
||||
Reference in New Issue
Block a user