Skip to content

Commit

Permalink
Advanced CategoriesFilter
Browse files Browse the repository at this point in the history
  • Loading branch information
julihereu committed Jan 5, 2025
1 parent c69fd12 commit 403d0a3
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 35 deletions.
25 changes: 22 additions & 3 deletions src/components/templates/CategoriesFilter.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,36 @@
import { MultiSelect } from "@mantine/core"
import appConfig from "app.config"
import { Loader, MultiSelect } from "@mantine/core"
import { useState } from "react"
import { useDebounce } from "use-debounce"
import { useFilter } from "~/contexts/FilterContext"
import { useSiteTranslation } from "~/hooks/useSiteTranslation"
import { getEmptyCategoryGroups, getGroupForCategory } from "~/utils/categoryUtils"
import { trpc } from "~/utils/trpc"

export const CategoriesFilter = () => {
const { t } = useSiteTranslation()
const filter = useFilter()
const [prefix, setPrefix] = useState("")
const [prefixDebounced] = useDebounce(prefix, 500)
const { data, error, status } = trpc.categories.getCategories.useQuery({
language: filter.language,
prefix: prefixDebounced,
})

const groupsWithCategories = getEmptyCategoryGroups()
data?.categories.forEach((category) => {
const group = getGroupForCategory(category.key)
groupsWithCategories[group].push(category.key)
})

return (
<MultiSelect
label={t("CategoriesFilter.inputLabel")}
placeholder={t("CategoriesFilter.inputPlaceholder")}
searchValue={prefix}
onSearchChange={(value) => setPrefix(value)}
value={filter.categories}
onChange={(value) => filter.setCategories(value)}
data={Object.entries(appConfig.availableCategories).map(([group, categories]) => ({
data={Object.entries(groupsWithCategories).map(([group, categories]) => ({
group: t(`categories.group.${group}`),
items: categories.map((category) => ({
value: category,
Expand All @@ -22,6 +39,8 @@ export const CategoriesFilter = () => {
}))}
searchable
clearable
rightSection={status === "loading" ? <Loader size="xs" /> : null}
error={error?.message}
/>
)
}
37 changes: 9 additions & 28 deletions src/server/routers/categories.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,22 @@
import { Prisma } from "@prisma/client"
import { paginate } from "~/utils/pagination"
import { GetCategoriesSchema } from "~/validations/categories"
import { prisma } from "../prisma"
import { publicProcedure, router } from "../trpc"

export const categoriesRouter = router({
getCategories: publicProcedure.input(GetCategoriesSchema).query(async ({ input }) => {
const { language, filter, skip, take } = input
const { language, prefix } = input

const where: Prisma.CategoryWhereInput = {
templates: { some: { language } },
key: filter ? { contains: filter, mode: "insensitive" } : {},
}

const {
items: categories,
hasMore,
nextPage,
count,
} = await paginate({
skip,
take,
count: () => prisma.category.count({ where }),
query: (paginateArgs) =>
prisma.category.findMany({
...paginateArgs,
where,
orderBy: { key: "asc" },
select: { key: true },
}),
const categories = await prisma.category.findMany({
where: {
templates: language ? { some: { language } } : {},
key: { startsWith: prefix },
},
orderBy: { key: "asc" },
select: { key: true },
})

return {
categories: categories.map((category) => category.key),
nextPage,
hasMore,
count,
categories,
}
}),
})
3 changes: 2 additions & 1 deletion src/server/routers/templates.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Prisma } from "@prisma/client"
import {
AUTHOR_ASC,
AUTHOR_DESC,
Expand All @@ -14,7 +15,7 @@ export const templatesRouter = router({
getTemplates: publicProcedure.input(GetTemplatesSchema).query(async ({ input }) => {
const { categories, language, search, username, sorting, skip, take } = input

const where = {
const where: Prisma.TemplateWhereInput = {
AND: categories.map((category) => ({
categories: { some: { key: category } },
})),
Expand Down
20 changes: 20 additions & 0 deletions src/utils/categoryUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import appConfig from "app.config"

const categoryToGroupMap: Record<string, string> = {}
for (const [group, categories] of Object.entries(appConfig.availableCategories)) {
for (const category of categories) {
categoryToGroupMap[category] = group
}
}

export function getGroupForCategory(category: string): string {
return categoryToGroupMap[category]
}

const emptyCategoryGroups = Object.fromEntries(
Object.keys(appConfig.availableCategories).map((group) => [group, []])
)

export function getEmptyCategoryGroups(): Record<string, string[]> {
return JSON.parse(JSON.stringify(emptyCategoryGroups))
}
5 changes: 2 additions & 3 deletions src/validations/categories.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { z } from "zod"
import { PaginationSchema } from "./common"

export const GetCategoriesSchema = PaginationSchema.extend({
export const GetCategoriesSchema = z.object({
language: z.string(),
filter: z.string().optional(),
prefix: z.string(),
})

0 comments on commit 403d0a3

Please sign in to comment.