switch to only query DB for the current page
This commit is contained in:
parent
024abe2548
commit
a069f4a03a
@ -4,9 +4,10 @@ import { ClipboardDocumentListIcon } from '@heroicons/react/24/outline';
|
|||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { translateEnumPlatform, translateEnumSkill } from '~/utils/enumWordLut';
|
import { translateEnumPlatform, translateEnumSkill } from '~/utils/enumWordLut';
|
||||||
import { type ChangeEvent, type Dispatch, type SetStateAction, useState } from 'react';
|
import { type ChangeEvent } from 'react';
|
||||||
import { ChevronDownIcon } from '@heroicons/react/24/outline';
|
import { ChevronDownIcon } from '@heroicons/react/24/outline';
|
||||||
import { type ParsedUrlQuery, type ParsedUrlQueryInput } from 'querystring';
|
import { type ParsedUrlQuery, type ParsedUrlQueryInput } from 'querystring';
|
||||||
|
import { useRouter } from 'next/router';
|
||||||
|
|
||||||
export const ResourceInfo = ({resource, showMoreInfo}: {resource: AuditoryResource, showMoreInfo?: boolean}) => {
|
export const ResourceInfo = ({resource, showMoreInfo}: {resource: AuditoryResource, showMoreInfo?: boolean}) => {
|
||||||
const PriceIcons = ({type}: {type: PaymentType}) => {
|
const PriceIcons = ({type}: {type: PaymentType}) => {
|
||||||
@ -169,10 +170,10 @@ interface PagesNavigationProps {
|
|||||||
currentPage: number;
|
currentPage: number;
|
||||||
pageCount: number;
|
pageCount: number;
|
||||||
resultsPerPage: number;
|
resultsPerPage: number;
|
||||||
updateResultsPerPage: Dispatch<SetStateAction<number>>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const PagesNavigation = ({query, currentPage, pageCount, resultsPerPage, updateResultsPerPage}: PagesNavigationProps) => {
|
const PagesNavigation = ({query, currentPage, pageCount, resultsPerPage}: PagesNavigationProps) => {
|
||||||
|
const router = useRouter();
|
||||||
const PageButton = ({number}: {number: number}) => {
|
const PageButton = ({number}: {number: number}) => {
|
||||||
const redirectQueryData: ParsedUrlQueryInput = {...query};
|
const redirectQueryData: ParsedUrlQueryInput = {...query};
|
||||||
redirectQueryData.page = number;
|
redirectQueryData.page = number;
|
||||||
@ -194,7 +195,28 @@ const PagesNavigation = ({query, currentPage, pageCount, resultsPerPage, updateR
|
|||||||
});
|
});
|
||||||
|
|
||||||
const handleChange = (event: ChangeEvent<HTMLSelectElement>) => {
|
const handleChange = (event: ChangeEvent<HTMLSelectElement>) => {
|
||||||
updateResultsPerPage(parseInt(event.target.value));
|
if (!query) {
|
||||||
|
router.push({
|
||||||
|
pathname: '/resources',
|
||||||
|
query: {
|
||||||
|
perPage: event.target.value,
|
||||||
|
}
|
||||||
|
}).catch((reason) => {
|
||||||
|
console.error(reason);
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
query['perPage'] = event.target.value;
|
||||||
|
router.push({
|
||||||
|
pathname: '/resources',
|
||||||
|
query: {
|
||||||
|
...query,
|
||||||
|
}
|
||||||
|
}).catch((reason) => {
|
||||||
|
console.error(reason);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -225,21 +247,23 @@ const PagesNavigation = ({query, currentPage, pageCount, resultsPerPage, updateR
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const ResourceTable = ({resources, currentPage, query}: {resources?: AuditoryResource[], currentPage: number, query?: ParsedUrlQuery}) => {
|
const ResourceTable = ({resources, resourcesPerPage, currentPage, totalPages, query}: {
|
||||||
const [resourcesPerPage, setResourcesPerPage] = useState<number>(10);
|
resources: AuditoryResource[],
|
||||||
|
resourcesPerPage: number,
|
||||||
const totalPages = Math.ceil((resources?.length ?? 0) / resourcesPerPage);
|
currentPage: number,
|
||||||
const pageResources = resources?.slice(resourcesPerPage*(currentPage-1), (resourcesPerPage*currentPage)) ?? [];
|
totalPages: number,
|
||||||
const resourceElements = pageResources?.map((resource, index) => {
|
query: ParsedUrlQuery
|
||||||
|
}) => {
|
||||||
|
const resourceElements = resources.map((resource, index) => {
|
||||||
return (<ResourceEntry key={index} resource={resource} />);
|
return (<ResourceEntry key={index} resource={resource} />);
|
||||||
}) ?? [];
|
}) ?? [];
|
||||||
|
|
||||||
return(
|
return(
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="mx-auto rounded-xl overflow-hidden border border-neutral-400">
|
<div className="mx-auto rounded-xl overflow-hidden border border-neutral-400 drop-shadow-md overflow-hidden">
|
||||||
<PagesNavigation query={query} updateResultsPerPage={setResourcesPerPage} resultsPerPage={resourcesPerPage} currentPage={currentPage} pageCount={totalPages} />
|
<PagesNavigation query={query} resultsPerPage={resourcesPerPage} currentPage={currentPage} pageCount={totalPages} />
|
||||||
<table className="w-full table-fixed bg-neutral-200 drop-shadow-md">
|
<table className="w-full table-fixed bg-neutral-200 border-b border-neutral-400">
|
||||||
<thead className="bg-gradient-to-t from-neutral-900 to-neutral-700 rounded-xl overflow-hidden">
|
<thead className="bg-gradient-to-t from-neutral-900 to-neutral-700 drop-shadow-md">
|
||||||
<tr>
|
<tr>
|
||||||
<th className="w-1/3 max-w-xs">
|
<th className="w-1/3 max-w-xs">
|
||||||
<span className="text-gray-300 block px-4 py-2 text-left">
|
<span className="text-gray-300 block px-4 py-2 text-left">
|
||||||
@ -262,6 +286,9 @@ const ResourceTable = ({resources, currentPage, query}: {resources?: AuditoryRes
|
|||||||
{resourceElements}
|
{resourceElements}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
{(resources && resources.length > 4) ?
|
||||||
|
<PagesNavigation query={query} resultsPerPage={resourcesPerPage} currentPage={currentPage} pageCount={totalPages} />
|
||||||
|
: undefined}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -12,17 +12,21 @@ const Resources = () => {
|
|||||||
const queryData = parseQueryData(router.query);
|
const queryData = parseQueryData(router.query);
|
||||||
const currentPage = queryData.page;
|
const currentPage = queryData.page;
|
||||||
|
|
||||||
const query = api.auditoryResource.search.useQuery({
|
const resourceQuery = api.auditoryResource.search.useQuery({
|
||||||
|
skip: (queryData.page - 1) * queryData.perPage,
|
||||||
|
take: queryData.perPage,
|
||||||
ages: queryData.age,
|
ages: queryData.age,
|
||||||
platforms: queryData.platforms,
|
platforms: queryData.platforms,
|
||||||
skill_levels: queryData.skill_levels,
|
skill_levels: queryData.skill_levels,
|
||||||
skills: queryData.skills,
|
skills: queryData.skills,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!query.data) {
|
if (!resourceQuery.data) {
|
||||||
return <></>
|
return <></>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const totalPages = Math.ceil(resourceQuery.data.count / queryData.perPage);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Head>
|
<Head>
|
||||||
@ -43,7 +47,7 @@ const Resources = () => {
|
|||||||
<p className="inline"> for specific resource recommendations.</p>
|
<p className="inline"> for specific resource recommendations.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ResourceTable query={router.query} resources={query.data} currentPage={currentPage} />
|
<ResourceTable resourcesPerPage={queryData.perPage} resources={resourceQuery.data.resources} totalPages={totalPages} query={router.query} currentPage={currentPage} />
|
||||||
</main>
|
</main>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { SkillLevel, Skill, Platform, AuditoryResource } from "@prisma/client";
|
import { SkillLevel, Skill, Platform, type AuditoryResource } from "@prisma/client";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -24,6 +24,8 @@ export const auditoryResourceRouter = createTRPCRouter({
|
|||||||
|
|
||||||
search: publicProcedure
|
search: publicProcedure
|
||||||
.input(z.object({
|
.input(z.object({
|
||||||
|
take: z.number().int(),
|
||||||
|
skip: z.number().int(),
|
||||||
ages: z.object({
|
ages: z.object({
|
||||||
min: z.number().int(),
|
min: z.number().int(),
|
||||||
max: z.number().int(),
|
max: z.number().int(),
|
||||||
@ -32,10 +34,8 @@ export const auditoryResourceRouter = createTRPCRouter({
|
|||||||
skill_levels: z.nativeEnum(SkillLevel).array().optional(),
|
skill_levels: z.nativeEnum(SkillLevel).array().optional(),
|
||||||
skills: z.nativeEnum(Skill).array().optional(),
|
skills: z.nativeEnum(Skill).array().optional(),
|
||||||
}))
|
}))
|
||||||
.query(({ input, ctx}) => {
|
.query(async ({ input, ctx}) => {
|
||||||
|
const search = {
|
||||||
return ctx.prisma.auditoryResource.findMany({
|
|
||||||
where: {
|
|
||||||
ages: {
|
ages: {
|
||||||
is: {
|
is: {
|
||||||
min: {
|
min: {
|
||||||
@ -60,6 +60,21 @@ export const auditoryResourceRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const [count, resources] = await ctx.prisma.$transaction([
|
||||||
|
ctx.prisma.auditoryResource.count({
|
||||||
|
where: search,
|
||||||
|
}),
|
||||||
|
ctx.prisma.auditoryResource.findMany({
|
||||||
|
skip: input.skip,
|
||||||
|
take: input.take,
|
||||||
|
where: search,
|
||||||
})
|
})
|
||||||
|
]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
count,
|
||||||
|
resources,
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
@ -3,6 +3,7 @@ import { type ParsedUrlQuery } from "querystring";
|
|||||||
|
|
||||||
export interface ViewDetails {
|
export interface ViewDetails {
|
||||||
page: number;
|
page: number;
|
||||||
|
perPage: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SearchQuery {
|
export interface SearchQuery {
|
||||||
@ -17,6 +18,7 @@ export type ParsedQueryData = SearchQuery & ViewDetails;
|
|||||||
export const parseQueryData = (query: ParsedUrlQuery): ParsedQueryData => {
|
export const parseQueryData = (query: ParsedUrlQuery): ParsedQueryData => {
|
||||||
const view = {
|
const view = {
|
||||||
page: Number(query["page"] ?? 1),
|
page: Number(query["page"] ?? 1),
|
||||||
|
perPage: Number(query["perPage"] ?? 10),
|
||||||
}
|
}
|
||||||
const filter: SearchQuery = {};
|
const filter: SearchQuery = {};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user