1
0

Part searching

This commit is contained in:
Ahmed Al-Taiar
2023-11-15 10:53:26 -05:00
parent 8060e1e452
commit adf1627405
4 changed files with 120 additions and 32 deletions

View File

@ -14,6 +14,7 @@ export const schema = gql`
page: Int! page: Int!
sort: SortMethod! sort: SortMethod!
order: SortOrder! order: SortOrder!
search: String
} }
enum SortMethod { enum SortMethod {
@ -30,7 +31,12 @@ export const schema = gql`
} }
type Query { type Query {
partPage(page: Int, sort: SortMethod, order: SortOrder): PartPage @skipAuth partPage(
page: Int!
sort: SortMethod!
order: SortOrder!
searchQuery: String
): PartPage @skipAuth
parts: [Part!]! @skipAuth parts: [Part!]! @skipAuth
part(id: Int!): Part @skipAuth part(id: Int!): Part @skipAuth
} }

View File

@ -1,10 +1,5 @@
import * as Filestack from 'filestack-js' import * as Filestack from 'filestack-js'
import type { import type { QueryResolvers, MutationResolvers } from 'types/graphql'
QueryResolvers,
MutationResolvers,
SortMethod,
SortOrder,
} from 'types/graphql'
import { db } from 'src/lib/db' import { db } from 'src/lib/db'
@ -23,14 +18,11 @@ export const part: QueryResolvers['part'] = ({ id }) => {
}) })
} }
export const partPage = ({ export const partPage: QueryResolvers['partPage'] = async ({
page = 1, page = 1,
sort = 'id', sort = 'id',
order = 'ascending', order = 'ascending',
}: { searchQuery,
page: number
sort: SortMethod
order: SortOrder
}) => { }) => {
const offset = (page - 1) * PARTS_PER_PAGE const offset = (page - 1) * PARTS_PER_PAGE
let orderByCase let orderByCase
@ -63,17 +55,42 @@ export const partPage = ({
break break
} }
return { if (searchQuery && searchQuery.length > 0)
parts: db.part.findMany({ return {
take: PARTS_PER_PAGE, parts: await db.part.findMany({
skip: offset, where: {
orderBy: orderByCase, name: {
}), contains: searchQuery,
count: db.part.count(), },
page, },
sort, take: PARTS_PER_PAGE,
order, skip: offset,
} orderBy: orderByCase,
}),
count: await db.part.count({
where: {
name: {
contains: searchQuery,
},
},
}),
page,
sort,
order,
search: searchQuery,
}
else
return {
parts: await db.part.findMany({
take: PARTS_PER_PAGE,
skip: offset,
orderBy: orderByCase,
}),
count: await db.part.count(),
page,
sort,
order,
}
} }
export const createPart: MutationResolvers['createPart'] = ({ input }) => { export const createPart: MutationResolvers['createPart'] = ({ input }) => {

View File

@ -1,4 +1,6 @@
/* eslint-disable jsx-a11y/no-noninteractive-tabindex */ /* eslint-disable jsx-a11y/no-noninteractive-tabindex */
import { useState } from 'react'
import { import {
mdiAlert, mdiAlert,
mdiChevronRight, mdiChevronRight,
@ -16,7 +18,7 @@ import PartsGridUnit from '../PartsGridUnit/PartsGridUnit'
const POSTS_PER_PAGE = 8 const POSTS_PER_PAGE = 8
export const beforeQuery = ({ page, sort, order }) => { export const beforeQuery = ({ page, sort, order, search }) => {
page = page ? parseInt(page, 10) : 1 page = page ? parseInt(page, 10) : 1
sort = sort =
sort && sort &&
@ -26,12 +28,17 @@ export const beforeQuery = ({ page, sort, order }) => {
order = order =
order && (['ascending', 'descending'].includes(order) ? order : 'ascending') order && (['ascending', 'descending'].includes(order) ? order : 'ascending')
return { variables: { page, sort, order } } return { variables: { page, sort, order, search } }
} }
export const QUERY = gql` export const QUERY = gql`
query PartsQuery($page: Int, $sort: SortMethod, $order: SortOrder) { query PartsQuery(
partPage(page: $page, sort: $sort, order: $order) { $page: Int!
$sort: SortMethod!
$order: SortOrder!
$search: String
) {
partPage(page: $page, sort: $sort, order: $order, searchQuery: $search) {
parts { parts {
id id
name name
@ -44,6 +51,7 @@ export const QUERY = gql`
page page
sort sort
order order
search
} }
} }
` `
@ -54,8 +62,33 @@ export const Loading = () => (
</div> </div>
) )
export const Empty = () => ( export const Empty = (
<div className="flex justify-center"> search: string,
setSearch: {
(value: React.SetStateAction<string>): void
(arg0: string): void
}
) => (
<div className="mx-auto w-fit flex-col justify-center space-y-3">
<div className="flex space-x-3 font-inter">
<input
type="search"
autoComplete="off"
spellCheck="false"
placeholder="Search"
className="input input-bordered w-full max-w-xs"
value={search}
onChange={(e) => setSearch(e.target.value)}
/>
<Link
className="btn"
to={routes.home({
search: search,
})}
>
Search
</Link>
</div>
<div className="alert w-auto"> <div className="alert w-auto">
<p className="text-center font-inter">It&#39;s empty in here...</p> <p className="text-center font-inter">It&#39;s empty in here...</p>
</div> </div>
@ -112,13 +145,37 @@ export const Success = ({ partPage }: CellSuccessProps<PartsQuery>) => {
return orderText return orderText
} }
if (partPage.count == 0) return Empty() const [search, setSearch] = useState(partPage.search ?? '')
if (partPage.count == 0) return Empty(search, setSearch)
else { else {
const sortByText: string = sortMethodToText(partPage.sort) const sortByText: string = sortMethodToText(partPage.sort)
const orderText: string = sortOrderToText(partPage.order) const orderText: string = sortOrderToText(partPage.order)
return ( return (
<div className="flex flex-col items-center space-y-6"> <div className="flex flex-col items-center space-y-6">
<div className="flex space-x-3 font-inter">
<input
type="search"
autoComplete="off"
spellCheck="false"
placeholder="Search (case sensitive)"
className="input input-bordered w-full max-w-xs"
value={search}
onChange={(e) => setSearch(e.target.value)}
/>
<Link
className="btn"
to={routes.home({
page: partPage.page,
sort: partPage.sort,
order: partPage.order,
search: search,
})}
>
Search
</Link>
</div>
<div className="flex space-x-3 font-inter"> <div className="flex space-x-3 font-inter">
<div className="dropdown"> <div className="dropdown">
<label tabIndex={0} className="btn m-1 normal-case"> <label tabIndex={0} className="btn m-1 normal-case">
@ -137,6 +194,7 @@ export const Success = ({ partPage }: CellSuccessProps<PartsQuery>) => {
page: partPage.page, page: partPage.page,
sort, sort,
order: partPage.order, order: partPage.order,
search: partPage.search,
})} })}
> >
{sortMethodToText(sort)} {sortMethodToText(sort)}
@ -162,6 +220,7 @@ export const Success = ({ partPage }: CellSuccessProps<PartsQuery>) => {
page: partPage.page, page: partPage.page,
sort: partPage.sort, sort: partPage.sort,
order, order,
search: partPage.search,
})} })}
> >
{sortOrderToText(order)} {sortOrderToText(order)}

View File

@ -8,9 +8,15 @@ interface Props {
page: number page: number
sort: SortMethod sort: SortMethod
order: SortOrder order: SortOrder
search?: string
} }
const HomePage = ({ page = 1, sort = 'id', order = 'ascending' }: Props) => { const HomePage = ({
page = 1,
sort = 'id',
order = 'ascending',
search,
}: Props) => {
return ( return (
<> <>
<MetaTags title="Home" description="Home page" /> <MetaTags title="Home" description="Home page" />
@ -21,7 +27,7 @@ const HomePage = ({ page = 1, sort = 'id', order = 'ascending' }: Props) => {
</h1> </h1>
<p className="pt-4 text-xl">Only take what you need</p> <p className="pt-4 text-xl">Only take what you need</p>
</div> </div>
<PartsCell page={page} sort={sort} order={order} /> <PartsCell page={page} sort={sort} order={order} search={search} />
</> </>
) )
} }