diff --git a/apps/console/src/pages/organizations/context/ContextLayout.tsx b/apps/console/src/pages/organizations/context/ContextLayoutLoader.tsx similarity index 87% rename from apps/console/src/pages/organizations/context/ContextLayout.tsx rename to apps/console/src/pages/organizations/context/ContextLayoutLoader.tsx index 3cfe0106b..b728498d2 100644 --- a/apps/console/src/pages/organizations/context/ContextLayout.tsx +++ b/apps/console/src/pages/organizations/context/ContextLayoutLoader.tsx @@ -5,7 +5,7 @@ import { Outlet } from "react-router"; import { useOrganizationId } from "#/hooks/useOrganizationId"; -export default function ContextLayout() { +export default function ContextLayoutLoader() { const { __ } = useTranslate(); const organizationId = useOrganizationId(); const prefix = `/organizations/${organizationId}/context`; @@ -21,7 +21,7 @@ export default function ContextLayout() { )} /> - {__("Context")} + {__("Context")} {__("Meetings")} diff --git a/apps/console/src/pages/organizations/context/ContextPageLoader.tsx b/apps/console/src/pages/organizations/context/ContextPageLoader.tsx index fa814d775..2a879487e 100644 --- a/apps/console/src/pages/organizations/context/ContextPageLoader.tsx +++ b/apps/console/src/pages/organizations/context/ContextPageLoader.tsx @@ -1,11 +1,15 @@ -import { type PreloadedQuery, usePreloadedQuery } from "react-relay"; +import { useEffect } from "react"; +import { type PreloadedQuery, usePreloadedQuery, useQueryLoader } from "react-relay"; import { graphql } from "relay-runtime"; import type { ContextPageLoaderQuery } from "#/__generated__/core/ContextPageLoaderQuery.graphql"; +import { LinkCardSkeleton } from "#/components/skeletons/LinkCardSkeleton"; +import { useOrganizationId } from "#/hooks/useOrganizationId"; +import { CoreRelayProvider } from "#/providers/CoreRelayProvider"; import ContextPage from "./ContextPage"; -export const contextPageQuery = graphql` +const contextPageQuery = graphql` query ContextPageLoaderQuery($organizationId: ID!) { organization: node(id: $organizationId) { ... on Organization { @@ -15,12 +19,31 @@ export const contextPageQuery = graphql` } `; -type Props = { - queryRef: PreloadedQuery; -}; +function ContextPageQueryLoader() { + const organizationId = useOrganizationId(); + const [queryRef, loadQuery] = useQueryLoader(contextPageQuery); -export default function ContextPageLoader(props: Props) { - const data = usePreloadedQuery(contextPageQuery, props.queryRef); + useEffect(() => { + if (!queryRef) { + loadQuery({ organizationId }); + } + }); + + if (!queryRef) return ; + + return ; +} + +function ContextPageInner({ queryRef }: { queryRef: PreloadedQuery }) { + const data = usePreloadedQuery(contextPageQuery, queryRef); return ; } + +export default function ContextPageLoader() { + return ( + + + + ); +} diff --git a/apps/console/src/pages/organizations/meetings/MeetingDetailPageLoader.tsx b/apps/console/src/pages/organizations/meetings/MeetingDetailPageLoader.tsx new file mode 100644 index 000000000..b59d4f15f --- /dev/null +++ b/apps/console/src/pages/organizations/meetings/MeetingDetailPageLoader.tsx @@ -0,0 +1,32 @@ +import { useEffect } from "react"; +import { useQueryLoader } from "react-relay"; +import { useParams } from "react-router"; + +import type { MeetingDetailPageQuery } from "#/__generated__/core/MeetingDetailPageQuery.graphql"; +import { PageSkeleton } from "#/components/skeletons/PageSkeleton"; +import { CoreRelayProvider } from "#/providers/CoreRelayProvider"; + +import MeetingDetailPage, { meetingDetailPageQuery } from "./MeetingDetailPage"; + +function MeetingDetailPageQueryLoader() { + const { meetingId } = useParams<{ meetingId: string }>(); + const [queryRef, loadQuery] = useQueryLoader(meetingDetailPageQuery); + + useEffect(() => { + if (!queryRef && meetingId) { + loadQuery({ meetingId }); + } + }); + + if (!queryRef) return ; + + return ; +} + +export default function MeetingDetailPageLoader() { + return ( + + + + ); +} diff --git a/apps/console/src/pages/organizations/meetings/MeetingsPageLoader.tsx b/apps/console/src/pages/organizations/meetings/MeetingsPageLoader.tsx new file mode 100644 index 000000000..9f2e9631b --- /dev/null +++ b/apps/console/src/pages/organizations/meetings/MeetingsPageLoader.tsx @@ -0,0 +1,32 @@ +import { useEffect } from "react"; +import { useQueryLoader } from "react-relay"; + +import type { MeetingsPageQuery } from "#/__generated__/core/MeetingsPageQuery.graphql"; +import { LinkCardSkeleton } from "#/components/skeletons/LinkCardSkeleton"; +import { useOrganizationId } from "#/hooks/useOrganizationId"; +import { CoreRelayProvider } from "#/providers/CoreRelayProvider"; + +import MeetingsPage, { meetingsPageQuery } from "./MeetingsPage"; + +function MeetingsPageQueryLoader() { + const organizationId = useOrganizationId(); + const [queryRef, loadQuery] = useQueryLoader(meetingsPageQuery); + + useEffect(() => { + if (!queryRef) { + loadQuery({ organizationId }); + } + }); + + if (!queryRef) return ; + + return ; +} + +export default function MeetingsPageLoader() { + return ( + + + + ); +} diff --git a/apps/console/src/routes/contextRoutes.ts b/apps/console/src/routes/contextRoutes.ts index 29e8ae7c2..57d190565 100644 --- a/apps/console/src/routes/contextRoutes.ts +++ b/apps/console/src/routes/contextRoutes.ts @@ -1,113 +1,46 @@ import { lazy } from "@probo/react-lazy"; -import { - type AppRoute, - loaderFromQueryLoader, - withQueryRef, -} from "@probo/routes"; -import { Fragment } from "react"; -import { loadQuery } from "react-relay"; -import { type LoaderFunctionArgs, redirect } from "react-router"; +import type { AppRoute } from "@probo/routes"; -import type { ContextPageLoaderQuery } from "#/__generated__/core/ContextPageLoaderQuery.graphql"; -import type { MeetingDetailPageQuery } from "#/__generated__/core/MeetingDetailPageQuery.graphql"; -import type { MeetingsPageQuery } from "#/__generated__/core/MeetingsPageQuery.graphql"; import { LinkCardSkeleton } from "#/components/skeletons/LinkCardSkeleton"; import { PageSkeleton } from "#/components/skeletons/PageSkeleton"; -import { coreEnvironment } from "#/environments"; -import { contextPageQuery } from "#/pages/organizations/context/ContextPageLoader"; -import { meetingDetailPageQuery } from "#/pages/organizations/meetings/MeetingDetailPage"; -import { meetingsPageQuery } from "#/pages/organizations/meetings/MeetingsPage"; - -const meetingTabs = (prefix: string) => { - return [ - { - path: `${prefix}`, - loader: ({ - params: { organizationId, meetingId }, - }: LoaderFunctionArgs) => { - const basePath = `/organizations/${organizationId}/context/meetings/${meetingId}`; - const redirectPath = `${basePath}/minutes`; - // eslint-disable-next-line - throw redirect(redirectPath); - }, - Component: Fragment, - }, - { - path: `${prefix}minutes`, - Fallback: LinkCardSkeleton, - Component: lazy( - () => import("../pages/organizations/meetings/tabs/MeetingMinutesTab"), - ), - }, - ]; -}; export const contextRoutes = [ { path: "context", Fallback: PageSkeleton, Component: lazy( - () => import("#/pages/organizations/context/ContextLayout"), + () => import("#/pages/organizations/context/ContextLayoutLoader"), ), children: [ { - path: "", - loader: ({ - params: { organizationId }, - }: LoaderFunctionArgs) => { - // eslint-disable-next-line - throw redirect(`/organizations/${organizationId}/context/overview`); - }, - Component: Fragment, - }, - { - path: "overview", - Fallback: PageSkeleton, - loader: loaderFromQueryLoader(({ organizationId }) => - loadQuery( - coreEnvironment, - contextPageQuery, - { organizationId }, - ), - ), - Component: withQueryRef( - lazy( - () => import("#/pages/organizations/context/ContextPageLoader"), - ), + index: true, + Fallback: LinkCardSkeleton, + Component: lazy( + () => import("#/pages/organizations/context/ContextPageLoader"), ), }, { path: "meetings", - Fallback: PageSkeleton, - loader: loaderFromQueryLoader(({ organizationId }) => - loadQuery( - coreEnvironment, - meetingsPageQuery, - { organizationId }, - ), - ), - Component: withQueryRef( - lazy( - () => import("#/pages/organizations/meetings/MeetingsPage"), - ), + Fallback: LinkCardSkeleton, + Component: lazy( + () => import("#/pages/organizations/meetings/MeetingsPageLoader"), ), }, { path: "meetings/:meetingId", Fallback: PageSkeleton, - loader: loaderFromQueryLoader(({ meetingId }) => - loadQuery( - coreEnvironment, - meetingDetailPageQuery, - { meetingId }, - ), + Component: lazy( + () => import("#/pages/organizations/meetings/MeetingDetailPageLoader"), ), - Component: withQueryRef( - lazy( - () => import("../pages/organizations/meetings/MeetingDetailPage"), - ), - ), - children: [...meetingTabs("")], + children: [ + { + index: true, + Fallback: LinkCardSkeleton, + Component: lazy( + () => import("#/pages/organizations/meetings/tabs/MeetingMinutesTab"), + ), + }, + ], }, ], },