首页、文章页背景色微调;
侧边抽屉完善;
标签组长度调整;
最近文章日期格式化,增加路由高亮,封装;
清除冗余代码;
This commit is contained in:
tangly1024
2021-11-03 17:40:19 +08:00
parent ab375a3cdc
commit 255a774e1c
11 changed files with 125 additions and 54 deletions

View File

@@ -2,18 +2,18 @@ import Link from 'next/link'
import BLOG from '@/blog.config'
import SearchInput from '@/components/SearchInput'
import MenuButtonGroup from '@/components/MenuButtonGroup'
import TocBar from '@/components/TocBar'
import React, { useImperativeHandle, useState } from 'react'
import InfoCard from '@/components/InfoCard'
import TagList from '@/components/TagList'
import Logo from '@/components/Logo'
import LastedPosts from '@/components/LastedPosts'
/**
* 抽屉面板,可以从侧面拉出
* @returns {JSX.Element}
* @constructor
*/
const Drawer = ({ post, currentTag, cRef, tags }) => {
const Drawer = ({ post, currentTag, cRef, tags, posts }) => {
// 暴露给父组件 通过cRef.current.handleMenuClick 调用
useImperativeHandle(cRef, () => {
return {
@@ -26,14 +26,13 @@ const Drawer = ({ post, currentTag, cRef, tags }) => {
switchShowDrawer(!showDrawer)
}
return <>
<div className='fixed top-0 left-0 z-40 h-full'>
<div className='fixed top-0 left-0 z-50 h-screen shadow-2xl bg-white dark:bg-gray-800'>
{/* LOGO */}
<div
className={(showDrawer ? 'shadow-2xl' : '-ml-72') + ' overflow-y-auto duration-200 w-72 h-full bg-white dark:bg-gray-800 border-r dark:border-gray-600'}>
{/* LOGO */}
<div
className='sticky top-0 z-20 bg-white w-72 flex space-x-4 px-5 py-1 dark:border-gray-500 border-b dark:bg-gray-600 '>
className={(showDrawer ? '' : '-ml-72') + ' duration-200 w-72 border-r dark:border-gray-600'}>
<div className='w-72 flex space-x-4 px-5 py-1 dark:border-gray-500 '>
<div
className='z-10 py-2 duration-200 mr-2 bg-white dark:bg-gray-600 text-gray-600 text-xl cursor-pointer dark:text-gray-300'>
className='z-10 py-2 duration-200 mr-2 text-gray-600 text-xl cursor-pointer dark:text-gray-300'>
<i className='fa hover:scale-125 transform duration-200 fa-bars ' onClick={handleMenuClick} />
</div>
<Logo/>
@@ -42,28 +41,45 @@ const Drawer = ({ post, currentTag, cRef, tags }) => {
{/* 侧边菜单 */}
<div
className={(showDrawer ? 'shadow-2xl' : '-ml-72') + ' w-72 duration-200 h-full fixed left-0 top-16 overflow-y-auto'}>
<div className='z-20'>
className={(showDrawer ? 'shadow-2xl' : '-ml-72') + ' overflow-y-scroll h-screen w-72 duration-200 overflow-y-auto'}>
<div className='pb-56'>
{/* 搜索框 */}
<div className='px-5 my-3 block md:hidden'>
<SearchInput currentTag={currentTag} />
</div>
<InfoCard/>
{/* 菜单 */}
<MenuButtonGroup allowCollapse={false} />
{tags && (
<div className='p-4'>
{/* 标签云 */}
<section>
<strong className='text-xl text-gray-600 dark:text-gray-400'>标签</strong>
<TagList tags={tags} currentTag={currentTag} />
</section>
{/* 信息卡 */}
<InfoCard />
<hr className='dark:border-gray-700' />
<MenuButtonGroup allowCollapse={true} />
<hr className='dark:border-gray-700 my-2' />
{/* 最新文章 */}
{posts && (
<div className='mt-2 sticky top-0'>
<LastedPosts posts={posts}/>
</div>
)}
{/* 标签云 */}
{tags && (
<div className='mt-2'>
<section
className='text-sm font-bold py-3 px-5 text-gray-600 dark:text-gray-400 dark:hover:bg-black duration-100 flex flex-nowrap align-middle'>
<div className='w-32'>标签</div>
</section>
<div className='px-5'>
<TagList tags={tags} currentTag={currentTag} />
</div>
</div>
)}
</div>
</div>
</div>
{/* 背景蒙版 */}
<div id='drawer-background' className={(showDrawer ? 'block' : 'hidden') + ' fixed top-0 left-0 z-30 w-full h-full bg-black bg-opacity-50'}
<div id='drawer-background' className={(showDrawer ? 'block' : 'hidden') + ' fixed top-0 left-0 z-30 w-full h-full bg-black bg-opacity-30'}
onClick={handleMenuClick} />
</>
}

45
components/LastedPosts.js Normal file
View File

@@ -0,0 +1,45 @@
import Link from 'next/link'
import BLOG from '@/blog.config'
import { formatDateFmt } from '@/lib/formatDate'
import { useRouter } from 'next/router'
/**
* 最新文章列表
* @param posts
* @constructor
*/
const LastedPosts = ({ posts }) => {
// 按时间排序
if (posts) {
posts = posts.sort((a, b) => {
const dateA = new Date(a?.lastEditedTime || a.createdTime)
const dateB = new Date(b?.lastEditedTime || b.createdTime)
return dateB - dateA
}).slice(0, 5)
}
const router = useRouter()
return <>
<section
className='text-sm font-bold py-3 px-5 text-gray-600 dark:text-gray-400 dark:hover:bg-black duration-100 flex flex-nowrap align-middle'>
<div className='w-32'>最近更新</div>
</section>
<div>
{posts.map(post => {
return (
<Link key={post.id} title={post.title} href={`${BLOG.path}/article/${post.slug}`} >
<div className={(router.asPath === `${BLOG.path}/article/${post.slug}` ? 'bg-gray-200 dark:bg-black' : '') + ' text-xs leading-5 py-1.5 px-5 cursor-pointer hover:underline flex'}>
<div className='mr-2 text-gray-500'>
{formatDateFmt(post.lastEditedTime, 'yyyy/MM/dd')}
</div>
<div className='text-sm flex w-50 overflow-x-hidden whitespace-nowrap dark:text-gray-300'>
{post.title}
</div>
</div>
</Link>
)
})}
</div>
</>
}
export default LastedPosts

View File

@@ -24,7 +24,7 @@ const MenuButtonGroup = ({ allowCollapse = false }) => {
link =>
link.show && (
<Link key={link.id + link.icon} title={link.to} href={link.to} >
<a className={(router.asPath === link.to ? 'bg-gray-200 dark:bg-gray-900' : '') + ' py-2 px-5 hover:bg-gray-100 cursor-pointer dark:hover:bg-black duration-100 flex flex-nowrap align-middle'} >
<a className={(router.asPath === link.to ? 'bg-gray-200 dark:bg-black' : '') + ' py-2 px-5 hover:bg-gray-100 cursor-pointer dark:hover:bg-black duration-100 flex flex-nowrap align-middle'} >
<div className='my-auto w-5 text-2xl justify-center flex'>
<i className={'fa ' + link.icon} />
</div>

View File

@@ -2,8 +2,7 @@ import React from 'react'
import MenuButtonGroup from '@/components/MenuButtonGroup'
import InfoCard from '@/components/InfoCard'
import TagList from '@/components/TagList'
import BLOG from '@/blog.config'
import Link from 'next/link'
import LastedPosts from '@/components/LastedPosts'
const SideBar = ({ tags, currentTag, post, posts }) => {
// 按时间排序
@@ -18,35 +17,19 @@ const SideBar = ({ tags, currentTag, post, posts }) => {
return <aside className='z-10 dark:border-gray-500 border-gray-200 bg-white hidden xl:block'>
<div
className='w-72 dark:bg-gray-800 h-full scroll-hidden left-0 duration-500 ease-in-out min-h-screen'>
<div id='sidebar' className='hidden md:block sticky top-20 duration-500'>
<div id='sidebar' className='hidden md:block sticky top-20 pb-56 duration-500'>
<>
<InfoCard />
<hr className='dark:border-gray-700' />
<MenuButtonGroup allowCollapse={true} />
</>
<hr className='dark:border-gray-700 my-2' />
{/* 最新文章 */}
{posts && (
<div className='mt-2'>
<hr className='dark:border-gray-700' />
<section
className='text-sm font-bold py-3 px-5 text-gray-600 dark:text-gray-400 dark:hover:bg-black duration-100 flex flex-nowrap align-middle'>
<div className='w-32'>最近更新</div>
</section>
<div>
{posts.map(post => {
return (
<Link key={post.id} title={post.title} href={`${BLOG.path}/article/${post.slug}`} >
<div className='text-sm py-1.5 px-5 cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-600 flex'>
<div className='w-12 overflow-hidden'>
<img className='w-12 w-12 object-cover cursor-pointer transform hover:scale-110 duration-500' src={post.page_cover} alt={post.title} />
</div>
<div className='w-60 ml-2 overflow-hidden whitespace-nowrap dark:text-gray-300'>{post.title}</div>
</div>
</Link>
)
})}
</div>
<LastedPosts posts={posts}/>
</div>
)}

View File

@@ -10,7 +10,7 @@ import TagItemMini from '@/components/TagItemMini'
const TagList = ({ tags, currentTag }) => {
if (!tags) return <></>
return (
<div id='tags-list' className='duration-500 dark:border-gray-600 dark:bg-gray-800 w-52'>
<div id='tags-list' className='duration-500 dark:border-gray-600 dark:bg-gray-800 w-66'>
{Object.keys(tags).map(tag => {
const selected = tag === currentTag
return (

View File

@@ -7,13 +7,13 @@ import Drawer from '@/components/Drawer'
import DrawerRight from '@/components/DrawerRight'
import Logo from '@/components/Logo'
const TopNav = ({ tags, currentTag, post }) => {
const TopNav = ({ tags, currentTag, post, posts }) => {
const drawer = useRef()
const drawerRight = useRef()
return (<>
{/* 侧面抽屉 */}
<Drawer post={post} currentTag={currentTag} cRef={drawer} tags={tags} />
<Drawer post={post} currentTag={currentTag} cRef={drawer} tags={tags} posts={posts}/>
<DrawerRight post={post} cRef={drawerRight}/>
{/* 导航栏 */}

View File

@@ -37,7 +37,7 @@ const BaseLayout = ({ children, layout, fullWidth, tags, meta, post, posts, ...c
<div id='wrapper' className={[BLOG.font, theme].join(' ')}>
<CommonHead meta={meta} />
<TopNav tags={tags} post={post} />
<TopNav tags={tags} post={post} posts={posts} />
{/* Middle Wrapper */}
<main className='flex dark:bg-black'>
<SideBar tags={tags} post={post} posts={posts} />

View File

@@ -1,4 +1,10 @@
export default function formatDate(date, local) {
/**
* 格式化日期
* @param date
* @param local
* @returns {string}
*/
export default function formatDate (date, local) {
const d = new Date(date)
const options = { year: 'numeric', month: 'short', day: 'numeric' }
const res = d.toLocaleDateString(local, options)
@@ -6,3 +12,25 @@ export default function formatDate(date, local) {
? res.replace('年', ' 年 ').replace('月', ' 月 ').replace('日', ' 日')
: res
}
export function formatDateFmt (timestamp, fmt) {
const date = new Date(timestamp)
const o = {
'M+': date.getMonth() + 1, // 月份
'd+': date.getDate(), // 日
'h+': date.getHours(), // 小时
'm+': date.getMinutes(), // 分
's+': date.getSeconds(), // 秒
'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
S: date.getMilliseconds() // 毫秒
}
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
}
for (const k in o) {
if (new RegExp('(' + k + ')').test(fmt)) {
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)))
}
}
return fmt.trim()
}

View File

@@ -1,7 +1,6 @@
import BLOG from '@/blog.config'
import { NotionAPI } from 'notion-client'
import { getDataFromCache, setDataToCache } from '@/lib/cache/cache_manager'
import { useRouter } from 'next/router'
export async function getPostBlocks (id, from) {
let pageBlock = await getDataFromCache('page_block_' + id)

View File

@@ -35,10 +35,10 @@ const BlogPost = ({ post, blockMap, tags, prev, next, posts }) => {
{/* 阅读进度条 */}
<Progress targetRef={targetRef} />
<div id='article-wrapper' ref={targetRef} className='flex-grow bg-white bg-opacity-90 dark:bg-black'>
<div id='article-wrapper' ref={targetRef} className='flex-grow bg-gray-200 dark:bg-black'>
{/* 中央区域 wrapper */}
<header
className='hover:shadow-2xl duration-200 mx-auto max-w-5xl mt-16 lg:mt-20 md:flex-shrink-0 animate__fadeIn animate__animated'>
className='hover:shadow-2xl duration-200 mx-auto max-w-5xl mt-16 lg:mt-32 md:flex-shrink-0 animate__fadeIn animate__animated'>
{/* 封面图 */}
{post.page_cover && post.page_cover.length > 1 && (
<img className='bg-center object-cover w-full' style={{ maxHeight: '40rem' }}
@@ -47,7 +47,7 @@ const BlogPost = ({ post, blockMap, tags, prev, next, posts }) => {
</header>
<article
className='w-screen md:w-full overflow-x-auto md:px-10 px-5 py-10 max-w-5xl mx-auto dark:border-gray-700 dark:bg-gray-700'>
className='w-screen md:w-full overflow-x-auto md:px-10 px-5 py-10 max-w-5xl mx-auto dark:border-gray-700 bg-white dark:bg-gray-700'>
{/* 文章标题 */}
<h1 className='font-bold text-4xl text-black my-5 dark:text-white animate__animated animate__fadeIn'>
{post.title}

View File

@@ -28,7 +28,7 @@ export async function getStaticProps () {
const Index = ({ posts, tags, meta }) => {
return (
<BaseLayout meta={meta} tags={tags} posts={posts}>
<div className='flex-grow'>
<div className='flex-grow bg-gray-200 dark:bg-black'>
<TagsBar tags={tags} />
<BlogPostListScroll posts={posts} tags={tags} />
</div>