mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-15 23:16:48 +00:00
合并notionData 接口
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
import BlogPostCard from '@/components/BlogPostCard'
|
||||
import PaginationNumber from './PaginationNumber'
|
||||
import BLOG from '@/blog.config'
|
||||
|
||||
import { useRouter } from 'next/router'
|
||||
import BlogPostListEmpty from '@/components/BlogPostListEmpty'
|
||||
|
||||
/**
|
||||
@@ -13,40 +11,20 @@ import BlogPostListEmpty from '@/components/BlogPostListEmpty'
|
||||
* @returns {JSX.Element}
|
||||
* @constructor
|
||||
*/
|
||||
const BlogPostListPage = ({ page = 1, posts = [] }) => {
|
||||
let filteredBlogPosts = posts
|
||||
const BlogPostListPage = ({ page = 1, posts = [], postCount }) => {
|
||||
const totalPage = Math.ceil(postCount / BLOG.postsPerPage)
|
||||
|
||||
// 处理查询过滤 支持标签、关键词过滤
|
||||
let currentSearch = ''
|
||||
const router = useRouter()
|
||||
if (router.query && router.query.s) {
|
||||
currentSearch = router.query.s
|
||||
filteredBlogPosts = posts.filter(post => {
|
||||
const tagContent = post.tags ? post.tags.join(' ') : ''
|
||||
const searchContent = post.title + post.summary + tagContent + post.slug
|
||||
return searchContent.toLowerCase().includes(currentSearch.toLowerCase())
|
||||
})
|
||||
}
|
||||
|
||||
// 处理分页
|
||||
const totalPage = Math.ceil(filteredBlogPosts.length / BLOG.postsPerPage)
|
||||
const postsToShow = filteredBlogPosts.slice(
|
||||
BLOG.postsPerPage * (page - 1),
|
||||
BLOG.postsPerPage * page
|
||||
)
|
||||
|
||||
if (!postsToShow || postsToShow.length === 0) {
|
||||
if (!posts || posts.length === 0) {
|
||||
return <BlogPostListEmpty />
|
||||
} else {
|
||||
return (
|
||||
<div id="container" className='mt-10'>
|
||||
{/* 文章列表 */}
|
||||
<div className="flex flex-wrap space-y-8 mx-5 md:mx-0">
|
||||
{postsToShow.map(post => (
|
||||
{posts.map(post => (
|
||||
<BlogPostCard key={post.id} post={post} />
|
||||
))}
|
||||
</div>
|
||||
|
||||
<PaginationNumber page={page} totalPage={totalPage} />
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import { faFileAlt } from '@fortawesome/free-solid-svg-icons'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { faArchive, faFileAlt } from '@fortawesome/free-solid-svg-icons'
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
@@ -10,25 +11,19 @@ import { useRouter } from 'next/router'
|
||||
* @param sliceCount 截取展示的数量 默认6
|
||||
* @constructor
|
||||
*/
|
||||
const LatestPostsGroup = ({ posts, sliceCount = 5 }) => {
|
||||
// 深拷贝
|
||||
let postsSortByDate = Object.create(posts)
|
||||
|
||||
// 时间排序
|
||||
postsSortByDate.sort((a, b) => {
|
||||
const dateA = new Date(a?.lastEditedTime || a.createdTime)
|
||||
const dateB = new Date(b?.lastEditedTime || b.createdTime)
|
||||
return dateB - dateA
|
||||
})
|
||||
|
||||
// 只取前五
|
||||
postsSortByDate = postsSortByDate.slice(0, sliceCount)
|
||||
|
||||
const LatestPostsGroup = ({ posts }) => {
|
||||
if (!posts) {
|
||||
return <></>
|
||||
}
|
||||
// 获取当前路径
|
||||
const currentPath = useRouter().asPath
|
||||
const { locale } = useGlobal()
|
||||
|
||||
return <>
|
||||
{postsSortByDate.map(post => {
|
||||
return <section className='mt-8'>
|
||||
<div className='text-sm pb-4 px-5 flex flex-nowrap justify-between'>
|
||||
<div className='font-light text-gray-600 dark:text-gray-200'><FontAwesomeIcon icon={faArchive} className='mr-2' />{locale.COMMON.LATEST_POSTS}</div>
|
||||
</div>
|
||||
{posts.map(post => {
|
||||
const selected = currentPath === `${BLOG.path}/article/${post.slug}`
|
||||
return (
|
||||
<Link key={post.id} title={post.title} href={`${BLOG.path}/article/${post.slug}`} passHref>
|
||||
@@ -42,6 +37,6 @@ const LatestPostsGroup = ({ posts, sliceCount = 5 }) => {
|
||||
</Link>
|
||||
)
|
||||
})}
|
||||
</>
|
||||
</section>
|
||||
}
|
||||
export default LatestPostsGroup
|
||||
|
||||
@@ -21,10 +21,9 @@ import Logo from './Logo'
|
||||
* @returns {JSX.Element}
|
||||
* @constructor
|
||||
*/
|
||||
const SideAreaLeft = ({ title, tags, currentTag, post, posts, categories, currentCategory, currentSearch, targetRef }) => {
|
||||
const SideAreaLeft = ({ title, tags, currentTag, post, postCount, categories, currentCategory, currentSearch, targetRef }) => {
|
||||
const { locale } = useGlobal()
|
||||
const showToc = post && post.toc && post.toc.length > 1
|
||||
const postCount = posts?.length || 0
|
||||
return <aside id='left' className='hidden lg:block flex-col w-60 mr-4'>
|
||||
|
||||
<section className='w-60'>
|
||||
@@ -48,7 +47,7 @@ const SideAreaLeft = ({ title, tags, currentTag, post, posts, categories, curren
|
||||
)}
|
||||
|
||||
<div key={locale.NAV.ABOUT} className='mb-5 bg-white dark:bg-gray-800 duration-200 py-6'>
|
||||
<InfoCard postCount={postCount} />
|
||||
<InfoCard />
|
||||
<Analytics postCount={postCount}/>
|
||||
</div>
|
||||
</Tabs>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import LatestPostsGroup from '@/components/LatestPostsGroup'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { faAngleDoubleRight, faAngleRight, faArchive, faTags, faThList } from '@fortawesome/free-solid-svg-icons'
|
||||
import { faAngleDoubleRight, faAngleRight, faTags, faThList } from '@fortawesome/free-solid-svg-icons'
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import Link from 'next/link'
|
||||
import React from 'react'
|
||||
@@ -25,7 +24,7 @@ const SideAreaRight = ({
|
||||
tags,
|
||||
currentTag,
|
||||
post,
|
||||
posts,
|
||||
slot,
|
||||
categories,
|
||||
currentCategory,
|
||||
currentSearch,
|
||||
@@ -69,19 +68,7 @@ const SideAreaRight = ({
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* 最新文章 */}
|
||||
{widget?.showLatestPost && posts && (
|
||||
<section className="shadow py-4 mb-5 bg-white dark:bg-gray-800 hover:shadow-xl duration-200">
|
||||
<div className="text-sm pb-2 px-5 flex flex-nowrap justify-between">
|
||||
<div className="font-light text-gray-600 dark:text-gray-300">
|
||||
<FontAwesomeIcon icon={faArchive} className="mr-2" />
|
||||
{locale.COMMON.LATEST_POSTS}
|
||||
<span className='text-red-500 text-xs ml-1'>NEW</span>
|
||||
</div>
|
||||
</div>
|
||||
<LatestPostsGroup posts={posts} />
|
||||
</section>
|
||||
)}
|
||||
{slot}
|
||||
|
||||
{widget?.showTagList && tags && (
|
||||
<section className="shadow py-4 mb-5 bg-white dark:bg-gray-800 hover:shadow-xl duration-200">
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import CategoryGroup from '@/components/CategoryGroup'
|
||||
import InfoCard from '@/components/InfoCard'
|
||||
import LatestPostsGroup from '@/components/LatestPostsGroup'
|
||||
import TagGroups from '@/components/TagGroups'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { faAngleDoubleRight, faArchive, faTags, faThList } from '@fortawesome/free-solid-svg-icons'
|
||||
import { faAngleDoubleRight, faTags, faThList } from '@fortawesome/free-solid-svg-icons'
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import Link from 'next/link'
|
||||
import React from 'react'
|
||||
@@ -21,7 +20,7 @@ import Logo from './Logo'
|
||||
* @returns {JSX.Element}
|
||||
* @constructor
|
||||
*/
|
||||
const SideBar = ({ title, tags, currentTag, post, posts, categories, currentCategory, currentSearch }) => {
|
||||
const SideBar = ({ title, tags, currentTag, post, slot, categories, currentCategory, currentSearch }) => {
|
||||
const { locale } = useGlobal()
|
||||
return <aside id='sidebar' className='bg-white dark:bg-gray-900 w-80 z-10 dark:border-gray-500 border-gray-200 scroll-hidden h-full'>
|
||||
|
||||
@@ -64,15 +63,8 @@ const SideBar = ({ title, tags, currentTag, post, posts, categories, currentCate
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* 最新文章 */}
|
||||
{posts && (
|
||||
<section className='mt-8'>
|
||||
<div className='text-sm pb-4 px-5 flex flex-nowrap justify-between'>
|
||||
<div className='font-light text-gray-600 dark:text-gray-200'><FontAwesomeIcon icon={faArchive} className='mr-2' />{locale.COMMON.LATEST_POSTS}</div>
|
||||
</div>
|
||||
<LatestPostsGroup posts={posts} />
|
||||
</section>
|
||||
)}
|
||||
{slot}
|
||||
|
||||
</div>
|
||||
|
||||
<section className='bg-white dark:bg-gray-900'>
|
||||
|
||||
@@ -7,7 +7,7 @@ import React, { useEffect, useImperativeHandle } from 'react'
|
||||
* @returns {JSX.Element}
|
||||
* @constructor
|
||||
*/
|
||||
const SideBarDrawer = ({ post, currentTag, cRef, tags, posts, categories, currentCategory }) => {
|
||||
const SideBarDrawer = ({ post, currentTag, cRef, tags, slot, categories, currentCategory }) => {
|
||||
// 暴露给父组件 通过cRef.current.handleMenuClick 调用
|
||||
useImperativeHandle(cRef, () => {
|
||||
return {
|
||||
@@ -49,7 +49,7 @@ const SideBarDrawer = ({ post, currentTag, cRef, tags, posts, categories, curren
|
||||
|
||||
return <div id='sidebar-wrapper' className='hidden'>
|
||||
<div id='sidebar-drawer' className='-ml-80 bg-white dark:bg-gray-900 flex flex-col duration-300 fixed h-full left-0 overflow-y-scroll scroll-hidden top-0 z-50 shadow-2xl'>
|
||||
<SideBar tags={tags} post={post} posts={posts} categories={categories} currentCategory={currentCategory} />
|
||||
<SideBar tags={tags} post={post} slot={slot} categories={categories} currentCategory={currentCategory} />
|
||||
</div>
|
||||
{/* 背景蒙版 */}
|
||||
<div id='sidebar-drawer-background' onClick={() => { switchSideDrawerVisible(false) }} className='hidden animate__animated animate__fadeIn fixed top-0 duration-300 left-0 z-30 w-full h-full glassmorphism'/>
|
||||
|
||||
@@ -15,7 +15,7 @@ let windowTop = 0
|
||||
* @param {*} param0
|
||||
* @returns
|
||||
*/
|
||||
const TopNav = ({ tags, currentTag, post, posts, categories, currentCategory, autoHide = true }) => {
|
||||
const TopNav = ({ tags, currentTag, post, slot, categories, currentCategory, autoHide = true }) => {
|
||||
const drawer = useRef()
|
||||
const { locale } = useGlobal()
|
||||
const searchDrawer = useRef()
|
||||
@@ -45,7 +45,7 @@ const TopNav = ({ tags, currentTag, post, posts, categories, currentCategory, au
|
||||
}, [])
|
||||
return (<div id='top-nav' className='sticky top-0 z-40 block lg:hidden'>
|
||||
{/* 侧面抽屉 */}
|
||||
<SideBarDrawer post={post} currentTag={currentTag} cRef={drawer} tags={tags} posts={posts} categories={categories} currentCategory={currentCategory}/>
|
||||
<SideBarDrawer post={post} currentTag={currentTag} cRef={drawer} tags={tags} slot={slot} categories={categories} currentCategory={currentCategory}/>
|
||||
<SearchDrawer cRef={searchDrawer}/>
|
||||
|
||||
{/* 导航栏 */}
|
||||
|
||||
@@ -35,7 +35,9 @@ const BaseLayout = ({
|
||||
tags,
|
||||
meta,
|
||||
post,
|
||||
totalPosts,
|
||||
postCount,
|
||||
sideBarSlot,
|
||||
rightAreaSlot,
|
||||
currentSearch,
|
||||
currentCategory,
|
||||
currentTag,
|
||||
@@ -49,14 +51,14 @@ const BaseLayout = ({
|
||||
|
||||
<CommonHead meta={meta} />
|
||||
|
||||
<TopNav tags={tags} post={post} posts={totalPosts} currentSearch={currentSearch} categories={categories} currentCategory={currentCategory} />
|
||||
<TopNav tags={tags} post={post} slot={sideBarSlot} currentSearch={currentSearch} categories={categories} currentCategory={currentCategory} />
|
||||
|
||||
<>{headerSlot}</>
|
||||
|
||||
<div className='h-0.5 w-full bg-gray-700 dark:bg-gray-600 hidden lg:block'></div>
|
||||
|
||||
<main id='wrapper' className='flex justify-center flex-1 mx-auto pb-12'>
|
||||
<SideAreaLeft targetRef={targetRef} post={post} posts={totalPosts} tags={tags} currentSearch={currentSearch} currentTag={currentTag} categories={categories} currentCategory={currentCategory}/>
|
||||
<SideAreaLeft targetRef={targetRef} post={post} postCount={postCount} tags={tags} currentSearch={currentSearch} currentTag={currentTag} categories={categories} currentCategory={currentCategory}/>
|
||||
<section id='center' className='flex-grow mt-14 md:mt-0 max-w-5xl min-h-screen' ref={targetRef}>
|
||||
{onLoading
|
||||
? <LoadingCover/>
|
||||
@@ -65,7 +67,7 @@ const BaseLayout = ({
|
||||
</>
|
||||
}
|
||||
</section>
|
||||
<SideAreaRight targetRef={targetRef} post={post} posts={totalPosts} tags={tags} currentSearch={currentSearch} currentTag={currentTag} categories={categories} currentCategory={currentCategory}/>
|
||||
<SideAreaRight targetRef={targetRef} post={post} slot={rightAreaSlot} postCount={postCount} tags={tags} currentSearch={currentSearch} currentTag={currentTag} categories={categories} currentCategory={currentCategory}/>
|
||||
</main>
|
||||
|
||||
<Footer title={meta.title}/>
|
||||
|
||||
@@ -1,7 +1,52 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import { idToUuid } from 'notion-utils'
|
||||
import { getDataFromCache, setDataToCache } from '@/lib/cache/cache_manager'
|
||||
import { getPostBlocks } from '@/lib/notion/getPostBlocks'
|
||||
import { idToUuid } from 'notion-utils'
|
||||
import { getAllCategories } from './getAllCategories'
|
||||
import { getAllPosts } from './getAllPosts'
|
||||
import { getAllTags } from './getAllTags'
|
||||
|
||||
/**
|
||||
* 获取博客数据
|
||||
* @param {*} pageId
|
||||
* @param {*} from
|
||||
* @returns
|
||||
* allPosts 所有博客
|
||||
* categories 所有分类
|
||||
* tags 所有标签
|
||||
*/
|
||||
export async function getGlobalNotionData ({
|
||||
pageId = BLOG.notionPageId,
|
||||
from,
|
||||
latestPostCount = 5,
|
||||
tagsCount = 16,
|
||||
includePage
|
||||
}) {
|
||||
const notionPageData = await getNotionPageData({ pageId, from })
|
||||
const tagOptions = notionPageData.tagOptions
|
||||
const allPosts = await getAllPosts({ notionPageData, from, includePage })
|
||||
const postCount = allPosts?.length
|
||||
const categories = await getAllCategories(allPosts)
|
||||
const tags = await getAllTags({ allPosts, tagOptions, sliceCount: tagsCount })
|
||||
// 深拷贝
|
||||
let latestPosts = Object.create(allPosts)
|
||||
// 时间排序
|
||||
latestPosts.sort((a, b) => {
|
||||
const dateA = new Date(a?.lastEditedTime || a.createdTime)
|
||||
const dateB = new Date(b?.lastEditedTime || b.createdTime)
|
||||
return dateB - dateA
|
||||
})
|
||||
|
||||
// 只取前五
|
||||
latestPosts = latestPosts.slice(0, latestPostCount)
|
||||
return {
|
||||
allPosts,
|
||||
latestPosts,
|
||||
categories,
|
||||
postCount,
|
||||
tags
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定notion的collection数据
|
||||
@@ -9,7 +54,7 @@ import { getPostBlocks } from '@/lib/notion/getPostBlocks'
|
||||
* @param from 请求来源
|
||||
* @returns {Promise<JSX.Element|*|*[]>}
|
||||
*/
|
||||
export async function getNotionPageData ({ pageId = BLOG.notionPageId, from }) {
|
||||
export async function getNotionPageData ({ pageId, from }) {
|
||||
// 尝试从缓存获取
|
||||
const cacheKey = 'page_record_map_' + pageId
|
||||
const data = await getDataFromCache(cacheKey)
|
||||
@@ -54,7 +99,10 @@ async function getPageRecordMapByNotionAPI ({ pageId, from }) {
|
||||
const tagOptions = getTagOptions(schema)
|
||||
|
||||
// Check Type Page-Database和Inline-Database
|
||||
if (rawMetadata?.type !== 'collection_view_page' && rawMetadata?.type !== 'collection_view') {
|
||||
if (
|
||||
rawMetadata?.type !== 'collection_view_page' &&
|
||||
rawMetadata?.type !== 'collection_view'
|
||||
) {
|
||||
console.warn(`pageId "${pageId}" is not a database`)
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import ArticleDetail from '@/components/ArticleDetail'
|
||||
import BaseLayout from '@/layouts/BaseLayout'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { getAllCategories, getAllPosts, getAllTags, getPostBlocks } from '@/lib/notion'
|
||||
import { getNotionPageData } from '@/lib/notion/getNotionData'
|
||||
import {
|
||||
getPostBlocks
|
||||
} from '@/lib/notion'
|
||||
import { getGlobalNotionData } from '@/lib/notion/getNotionData'
|
||||
import Custom404 from '@/pages/404'
|
||||
import { getPageTableOfContents } from 'notion-utils'
|
||||
import 'prismjs'
|
||||
@@ -12,7 +15,6 @@ import 'prismjs/components/prism-markup'
|
||||
import 'prismjs/components/prism-python'
|
||||
import 'prismjs/components/prism-typescript'
|
||||
import React from 'react'
|
||||
import BLOG from '@/blog.config'
|
||||
|
||||
/**
|
||||
* 关于页面,默认取notion中slug为about的文章
|
||||
@@ -32,15 +34,22 @@ const About = ({ post, blockMap, tags, prev, next, allPosts, categories }) => {
|
||||
tags: []
|
||||
}
|
||||
|
||||
return <BaseLayout meta={meta} tags={tags} post={post} totalPosts={allPosts} categories={categories}>
|
||||
<ArticleDetail post={post} blockMap={blockMap} allPosts={allPosts}/>
|
||||
</BaseLayout>
|
||||
return (
|
||||
<BaseLayout
|
||||
meta={meta}
|
||||
tags={tags}
|
||||
post={post}
|
||||
totalPosts={allPosts}
|
||||
categories={categories}
|
||||
>
|
||||
<ArticleDetail post={post} blockMap={blockMap} allPosts={allPosts} prev={prev} next={next} />
|
||||
</BaseLayout>
|
||||
)
|
||||
}
|
||||
|
||||
export async function getStaticProps () {
|
||||
const from = 'about-props'
|
||||
const notionPageData = await getNotionPageData({ from })
|
||||
let allPosts = await getAllPosts({ notionPageData, from, includePage: true })
|
||||
const { allPosts, categories, tags, postCount, latestPosts } = await getGlobalNotionData({ from, includePage: true })
|
||||
const post = allPosts.find(p => p.slug === 'about')
|
||||
|
||||
if (!post) {
|
||||
@@ -54,16 +63,12 @@ export async function getStaticProps () {
|
||||
post.toc = getPageTableOfContents(post, blockMap)
|
||||
}
|
||||
|
||||
allPosts = allPosts.filter(post => post.type[0] === 'Post')
|
||||
const tagOptions = notionPageData.tagOptions
|
||||
const tags = await getAllTags({ allPosts, tagOptions })
|
||||
const categories = await getAllCategories(allPosts)
|
||||
const index = allPosts.indexOf(post)
|
||||
const prev = allPosts.slice(index - 1, index)[0] ?? allPosts.slice(-1)[0]
|
||||
const next = allPosts.slice(index + 1, index + 2)[0] ?? allPosts[0]
|
||||
|
||||
return {
|
||||
props: { post, blockMap, tags, prev, next, allPosts, categories },
|
||||
props: { post, blockMap, tags, prev, next, allPosts, categories, postCount, latestPosts },
|
||||
revalidate: 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +1,31 @@
|
||||
import { getAllCategories, getAllPosts, getAllTags } from '@/lib/notion'
|
||||
import BLOG from '@/blog.config'
|
||||
import BaseLayout from '@/layouts/BaseLayout'
|
||||
import { getNotionPageData } from '@/lib/notion/getNotionData'
|
||||
import React, { useEffect } from 'react'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import BlogPostArchive from '@/components/BlogPostArchive'
|
||||
import Live2D from '@/components/Live2D'
|
||||
import BaseLayout from '@/layouts/BaseLayout'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { getGlobalNotionData } from '@/lib/notion/getNotionData'
|
||||
import React, { useEffect } from 'react'
|
||||
|
||||
export async function getStaticProps () {
|
||||
const from = 'index'
|
||||
const notionPageData = await getNotionPageData({ from })
|
||||
const allPosts = await getAllPosts({ notionPageData, from })
|
||||
const categories = await getAllCategories(allPosts)
|
||||
const tagOptions = notionPageData.tagOptions
|
||||
const tags = await getAllTags({ allPosts, tagOptions })
|
||||
const { allPosts, categories, tags, postCount } =
|
||||
await getGlobalNotionData({ from, includePage: true })
|
||||
|
||||
return {
|
||||
props: {
|
||||
allPosts,
|
||||
posts: allPosts,
|
||||
tags,
|
||||
categories
|
||||
categories,
|
||||
postCount
|
||||
},
|
||||
revalidate: 1
|
||||
}
|
||||
}
|
||||
|
||||
const Index = ({ allPosts, tags, categories }) => {
|
||||
const Index = ({ posts, tags, categories, postCount }) => {
|
||||
const { locale } = useGlobal()
|
||||
// 深拷贝
|
||||
const postsSortByDate = Object.create(allPosts)
|
||||
const postsSortByDate = Object.create(posts)
|
||||
|
||||
// 时间排序
|
||||
postsSortByDate.sort((a, b) => {
|
||||
@@ -42,7 +40,7 @@ const Index = ({ allPosts, tags, categories }) => {
|
||||
type: 'website'
|
||||
}
|
||||
|
||||
const archivePosts = { }
|
||||
const archivePosts = {}
|
||||
|
||||
postsSortByDate.forEach(post => {
|
||||
const date = post.date.start_date.slice(0, 7)
|
||||
@@ -53,29 +51,32 @@ const Index = ({ allPosts, tags, categories }) => {
|
||||
}
|
||||
})
|
||||
|
||||
useEffect(
|
||||
() => {
|
||||
if (window) {
|
||||
const anchor = window.location.hash
|
||||
if (anchor) {
|
||||
setTimeout(() => {
|
||||
const anchorElement = document.getElementById(anchor.substring(1))
|
||||
if (anchorElement) { anchorElement.scrollIntoView({ block: 'start', behavior: 'smooth' }) }
|
||||
}, 300)
|
||||
}
|
||||
useEffect(() => {
|
||||
if (window) {
|
||||
const anchor = window.location.hash
|
||||
if (anchor) {
|
||||
setTimeout(() => {
|
||||
const anchorElement = document.getElementById(anchor.substring(1))
|
||||
if (anchorElement) {
|
||||
anchorElement.scrollIntoView({ block: 'start', behavior: 'smooth' })
|
||||
}
|
||||
}, 300)
|
||||
}
|
||||
},
|
||||
[]
|
||||
)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<BaseLayout meta={meta} tags={tags} categories={categories}>
|
||||
<div className='mb-10 pb-20 bg-white md:p-12 p-3 dark:bg-gray-800 shadow-md min-h-full'>
|
||||
{Object.keys(archivePosts).map(archiveTitle => (
|
||||
<BlogPostArchive key={archiveTitle} posts={archivePosts[archiveTitle]} archiveTitle={archiveTitle}/>
|
||||
))}
|
||||
</div>
|
||||
<Live2D/>
|
||||
<BaseLayout meta={meta} tags={tags} categories={categories} postCount={postCount}>
|
||||
<div className="mb-10 pb-20 bg-white md:p-12 p-3 dark:bg-gray-800 shadow-md min-h-full">
|
||||
{Object.keys(archivePosts).map(archiveTitle => (
|
||||
<BlogPostArchive
|
||||
key={archiveTitle}
|
||||
posts={archivePosts[archiveTitle]}
|
||||
archiveTitle={archiveTitle}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<Live2D />
|
||||
</BaseLayout>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,19 +1,28 @@
|
||||
import { getAllCategories, getAllPosts, getAllTags, getPostBlocks } from '@/lib/notion'
|
||||
import BLOG from '@/blog.config'
|
||||
import { getPageTableOfContents } from 'notion-utils'
|
||||
|
||||
import BaseLayout from '@/layouts/BaseLayout'
|
||||
import Custom404 from '@/pages/404'
|
||||
|
||||
import ArticleDetail from '@/components/ArticleDetail'
|
||||
import { getNotionPageData } from '@/lib/notion/getNotionData'
|
||||
import BaseLayout from '@/layouts/BaseLayout'
|
||||
import { getAllPosts, getPostBlocks } from '@/lib/notion'
|
||||
import { getGlobalNotionData } from '@/lib/notion/getNotionData'
|
||||
import Custom404 from '@/pages/404'
|
||||
import { getPageTableOfContents } from 'notion-utils'
|
||||
|
||||
/**
|
||||
* 根据notion的slug访问页面
|
||||
* @param {*} param0
|
||||
* @returns
|
||||
*/
|
||||
const Slug = ({ post, blockMap, tags, prev, next, allPosts, recommendPosts, categories }) => {
|
||||
const Slug = ({
|
||||
post,
|
||||
blockMap,
|
||||
tags,
|
||||
prev,
|
||||
next,
|
||||
allPosts,
|
||||
recommendPosts,
|
||||
categories,
|
||||
postCount,
|
||||
latestPosts
|
||||
}) => {
|
||||
if (!post) {
|
||||
return <Custom404 />
|
||||
}
|
||||
@@ -24,15 +33,31 @@ const Slug = ({ post, blockMap, tags, prev, next, allPosts, recommendPosts, cate
|
||||
tags: post.tags
|
||||
}
|
||||
|
||||
return <BaseLayout meta={meta} tags={tags} post={post} totalPosts={allPosts} categories={categories}>
|
||||
<ArticleDetail post={post} blockMap={blockMap} recommendPosts={recommendPosts} prev={prev} next={next}/>
|
||||
</BaseLayout>
|
||||
return (
|
||||
<BaseLayout
|
||||
meta={meta}
|
||||
tags={tags}
|
||||
post={post}
|
||||
postCount={postCount}
|
||||
latestPosts={latestPosts}
|
||||
totalPosts={allPosts}
|
||||
categories={categories}
|
||||
>
|
||||
<ArticleDetail
|
||||
post={post}
|
||||
blockMap={blockMap}
|
||||
recommendPosts={recommendPosts}
|
||||
prev={prev}
|
||||
next={next}
|
||||
/>
|
||||
</BaseLayout>
|
||||
)
|
||||
}
|
||||
|
||||
export async function getStaticPaths () {
|
||||
let posts = []
|
||||
if (BLOG.isProd) {
|
||||
posts = await getAllPosts({ from: 'slug - paths', includePage: true })
|
||||
posts = await getAllPosts({ from: 'slug - paths', includePage: false })
|
||||
}
|
||||
return {
|
||||
paths: posts.map(row => ({ params: { slug: row.slug } })),
|
||||
@@ -42,8 +67,9 @@ export async function getStaticPaths () {
|
||||
|
||||
export async function getStaticProps ({ params: { slug } }) {
|
||||
const from = `slug-props-${slug}`
|
||||
const notionPageData = await getNotionPageData({ from })
|
||||
let allPosts = await getAllPosts({ notionPageData, from, includePage: true })
|
||||
const { allPosts, categories, tags, postCount, latestPosts } =
|
||||
await getGlobalNotionData({ from, includePage: false })
|
||||
|
||||
const post = allPosts.find(p => p.slug === slug)
|
||||
|
||||
if (!post) {
|
||||
@@ -56,10 +82,6 @@ export async function getStaticProps ({ params: { slug } }) {
|
||||
post.toc = getPageTableOfContents(post, blockMap)
|
||||
}
|
||||
|
||||
allPosts = allPosts.filter(post => post.type[0] === 'Post')
|
||||
const tagOptions = notionPageData.tagOptions
|
||||
const tags = await getAllTags({ allPosts, tagOptions })
|
||||
const categories = await getAllCategories(allPosts)
|
||||
// 上一篇、下一篇文章关联
|
||||
const index = allPosts.indexOf(post)
|
||||
const prev = allPosts.slice(index - 1, index)[0] ?? allPosts.slice(-1)[0]
|
||||
@@ -68,7 +90,18 @@ export async function getStaticProps ({ params: { slug } }) {
|
||||
const recommendPosts = getRecommendPost(post, allPosts)
|
||||
|
||||
return {
|
||||
props: { post, blockMap, tags, prev, next, allPosts, recommendPosts, categories },
|
||||
props: {
|
||||
post,
|
||||
blockMap,
|
||||
tags,
|
||||
prev,
|
||||
next,
|
||||
allPosts,
|
||||
recommendPosts,
|
||||
categories,
|
||||
postCount,
|
||||
latestPosts
|
||||
},
|
||||
revalidate: 1
|
||||
}
|
||||
}
|
||||
@@ -86,11 +119,7 @@ function getRecommendPost (post, allPosts, count = 5) {
|
||||
if (post.tags && post.tags.length) {
|
||||
const currentTag = post.tags[0]
|
||||
filteredPosts = filteredPosts.filter(
|
||||
p =>
|
||||
p &&
|
||||
p.tags &&
|
||||
p.tags.includes(currentTag) &&
|
||||
p.slug !== post.slug
|
||||
p => p && p.tags && p.tags.includes(currentTag) && p.slug !== post.slug
|
||||
)
|
||||
}
|
||||
shuffleSort(filteredPosts)
|
||||
|
||||
@@ -1,26 +1,25 @@
|
||||
import { getAllCategories, getAllPosts, getAllTags } from '@/lib/notion'
|
||||
import BLOG from '@/blog.config'
|
||||
import BlogPostListScroll from '@/components/BlogPostListScroll'
|
||||
import CategoryList from '@/components/CategoryList'
|
||||
import StickyBar from '@/components/StickyBar'
|
||||
import BaseLayout from '@/layouts/BaseLayout'
|
||||
import BlogPostListScroll from '@/components/BlogPostListScroll'
|
||||
import React from 'react'
|
||||
import CategoryList from '@/components/CategoryList'
|
||||
import { getNotionPageData } from '@/lib/notion/getNotionData'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { getGlobalNotionData } from '@/lib/notion/getNotionData'
|
||||
import React from 'react'
|
||||
|
||||
export default function Category ({ tags, allPosts, filteredPosts, category, categories }) {
|
||||
export default function Category ({ tags, posts, category, categories, latestPosts, postCount }) {
|
||||
const { locale } = useGlobal()
|
||||
const meta = {
|
||||
title: `${category} | ${locale.COMMON.CATEGORY} | ${BLOG.title}`,
|
||||
description: BLOG.description,
|
||||
type: 'website'
|
||||
}
|
||||
return <BaseLayout meta={meta} tags={tags} currentCategory={category} totalPosts={allPosts} categories={categories}>
|
||||
return <BaseLayout meta={meta} tags={tags} currentCategory={category} postCount={postCount} latestPosts={latestPosts} categories={categories}>
|
||||
<StickyBar>
|
||||
<CategoryList currentCategory={category} categories={categories} />
|
||||
</StickyBar>
|
||||
<div className='md:mt-8'>
|
||||
<BlogPostListScroll posts={filteredPosts} tags={tags} currentCategory={category}/>
|
||||
<BlogPostListScroll posts={posts} tags={tags} currentCategory={category}/>
|
||||
</div>
|
||||
</BaseLayout>
|
||||
}
|
||||
@@ -28,31 +27,26 @@ export default function Category ({ tags, allPosts, filteredPosts, category, cat
|
||||
export async function getStaticProps ({ params }) {
|
||||
const from = 'category-props'
|
||||
const category = params.category
|
||||
const notionPageData = await getNotionPageData({ from })
|
||||
const allPosts = await getAllPosts({ notionPageData, from })
|
||||
const categories = await getAllCategories(allPosts)
|
||||
const tagOptions = notionPageData.tagOptions
|
||||
const tags = await getAllTags({ allPosts, tagOptions })
|
||||
const { allPosts, categories, tags, postCount, latestPosts } = await getGlobalNotionData({ from })
|
||||
const filteredPosts = allPosts.filter(
|
||||
post => post && post.category && post.category.includes(category)
|
||||
)
|
||||
return {
|
||||
props: {
|
||||
tags,
|
||||
allPosts,
|
||||
filteredPosts,
|
||||
posts: filteredPosts,
|
||||
category,
|
||||
categories
|
||||
categories,
|
||||
postCount,
|
||||
latestPosts
|
||||
},
|
||||
revalidate: 1
|
||||
}
|
||||
}
|
||||
|
||||
export async function getStaticPaths () {
|
||||
let posts = []
|
||||
let categories = []
|
||||
posts = await getAllPosts({ from: 'category-path' })
|
||||
categories = await getAllCategories(posts)
|
||||
const from = 'category-paths'
|
||||
const { categories } = await getGlobalNotionData({ from })
|
||||
return {
|
||||
paths: Object.keys(categories).map(category => ({ params: { category } })),
|
||||
fallback: true
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
import { getAllCategories, getAllPosts, getAllTags } from '@/lib/notion'
|
||||
import BLOG from '@/blog.config'
|
||||
import BaseLayout from '@/layouts/BaseLayout'
|
||||
import { getNotionPageData } from '@/lib/notion/getNotionData'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import React from 'react'
|
||||
import Link from 'next/link'
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import { getGlobalNotionData } from '@/lib/notion/getNotionData'
|
||||
import { faFolder, faThList } from '@fortawesome/free-solid-svg-icons'
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import Link from 'next/link'
|
||||
import React from 'react'
|
||||
|
||||
export default function Category ({ tags, allPosts, categories }) {
|
||||
export default function Category ({ tags, allPosts, categories, postCount, latestPosts }) {
|
||||
const { locale } = useGlobal()
|
||||
const meta = {
|
||||
title: `${locale.COMMON.CATEGORY} | ${BLOG.title}`,
|
||||
description: BLOG.description,
|
||||
type: 'website'
|
||||
}
|
||||
return <BaseLayout meta={meta} totalPosts={allPosts} tags={tags}>
|
||||
return <BaseLayout meta={meta} totalPosts={allPosts} tags={tags} postCount={postCount} latestPosts={latestPosts}>
|
||||
<div className='bg-white dark:bg-gray-700 px-10 py-10 shadow'>
|
||||
<div className='dark:text-gray-200 mb-5'><FontAwesomeIcon icon={faThList} className='mr-4' />{locale.COMMON.CATEGORY}:</div>
|
||||
<div id='category-list' className='duration-200 flex flex-wrap'>
|
||||
@@ -31,17 +30,16 @@ export default function Category ({ tags, allPosts, categories }) {
|
||||
}
|
||||
|
||||
export async function getStaticProps () {
|
||||
const from = 'tag-index-props'
|
||||
const notionPageData = await getNotionPageData({ from })
|
||||
const allPosts = await getAllPosts({ notionPageData, from })
|
||||
const categories = await getAllCategories(allPosts)
|
||||
const tagOptions = notionPageData.tagOptions
|
||||
const tags = await getAllTags({ allPosts, sliceCount: 12, tagOptions })
|
||||
const from = 'category-index-props'
|
||||
const { allPosts, categories, tags, postCount, latestPosts } = await getGlobalNotionData({ from })
|
||||
|
||||
return {
|
||||
props: {
|
||||
tags,
|
||||
allPosts,
|
||||
categories
|
||||
categories,
|
||||
postCount,
|
||||
latestPosts
|
||||
},
|
||||
revalidate: 1
|
||||
}
|
||||
|
||||
@@ -1,26 +1,37 @@
|
||||
import { getAllCategories, getAllPosts, getAllTags } from '@/lib/notion'
|
||||
import BLOG from '@/blog.config'
|
||||
import BaseLayout from '@/layouts/BaseLayout'
|
||||
import BlogPostListScroll from '@/components/BlogPostListScroll'
|
||||
import { getNotionPageData } from '@/lib/notion/getNotionData'
|
||||
import { getGlobalNotionData } from '@/lib/notion/getNotionData'
|
||||
import Header from '@/components/Header'
|
||||
import BlogPostListPage from '@/components/BlogPostListPage'
|
||||
import LatestPostsGroup from '@/components/LatestPostsGroup'
|
||||
|
||||
export async function getStaticProps () {
|
||||
const from = 'index'
|
||||
const notionPageData = await getNotionPageData({ from })
|
||||
const allPosts = await getAllPosts({ notionPageData, from })
|
||||
const categories = await getAllCategories(allPosts)
|
||||
const tagOptions = notionPageData.tagOptions
|
||||
const tags = await getAllTags({ allPosts, tagOptions })
|
||||
const { allPosts, latestPosts, categories, tags, postCount } = await getGlobalNotionData({ from })
|
||||
const meta = {
|
||||
title: `${BLOG.title}`,
|
||||
description: BLOG.description,
|
||||
type: 'website'
|
||||
}
|
||||
|
||||
// 处理分页
|
||||
const page = 1
|
||||
let postsToShow = []
|
||||
if (BLOG.postListStyle !== 'page') {
|
||||
postsToShow = Object.create(allPosts)
|
||||
} else {
|
||||
postsToShow = allPosts.slice(
|
||||
BLOG.postsPerPage * (page - 1),
|
||||
BLOG.postsPerPage * page
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
props: {
|
||||
allPosts,
|
||||
posts: postsToShow,
|
||||
latestPosts,
|
||||
postCount,
|
||||
tags,
|
||||
categories,
|
||||
meta
|
||||
@@ -29,18 +40,20 @@ export async function getStaticProps () {
|
||||
}
|
||||
}
|
||||
|
||||
const Index = ({ allPosts, tags, meta, categories }) => {
|
||||
const Index = ({ posts, tags, meta, categories, postCount, latestPosts }) => {
|
||||
return (
|
||||
<BaseLayout
|
||||
headerSlot={BLOG.home.showHomeBanner && <Header />}
|
||||
meta={meta}
|
||||
tags={tags}
|
||||
totalPosts={allPosts}
|
||||
sideBarSlot={<LatestPostsGroup posts={latestPosts} />}
|
||||
rightAreaSlot={BLOG.widget?.showLatestPost && <LatestPostsGroup posts={latestPosts} />}
|
||||
postCount={postCount}
|
||||
categories={categories}
|
||||
>
|
||||
{BLOG.postListStyle !== 'page'
|
||||
? (<BlogPostListScroll posts={allPosts} tags={tags} />)
|
||||
: (<BlogPostListPage posts={allPosts} tags={tags} />)
|
||||
? (<BlogPostListScroll posts={posts} tags={tags} />)
|
||||
: (<BlogPostListPage posts={posts} tags={tags} postCount={postCount} />)
|
||||
}
|
||||
|
||||
</BaseLayout>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { getAllCategories, getAllPosts, getAllTags } from '@/lib/notion'
|
||||
import BLOG from '@/blog.config'
|
||||
import BaseLayout from '@/layouts/BaseLayout'
|
||||
import { getNotionPageData } from '@/lib/notion/getNotionData'
|
||||
import Header from '@/components/Header'
|
||||
import Custom404 from '../404'
|
||||
import BlogPostListPage from '@/components/BlogPostListPage'
|
||||
import Header from '@/components/Header'
|
||||
import LatestPostsGroup from '@/components/LatestPostsGroup'
|
||||
import BaseLayout from '@/layouts/BaseLayout'
|
||||
import { getGlobalNotionData } from '@/lib/notion/getNotionData'
|
||||
import Custom404 from '../404'
|
||||
|
||||
const Page = ({ page, allPosts, tags, meta, categories }) => {
|
||||
const Page = ({ page, posts, tags, meta, categories, postCount, latestPosts }) => {
|
||||
if (!meta || BLOG.postListStyle !== 'page') {
|
||||
return <Custom404/>
|
||||
}
|
||||
@@ -16,19 +16,20 @@ const Page = ({ page, allPosts, tags, meta, categories }) => {
|
||||
headerSlot={BLOG.home.showHomeBanner && <Header />}
|
||||
meta={meta}
|
||||
tags={tags}
|
||||
totalPosts={allPosts}
|
||||
sideBarSlot={<LatestPostsGroup posts={latestPosts} />}
|
||||
rightAreaSlot={BLOG.widget?.showLatestPost && <LatestPostsGroup posts={latestPosts} />}
|
||||
postCount={postCount}
|
||||
categories={categories}
|
||||
>
|
||||
<BlogPostListPage page={page} posts={allPosts} tags={tags} />
|
||||
<BlogPostListPage page={page} posts={posts} postCount={postCount} />
|
||||
</BaseLayout>
|
||||
)
|
||||
}
|
||||
|
||||
export async function getStaticPaths () {
|
||||
const from = 'page'
|
||||
const notionPageData = await getNotionPageData({ from })
|
||||
const allPosts = await getAllPosts({ notionPageData, from })
|
||||
const totalPages = Math.ceil(allPosts?.length / BLOG.postsPerPage)
|
||||
const from = 'page-paths'
|
||||
const { postCount } = await getGlobalNotionData({ from })
|
||||
const totalPages = Math.ceil(postCount / BLOG.postsPerPage)
|
||||
return {
|
||||
// remove first page, we 're not gonna handle that.
|
||||
paths: Array.from({ length: totalPages - 1 }, (_, i) => ({ params: { page: '' + (i + 2) } })),
|
||||
@@ -37,21 +38,29 @@ export async function getStaticPaths () {
|
||||
}
|
||||
|
||||
export async function getStaticProps ({ params: { page } }) {
|
||||
const from = 'page'
|
||||
const notionPageData = await getNotionPageData({ from })
|
||||
const allPosts = await getAllPosts({ notionPageData, from })
|
||||
const categories = await getAllCategories(allPosts)
|
||||
const tagOptions = notionPageData.tagOptions
|
||||
const tags = await getAllTags({ allPosts, tagOptions })
|
||||
const from = `page-${page}`
|
||||
const { allPosts, latestPosts, categories, tags, postCount } = await getGlobalNotionData({ from })
|
||||
const meta = {
|
||||
title: `${page} | Page | ${BLOG.title}`,
|
||||
description: BLOG.description,
|
||||
type: 'website'
|
||||
}
|
||||
// 处理分页
|
||||
let postsToShow = []
|
||||
if (BLOG.postListStyle !== 'page') {
|
||||
postsToShow = Object.create(allPosts)
|
||||
} else {
|
||||
postsToShow = allPosts.slice(
|
||||
BLOG.postsPerPage * (page - 1),
|
||||
BLOG.postsPerPage * page
|
||||
)
|
||||
}
|
||||
return {
|
||||
props: {
|
||||
page,
|
||||
allPosts,
|
||||
posts: postsToShow,
|
||||
postCount,
|
||||
latestPosts,
|
||||
tags,
|
||||
categories,
|
||||
meta
|
||||
|
||||
@@ -1,57 +1,66 @@
|
||||
import { getAllCategories, getAllPosts, getAllTags } from '@/lib/notion'
|
||||
import BLOG from '@/blog.config'
|
||||
import BaseLayout from '@/layouts/BaseLayout'
|
||||
import StickyBar from '@/components/StickyBar'
|
||||
import BlogPostListScroll from '@/components/BlogPostListScroll'
|
||||
import { useRouter } from 'next/router'
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import { faSearch } from '@fortawesome/free-solid-svg-icons'
|
||||
import { getNotionPageData } from '@/lib/notion/getNotionData'
|
||||
import StickyBar from '@/components/StickyBar'
|
||||
import BaseLayout from '@/layouts/BaseLayout'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { getGlobalNotionData } from '@/lib/notion/getNotionData'
|
||||
import { faSearch } from '@fortawesome/free-solid-svg-icons'
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
export async function getStaticProps () {
|
||||
const from = 'search-props'
|
||||
const notionPageData = await getNotionPageData({ from })
|
||||
const allPosts = await getAllPosts({ notionPageData, from })
|
||||
const categories = await getAllCategories(allPosts)
|
||||
const tagOptions = notionPageData.tagOptions
|
||||
const tags = await getAllTags({ allPosts, tagOptions })
|
||||
const { allPosts, categories, tags, postCount, latestPosts } =
|
||||
await getGlobalNotionData({ from })
|
||||
|
||||
return {
|
||||
props: {
|
||||
allPosts,
|
||||
posts: allPosts,
|
||||
tags,
|
||||
categories
|
||||
categories,
|
||||
postCount,
|
||||
latestPosts
|
||||
},
|
||||
revalidate: 1
|
||||
}
|
||||
}
|
||||
|
||||
const Search = ({ allPosts, tags, categories }) => {
|
||||
// 处理查询过滤 支持标签、关键词过滤
|
||||
const Search = ({ posts, tags, categories, postCount, latestPosts }) => {
|
||||
let filteredPosts = []
|
||||
const searchKey = getSearchKey()
|
||||
if (searchKey) {
|
||||
filteredPosts = allPosts.filter(post => {
|
||||
filteredPosts = posts.filter(post => {
|
||||
const tagContent = post.tags ? post.tags.join(' ') : ''
|
||||
const searchContent = post.title + post.summary + tagContent
|
||||
return searchContent.toLowerCase().includes(searchKey.toLowerCase())
|
||||
})
|
||||
} else {
|
||||
filteredPosts = posts
|
||||
}
|
||||
|
||||
const { locale } = useGlobal()
|
||||
const meta = {
|
||||
title: `${locale.NAV.SEARCH} ${searchKey}| ${BLOG.title} `,
|
||||
title: `${searchKey || ''} | ${locale.NAV.SEARCH} | ${BLOG.title} `,
|
||||
description: BLOG.description,
|
||||
type: 'website'
|
||||
}
|
||||
return (
|
||||
<BaseLayout meta={meta} tags={tags} totalPosts={allPosts} currentSearch={searchKey} categories={categories}>
|
||||
<StickyBar>
|
||||
<div className='p-4 dark:text-gray-200'><FontAwesomeIcon icon={faSearch} className='mr-1'/> {locale.NAV.SEARCH}: {searchKey}</div>
|
||||
</StickyBar>
|
||||
<div className='md:mt-5'>
|
||||
<BlogPostListScroll posts={filteredPosts} tags={tags} currentSearch={searchKey} />
|
||||
<BaseLayout
|
||||
meta={meta}
|
||||
tags={tags}
|
||||
postCount={postCount}
|
||||
currentSearch={searchKey}
|
||||
categories={categories}
|
||||
>
|
||||
<StickyBar>
|
||||
<div className="p-4 dark:text-gray-200">
|
||||
<FontAwesomeIcon icon={faSearch} className="mr-1" />{' '}
|
||||
{locale.NAV.SEARCH}: {searchKey}
|
||||
</div>
|
||||
</StickyBar>
|
||||
<div className="md:mt-5">
|
||||
<BlogPostListScroll posts={filteredPosts} tags={tags} />
|
||||
</div>
|
||||
</BaseLayout>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { getAllCategories, getAllPosts, getAllTags } from '@/lib/notion'
|
||||
import BLOG from '@/blog.config'
|
||||
import StickyBar from '@/components/StickyBar'
|
||||
import BaseLayout from '@/layouts/BaseLayout'
|
||||
import BlogPostListScroll from '@/components/BlogPostListScroll'
|
||||
import StickyBar from '@/components/StickyBar'
|
||||
import TagList from '@/components/TagList'
|
||||
import { getNotionPageData } from '@/lib/notion/getNotionData'
|
||||
import BaseLayout from '@/layouts/BaseLayout'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { getAllPosts } from '@/lib/notion'
|
||||
import { getGlobalNotionData } from '@/lib/notion/getNotionData'
|
||||
|
||||
export default function Tag ({ tags, allPosts, filteredPosts, tag, categories }) {
|
||||
export default function Tag ({ tags, posts, tag, categories, postCount, latestPosts }) {
|
||||
const { locale } = useGlobal()
|
||||
|
||||
const meta = {
|
||||
@@ -21,12 +21,12 @@ export default function Tag ({ tags, allPosts, filteredPosts, tag, categories })
|
||||
const currentTag = tags?.find(r => r?.name === tag)
|
||||
const newTags = currentTag ? [currentTag].concat(tags.filter(r => r?.name !== tag)) : tags.filter(r => r?.name !== tag)
|
||||
|
||||
return <BaseLayout meta={meta} tags={tags} currentTag={tag} categories={categories} totalPosts={allPosts}>
|
||||
return <BaseLayout meta={meta} tags={tags} currentTag={tag} categories={categories} postCount={postCount} latestPosts={latestPosts}>
|
||||
<StickyBar>
|
||||
<TagList tags={newTags} currentTag={tag}/>
|
||||
</StickyBar>
|
||||
<div className='md:mt-8'>
|
||||
<BlogPostListScroll posts={filteredPosts} tags={tags} currentTag={tag}/>
|
||||
<BlogPostListScroll posts={posts} tags={tags} currentTag={tag}/>
|
||||
</div>
|
||||
</BaseLayout>
|
||||
}
|
||||
@@ -34,21 +34,18 @@ export default function Tag ({ tags, allPosts, filteredPosts, tag, categories })
|
||||
export async function getStaticProps ({ params }) {
|
||||
const tag = params.tag
|
||||
const from = 'tag-props'
|
||||
const notionPageData = await getNotionPageData({ from })
|
||||
const allPosts = await getAllPosts({ notionPageData, from })
|
||||
const categories = await getAllCategories(allPosts)
|
||||
const tagOptions = notionPageData.tagOptions
|
||||
const tags = await getAllTags({ allPosts, tagOptions, sliceCount: 0 })
|
||||
const { allPosts, categories, tags, postCount, latestPosts } = await getGlobalNotionData({ from, includePage: true, tagsCount: 0 })
|
||||
const filteredPosts = allPosts.filter(
|
||||
post => post && post.tags && post.tags.includes(tag)
|
||||
)
|
||||
return {
|
||||
props: {
|
||||
tags,
|
||||
allPosts,
|
||||
filteredPosts,
|
||||
posts: filteredPosts,
|
||||
tag,
|
||||
categories
|
||||
categories,
|
||||
postCount,
|
||||
latestPosts
|
||||
},
|
||||
revalidate: 1
|
||||
}
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
import { getAllCategories, getAllPosts, getAllTags } from '@/lib/notion'
|
||||
import BLOG from '@/blog.config'
|
||||
import BaseLayout from '@/layouts/BaseLayout'
|
||||
import TagItem from '@/components/TagItem'
|
||||
import { getNotionPageData } from '@/lib/notion/getNotionData'
|
||||
import BaseLayout from '@/layouts/BaseLayout'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import React from 'react'
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import { getGlobalNotionData } from '@/lib/notion/getNotionData'
|
||||
import { faTags } from '@fortawesome/free-solid-svg-icons'
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import React from 'react'
|
||||
|
||||
export default function Tag ({ tags, allPosts, categories }) {
|
||||
export default function Tag ({ tags, allPosts, categories, postCount, latestPosts }) {
|
||||
const { locale } = useGlobal()
|
||||
const meta = {
|
||||
title: `${locale.COMMON.TAGS} | ${BLOG.title}`,
|
||||
description: BLOG.description,
|
||||
type: 'website'
|
||||
}
|
||||
return <BaseLayout meta={meta} categories={categories} totalPosts={allPosts}>
|
||||
return <BaseLayout meta={meta} categories={categories} totalPosts={allPosts} postCount={postCount} latestPosts={latestPosts}>
|
||||
<div className='bg-white dark:bg-gray-700 px-10 py-10 shadow'>
|
||||
<div className='dark:text-gray-200 mb-5'><FontAwesomeIcon icon={faTags} className='mr-4'/>{locale.COMMON.TAGS}:</div>
|
||||
<div id='tags-list' className='duration-200 flex flex-wrap'>
|
||||
@@ -29,16 +28,15 @@ export default function Tag ({ tags, allPosts, categories }) {
|
||||
|
||||
export async function getStaticProps () {
|
||||
const from = 'tag-index-props'
|
||||
const notionPageData = await getNotionPageData({ from })
|
||||
const allPosts = await getAllPosts({ notionPageData, from })
|
||||
const categories = await getAllCategories(allPosts)
|
||||
const tagOptions = notionPageData.tagOptions
|
||||
const tags = await getAllTags({ allPosts, sliceCount: 0, tagOptions })
|
||||
const { allPosts, categories, tags, postCount, latestPosts } = await getGlobalNotionData({ from, includePage: true, tagsCount: 0 })
|
||||
|
||||
return {
|
||||
props: {
|
||||
tags,
|
||||
allPosts,
|
||||
categories
|
||||
posts: allPosts,
|
||||
categories,
|
||||
postCount,
|
||||
latestPosts
|
||||
},
|
||||
revalidate: 1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user