Skip to content

Commit

Permalink
chore(dashboard): render main layout as home page for v2 (#6823)
Browse files Browse the repository at this point in the history
* chore(dashboard): render main layout as home page for v2

* chore: throw an error on store not existing
  • Loading branch information
riqwan authored Mar 26, 2024
1 parent a843b12 commit 448a30d
Show file tree
Hide file tree
Showing 7 changed files with 246 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./main-layout"
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
import {
Buildings,
ChevronDownMini,
CurrencyDollar,
MinusMini,
ReceiptPercent,
ShoppingCart,
SquaresPlus,
Tag,
Users,
} from "@medusajs/icons"
import { Avatar, Text } from "@medusajs/ui"
import * as Collapsible from "@radix-ui/react-collapsible"
import { useTranslation } from "react-i18next"
import { useV2Store } from "../../../lib/api-v2"

import { Skeleton } from "../../common/skeleton"
import { NavItem, NavItemProps } from "../../layout/nav-item"
import { Shell } from "../../layout/shell"

import extensions from "medusa-admin:routes/links"

export const MainLayout = () => {
return (
<Shell>
<MainSidebar />
</Shell>
)
}

const MainSidebar = () => {
return (
<aside className="flex flex-1 flex-col justify-between overflow-y-auto">
<div className="flex flex-1 flex-col">
<div className="bg-ui-bg-subtle sticky top-0">
<Header />
<div className="px-3">
<div className="border-ui-border-strong h-px w-full border-b border-dashed" />
</div>
</div>
<CoreRouteSection />
<ExtensionRouteSection />
</div>
</aside>
)
}

const Header = () => {
const { store, isError, error } = useV2Store({})

const name = store?.name
const fallback = store?.name?.slice(0, 1).toUpperCase()

if (isError) {
throw error
}

return (
<div className="w-full px-3 py-2">
<div className="flex items-center p-1 md:pr-2">
<div className="flex items-center gap-x-3">
{fallback ? (
<Avatar variant="squared" fallback={fallback} />
) : (
<Skeleton className="h-8 w-8 rounded-md" />
)}
{name ? (
<Text size="small" weight="plus" leading="compact">
{store.name}
</Text>
) : (
<Skeleton className="h-[9px] w-[120px]" />
)}
</div>
</div>
</div>
)
}

const useCoreRoutes = (): Omit<NavItemProps, "pathname">[] => {
const { t } = useTranslation()

return [
{
icon: <ShoppingCart />,
label: t("orders.domain"),
to: "/orders",
items: [
{
label: t("draftOrders.domain"),
to: "/draft-orders",
},
],
},
{
icon: <Tag />,
label: t("products.domain"),
to: "/products",
items: [
{
label: t("collections.domain"),
to: "/collections",
},
{
label: t("categories.domain"),
to: "/categories",
},
{
label: t("giftCards.domain"),
to: "/gift-cards",
},
],
},
{
icon: <Buildings />,
label: t("inventory.domain"),
to: "/inventory",
items: [
{
label: t("reservations.domain"),
to: "/reservations",
},
],
},
{
icon: <Users />,
label: t("customers.domain"),
to: "/customers",
items: [
{
label: t("customerGroups.domain"),
to: "/customer-groups",
},
],
},
{
icon: <ReceiptPercent />,
label: t("discounts.domain"),
to: "/discounts",
},
{
icon: <CurrencyDollar />,
label: t("pricing.domain"),
to: "/pricing",
},
]
}

const CoreRouteSection = () => {
const coreRoutes = useCoreRoutes()

return (
<nav className="flex flex-col gap-y-1 py-2">
{coreRoutes.map((route) => {
return <NavItem key={route.to} {...route} />
})}
</nav>
)
}

const ExtensionRouteSection = () => {
if (!extensions.links || extensions.links.length === 0) {
return null
}

return (
<div>
<div className="px-3">
<div className="border-ui-border-strong h-px w-full border-b border-dashed" />
</div>
<div className="flex flex-col gap-y-1 py-2">
<Collapsible.Root defaultOpen>
<div className="px-4">
<Collapsible.Trigger asChild className="group/trigger">
<button className="text-ui-fg-subtle flex w-full items-center justify-between px-2">
<Text size="xsmall" weight="plus" leading="compact">
Extensions
</Text>
<div className="text-ui-fg-muted">
<ChevronDownMini className="group-data-[state=open]/trigger:hidden" />
<MinusMini className="group-data-[state=closed]/trigger:hidden" />
</div>
</button>
</Collapsible.Trigger>
</div>
<Collapsible.Content>
<div className="flex flex-col gap-y-1 py-1 pb-4">
{extensions.links.map((link) => {
return (
<NavItem
key={link.path}
to={link.path}
label={link.label}
icon={link.icon ? <link.icon /> : <SquaresPlus />}
type="extension"
/>
)
})}
</div>
</Collapsible.Content>
</Collapsible.Root>
</div>
</div>
)
}
6 changes: 5 additions & 1 deletion packages/admin-next/dashboard/src/lib/api-v2/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ export const useV2Store = ({ initialData }: { initialData?: any }) => {
{ initialData }
)

const store = data.stores[0]
const store = data?.stores[0]

if (!isLoading && !isError && typeof store === "undefined") {
throw new Error("Store does not exist")
}

return { store, isLoading, isError, error }
}
31 changes: 28 additions & 3 deletions packages/admin-next/dashboard/src/providers/router-provider/v2.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { Navigate, RouteObject, useLocation } from "react-router-dom"
import { MainLayout } from "../../components/layout-v2/main-layout"
import { SettingsLayout } from "../../components/layout/settings-layout"

import { Outlet } from "react-router-dom"

import { SidebarProvider } from "../sidebar-provider"
import { SearchProvider } from "../search-provider"
import { ErrorBoundary } from "../../components/error/error-boundary"
import { Spinner } from "@medusajs/icons"
import { ErrorBoundary } from "../../components/error/error-boundary"
import { useV2Session } from "../../lib/api-v2"
import { SearchProvider } from "../search-provider"
import { SidebarProvider } from "../sidebar-provider"

export const ProtectedRoute = () => {
const { user, isLoading } = useV2Session()
Expand Down Expand Up @@ -52,6 +53,30 @@ export const v2Routes: RouteObject[] = [
path: "*",
lazy: () => import("../../routes/no-match"),
},
{
element: <ProtectedRoute />,
errorElement: <ErrorBoundary />,
children: [
{
path: "/",
element: <MainLayout />,
children: [
{
path: "/orders",
handle: {
crumb: () => "Orders",
},
children: [
{
path: "",
lazy: () => import("../../v2-routes/orders/order-list"),
},
],
},
],
},
],
},
{
element: <ProtectedRoute />,
errorElement: <ErrorBoundary />,
Expand Down
3 changes: 1 addition & 2 deletions packages/admin-next/dashboard/src/v2-routes/home/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ import { useNavigate } from "react-router-dom"
export const Home = () => {
const navigate = useNavigate()

// Currently, the home page simply redirects to the settings page
useEffect(() => {
navigate("/settings", { replace: true })
navigate("/orders", { replace: true })
}, [navigate])

return <div />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { OrderList as Component } from "./order-list"
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// TODO: This is just a placeholder to render the actual "home" page
// after logging in. Replace this with the actual order components when ready
export const OrderList = () => {
return <div className="flex w-full flex-col gap-y-2"></div>
}

0 comments on commit 448a30d

Please sign in to comment.