From c384ede3b1549fbb6a864f4e3abfa7dab6e12b43 Mon Sep 17 00:00:00 2001 From: Kasper Fabricius Kristensen <45367945+kasperkristensen@users.noreply.github.com> Date: Thu, 14 Mar 2024 19:05:44 +0100 Subject: [PATCH] feat(dashboard): Setup parallel V2 routes (#6691) **What** - Moves all current route definitions to `v1.tsx` - Creates a new `v2.tsx` file for future V2 routes. - Updates RouteProvider to serve V1 or V2 routes based on if `MEDUSA_V2` is set. **How to use it** When working on V2 domains you should set `MEDUSA_V2=true` in `/packages/admin-next/dashboard/.env`. We can't use the Feature Flag in the Medusa project since there are breaking changes in the `/admin/store` endpoint between the two versions, so it needs to be managed manually. **For people implementing V2 domains** To add a new route you should: - Add the route component in `/v2-routes` - Define which path will render it in `v2.tsx`. I would prefer that we don't try to implement a lot of conditional code that will make the codebase unnecessarily complex. So if I was to implement the V2 login page, I would copy/past the v1 login route into `v2-routes`, make the required changes, eg. replace `useAdminLogin` with `useAdminCustomPost(...)`, instead of trying to force the current V1 Login page to work with both APIs. There will hopefully be a lot of components/sections from each domain that is re-usable between versions. As an example if you are working on the Product details page for V2 you might want to reuse the `product-general-section.tsx` file, as it works without having to make any modifications. In that case I propose that we create a `modules/product` folder and move the component in there which we can them import into both the v1 and v2 version of the route. --- .../router-provider/router-provider.tsx | 792 +---------------- .../src/providers/router-provider/v1.tsx | 795 ++++++++++++++++++ .../src/providers/router-provider/v2.tsx | 17 + .../dashboard/src/v2-routes/login/index.ts | 1 + .../dashboard/src/v2-routes/login/login.tsx | 3 + .../admin-next/dashboard/src/vite-env.d.ts | 3 +- 6 files changed, 822 insertions(+), 789 deletions(-) create mode 100644 packages/admin-next/dashboard/src/providers/router-provider/v1.tsx create mode 100644 packages/admin-next/dashboard/src/providers/router-provider/v2.tsx create mode 100644 packages/admin-next/dashboard/src/v2-routes/login/index.ts create mode 100644 packages/admin-next/dashboard/src/v2-routes/login/login.tsx diff --git a/packages/admin-next/dashboard/src/providers/router-provider/router-provider.tsx b/packages/admin-next/dashboard/src/providers/router-provider/router-provider.tsx index 0ce7cbf455..8c42e124a1 100644 --- a/packages/admin-next/dashboard/src/providers/router-provider/router-provider.tsx +++ b/packages/admin-next/dashboard/src/providers/router-provider/router-provider.tsx @@ -1,798 +1,14 @@ -import type { - AdminCollectionsRes, - AdminCustomerGroupsRes, - AdminCustomersRes, - AdminGiftCardsRes, - AdminOrdersRes, - AdminProductsRes, - AdminPublishableApiKeysRes, - AdminRegionsRes, - AdminSalesChannelsRes, - AdminUserRes, -} from "@medusajs/medusa" import { - Outlet, RouterProvider as Provider, - RouteObject, createBrowserRouter, } from "react-router-dom" -import { ProtectedRoute } from "../../components/authentication/require-auth" -import { ErrorBoundary } from "../../components/error/error-boundary" -import { MainLayout } from "../../components/layout/main-layout" -import { SettingsLayout } from "../../components/layout/settings-layout" +import { v1Routes } from "./v1" +import { v2Routes } from "./v2" -import routes from "medusa-admin:routes/pages" -import settings from "medusa-admin:settings/pages" +const V2_ENABLED = import.meta.env.MEDUSA_V2 || false -const routeExtensions: RouteObject[] = routes.pages.map((ext) => { - return { - path: ext.path, - async lazy() { - const { default: Component } = await import(/* @vite-ignore */ ext.file) - return { Component } - }, - } -}) - -const settingsExtensions: RouteObject[] = settings.pages.map((ext) => { - return { - path: `/settings${ext.path}`, - async lazy() { - const { default: Component } = await import(/* @vite-ignore */ ext.file) - return { Component } - }, - } -}) - -const router = createBrowserRouter([ - { - path: "/login", - lazy: () => import("../../routes/login"), - }, - { - path: "/reset-password", - element: , - children: [ - { - index: true, - lazy: () => - import("../../routes/reset-password/reset-password-request"), - }, - { - path: ":token", - lazy: () => import("../../routes/reset-password/reset-password-token"), - }, - ], - }, - { - path: "/invite", - lazy: () => import("../../routes/invite"), - }, - { - element: , - errorElement: , - children: [ - { - path: "/", - element: , - children: [ - { - index: true, - lazy: () => import("../../routes/home"), - }, - { - path: "/orders", - handle: { - crumb: () => "Orders", - }, - children: [ - { - path: "", - lazy: () => import("../../routes/orders/order-list"), - }, - { - path: ":id", - lazy: () => import("../../routes/orders/order-detail"), - handle: { - crumb: (data: AdminOrdersRes) => - `Order #${data.order.display_id}`, - }, - }, - ], - }, - { - path: "/draft-orders", - handle: { - crumb: () => "Draft Orders", - }, - children: [ - { - index: true, - lazy: () => - import("../../routes/draft-orders/draft-order-list"), - }, - { - path: ":id", - lazy: () => - import("../../routes/draft-orders/draft-order-detail"), - }, - ], - }, - { - path: "/products", - handle: { - crumb: () => "Products", - }, - children: [ - { - path: "", - lazy: () => import("../../routes/products/product-list"), - children: [ - { - path: "create", - lazy: () => import("../../routes/products/product-create"), - }, - ], - }, - { - path: ":id", - lazy: () => import("../../routes/products/product-detail"), - handle: { - crumb: (data: AdminProductsRes) => data.product.title, - }, - children: [ - { - path: "edit", - lazy: () => import("../../routes/products/product-edit"), - }, - { - path: "sales-channels", - lazy: () => - import("../../routes/products/product-sales-channels"), - }, - { - path: "attributes", - lazy: () => - import("../../routes/products/product-attributes"), - }, - { - path: "options", - lazy: () => import("../../routes/products/product-options"), - }, - { - path: "gallery", - lazy: () => import("../../routes/products/product-gallery"), - }, - ], - }, - ], - }, - { - path: "/categories", - handle: { - crumb: () => "Categories", - }, - children: [ - { - index: true, - lazy: () => import("../../routes/categories/list"), - }, - { - path: ":id", - lazy: () => import("../../routes/categories/details"), - }, - ], - }, - { - path: "/collections", - handle: { - crumb: () => "Collections", - }, - children: [ - { - path: "", - lazy: () => import("../../routes/collections/collection-list"), - children: [ - { - path: "create", - lazy: () => - import("../../routes/collections/collection-create"), - }, - ], - }, - { - path: ":id", - handle: { - crumb: (data: AdminCollectionsRes) => data.collection.title, - }, - lazy: () => - import("../../routes/collections/collection-detail"), - children: [ - { - path: "edit", - lazy: () => - import("../../routes/collections/collection-edit"), - }, - { - path: "add-products", - lazy: () => - import( - "../../routes/collections/collection-add-products" - ), - }, - ], - }, - ], - }, - { - path: "/inventory", - handle: { - crumb: () => "Inventory", - }, - lazy: () => import("../../routes/inventory/inventory-list"), - }, - { - path: "/reservations", - handle: { - crumb: () => "Reservations", - }, - children: [ - { - path: "", - lazy: () => - import("../../routes/reservations/reservation-list"), - }, - { - path: ":id", - lazy: () => - import("../../routes/reservations/reservation-detail"), - // children: [ - // { - // path: "edit", - // lazy: () => - // import("../../routes/reservations/reservation-edit"), - // }, - // ], - }, - ], - }, - { - path: "/customers", - handle: { - crumb: () => "Customers", - }, - children: [ - { - path: "", - lazy: () => import("../../routes/customers/customer-list"), - children: [ - { - path: "create", - lazy: () => - import("../../routes/customers/customer-create"), - }, - ], - }, - { - path: ":id", - lazy: () => import("../../routes/customers/customer-detail"), - handle: { - crumb: (data: AdminCustomersRes) => data.customer.email, - }, - children: [ - { - path: "edit", - lazy: () => import("../../routes/customers/customer-edit"), - }, - ], - }, - ], - }, - { - path: "/customer-groups", - handle: { - crumb: () => "Customer Groups", - }, - children: [ - { - path: "", - lazy: () => - import("../../routes/customer-groups/customer-group-list"), - children: [ - { - path: "create", - lazy: () => - import( - "../../routes/customer-groups/customer-group-create" - ), - }, - ], - }, - { - path: ":id", - lazy: () => - import("../../routes/customer-groups/customer-group-detail"), - handle: { - crumb: (data: AdminCustomerGroupsRes) => - data.customer_group.name, - }, - children: [ - { - path: "add-customers", - lazy: () => - import( - "../../routes/customer-groups/customer-group-add-customers" - ), - }, - { - path: "edit", - lazy: () => - import( - "../../routes/customer-groups/customer-group-edit" - ), - }, - ], - }, - ], - }, - { - path: "/gift-cards", - handle: { - crumb: () => "Gift Cards", - }, - children: [ - { - path: "", - lazy: () => import("../../routes/gift-cards/gift-card-list"), - children: [ - { - path: "create", - lazy: () => - import("../../routes/gift-cards/gift-card-create"), - }, - ], - }, - { - path: ":id", - lazy: () => import("../../routes/gift-cards/gift-card-detail"), - handle: { - crumb: (data: AdminGiftCardsRes) => data.gift_card.code, - }, - children: [ - { - path: "edit", - lazy: () => - import("../../routes/gift-cards/gift-card-edit"), - }, - ], - }, - ], - }, - { - path: "/discounts", - handle: { - crumb: () => "Discounts", - }, - children: [ - { - index: true, - lazy: () => import("../../routes/discounts/list"), - }, - { - path: "create", - lazy: () => import("../../routes/discounts/create"), - }, - { - path: ":id", - lazy: () => import("../../routes/discounts/details"), - children: [ - { - path: "edit", - lazy: () => import("../../routes/discounts/edit-details"), - }, - { - path: "configuration", - lazy: () => - import("../../routes/discounts/edit-configuration"), - }, - ], - }, - ], - }, - { - path: "/pricing", - handle: { - crumb: () => "Pricing", - }, - children: [ - { - path: "", - lazy: () => import("../../routes/pricing/pricing-list"), - children: [ - // { - // path: "create", - // lazy: () => import("../../routes/pricing/pricing-create"), - // }, - ], - }, - { - path: ":id", - lazy: () => import("../../routes/pricing/pricing-detail"), - children: [ - { - path: "edit", - lazy: () => import("../../routes/pricing/pricing-edit"), - }, - { - path: "products/add", - lazy: () => - import("../../routes/pricing/pricing-products-add"), - }, - { - path: "products/edit", - lazy: () => - import("../../routes/pricing/pricing-products-edit"), - }, - ], - }, - ], - }, - ], - }, - { - path: "/settings", - element: , - handle: { - crumb: () => "Settings", - }, - children: [ - { - index: true, - lazy: () => import("../../routes/settings"), - }, - { - path: "profile", - lazy: () => import("../../routes/profile/profile-detail"), - handle: { - crumb: () => "Profile", - }, - children: [ - { - path: "edit", - lazy: () => import("../../routes/profile/profile-edit"), - }, - ], - }, - { - path: "store", - lazy: () => import("../../routes/store/store-detail"), - handle: { - crumb: () => "Store", - }, - children: [ - { - path: "edit", - lazy: () => import("../../routes/store/store-edit"), - }, - { - path: "add-currencies", - lazy: () => import("../../routes/store/store-add-currencies"), - }, - ], - }, - { - path: "locations", - element: , - handle: { - crumb: () => "Locations", - }, - children: [ - { - path: "", - lazy: () => import("../../routes/locations/location-list"), - children: [ - { - path: "create", - lazy: () => - import("../../routes/locations/location-create"), - }, - ], - }, - { - path: ":id", - lazy: () => import("../../routes/locations/location-detail"), - children: [ - { - path: "edit", - lazy: () => import("../../routes/locations/location-edit"), - }, - { - path: "add-sales-channels", - lazy: () => - import( - "../../routes/locations/location-add-sales-channels" - ), - }, - ], - }, - ], - }, - { - path: "return-reasons", - element: , - handle: { - crumb: () => "Return Reasons", - }, - children: [ - { - path: "", - lazy: () => - import("../../routes/return-reasons/return-reason-list"), - children: [ - { - path: "create", - lazy: () => - import( - "../../routes/return-reasons/return-reason-create" - ), - }, - { - path: ":id/edit", - lazy: () => - import("../../routes/return-reasons/return-reason-edit"), - }, - ], - }, - ], - }, - { - path: "regions", - element: , - handle: { - crumb: () => "Regions", - }, - children: [ - { - path: "", - lazy: () => import("../../routes/regions/region-list"), - children: [ - { - path: "create", - lazy: () => import("../../routes/regions/region-create"), - }, - ], - }, - { - path: ":id", - lazy: () => import("../../routes/regions/region-detail"), - handle: { - crumb: (data: AdminRegionsRes) => data.region.name, - }, - children: [ - { - path: "edit", - lazy: () => import("../../routes/regions/region-edit"), - }, - { - path: "countries/add", - lazy: () => - import("../../routes/regions/region-add-countries"), - }, - { - path: "shipping-options/:so_id/edit", - lazy: () => - import( - "../../routes/regions/region-edit-shipping-option" - ), - }, - { - path: "shipping-options/create", - lazy: () => - import( - "../../routes/regions/region-create-shipping-option" - ), - }, - ], - }, - ], - }, - { - path: "users", - element: , - handle: { - crumb: () => "Users", - }, - children: [ - { - path: "", - lazy: () => import("../../routes/users/user-list"), - children: [ - { - path: "invite", - lazy: () => import("../../routes/users/user-invite"), - }, - ], - }, - { - path: ":id", - lazy: () => import("../../routes/users/user-detail"), - handle: { - crumb: (data: AdminUserRes) => data.user.email, - }, - children: [ - { - path: "edit", - lazy: () => import("../../routes/users/user-edit"), - }, - ], - }, - ], - }, - { - path: "taxes", - handle: { - crumb: () => "Taxes", - }, - children: [ - { - path: "", - lazy: () => import("../../routes/taxes/tax-list"), - }, - { - path: ":id", - lazy: () => import("../../routes/taxes/tax-detail"), - handle: { - crumb: (data: AdminRegionsRes) => data.region.name, - }, - children: [ - { - path: "edit", - lazy: () => import("../../routes/taxes/tax-edit"), - }, - { - path: "tax-rates/create", - lazy: () => import("../../routes/taxes/tax-rate-create"), - }, - { - path: "tax-rates/:rate_id/edit", - lazy: () => import("../../routes/taxes/tax-rate-edit"), - }, - { - path: "tax-rates/:rate_id/edit-overrides", - lazy: () => - import("../../routes/taxes/tax-rate-edit-overrides"), - }, - ], - }, - ], - }, - { - path: "sales-channels", - element: , - handle: { - crumb: () => "Sales Channels", - }, - children: [ - { - path: "", - lazy: () => - import("../../routes/sales-channels/sales-channel-list"), - children: [ - { - path: "create", - lazy: () => - import( - "../../routes/sales-channels/sales-channel-create" - ), - }, - ], - }, - { - path: ":id", - lazy: () => - import("../../routes/sales-channels/sales-channel-detail"), - handle: { - crumb: (data: AdminSalesChannelsRes) => - data.sales_channel.name, - }, - children: [ - { - path: "edit", - lazy: () => - import("../../routes/sales-channels/sales-channel-edit"), - }, - { - path: "add-products", - lazy: () => - import( - "../../routes/sales-channels/sales-channel-add-products" - ), - }, - ], - }, - ], - }, - { - path: "api-key-management", - element: , - handle: { - crumb: () => "API Key Management", - }, - children: [ - { - path: "", - lazy: () => - import( - "../../routes/api-key-management/api-key-management-list" - ), - children: [ - { - path: "create", - lazy: () => - import( - "../../routes/api-key-management/api-key-management-create" - ), - }, - ], - }, - { - path: ":id", - lazy: () => - import( - "../../routes/api-key-management/api-key-management-detail" - ), - handle: { - crumb: (data: AdminPublishableApiKeysRes) => - data.publishable_api_key.title, - }, - children: [ - { - path: "edit", - lazy: () => - import( - "../../routes/api-key-management/api-key-management-edit" - ), - }, - { - path: "add-sales-channels", - lazy: () => - import( - "../../routes/api-key-management/api-key-management-add-sales-channels" - ), - }, - ], - }, - ], - }, - { - path: "executions", - element: , - handle: { - crumb: () => "Executions", - }, - children: [ - { - path: "", - lazy: () => import("../../routes/executions/execution-list"), - }, - { - path: ":id", - lazy: () => import("../../routes/executions/execution-detail"), - }, - ], - }, - ...settingsExtensions, - ], - }, - ...routeExtensions, - ], - }, - { - path: "*", - lazy: () => import("../../routes/no-match"), - }, -]) +const router = createBrowserRouter(V2_ENABLED ? v2Routes : v1Routes) export const RouterProvider = () => { return diff --git a/packages/admin-next/dashboard/src/providers/router-provider/v1.tsx b/packages/admin-next/dashboard/src/providers/router-provider/v1.tsx new file mode 100644 index 0000000000..32196430f8 --- /dev/null +++ b/packages/admin-next/dashboard/src/providers/router-provider/v1.tsx @@ -0,0 +1,795 @@ +import type { + AdminCollectionsRes, + AdminCustomerGroupsRes, + AdminCustomersRes, + AdminGiftCardsRes, + AdminOrdersRes, + AdminProductsRes, + AdminPublishableApiKeysRes, + AdminRegionsRes, + AdminSalesChannelsRes, + AdminUserRes, +} from "@medusajs/medusa" +import { Outlet, RouteObject } from "react-router-dom" + +import { ProtectedRoute } from "../../components/authentication/require-auth" +import { ErrorBoundary } from "../../components/error/error-boundary" +import { MainLayout } from "../../components/layout/main-layout" +import { SettingsLayout } from "../../components/layout/settings-layout" + +import routes from "medusa-admin:routes/pages" +import settings from "medusa-admin:settings/pages" + +const routeExtensions: RouteObject[] = routes.pages.map((ext) => { + return { + path: ext.path, + async lazy() { + const { default: Component } = await import(/* @vite-ignore */ ext.file) + return { Component } + }, + } +}) + +const settingsExtensions: RouteObject[] = settings.pages.map((ext) => { + return { + path: `/settings${ext.path}`, + async lazy() { + const { default: Component } = await import(/* @vite-ignore */ ext.file) + return { Component } + }, + } +}) + +/** + * V1 routes. + * + * These routes are loaded by default. + */ +export const v1Routes: RouteObject[] = [ + { + path: "/login", + lazy: () => import("../../routes/login"), + }, + { + path: "/reset-password", + element: , + children: [ + { + index: true, + lazy: () => + import("../../routes/reset-password/reset-password-request"), + }, + { + path: ":token", + lazy: () => import("../../routes/reset-password/reset-password-token"), + }, + ], + }, + { + path: "/invite", + lazy: () => import("../../routes/invite"), + }, + { + element: , + errorElement: , + children: [ + { + path: "/", + element: , + children: [ + { + index: true, + lazy: () => import("../../routes/home"), + }, + { + path: "/orders", + handle: { + crumb: () => "Orders", + }, + children: [ + { + path: "", + lazy: () => import("../../routes/orders/order-list"), + }, + { + path: ":id", + lazy: () => import("../../routes/orders/order-detail"), + handle: { + crumb: (data: AdminOrdersRes) => + `Order #${data.order.display_id}`, + }, + }, + ], + }, + { + path: "/draft-orders", + handle: { + crumb: () => "Draft Orders", + }, + children: [ + { + index: true, + lazy: () => + import("../../routes/draft-orders/draft-order-list"), + }, + { + path: ":id", + lazy: () => + import("../../routes/draft-orders/draft-order-detail"), + }, + ], + }, + { + path: "/products", + handle: { + crumb: () => "Products", + }, + children: [ + { + path: "", + lazy: () => import("../../routes/products/product-list"), + children: [ + { + path: "create", + lazy: () => import("../../routes/products/product-create"), + }, + ], + }, + { + path: ":id", + lazy: () => import("../../routes/products/product-detail"), + handle: { + crumb: (data: AdminProductsRes) => data.product.title, + }, + children: [ + { + path: "edit", + lazy: () => import("../../routes/products/product-edit"), + }, + { + path: "sales-channels", + lazy: () => + import("../../routes/products/product-sales-channels"), + }, + { + path: "attributes", + lazy: () => + import("../../routes/products/product-attributes"), + }, + { + path: "options", + lazy: () => import("../../routes/products/product-options"), + }, + { + path: "gallery", + lazy: () => import("../../routes/products/product-gallery"), + }, + ], + }, + ], + }, + { + path: "/categories", + handle: { + crumb: () => "Categories", + }, + children: [ + { + index: true, + lazy: () => import("../../routes/categories/list"), + }, + { + path: ":id", + lazy: () => import("../../routes/categories/details"), + }, + ], + }, + { + path: "/collections", + handle: { + crumb: () => "Collections", + }, + children: [ + { + path: "", + lazy: () => import("../../routes/collections/collection-list"), + children: [ + { + path: "create", + lazy: () => + import("../../routes/collections/collection-create"), + }, + ], + }, + { + path: ":id", + handle: { + crumb: (data: AdminCollectionsRes) => data.collection.title, + }, + lazy: () => + import("../../routes/collections/collection-detail"), + children: [ + { + path: "edit", + lazy: () => + import("../../routes/collections/collection-edit"), + }, + { + path: "add-products", + lazy: () => + import( + "../../routes/collections/collection-add-products" + ), + }, + ], + }, + ], + }, + { + path: "/inventory", + handle: { + crumb: () => "Inventory", + }, + lazy: () => import("../../routes/inventory/inventory-list"), + }, + { + path: "/reservations", + handle: { + crumb: () => "Reservations", + }, + children: [ + { + path: "", + lazy: () => + import("../../routes/reservations/reservation-list"), + }, + { + path: ":id", + lazy: () => + import("../../routes/reservations/reservation-detail"), + // children: [ + // { + // path: "edit", + // lazy: () => + // import("../../routes/reservations/reservation-edit"), + // }, + // ], + }, + ], + }, + { + path: "/customers", + handle: { + crumb: () => "Customers", + }, + children: [ + { + path: "", + lazy: () => import("../../routes/customers/customer-list"), + children: [ + { + path: "create", + lazy: () => + import("../../routes/customers/customer-create"), + }, + ], + }, + { + path: ":id", + lazy: () => import("../../routes/customers/customer-detail"), + handle: { + crumb: (data: AdminCustomersRes) => data.customer.email, + }, + children: [ + { + path: "edit", + lazy: () => import("../../routes/customers/customer-edit"), + }, + ], + }, + ], + }, + { + path: "/customer-groups", + handle: { + crumb: () => "Customer Groups", + }, + children: [ + { + path: "", + lazy: () => + import("../../routes/customer-groups/customer-group-list"), + children: [ + { + path: "create", + lazy: () => + import( + "../../routes/customer-groups/customer-group-create" + ), + }, + ], + }, + { + path: ":id", + lazy: () => + import("../../routes/customer-groups/customer-group-detail"), + handle: { + crumb: (data: AdminCustomerGroupsRes) => + data.customer_group.name, + }, + children: [ + { + path: "add-customers", + lazy: () => + import( + "../../routes/customer-groups/customer-group-add-customers" + ), + }, + { + path: "edit", + lazy: () => + import( + "../../routes/customer-groups/customer-group-edit" + ), + }, + ], + }, + ], + }, + { + path: "/gift-cards", + handle: { + crumb: () => "Gift Cards", + }, + children: [ + { + path: "", + lazy: () => import("../../routes/gift-cards/gift-card-list"), + children: [ + { + path: "create", + lazy: () => + import("../../routes/gift-cards/gift-card-create"), + }, + ], + }, + { + path: ":id", + lazy: () => import("../../routes/gift-cards/gift-card-detail"), + handle: { + crumb: (data: AdminGiftCardsRes) => data.gift_card.code, + }, + children: [ + { + path: "edit", + lazy: () => + import("../../routes/gift-cards/gift-card-edit"), + }, + ], + }, + ], + }, + { + path: "/discounts", + handle: { + crumb: () => "Discounts", + }, + children: [ + { + index: true, + lazy: () => import("../../routes/discounts/list"), + }, + { + path: "create", + lazy: () => import("../../routes/discounts/create"), + }, + { + path: ":id", + lazy: () => import("../../routes/discounts/details"), + children: [ + { + path: "edit", + lazy: () => import("../../routes/discounts/edit-details"), + }, + { + path: "configuration", + lazy: () => + import("../../routes/discounts/edit-configuration"), + }, + ], + }, + ], + }, + { + path: "/pricing", + handle: { + crumb: () => "Pricing", + }, + children: [ + { + path: "", + lazy: () => import("../../routes/pricing/pricing-list"), + children: [ + // { + // path: "create", + // lazy: () => import("../../routes/pricing/pricing-create"), + // }, + ], + }, + { + path: ":id", + lazy: () => import("../../routes/pricing/pricing-detail"), + children: [ + { + path: "edit", + lazy: () => import("../../routes/pricing/pricing-edit"), + }, + { + path: "products/add", + lazy: () => + import("../../routes/pricing/pricing-products-add"), + }, + { + path: "products/edit", + lazy: () => + import("../../routes/pricing/pricing-products-edit"), + }, + ], + }, + ], + }, + ], + }, + { + path: "/settings", + element: , + handle: { + crumb: () => "Settings", + }, + children: [ + { + index: true, + lazy: () => import("../../routes/settings"), + }, + { + path: "profile", + lazy: () => import("../../routes/profile/profile-detail"), + handle: { + crumb: () => "Profile", + }, + children: [ + { + path: "edit", + lazy: () => import("../../routes/profile/profile-edit"), + }, + ], + }, + { + path: "store", + lazy: () => import("../../routes/store/store-detail"), + handle: { + crumb: () => "Store", + }, + children: [ + { + path: "edit", + lazy: () => import("../../routes/store/store-edit"), + }, + { + path: "add-currencies", + lazy: () => import("../../routes/store/store-add-currencies"), + }, + ], + }, + { + path: "locations", + element: , + handle: { + crumb: () => "Locations", + }, + children: [ + { + path: "", + lazy: () => import("../../routes/locations/location-list"), + children: [ + { + path: "create", + lazy: () => + import("../../routes/locations/location-create"), + }, + ], + }, + { + path: ":id", + lazy: () => import("../../routes/locations/location-detail"), + children: [ + { + path: "edit", + lazy: () => import("../../routes/locations/location-edit"), + }, + { + path: "add-sales-channels", + lazy: () => + import( + "../../routes/locations/location-add-sales-channels" + ), + }, + ], + }, + ], + }, + { + path: "return-reasons", + element: , + handle: { + crumb: () => "Return Reasons", + }, + children: [ + { + path: "", + lazy: () => + import("../../routes/return-reasons/return-reason-list"), + children: [ + { + path: "create", + lazy: () => + import( + "../../routes/return-reasons/return-reason-create" + ), + }, + { + path: ":id/edit", + lazy: () => + import("../../routes/return-reasons/return-reason-edit"), + }, + ], + }, + ], + }, + { + path: "regions", + element: , + handle: { + crumb: () => "Regions", + }, + children: [ + { + path: "", + lazy: () => import("../../routes/regions/region-list"), + children: [ + { + path: "create", + lazy: () => import("../../routes/regions/region-create"), + }, + ], + }, + { + path: ":id", + lazy: () => import("../../routes/regions/region-detail"), + handle: { + crumb: (data: AdminRegionsRes) => data.region.name, + }, + children: [ + { + path: "edit", + lazy: () => import("../../routes/regions/region-edit"), + }, + { + path: "countries/add", + lazy: () => + import("../../routes/regions/region-add-countries"), + }, + { + path: "shipping-options/:so_id/edit", + lazy: () => + import( + "../../routes/regions/region-edit-shipping-option" + ), + }, + { + path: "shipping-options/create", + lazy: () => + import( + "../../routes/regions/region-create-shipping-option" + ), + }, + ], + }, + ], + }, + { + path: "users", + element: , + handle: { + crumb: () => "Users", + }, + children: [ + { + path: "", + lazy: () => import("../../routes/users/user-list"), + children: [ + { + path: "invite", + lazy: () => import("../../routes/users/user-invite"), + }, + ], + }, + { + path: ":id", + lazy: () => import("../../routes/users/user-detail"), + handle: { + crumb: (data: AdminUserRes) => data.user.email, + }, + children: [ + { + path: "edit", + lazy: () => import("../../routes/users/user-edit"), + }, + ], + }, + ], + }, + { + path: "taxes", + handle: { + crumb: () => "Taxes", + }, + children: [ + { + path: "", + lazy: () => import("../../routes/taxes/tax-list"), + }, + { + path: ":id", + lazy: () => import("../../routes/taxes/tax-detail"), + handle: { + crumb: (data: AdminRegionsRes) => data.region.name, + }, + children: [ + { + path: "edit", + lazy: () => import("../../routes/taxes/tax-edit"), + }, + { + path: "tax-rates/create", + lazy: () => import("../../routes/taxes/tax-rate-create"), + }, + { + path: "tax-rates/:rate_id/edit", + lazy: () => import("../../routes/taxes/tax-rate-edit"), + }, + { + path: "tax-rates/:rate_id/edit-overrides", + lazy: () => + import("../../routes/taxes/tax-rate-edit-overrides"), + }, + ], + }, + ], + }, + { + path: "sales-channels", + element: , + handle: { + crumb: () => "Sales Channels", + }, + children: [ + { + path: "", + lazy: () => + import("../../routes/sales-channels/sales-channel-list"), + children: [ + { + path: "create", + lazy: () => + import( + "../../routes/sales-channels/sales-channel-create" + ), + }, + ], + }, + { + path: ":id", + lazy: () => + import("../../routes/sales-channels/sales-channel-detail"), + handle: { + crumb: (data: AdminSalesChannelsRes) => + data.sales_channel.name, + }, + children: [ + { + path: "edit", + lazy: () => + import("../../routes/sales-channels/sales-channel-edit"), + }, + { + path: "add-products", + lazy: () => + import( + "../../routes/sales-channels/sales-channel-add-products" + ), + }, + ], + }, + ], + }, + { + path: "api-key-management", + element: , + handle: { + crumb: () => "API Key Management", + }, + children: [ + { + path: "", + lazy: () => + import( + "../../routes/api-key-management/api-key-management-list" + ), + children: [ + { + path: "create", + lazy: () => + import( + "../../routes/api-key-management/api-key-management-create" + ), + }, + ], + }, + { + path: ":id", + lazy: () => + import( + "../../routes/api-key-management/api-key-management-detail" + ), + handle: { + crumb: (data: AdminPublishableApiKeysRes) => + data.publishable_api_key.title, + }, + children: [ + { + path: "edit", + lazy: () => + import( + "../../routes/api-key-management/api-key-management-edit" + ), + }, + { + path: "add-sales-channels", + lazy: () => + import( + "../../routes/api-key-management/api-key-management-add-sales-channels" + ), + }, + ], + }, + ], + }, + { + path: "executions", + element: , + handle: { + crumb: () => "Executions", + }, + children: [ + { + path: "", + lazy: () => import("../../routes/executions/execution-list"), + }, + { + path: ":id", + lazy: () => import("../../routes/executions/execution-detail"), + }, + ], + }, + ...settingsExtensions, + ], + }, + ...routeExtensions, + ], + }, + { + path: "*", + lazy: () => import("../../routes/no-match"), + }, +] diff --git a/packages/admin-next/dashboard/src/providers/router-provider/v2.tsx b/packages/admin-next/dashboard/src/providers/router-provider/v2.tsx new file mode 100644 index 0000000000..588e3fa6c3 --- /dev/null +++ b/packages/admin-next/dashboard/src/providers/router-provider/v2.tsx @@ -0,0 +1,17 @@ +import { RouteObject } from "react-router-dom" + +/** + * Experimental V2 routes. + * + * These routes are only available if the `MEDUSA_V2` feature flag is enabled. + */ +export const v2Routes: RouteObject[] = [ + { + path: "/login", + lazy: () => import("../../v2-routes/login"), + }, + { + path: "*", + lazy: () => import("../../routes/no-match"), + }, +] diff --git a/packages/admin-next/dashboard/src/v2-routes/login/index.ts b/packages/admin-next/dashboard/src/v2-routes/login/index.ts new file mode 100644 index 0000000000..f1fc40c3a3 --- /dev/null +++ b/packages/admin-next/dashboard/src/v2-routes/login/index.ts @@ -0,0 +1 @@ +export { Login as Component } from "./login" diff --git a/packages/admin-next/dashboard/src/v2-routes/login/login.tsx b/packages/admin-next/dashboard/src/v2-routes/login/login.tsx new file mode 100644 index 0000000000..8f14c1f8c7 --- /dev/null +++ b/packages/admin-next/dashboard/src/v2-routes/login/login.tsx @@ -0,0 +1,3 @@ +export const Login = () => { + return
Medusa V2 Login
+} diff --git a/packages/admin-next/dashboard/src/vite-env.d.ts b/packages/admin-next/dashboard/src/vite-env.d.ts index d87dfc2661..0351443b82 100644 --- a/packages/admin-next/dashboard/src/vite-env.d.ts +++ b/packages/admin-next/dashboard/src/vite-env.d.ts @@ -1,7 +1,8 @@ -/// +// / interface ImportMetaEnv { readonly MEDUSA_ADMIN_BACKEND_URL: string + readonly MEDUSA_V2: boolean } interface ImportMeta {