Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/api/v2/barometers/getters.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { type Prisma } from '@prisma/client'
import { SortValue } from '@/app/collection/categories/[category]/types'
import { SortValue } from '@/app/collection/categories/[...category]/types'
import { withPrisma } from '@/prisma/prismaClient'

function getSortCriteria(
Expand Down
2 changes: 1 addition & 1 deletion app/api/v2/barometers/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { revalidatePath } from 'next/cache'
import { Prisma } from '@prisma/client'
import { withPrisma } from '@/prisma/prismaClient'
import { cleanObject, slug as slugify } from '@/utils/misc'
import { type SortValue } from '@/app/collection/categories/[category]/types'
import { type SortValue } from '@/app/collection/categories/[...category]/types'
import { DEFAULT_PAGE_SIZE } from '../parameters'
import { getAllBarometers, getBarometersByParams } from './getters'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,19 @@ import { Container, Grid, GridCol, Stack, Title } from '@mantine/core'
import { barometerRoute, googleStorageImagesFolder, barometerTypesRoute } from '@/app/constants'
import { BarometerCard } from './components/barometer-card'
import { slug } from '@/utils/misc'
import { SortValue } from './types'
import { SortValue, SortOptions } from './types'
import Sort from './sort'
import { DescriptionText } from '@/app/components/description-text'
import { title, openGraph, twitter } from '@/app/metadata'
import { Pagination } from '@/app/components/pagination'
import { Pagination } from './pagination'
import { withPrisma } from '@/prisma/prismaClient'
import { getCategory } from '@/app/api/v2/categories/[name]/getters'
import { getBarometersByParams } from '@/app/api/v2/barometers/getters'

interface CollectionProps {
params: {
category: string
}
searchParams: {
sort?: SortValue
page?: string
// category should include [categoryName, sortCriteria, pageNo]
category: string[]
}
}

Expand All @@ -28,16 +25,17 @@ const PAGE_SIZE = 12
export async function generateMetadata({
params: { category },
}: CollectionProps): Promise<Metadata> {
const { description } = await getCategory(category)
const { barometers } = await getBarometersByParams(category, 1, 5, 'date')
const collectionTitle = `${title}: ${capitalize(category)} Barometers Collection`
const [categoryName] = category
const { description } = await getCategory(categoryName)
const { barometers } = await getBarometersByParams(categoryName, 1, 5, 'date')
const collectionTitle = `${title}: ${capitalize(categoryName)} Barometers Collection`
const barometerImages = barometers
.filter(({ images }) => images && images.length > 0)
.map(({ images, name }) => ({
url: googleStorageImagesFolder + images.at(0),
alt: name,
}))
const url = barometerTypesRoute + category
const url = `${barometerTypesRoute}${category.join('/')}`
return {
title: collectionTitle,
description,
Expand All @@ -57,19 +55,23 @@ export async function generateMetadata({
}
}

export default async function Collection({ params: { category }, searchParams }: CollectionProps) {
const sort = searchParams.sort ?? 'date'
const page = searchParams.page ?? '1'
const { barometers, totalPages } = await getBarometersByParams(category, +page, PAGE_SIZE, sort)
const { description } = await getCategory(category)
export default async function Collection({ params: { category } }: CollectionProps) {
const [categoryName, sort, page] = category
const { barometers, totalPages } = await getBarometersByParams(
categoryName,
Number(page),
PAGE_SIZE,
sort as SortValue,
)
const { description } = await getCategory(categoryName)
return (
<Container py="xl" size="xl">
<Stack gap="xs">
<Title mb="sm" fw={500} order={2} tt="capitalize">
{category}
{categoryName}
</Title>
{description && <DescriptionText size="sm" description={description} />}
<Sort sortBy={sort} style={{ alignSelf: 'flex-end' }} />
<Sort sortBy={sort as SortValue} style={{ alignSelf: 'flex-end' }} />
<Grid justify="center" gutter="xl">
{barometers.map(({ name, id, images, manufacturer }, i) => (
<GridCol span={{ base: 6, xs: 3, lg: 3 }} key={id}>
Expand All @@ -89,9 +91,32 @@ export default async function Collection({ params: { category }, searchParams }:
)
}

// all non-generated posts will give 404
export const dynamicParams = false

export const generateStaticParams = withPrisma(async prisma => {
const categories = await prisma.category.findMany({ select: { name: true } })
return categories.map(({ name }) => ({
category: name.toLowerCase(),
}))
const categories = await prisma.category.findMany({ select: { name: true, id: true } })
const categoriesWithCount = await prisma.barometer.groupBy({
by: ['categoryId'],
_count: {
_all: true,
},
})
// page rout is /collection/categories/{categoryName}/{sortCriteria}/{pageNumber}
const params: { category: string[] }[] = []

for (const { name, id } of categories) {
const categoryData = categoriesWithCount.find(({ categoryId }) => categoryId === id)
const barometersPerCategory = categoryData?._count._all ?? 0
const pagesPerCategory = Math.ceil(barometersPerCategory / PAGE_SIZE)
// generate all combinations of of category/sort/page for static page generation
for (const { value: sort } of SortOptions) {
for (let page = 1; page <= pagesPerCategory; page += 1) {
params.push({
category: [name.toLowerCase(), sort, String(page)],
})
}
}
}
return params
})
13 changes: 13 additions & 0 deletions app/collection/categories/[...category]/pagination.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
'use client'

import { Pagination as MantinePagination, PaginationProps } from '@mantine/core'
import { useRouter, usePathname } from 'next/navigation'

export function Pagination(props: PaginationProps) {
const router = useRouter()
const pathname = usePathname()
const handlePageChange = (newPage: number) => {
router.push(pathname.split('/').slice(0, -1).concat(`${newPage}`).join('/'))
}
return <MantinePagination onChange={handlePageChange} {...props} />
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client'

import { CSSProperties, Select } from '@mantine/core'
import { useRouter } from 'next/navigation'
import { usePathname, useRouter } from 'next/navigation'
import { SortValue, SortOptions } from './types'

interface SortProps {
Expand All @@ -12,10 +12,12 @@ interface SortProps {

export default function Sort({ sortBy, style }: SortProps) {
const router = useRouter()
const pathName = usePathname()

const handleSortChange = (value: string | null) => {
if (value) {
router.push(`?${new URLSearchParams({ sort: value })}`)
const path = pathName.split('/')
router.push(path.slice(0, -2).concat(value).concat('1').join('/'))
}
}

Expand Down
4 changes: 2 additions & 2 deletions app/collection/items/[slug]/components/breadcrumbs.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Link from 'next/link'
import { Breadcrumbs, Anchor, Text } from '@mantine/core'
import { barometerTypesRoute } from '@/app/constants'
import { barometerTypesRoute, postfix } from '@/app/constants'

interface BreadcrumbsComponentProps {
type: string
Expand All @@ -10,7 +10,7 @@ interface BreadcrumbsComponentProps {
export function BreadcrumbsComponent({ type, catId, ...props }: BreadcrumbsComponentProps) {
const breadcrumbs = [
{ title: 'Home', href: '/' },
{ title: type.toLowerCase(), href: barometerTypesRoute + type.toLowerCase() },
{ title: type.toLowerCase(), href: barometerTypesRoute + type.toLowerCase() + postfix },
{ title: catId },
]

Expand Down
8 changes: 4 additions & 4 deletions app/components/header/tabs/tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import { AccessRole } from '@prisma/client'
import sx from './tabs.module.scss'
import { menuData } from '../menudata'
import { useBarometers } from '@/app/hooks/useBarometers'
import { barometerTypesRoute } from '@/app/constants'
import { barometerTypesRoute, postfix } from '@/app/constants'
import { isAdmin } from '../../is-admin'

const WideScreenTabs = ({ className, ...props }: CenterProps) => {
const { categories: types } = useBarometers()
const { categories } = useBarometers()
const { data: session } = useSession()
const router = useRouter()
const pathname = usePathname()
Expand Down Expand Up @@ -78,10 +78,10 @@ const WideScreenTabs = ({ className, ...props }: CenterProps) => {
>
<Menu.Target>{renderTab()}</Menu.Target>
<Menu.Dropdown>
{types.data.map(({ label, id, name }) => (
{categories.data.map(({ label, id, name }) => (
<Anchor
key={id}
href={barometerTypesRoute + name.toLocaleLowerCase()}
href={barometerTypesRoute + name.toLocaleLowerCase() + postfix}
component={Link}
c="inherit"
underline="never"
Expand Down
1 change: 0 additions & 1 deletion app/components/pagination/index.ts

This file was deleted.

31 changes: 0 additions & 31 deletions app/components/pagination/pagination.tsx

This file was deleted.

2 changes: 2 additions & 0 deletions app/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@ export const barometerRoute = '/collection/items/'
// External links
export const googleStorageImagesFolder = 'https://storage.googleapis.com/barometers/'
export const github = 'https://github.com/shenshin'

export const postfix = '/date/1'
4 changes: 2 additions & 2 deletions app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Container, Grid, GridCol } from '@mantine/core'
import { HeadingImage } from './components/heading-image'
import { CategoryCard } from './components/category-card'
import { barometerTypesRoute } from './constants'
import { barometerTypesRoute, postfix } from './constants'
import { SearchField } from './components/search-field'
import { getCategories } from './api/v2/categories/getters'

Expand All @@ -24,7 +24,7 @@ export default async function HomePage() {
priority={i < 3}
image={image.url}
name={label}
link={barometerTypesRoute + name.toLowerCase()}
link={`${barometerTypesRoute}${name.toLowerCase()}${postfix}`}
/>
</GridCol>
))}
Expand Down
2 changes: 1 addition & 1 deletion app/search/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Box, Container, Stack, Title } from '@mantine/core'
import { googleStorageImagesFolder, barometerRoute } from '../constants'
import { SearchItem } from './search-item'
import { Pagination } from '../components/pagination'
import { searchBarometers } from '@/utils/fetch'
import { SearchInfo } from './search-info'
import { Pagination } from './pagination'

interface SearchProps {
searchParams: Record<string, string>
Expand Down
17 changes: 17 additions & 0 deletions app/search/pagination.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use client'

import { Pagination as MantinePagination, PaginationProps } from '@mantine/core'
import { useRouter, useSearchParams, usePathname } from 'next/navigation'

export function Pagination(props: PaginationProps) {
const router = useRouter()
const searchParams = useSearchParams()
const pathname = usePathname()

const handlePageChange = (newPage: number) => {
const params = new URLSearchParams(searchParams)
params.set('page', String(newPage))
router.push(`${pathname}?${params}`)
}
return <MantinePagination onChange={handlePageChange} {...props} />
}
12 changes: 12 additions & 0 deletions theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,16 @@ export const theme = createTheme({
light: 'red',
}),
},
components: {
Pagination: {
defaultProps: {
mt: 'lg',
c: 'dark',
color: 'dark',
style: {
alignSelf: 'center',
},
},
},
},
})
2 changes: 1 addition & 1 deletion utils/fetch.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Manufacturer } from '@prisma/client'
import { SortValue } from '@/app/collection/categories/[category]/types'
import { SortValue } from '@/app/collection/categories/[...category]/types'
import {
barometersApiRoute,
barometersSearchRoute,
Expand Down
Loading