Skip to content

Commit f285a78

Browse files
Simple filter options for articles (#205)
* Simple filter options for articles
1 parent 3e29f27 commit f285a78

3 files changed

Lines changed: 63 additions & 10 deletions

File tree

pages/articles/index.tsx

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,33 @@
11
import { Children, Fragment, useEffect } from "react";
2-
32
import Head from "next/head";
43
import ArticlePreview from "../../components/ArticlePreview/ArticlePreview";
54
import ArticleLoading from "../../components/ArticlePreview/ArticleLoading";
65
import Layout from "../../components/Layout/Layout";
7-
import PageHeading from "../../components/PageHeading/PageHeading";
86
import { trpc } from "../../utils/trpc";
97
import { useInView } from "react-intersection-observer";
8+
import { useRouter } from "next/router";
109

1110
const ArticlesPage = () => {
11+
const router = useRouter();
12+
13+
const { filter } = router.query;
14+
15+
type Filter = "newest" | "oldest" | "top";
16+
const filters: Filter[] = ["newest", "oldest", "top"];
17+
18+
const getSortBy = () => {
19+
if (typeof filter === "string") {
20+
const hasFilter = filters.some((f) => f === filter);
21+
if (hasFilter) return filter as Filter;
22+
}
23+
return "newest";
24+
};
25+
26+
const selectedSortFilter = getSortBy();
27+
1228
const { status, data, isFetchingNextPage, fetchNextPage, hasNextPage } =
1329
trpc.post.all.useInfiniteQuery(
14-
{ limit: 15 },
30+
{ limit: 15, sort: selectedSortFilter },
1531
{
1632
getNextPageParam: (lastPage) => lastPage.nextCursor,
1733
}
@@ -28,7 +44,7 @@ const ArticlesPage = () => {
2844
return (
2945
<>
3046
<Head>
31-
<title>Codú | Articles - View our latest web developer articles</title>
47+
<title>{`Codú - View our ${selectedSortFilter} web developer articles`}</title>
3248
<meta name="description" content="Codú | Web Developer Community" />
3349
<link rel="icon" href="/favicon.ico" />
3450
<link rel="manifest" href="site.webmanifest" />
@@ -40,7 +56,7 @@ const ArticlesPage = () => {
4056
<link rel="alternate" type="application/rss+xml" href="/feed.xml" />
4157
<meta
4258
property="og:image"
43-
content="/images/og/home-og.png"
59+
content="https://codu.co/images/og/home-og.png"
4460
key="og:image"
4561
/>
4662
<meta property="og:type" content="website" />
@@ -49,7 +65,29 @@ const ArticlesPage = () => {
4965
<Layout>
5066
<div className="border-t border-white">
5167
<div className="relative sm:mx-auto max-w-2xl mx-4">
52-
<PageHeading>Articles</PageHeading>
68+
<div className="my-8 border-b-2 pb-4 flex justify-between items-center">
69+
<h1 className="text-3xl tracking-tight font-extrabold text-gray-50 sm:text-4xl ">
70+
Articles
71+
</h1>
72+
<div>
73+
<label htmlFor="filter" className="sr-only">
74+
Location
75+
</label>
76+
<select
77+
id="filter"
78+
name="filter"
79+
className="capitalize mt-2 block w-full rounded-md border-0 py-1.5 pl-3 pr-10 ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-pink-600 sm:text-sm sm:leading-6 "
80+
onChange={(e) => {
81+
router.push(`/articles?filter=${e.target.value}`);
82+
}}
83+
value={selectedSortFilter}
84+
>
85+
<option>newest</option>
86+
<option>oldest</option>
87+
<option>top</option>
88+
</select>
89+
</div>
90+
</div>
5391
<section>
5492
{status === "error" && (
5593
<div>Something went wrong... Please refresh your page.</div>

schema/post.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export const GetPostsSchema = z.object({
5858
userId: z.string().optional(),
5959
limit: z.number().min(1).max(100).nullish(),
6060
cursor: z.string().nullish(),
61+
sort: z.enum(["newest", "oldest", "top"]),
6162
});
6263

6364
export type SavePostInput = z.TypeOf<typeof SavePostSchema>;

server/trpc/router/post.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
GetByIdSchema,
1515
} from "../../../schema/post";
1616
import { removeMarkdown } from "../../../utils/removeMarkdown";
17+
import { Prisma } from "@prisma/client";
1718

1819
export const postRouter = router({
1920
create: protectedProcedure
@@ -239,7 +240,22 @@ export const postRouter = router({
239240
all: publicProcedure.input(GetPostsSchema).query(async ({ ctx, input }) => {
240241
const userId = ctx.session?.user?.id;
241242
const limit = input?.limit ?? 50;
242-
const { cursor } = input;
243+
const { cursor, sort } = input;
244+
const orderMapping = {
245+
newest: {
246+
published: "desc" as Prisma.SortOrder,
247+
},
248+
oldest: {
249+
published: "asc" as Prisma.SortOrder,
250+
},
251+
top: {
252+
likes: {
253+
_count: "desc" as Prisma.SortOrder,
254+
},
255+
},
256+
};
257+
const orderBy = orderMapping[sort] || orderMapping["newest"];
258+
243259
const response = await ctx.prisma.post.findMany({
244260
take: limit + 1,
245261
where: {
@@ -264,9 +280,7 @@ export const postRouter = router({
264280
},
265281
cursor: cursor ? { id: cursor } : undefined,
266282
skip: cursor ? 1 : 0,
267-
orderBy: {
268-
published: "desc",
269-
},
283+
orderBy,
270284
});
271285

272286
const cleaned = response.map((post) => {

0 commit comments

Comments
 (0)