mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-22 23:16:48 +00:00
feature:
新增StickyBar组件; 标签页、分类页、搜索页重排;
This commit is contained in:
@@ -53,18 +53,6 @@ const BlogPostListScroll = ({ posts = [], tags, currentSearch, currentCategory,
|
|||||||
} else {
|
} else {
|
||||||
return <div id='post-list-wrapper' className='mt-20 mx-2 lg:mx-20' ref={targetRef}>
|
return <div id='post-list-wrapper' className='mt-20 mx-2 lg:mx-20' ref={targetRef}>
|
||||||
|
|
||||||
<div className='w-full mb-4 xl:sticky xl:top-0 z-30 shadow-card bg-white dark:bg-gray-700 dark:text-gray-200'>
|
|
||||||
{currentCategory && (
|
|
||||||
<div className='p-2 mr-2'><i className='fa fa-folder-open-o mr-1' />{currentCategory}</div>
|
|
||||||
)}
|
|
||||||
{currentSearch && (
|
|
||||||
<div className='p-2 mr-2'><i className='fa fa-search mr-1' />关键字:{currentSearch}</div>
|
|
||||||
)}
|
|
||||||
{currentTag && (
|
|
||||||
<div className='p-2 mr-2'> <i className='fa fa-tag mr-1' /> {currentTag}</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* 文章列表 */}
|
{/* 文章列表 */}
|
||||||
<div className='flex flex-wrap'>
|
<div className='flex flex-wrap'>
|
||||||
{postsToShow.map(post => (
|
{postsToShow.map(post => (
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
const PostsCategories = ({ currentCategory, categories }) => {
|
const CategoryGroup = ({ currentCategory, categories }) => {
|
||||||
return <>
|
return <>
|
||||||
<section
|
<section
|
||||||
className='text-sm font-bold py-3 px-5 text-gray-600 dark:text-gray-400 duration-100 flex flex-nowrap align-middle'>
|
className='text-sm font-bold py-3 px-5 text-gray-600 dark:text-gray-400 duration-100 flex flex-nowrap align-middle'>
|
||||||
@@ -19,4 +19,4 @@ const PostsCategories = ({ currentCategory, categories }) => {
|
|||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default PostsCategories
|
export default CategoryGroup
|
||||||
26
components/CategoryList.js
Normal file
26
components/CategoryList.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import Link from 'next/link'
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
const CategoryList = ({ currentCategory, categories }) => {
|
||||||
|
return <ul className='flex py-1 space-x-3'>
|
||||||
|
<li className='w-10 py-2 dark:text-gray-200'>分类:</li>
|
||||||
|
{Object.keys(categories).map(category => {
|
||||||
|
const selected = category === currentCategory
|
||||||
|
return (
|
||||||
|
<Link key={category} href={`/category/${category}`}>
|
||||||
|
<li
|
||||||
|
className={`cursor-pointer border hover:bg-gray-300 rounded-xl duration-200 mr-1 my-1 px-2 py-1 font-medium font-light text-sm whitespace-nowrap
|
||||||
|
dark:text-gray-300 dark:hover:bg-gray-800 ${selected ? 'text-white bg-black dark:hover:bg-gray-900 dark:bg-black dark:border-gray-800' : 'bg-gray-100 text-gray-600 dark:bg-gray-600 dark:border-gray-600'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<a>
|
||||||
|
<i className='fa fa-folder-open-o mr-1'/>
|
||||||
|
{`${category} `}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</Link>)
|
||||||
|
})}
|
||||||
|
</ul>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CategoryList
|
||||||
@@ -34,11 +34,11 @@ const RecommendPosts = ({ currentPost, totalPosts }) => {
|
|||||||
filteredPosts = filteredPosts.slice(0, 5)
|
filteredPosts = filteredPosts.slice(0, 5)
|
||||||
}
|
}
|
||||||
|
|
||||||
return <div className='dark:text-gray-300 dark:bg-gray-900 bg-gray-100 p-2 mb-2 border-l-4 border-yellow-500'>
|
return <div className='dark:text-gray-300 dark:bg-gray-800 bg-gray-100 p-2 mb-2 border-l-4 border-yellow-500'>
|
||||||
<h2 className='ml-2 mb-2 font-bold'>相关推荐</h2>
|
<h2 className='ml-2 mb-2 font-bold'>相关推荐</h2>
|
||||||
<ul className='list-disc px-5'>
|
<ul className='list-disc px-5'>
|
||||||
{filteredPosts.map(post => (
|
{filteredPosts.map(post => (
|
||||||
<li className='py-1' key={post.id} ><Link href={`/article/${post.slug}`}><a className='cursor-pointer underline'>{post.title}</a></Link></li>
|
<li className='py-1' key={post.id} ><Link href={`/article/${post.slug}`}><a className='cursor-pointer hover:underline'>{post.title}</a></Link></li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import MenuButtonGroup from '@/components/MenuButtonGroup'
|
import MenuButtonGroup from '@/components/MenuButtonGroup'
|
||||||
import InfoCard from '@/components/InfoCard'
|
import InfoCard from '@/components/InfoCard'
|
||||||
import TagList from '@/components/TagList'
|
import TagGroups from '@/components/TagGroups'
|
||||||
import LatestPosts from '@/components/LatestPosts'
|
import LatestPosts from '@/components/LatestPosts'
|
||||||
import PostsCategories from '@/components/PostsCategories'
|
import CategoryGroup from '@/components/CategoryGroup'
|
||||||
import Toc from '@/components/Toc'
|
import Toc from '@/components/Toc'
|
||||||
import SearchInput from '@/components/SearchInput'
|
import SearchInput from '@/components/SearchInput'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
@@ -16,10 +16,11 @@ import Link from 'next/link'
|
|||||||
* @param posts
|
* @param posts
|
||||||
* @param categories
|
* @param categories
|
||||||
* @param currentCategory
|
* @param currentCategory
|
||||||
|
* @param currentSearch
|
||||||
* @returns {JSX.Element}
|
* @returns {JSX.Element}
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
const SideBar = ({ tags, currentTag, post, posts, categories, currentCategory }) => {
|
const SideBar = ({ tags, currentTag, post, posts, categories, currentCategory, currentSearch }) => {
|
||||||
return <aside id='sidebar' className='pt-10 bg-white dark:bg-gray-800 w-72 z-10 dark:border-gray-500 border-gray-200 scroll-hidden h-full'>
|
return <aside id='sidebar' className='pt-10 bg-white dark:bg-gray-800 w-72 z-10 dark:border-gray-500 border-gray-200 scroll-hidden h-full'>
|
||||||
<section>
|
<section>
|
||||||
<InfoCard />
|
<InfoCard />
|
||||||
@@ -29,7 +30,7 @@ const SideBar = ({ tags, currentTag, post, posts, categories, currentCategory })
|
|||||||
|
|
||||||
{/* 搜索框 */}
|
{/* 搜索框 */}
|
||||||
<section className='p-5'>
|
<section className='p-5'>
|
||||||
<SearchInput currentTag={currentTag} />
|
<SearchInput currentTag={currentTag} currentSearch={currentSearch} />
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
@@ -41,7 +42,7 @@ const SideBar = ({ tags, currentTag, post, posts, categories, currentCategory })
|
|||||||
{/* 分类 */}
|
{/* 分类 */}
|
||||||
{categories && (
|
{categories && (
|
||||||
<section className='mt-2'>
|
<section className='mt-2'>
|
||||||
<PostsCategories currentCategory={currentCategory} categories={categories} />
|
<CategoryGroup currentCategory={currentCategory} categories={categories} />
|
||||||
</section>
|
</section>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -61,7 +62,7 @@ const SideBar = ({ tags, currentTag, post, posts, categories, currentCategory })
|
|||||||
<div><Link href='/tag'><div className='hover:underline cursor-pointer opacity-50'>更多标签</div></Link></div>
|
<div><Link href='/tag'><div className='hover:underline cursor-pointer opacity-50'>更多标签</div></Link></div>
|
||||||
</section>
|
</section>
|
||||||
<div className='px-5'>
|
<div className='px-5'>
|
||||||
<TagList tags={tags} currentTag={currentTag} />
|
<TagGroups tags={tags} currentTag={currentTag} />
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
)}
|
)}
|
||||||
|
|||||||
29
components/StickyBar.js
Normal file
29
components/StickyBar.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* 标签组导航条,默认隐藏仅在移动端显示
|
||||||
|
* @param tags
|
||||||
|
* @param currentTag
|
||||||
|
* @returns {JSX.Element}
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
const StickyBar = ({ children }) => {
|
||||||
|
if (!children) return <></>
|
||||||
|
return (
|
||||||
|
<div id='sticky-bar' className='fixed lg:top-0 top-16 duration-500 z-10 w-full border-b dark:border-gray-600'>
|
||||||
|
<div className='bg-white dark:bg-gray-800 flex overflow-x-auto'>
|
||||||
|
<div className='z-30 sticky left-0 flex'>
|
||||||
|
<div className='pr-2 bg-white dark:bg-gray-800'/>
|
||||||
|
<div className='pr-3 -line-x-opacity bg-black'/>
|
||||||
|
</div>
|
||||||
|
<div id='tag-container'>
|
||||||
|
{ children }
|
||||||
|
</div>
|
||||||
|
<div className='z-30 sticky right-0 flex'>
|
||||||
|
<div className='px-5 line-x-opacity'/>
|
||||||
|
<div className='px-2 bg-white dark:bg-gray-800'/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default StickyBar
|
||||||
24
components/TagGroups.js
Normal file
24
components/TagGroups.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import TagItemMini from '@/components/TagItemMini'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标签组
|
||||||
|
* @param tags
|
||||||
|
* @param currentTag
|
||||||
|
* @returns {JSX.Element}
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
const TagGroups = ({ tags, currentTag }) => {
|
||||||
|
if (!tags) return <></>
|
||||||
|
return (
|
||||||
|
<div id='tags-group' className='dark:border-gray-600 dark:bg-gray-800 w-66'>
|
||||||
|
{
|
||||||
|
tags.map(tag => {
|
||||||
|
const selected = tag.name === currentTag
|
||||||
|
return <TagItemMini key={tag.name} tag={tag.name} selected={selected} count={tag.count} />
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TagGroups
|
||||||
@@ -3,10 +3,10 @@ import Link from 'next/link'
|
|||||||
const TagItemMini = ({ tag, selected = false, count }) => {
|
const TagItemMini = ({ tag, selected = false, count }) => {
|
||||||
return <Link key={tag} href={selected ? '/' : `/tag/${encodeURIComponent(tag)}`}>
|
return <Link key={tag} href={selected ? '/' : `/tag/${encodeURIComponent(tag)}`}>
|
||||||
<div className={`cursor-pointer inline-block border rounded hover:bg-gray-500 shadow-card
|
<div className={`cursor-pointer inline-block border rounded hover:bg-gray-500 shadow-card
|
||||||
mr-2 my-1 p-1 font-medium font-light text-xs whitespace-nowrap dark:text-gray-300 dark:hover:bg-gray-500
|
mr-2 my-1 p-1 font-medium font-light text-xs whitespace-nowrap dark:text-gray-300
|
||||||
${selected
|
${selected
|
||||||
? 'text-white bg-black dark:hover:bg-gray-900 dark:bg-black dark:border-gray-800'
|
? 'text-white bg-gray-700 dark:hover:bg-gray-900 dark:bg-gray-500 border-gray-800'
|
||||||
: 'bg-white text-gray-500 hover:shadow-xl hover:text-white border-gray-500 dark:bg-gray-800 dark:border-gray-600'}` }>
|
: 'bg-white text-gray-500 hover:shadow-xl hover:text-white border-gray-500 dark:bg-gray-800 dark:hover:bg-gray-600 dark:border-gray-600'}` }>
|
||||||
<div> <i className='fa fa-tag mr-2 py-0.5'/>{tag + (count ? `(${count})` : '')} </div>
|
<div> <i className='fa fa-tag mr-2 py-0.5'/>{tag + (count ? `(${count})` : '')} </div>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -1,24 +1,33 @@
|
|||||||
import TagItemMini from '@/components/TagItemMini'
|
import Link from 'next/link'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 标签组
|
* 横向的标签列表
|
||||||
* @param tags
|
* @param tags
|
||||||
* @param currentTag
|
* @param currentTag
|
||||||
* @returns {JSX.Element}
|
* @returns {JSX.Element}
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
const TagList = ({ tags, currentTag }) => {
|
const TagList = ({ tags, currentTag }) => {
|
||||||
if (!tags) return <></>
|
return <ul className='flex py-1 space-x-3'>
|
||||||
return (
|
<li className='w-10 py-2 dark:text-gray-200'>标签:</li>
|
||||||
<div id='tags-list' className='duration-500 dark:border-gray-600 dark:bg-gray-800 w-66'>
|
{tags.map(tag => {
|
||||||
{
|
const selected = tag.name === currentTag
|
||||||
tags.map(tag => {
|
return (
|
||||||
const selected = tag.name === currentTag
|
<Link key={tag.name} href={selected ? '/' : `/tag/${encodeURIComponent(tag.name)}`}>
|
||||||
return <TagItemMini key={tag.name} tag={tag.name} selected={selected} count={tag.count} />
|
<li
|
||||||
})
|
className={`cursor-pointer border hover:bg-gray-300 rounded-xl duration-200 mr-1 my-1 px-2 py-1 font-medium font-light text-sm whitespace-nowrap
|
||||||
}
|
dark:text-gray-300 dark:hover:bg-gray-800 ${selected ? 'text-white bg-black dark:hover:bg-gray-900 dark:bg-black dark:border-gray-800' : 'bg-gray-100 text-gray-600 dark:bg-gray-600 dark:border-gray-600'
|
||||||
</div>
|
}`}
|
||||||
)
|
>
|
||||||
|
<a>
|
||||||
|
<i className='fa fa-tag mr-1'/>
|
||||||
|
{`${tag.name} (${tag.count})`}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</ul>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TagList
|
export default TagList
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
import Link from 'next/link'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 标签组导航条,默认隐藏仅在移动端显示
|
|
||||||
* @param tags
|
|
||||||
* @param currentTag
|
|
||||||
* @returns {JSX.Element}
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
const TagsBar = ({ tags, currentTag }) => {
|
|
||||||
if (!tags) return <></>
|
|
||||||
return (
|
|
||||||
<div id='tags-bar' className='fixed block lg:hidden top-16 duration-500 z-10 w-full border-b dark:border-gray-600'>
|
|
||||||
<div className='bg-white dark:bg-gray-800 flex overflow-x-auto'>
|
|
||||||
<div className='z-30 sticky left-0 flex'>
|
|
||||||
<div className='px-2 bg-white dark:bg-gray-800'/>
|
|
||||||
<div className='px-5 -line-x-opacity bg-black'/>
|
|
||||||
</div>
|
|
||||||
<ul id='tag-container' className='flex py-1 space-x-3'>
|
|
||||||
<li className='w-10 py-2 dark:text-gray-200'>标签:</li>
|
|
||||||
{tags.map(tag => {
|
|
||||||
const selected = tag.name === currentTag
|
|
||||||
return (
|
|
||||||
<Link key={tag.name} href={selected ? '/' : `/tag/${encodeURIComponent(tag)}`}>
|
|
||||||
<li
|
|
||||||
className={`cursor-pointer border hover:bg-gray-300 rounded-xl duration-200 mr-1 my-1 px-2 py-1 font-medium font-light text-sm whitespace-nowrap
|
|
||||||
dark:text-gray-300 dark:hover:bg-gray-800 ${selected ? 'text-white bg-black dark:hover:bg-gray-900 dark:bg-black dark:border-gray-800' : 'bg-gray-100 text-gray-600 dark:bg-gray-600 dark:border-gray-600'
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
<a>
|
|
||||||
{`${tag.name} (${tag.count})`}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</Link>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</ul>
|
|
||||||
<div className='z-30 sticky right-0 flex'>
|
|
||||||
<div className='px-5 line-x-opacity'/>
|
|
||||||
<div className='px-2 bg-white dark:bg-gray-800'/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default TagsBar
|
|
||||||
@@ -21,6 +21,7 @@ import DarkModeButton from '@/components/DarkModeButton'
|
|||||||
* @param totalPosts
|
* @param totalPosts
|
||||||
* @param currentSearch
|
* @param currentSearch
|
||||||
* @param currentCategory
|
* @param currentCategory
|
||||||
|
* @param currentTag
|
||||||
* @param categories
|
* @param categories
|
||||||
* @param customMeta
|
* @param customMeta
|
||||||
* @returns {JSX.Element}
|
* @returns {JSX.Element}
|
||||||
@@ -36,6 +37,7 @@ const BaseLayout = ({
|
|||||||
totalPosts,
|
totalPosts,
|
||||||
currentSearch,
|
currentSearch,
|
||||||
currentCategory,
|
currentCategory,
|
||||||
|
currentTag,
|
||||||
categories,
|
categories,
|
||||||
...customMeta
|
...customMeta
|
||||||
}) => {
|
}) => {
|
||||||
@@ -76,13 +78,13 @@ const BaseLayout = ({
|
|||||||
{/* Middle Wrapper */}
|
{/* Middle Wrapper */}
|
||||||
<main className='flex dark:bg-black'>
|
<main className='flex dark:bg-black'>
|
||||||
<div className='hidden lg:block z-10'>
|
<div className='hidden lg:block z-10'>
|
||||||
<SideBar tags={tags} post={post} posts={totalPosts} categories={categories} currentCategory={currentCategory} />
|
<SideBar post={post} posts={totalPosts} tags={tags} currentSearch={currentSearch} currentTag={currentTag} categories={categories} currentCategory={currentCategory} />
|
||||||
</div>
|
</div>
|
||||||
<div className='flex flex-grow' ref={targetRef}>
|
<div className='flex flex-grow' ref={targetRef}>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
<JumpToTopButton targetRef={targetRef} showPercent={true} />
|
<JumpToTopButton targetRef={targetRef} showPercent={true} />
|
||||||
<div className='hidden lg:block fixed right-4 top-4 p-1 rounded-full
|
<div className='hidden lg:block fixed right-4 top-20 p-1 rounded-full
|
||||||
bg-white text-black
|
bg-white text-black
|
||||||
dark:border-gray-500 dark:bg-gray-700 dark:text-white
|
dark:border-gray-500 dark:bg-gray-700 dark:text-white
|
||||||
' style={{ boxShadow: 'rgba(41, 50, 60, 0.5) 0px 2px 16px', borderRadius: '28px' }}>
|
' style={{ boxShadow: 'rgba(41, 50, 60, 0.5) 0px 2px 16px', borderRadius: '28px' }}>
|
||||||
@@ -104,8 +106,8 @@ const handleScrollDown = () => {
|
|||||||
const nav = document.querySelector('#sticky-nav')
|
const nav = document.querySelector('#sticky-nav')
|
||||||
nav && nav.classList.replace('top-0', '-top-16')
|
nav && nav.classList.replace('top-0', '-top-16')
|
||||||
|
|
||||||
const tagsBar = document.querySelector('#tags-bar')
|
const stickyBar = document.querySelector('#sticky-bar')
|
||||||
tagsBar && tagsBar.classList.replace('top-16', 'top-0')
|
stickyBar && stickyBar.classList.replace('top-16', 'top-0')
|
||||||
|
|
||||||
const tocDrawerButton = document.querySelector('#toc-drawer-button')
|
const tocDrawerButton = document.querySelector('#toc-drawer-button')
|
||||||
tocDrawerButton && tocDrawerButton.classList.replace('hidden', 'block')
|
tocDrawerButton && tocDrawerButton.classList.replace('hidden', 'block')
|
||||||
@@ -126,8 +128,8 @@ const handleScrollUp = () => {
|
|||||||
const nav = document.querySelector('#sticky-nav')
|
const nav = document.querySelector('#sticky-nav')
|
||||||
nav && nav.classList.replace('-top-16', 'top-0')
|
nav && nav.classList.replace('-top-16', 'top-0')
|
||||||
|
|
||||||
const tagsBar = document.querySelector('#tags-bar')
|
const stickyBar = document.querySelector('#sticky-bar')
|
||||||
tagsBar && tagsBar.classList.replace('top-0', 'top-16')
|
stickyBar && stickyBar.classList.replace('top-0', 'top-16')
|
||||||
|
|
||||||
// const tocDrawerButton = document.querySelector('#toc-drawer-button')
|
// const tocDrawerButton = document.querySelector('#toc-drawer-button')
|
||||||
// tocDrawerButton && tocDrawerButton.classList.replace('block', 'hidden')
|
// tocDrawerButton && tocDrawerButton.classList.replace('block', 'hidden')
|
||||||
|
|||||||
@@ -48,15 +48,15 @@ const ArticleDetail = ({ post, blockMap, tags, prev, next, posts, categories })
|
|||||||
<div id='article-wrapper' ref={targetRef} className='flex-grow bg-gray-200 dark:bg-black'>
|
<div id='article-wrapper' ref={targetRef} className='flex-grow bg-gray-200 dark:bg-black'>
|
||||||
{/* 中央区域 wrapper */}
|
{/* 中央区域 wrapper */}
|
||||||
<header
|
<header
|
||||||
className='shadow-card duration-200 mx-auto max-w-5xl mt-16 lg:mt-32 md:flex-shrink-0 animate__fadeIn animate__animated'>
|
className='hover:shadow-2xl hover:scale-105 transform duration-200 mx-auto max-w-5xl mt-16 mb-2 lg:mt-32 md:flex-shrink-0 animate__fadeIn animate__animated'>
|
||||||
{/* 封面图 */}
|
{/* 封面图 */}
|
||||||
{post.page_cover && post.page_cover.length > 1 && (
|
{post.page_cover && post.page_cover.length > 1 && (
|
||||||
<img className='bg-center object-cover w-full' style={{ maxHeight: '40rem' }}
|
<img className='bg-center object-cover w-full' style={{ maxHeight: '40rem' }} loading="lazy"
|
||||||
src={post.page_cover} alt={post.title} />
|
src={post.page_cover} alt={post.title} />
|
||||||
)}
|
)}
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<article className='shadow-card mb-20 w-screen md:w-full overflow-x-auto md:px-10 px-5 pt-10 max-w-5xl mx-auto dark:border-gray-700 bg-white dark:bg-gray-900'>
|
<article className='hover:shadow-2xl duration-200 shadow-card mb-20 w-screen md:w-full overflow-x-auto md:px-10 px-5 pt-10 max-w-5xl mx-auto dark:border-gray-700 bg-white dark:bg-gray-900'>
|
||||||
{/* 文章标题 */}
|
{/* 文章标题 */}
|
||||||
<h1 className='font-bold text-4xl text-black my-5 dark:text-white animate__animated animate__fadeIn'>
|
<h1 className='font-bold text-4xl text-black my-5 dark:text-white animate__animated animate__fadeIn'>
|
||||||
{post.title}
|
{post.title}
|
||||||
@@ -109,7 +109,7 @@ const ArticleDetail = ({ post, blockMap, tags, prev, next, posts, categories })
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='flex justify-center pb-5'>
|
<div className='flex justify-center pb-10'>
|
||||||
<RewardButton />
|
<RewardButton />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ const ArticleDetail = ({ post, blockMap, tags, prev, next, posts, categories })
|
|||||||
|
|
||||||
{/* 版权声明 */}
|
{/* 版权声明 */}
|
||||||
<section
|
<section
|
||||||
className='overflow-auto dark:bg-gray-700 dark:text-gray-300 bg-gray-100 p-5 leading-8 border-l-4 border-red-500'>
|
className='overflow-auto dark:bg-gray-800 dark:text-gray-300 bg-gray-100 p-5 leading-8 border-l-4 border-red-500'>
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>本文作者:</strong>{BLOG.author}</li>
|
<li><strong>本文作者:</strong>{BLOG.author}</li>
|
||||||
<li><strong>本文链接:</strong> <a href={url}>{url}</a> 《{post.title}》</li>
|
<li><strong>本文链接:</strong> <a href={url}>{url}</a> 《{post.title}》</li>
|
||||||
@@ -145,8 +145,8 @@ const ArticleDetail = ({ post, blockMap, tags, prev, next, posts, categories })
|
|||||||
<div className='text-gray-800 my-5 dark:text-gray-300'>
|
<div className='text-gray-800 my-5 dark:text-gray-300'>
|
||||||
<hr/>
|
<hr/>
|
||||||
<div className='flex flex-wrap lg:flex-nowrap lg:space-x-10 justify-between py-2'>
|
<div className='flex flex-wrap lg:flex-nowrap lg:space-x-10 justify-between py-2'>
|
||||||
<Link href={`/article/${prev.slug}`}><div className=' py-3 text-blue-500 text-xl hover:underline cursor-pointer'><i className='fa fa-angle-double-left mr-1'/>{prev.title}</div></Link>
|
<Link href={`/article/${prev.slug}`}><div className='py-3 text-blue-500 text-lg hover:underline cursor-pointer'><i className='fa fa-angle-double-left mr-1'/>{prev.title}</div></Link>
|
||||||
<Link href={`/article/${next.slug}`}><div className='flex py-3 text-blue-500 text-xl hover:underline cursor-pointer'>{next.title}<i className='fa fa-angle-double-right ml-1'/></div></Link>
|
<Link href={`/article/${next.slug}`}><div className='flex py-3 text-blue-500 text-lg hover:underline cursor-pointer'>{next.title}<i className='fa fa-angle-double-right ml-1'/></div></Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import { getAllCategories, getAllPosts, getAllTags } from '@/lib/notion'
|
import { getAllCategories, getAllPosts, getAllTags } from '@/lib/notion'
|
||||||
import BLOG from '@/blog.config'
|
import BLOG from '@/blog.config'
|
||||||
import TagsBar from '@/components/TagsBar'
|
import StickyBar from '@/components/StickyBar'
|
||||||
import BaseLayout from '@/layouts/BaseLayout'
|
import BaseLayout from '@/layouts/BaseLayout'
|
||||||
import BlogPostListScroll from '@/components/BlogPostListScroll'
|
import BlogPostListScroll from '@/components/BlogPostListScroll'
|
||||||
|
import React from 'react'
|
||||||
|
import CategoryList from '@/components/CategoryList'
|
||||||
|
|
||||||
export default function Category ({ tags, posts, category, categories }) {
|
export default function Category ({ tags, posts, category, categories }) {
|
||||||
const meta = {
|
const meta = {
|
||||||
@@ -12,7 +14,9 @@ export default function Category ({ tags, posts, category, categories }) {
|
|||||||
}
|
}
|
||||||
return <BaseLayout meta={meta} tags={tags} currentCategory={category} totalPosts={posts} categories={categories}>
|
return <BaseLayout meta={meta} tags={tags} currentCategory={category} totalPosts={posts} categories={categories}>
|
||||||
<div className='flex-grow bg-gray-200 dark:bg-black shadow-inner'>
|
<div className='flex-grow bg-gray-200 dark:bg-black shadow-inner'>
|
||||||
<TagsBar tags={tags} />
|
<StickyBar >
|
||||||
|
<CategoryList currentCategory={category} categories={categories} />
|
||||||
|
</StickyBar>
|
||||||
<BlogPostListScroll posts={posts} tags={tags} currentCategory={category}/>
|
<BlogPostListScroll posts={posts} tags={tags} currentCategory={category}/>
|
||||||
</div>
|
</div>
|
||||||
</BaseLayout>
|
</BaseLayout>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { getAllCategories, getAllPosts, getAllTags } from '@/lib/notion'
|
import { getAllCategories, getAllPosts, getAllTags } from '@/lib/notion'
|
||||||
import BLOG from '@/blog.config'
|
import BLOG from '@/blog.config'
|
||||||
import BaseLayout from '@/layouts/BaseLayout'
|
import BaseLayout from '@/layouts/BaseLayout'
|
||||||
import TagsBar from '@/components/TagsBar'
|
import StickyBar from '@/components/StickyBar'
|
||||||
import BlogPostListScroll from '@/components/BlogPostListScroll'
|
import BlogPostListScroll from '@/components/BlogPostListScroll'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
|
|
||||||
@@ -43,9 +43,9 @@ const Search = ({ posts, tags, meta, categories }) => {
|
|||||||
return (
|
return (
|
||||||
<BaseLayout meta={meta} tags={tags} totalPosts={posts} currentSearch={searchKey} categories={categories}>
|
<BaseLayout meta={meta} tags={tags} totalPosts={posts} currentSearch={searchKey} categories={categories}>
|
||||||
<div className='flex-grow bg-gray-200 dark:bg-black shadow-inner'>
|
<div className='flex-grow bg-gray-200 dark:bg-black shadow-inner'>
|
||||||
<TagsBar tags={tags} />
|
<StickyBar>
|
||||||
{/* 标签栏留白 */}
|
<div className='p-4 dark:text-gray-200'><i className='fa fa-search mr-1'/> 搜索词: {searchKey}</div>
|
||||||
<div className='my-6 md:pt-0'/>
|
</StickyBar>
|
||||||
<BlogPostListScroll posts={filteredPosts} tags={tags} currentSearch={searchKey} />
|
<BlogPostListScroll posts={filteredPosts} tags={tags} currentSearch={searchKey} />
|
||||||
</div>
|
</div>
|
||||||
</BaseLayout>
|
</BaseLayout>
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { getAllCategories, getAllPosts, getAllTags } from '@/lib/notion'
|
import { getAllCategories, getAllPosts, getAllTags } from '@/lib/notion'
|
||||||
import BLOG from '@/blog.config'
|
import BLOG from '@/blog.config'
|
||||||
import TagsBar from '@/components/TagsBar'
|
import StickyBar from '@/components/StickyBar'
|
||||||
import BaseLayout from '@/layouts/BaseLayout'
|
import BaseLayout from '@/layouts/BaseLayout'
|
||||||
import BlogPostListScroll from '@/components/BlogPostListScroll'
|
import BlogPostListScroll from '@/components/BlogPostListScroll'
|
||||||
|
import TagList from '@/components/TagList'
|
||||||
|
|
||||||
export default function Tag ({ tags, posts, currentTag, categories }) {
|
export default function Tag ({ tags, posts, currentTag, categories }) {
|
||||||
const meta = {
|
const meta = {
|
||||||
@@ -12,7 +13,9 @@ export default function Tag ({ tags, posts, currentTag, categories }) {
|
|||||||
}
|
}
|
||||||
return <BaseLayout meta={meta} tags={tags} currentTag={currentTag} categories={categories} totalPosts={posts}>
|
return <BaseLayout meta={meta} tags={tags} currentTag={currentTag} categories={categories} totalPosts={posts}>
|
||||||
<div className='flex-grow bg-gray-200 dark:bg-black shadow-inner'>
|
<div className='flex-grow bg-gray-200 dark:bg-black shadow-inner'>
|
||||||
<TagsBar tags={tags} currentTag={currentTag}/>
|
<StickyBar>
|
||||||
|
<TagList tags={tags} currentTag={currentTag}/>
|
||||||
|
</StickyBar>
|
||||||
<BlogPostListScroll posts={posts} tags={tags} currentTag={currentTag}/>
|
<BlogPostListScroll posts={posts} tags={tags} currentTag={currentTag}/>
|
||||||
</div>
|
</div>
|
||||||
</BaseLayout>
|
</BaseLayout>
|
||||||
|
|||||||
Reference in New Issue
Block a user