Part searching
This commit is contained in:
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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 }) => {
|
||||||
|
@ -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's empty in here...</p>
|
<p className="text-center font-inter">It'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)}
|
||||||
|
@ -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} />
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user