create reusable query render wrapper that handles loading and error states
This commit is contained in:
parent
9074f79dee
commit
1566be88f6
34
src/components/LoadingWrapper.tsx
Normal file
34
src/components/LoadingWrapper.tsx
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { type UseTRPCQueryResult } from "@trpc/react-query/shared";
|
||||||
|
import { LoadingBarChart } from "./LoadingBarChart";
|
||||||
|
import { ErrorNotice } from "./notice";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic query wrapper which handles the states of a query
|
||||||
|
* (loading, error, etc.). Will hydrate child with query.data
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export function QueryWaitWrapper<TData, TError>({
|
||||||
|
query,
|
||||||
|
Render,
|
||||||
|
}: {
|
||||||
|
query: UseTRPCQueryResult<TData, TError>;
|
||||||
|
Render: (data: TData) => JSX.Element;
|
||||||
|
}) {
|
||||||
|
if (query.isLoading) {
|
||||||
|
return <LoadingBarChart width={200} height={200} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!query.data || query.isError) {
|
||||||
|
return (
|
||||||
|
<div className="my-10 sm:my-16 md:my-28">
|
||||||
|
<ErrorNotice
|
||||||
|
icon
|
||||||
|
header="Unable to retrieve page data. Please try again."
|
||||||
|
body="If this issue persists, please contact a site administrator"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return <Render {...query.data} />;
|
||||||
|
}
|
@ -5,9 +5,9 @@ import { useRouter } from "next/router";
|
|||||||
import ResourceTable from "~/components/ResourceTable";
|
import ResourceTable from "~/components/ResourceTable";
|
||||||
import { api } from "~/utils/api";
|
import { api } from "~/utils/api";
|
||||||
import { parseQueryData } from "~/utils/parseSearchForm";
|
import { parseQueryData } from "~/utils/parseSearchForm";
|
||||||
import { LoadingBarChart } from "~/components/LoadingBarChart";
|
|
||||||
import { ErrorNotice } from "~/components/notice";
|
|
||||||
import { HeaderFooterLayout } from "~/layouts/HeaderFooterLayout";
|
import { HeaderFooterLayout } from "~/layouts/HeaderFooterLayout";
|
||||||
|
import { type AuditoryResource } from "@prisma/client";
|
||||||
|
import { QueryWaitWrapper } from "~/components/LoadingWrapper";
|
||||||
|
|
||||||
const Resources = () => {
|
const Resources = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -30,29 +30,16 @@ const Resources = () => {
|
|||||||
: "";
|
: "";
|
||||||
const printLink = `${router.route}/print?${printQueryStr}`;
|
const printLink = `${router.route}/print?${printQueryStr}`;
|
||||||
|
|
||||||
const ConditionalTable = () => {
|
const ConditionalTable = (data: {
|
||||||
if (resourceQuery.isLoading) {
|
count: number;
|
||||||
return <LoadingBarChart width={200} height={200} />;
|
resources: AuditoryResource[];
|
||||||
}
|
}) => {
|
||||||
|
const totalPages = Math.ceil(data.count / queryData.perPage);
|
||||||
if (!resourceQuery.data || resourceQuery.isError) {
|
|
||||||
return (
|
|
||||||
<div className="my-10 sm:my-16 md:my-28">
|
|
||||||
<ErrorNotice
|
|
||||||
icon
|
|
||||||
header="Unable to pull available resources. Please try again."
|
|
||||||
body="If this issue persists, please contact a site administrator"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const totalPages = Math.ceil(resourceQuery.data.count / queryData.perPage);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ResourceTable
|
<ResourceTable
|
||||||
resourcesPerPage={queryData.perPage}
|
resourcesPerPage={queryData.perPage}
|
||||||
resources={resourceQuery.data.resources}
|
resources={data.resources}
|
||||||
totalPages={totalPages}
|
totalPages={totalPages}
|
||||||
query={router.query}
|
query={router.query}
|
||||||
currentPage={currentPage}
|
currentPage={currentPage}
|
||||||
@ -92,7 +79,8 @@ const Resources = () => {
|
|||||||
</Link>
|
</Link>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
<ConditionalTable />
|
|
||||||
|
<QueryWaitWrapper query={resourceQuery} Render={ConditionalTable} />
|
||||||
</div>
|
</div>
|
||||||
</HeaderFooterLayout>
|
</HeaderFooterLayout>
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user