Skip to content

Commit

Permalink
use nuqs, add slug to blog.category
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchuman committed Nov 24, 2024
1 parent 594b67f commit 533a45e
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 46 deletions.
35 changes: 33 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sanitypress",
"version": "5.1.11",
"version": "5.1.12",
"description": "A Next.js + Sanity.io Starter Template",
"author": "nuotsu <mitchell@nuotsu.dev> (https://nuotsu.dev)",
"license": "ISC",
Expand All @@ -27,6 +27,7 @@
"next": "^15.0.3",
"next-sanity": "^9.8.16",
"next-sanity-image": "^6.1.1",
"nuqs": "^2.2.3",
"octokit": "^4.0.2",
"react": "^18",
"react-device-detect": "^2.2.3",
Expand Down
20 changes: 12 additions & 8 deletions src/app/(frontend)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// import { GoogleTagManager } from '@next/third-parties/google'
import { NuqsAdapter } from 'nuqs/adapters/next/app'
import SkipToContent from '@/ui/SkipToContent'
import Announcement from '@/ui/Announcement'
import Header from '@/ui/header'
Expand All @@ -18,15 +19,18 @@ export default async function RootLayout({
{/* <GoogleTagManager gtmId='' /> */}

<body className="bg-canvas text-ink">
<SkipToContent />
<Announcement />
<Header />
<main id="main-content" tabIndex={-1}>
{children}
</main>
<Footer />
<NuqsAdapter>
<SkipToContent />
<Announcement />
<Header />
<main id="main-content" tabIndex={-1}>
{children}
</main>
<Footer />

<VisualEditingControls />
</NuqsAdapter>

<VisualEditingControls />
<Analytics />
<SpeedInsights />
</body>
Expand Down
9 changes: 9 additions & 0 deletions src/sanity/schemas/documents/blog.category.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ export default defineType({
defineField({
name: 'title',
type: 'string',
validation: (Rule) => Rule.required(),
}),
defineField({
name: 'slug',
type: 'slug',
options: {
source: 'title',
},
validation: (Rule) => Rule.required(),
}),
],
})
1 change: 1 addition & 0 deletions src/types/Sanity.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ declare global {

type BlogCategory = SanityDocument<{
title: string
slug: { current: string }
}>

// miscellaneous
Expand Down
6 changes: 3 additions & 3 deletions src/ui/modules/blog/BlogFrontpage/Paginated.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
'use client'

import { useEffect } from 'react'
import { useCategory } from '../store'
import usePagination from '@/lib/usePagination'
import { categoryStore } from '../store'
import List, { filterPosts } from '../BlogList/List'

export default function Paginated({
Expand All @@ -18,9 +18,9 @@ export default function Paginated({
itemsPerPage,
})

const { selected } = categoryStore()
const { category } = useCategory()

useEffect(resetPage, [selected])
useEffect(resetPage, [category])

return (
<div className="relative space-y-12">
Expand Down
12 changes: 4 additions & 8 deletions src/ui/modules/blog/BlogList/Filter.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
'use client'

import { useEffect } from 'react'
import { usePathname } from 'next/navigation'
import { categoryStore } from '../store'
import { useCategory } from '../store'
import Category from '../Category'
import { cn } from '@/lib/utils'
import css from './FilterList.module.css'
Expand All @@ -14,20 +12,18 @@ export default function Filter({
label: string
value?: 'All' | string
}) {
const { selected, setSelected, reset } = categoryStore()

useEffect(reset, [usePathname()])
const { category, setCategory } = useCategory()

return (
<button
className={cn(
css.filter,
'!py-1',
selected === value
category === value
? 'action *:text-white/50'
: 'ghost border border-transparent',
)}
onClick={() => setSelected(value)}
onClick={() => setCategory(value)}
>
<Category label={label} />
</button>
Expand Down
6 changes: 5 additions & 1 deletion src/ui/modules/blog/BlogList/FilterList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ export default async function FilterList() {
<Filter label="All" />

{categories?.map((category, key) => (
<Filter label={category.title} value={category._id} key={key} />
<Filter
label={category.title}
value={category.slug?.current}
key={key}
/>
))}
</div>
</fieldset>
Expand Down
14 changes: 4 additions & 10 deletions src/ui/modules/blog/BlogList/List.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
'use client'

import { useEffect } from 'react'
import { usePathname } from 'next/navigation'
import { categoryStore } from '../store'
import PostPreview from '../PostPreview'
import { useCategory } from '../store'

export default function List({
posts,
...props
}: {
posts: Sanity.BlogPost[]
} & React.ComponentProps<'ul'>) {
const { reset } = categoryStore()

useEffect(reset, [usePathname()])

const filtered = filterPosts(posts)

if (!filtered.length) {
Expand All @@ -33,11 +27,11 @@ export default function List({
}

export function filterPosts(posts: Sanity.BlogPost[]) {
const { selected } = categoryStore()
const { category } = useCategory()

return posts.filter(
(post) =>
selected === 'All' ||
post.categories?.some((category) => category._id === selected),
category === 'All' ||
post.categories?.some(({ slug }) => slug?.current === category),
)
}
21 changes: 8 additions & 13 deletions src/ui/modules/blog/store.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
import { create } from 'zustand'
import { useQueryState } from 'nuqs'

export const categoryStore = create<{
selected: 'All' | string
setSelected: (selected: 'All' | string) => void
reset: () => void
}>((set) => ({
selected: 'All',
setSelected: (selected) =>
set((state) => ({
selected: state.selected === selected ? 'All' : selected,
})),
reset: () => set({ selected: 'All' }),
}))
export const useCategory = () => {
const [category, setCategory] = useQueryState('category', {
defaultValue: 'All',
})

return { category, setCategory }
}

0 comments on commit 533a45e

Please sign in to comment.