mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-30 07:26:45 +00:00
Magzine主题基本完成
This commit is contained in:
@@ -1,36 +0,0 @@
|
||||
import Link from 'next/link'
|
||||
|
||||
/**
|
||||
* 归档分组
|
||||
* @param {*} param0
|
||||
* @returns
|
||||
*/
|
||||
export default function ArchiveItem({ archiveTitle, archivePosts }) {
|
||||
return (
|
||||
<div key={archiveTitle}>
|
||||
<div id={archiveTitle} className='pt-16 pb-4 text-3xl dark:text-gray-300'>
|
||||
{archiveTitle}
|
||||
</div>
|
||||
<ul>
|
||||
{archivePosts[archiveTitle]?.map(post => {
|
||||
return (
|
||||
<li
|
||||
key={post.id}
|
||||
className='border-l-2 p-1 text-xs md:text-base items-center hover:scale-x-105 hover:border-gray-500 dark:hover:border-gray-300 dark:border-gray-400 transform duration-500'>
|
||||
<div id={post?.publishDay}>
|
||||
<span className='text-gray-400'>{post.date?.start_date}</span>{' '}
|
||||
|
||||
<Link
|
||||
passHref
|
||||
href={post?.href}
|
||||
className='dark:text-gray-400 dark:hover:text-gray-300 overflow-x-hidden hover:underline cursor-pointer text-gray-600'>
|
||||
{post.title}
|
||||
</Link>
|
||||
</div>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
import LazyImage from '@/components/LazyImage'
|
||||
import NotionIcon from '@/components/NotionIcon'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import Link from 'next/link'
|
||||
import CategoryItem from './CategoryItem'
|
||||
import TagItemMini from './TagItemMini'
|
||||
|
||||
@@ -15,8 +14,8 @@ export default function ArticleInfo(props) {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='flex flex-col gap-y-8'>
|
||||
<div className='flex justify-center py-2 mr-2 items-center'>
|
||||
<div className='flex flex-col gap-y-4 py-4'>
|
||||
<div className='flex justify-center mr-2 items-center'>
|
||||
{siteConfig('MAGZINE_POST_LIST_CATEGORY') && (
|
||||
<CategoryItem category={post?.category} />
|
||||
)}
|
||||
@@ -32,7 +31,7 @@ export default function ArticleInfo(props) {
|
||||
</div>
|
||||
|
||||
{/* title */}
|
||||
<h2 className='text-5xl text-center dark:text-gray-300'>
|
||||
<h2 className='text-4xl text-center dark:text-gray-300'>
|
||||
{siteConfig('POST_TITLE_ICON') && (
|
||||
<NotionIcon icon={post?.pageIcon} />
|
||||
)}
|
||||
@@ -51,40 +50,6 @@ export default function ArticleInfo(props) {
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* meta */}
|
||||
<section className='py-2 items-center text-sm px-1'>
|
||||
<div className='flex flex-wrap text-gray-500 py-1 dark:text-gray-600'>
|
||||
<span className='whitespace-nowrap'>
|
||||
{' '}
|
||||
<i className='far fa-calendar mr-2' />
|
||||
{post?.publishDay}
|
||||
</span>
|
||||
<span className='mx-1'>|</span>
|
||||
<span className='whitespace-nowrap mr-2'>
|
||||
<i className='far fa-calendar-check mr-2' />
|
||||
{post?.lastEditedDay}
|
||||
</span>
|
||||
<div className='hidden busuanzi_container_page_pv mr-2 whitespace-nowrap'>
|
||||
<i className='mr-1 fas fa-eye' />
|
||||
<span className='busuanzi_value_page_pv' />
|
||||
</div>
|
||||
</div>
|
||||
<Link href='/about' passHref legacyBehavior>
|
||||
<div className='flex pt-2'>
|
||||
<LazyImage
|
||||
src={siteInfo?.icon}
|
||||
className='rounded-full cursor-pointer'
|
||||
width={22}
|
||||
alt={siteConfig('AUTHOR')}
|
||||
/>
|
||||
|
||||
<div className='mr-3 ml-2 my-auto text-gray-500 cursor-pointer'>
|
||||
{siteConfig('AUTHOR')}
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</section>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
30
themes/magzine/components/BannerFullWidth.js
Normal file
30
themes/magzine/components/BannerFullWidth.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import LazyImage from '@/components/LazyImage'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import BannerItem from './BannerItem'
|
||||
|
||||
/**
|
||||
* 全宽
|
||||
* @param {*} props
|
||||
* @returns
|
||||
*/
|
||||
export default function BannerFullWidth() {
|
||||
const { siteInfo } = useGlobal()
|
||||
const banner = siteConfig('MAGZINE_HOME_BANNER_ENABLE')
|
||||
if (!banner) {
|
||||
return null
|
||||
}
|
||||
return (
|
||||
<div className='w-full flex lg:flex-row flex-col justify-between h-96 bg-black'>
|
||||
<LazyImage
|
||||
alt={siteInfo?.title}
|
||||
src={siteInfo?.pageCover}
|
||||
className={`banner-cover w-full h-96 object-cover object-center `}
|
||||
/>
|
||||
|
||||
<div className='w-full flex items-center justify-center'>
|
||||
<BannerItem />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
35
themes/magzine/components/BannerItem.js
Normal file
35
themes/magzine/components/BannerItem.js
Normal file
@@ -0,0 +1,35 @@
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import Link from 'next/link'
|
||||
|
||||
/**
|
||||
* 文字广告Banner
|
||||
* @param {*} props
|
||||
* @returns
|
||||
*/
|
||||
export default function BannerItem() {
|
||||
// 首屏信息栏按钮文字
|
||||
const banner = siteConfig('MAGZINE_HOME_BANNER_ENABLE')
|
||||
const button = siteConfig('MAGZINE_HOME_BUTTON')
|
||||
const text = siteConfig('MAGZINE_HOME_BUTTON_TEXT')
|
||||
const url = siteConfig('MAGZINE_HOME_BUTTON_URL')
|
||||
const title = siteConfig('MAGZINE_HOME_TITLE')
|
||||
const description = siteConfig('MAGZINE_HOME_DESCRIPTION')
|
||||
const tips = siteConfig('MAGZINE_HOME_TIPS')
|
||||
if (!banner) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='flex flex-col p-5 gap-y-5 dark items-center justify-between w-full bg-black text-white'>
|
||||
{/* 首屏导航按钮 */}
|
||||
<h2 className='text-2xl font-semibold'>{title}</h2>
|
||||
<h3 className='text-sm'>{description}</h3>
|
||||
{button && (
|
||||
<div className='mt-2 text-center px-6 py-3 font-semibold rounded-3xl text-black bg-[#7BE986] hover:bg-[#62BA6B]'>
|
||||
<Link href={url}>{text}</Link>
|
||||
</div>
|
||||
)}
|
||||
<span className='text-xs'>{tips}</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import Progress from './Progress'
|
||||
* @returns {JSX.Element}
|
||||
* @constructor
|
||||
*/
|
||||
const Catalog = ({ toc }) => {
|
||||
const Catalog = ({ toc, className }) => {
|
||||
const tocIds = []
|
||||
|
||||
// 目录自动滚动
|
||||
@@ -62,7 +62,7 @@ const Catalog = ({ toc }) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='px-3'>
|
||||
<div className={className}>
|
||||
<div className='w-full mt-2 mb-4'>
|
||||
<Progress />
|
||||
</div>
|
||||
|
||||
@@ -13,11 +13,8 @@ const CategoryGroup = ({ currentCategory, categoryOptions }) => {
|
||||
}
|
||||
return (
|
||||
<div id='category-list' className='pt-4'>
|
||||
<div className='mb-2'>
|
||||
<i className='mr-2 fas fa-th' />
|
||||
{locale.COMMON.CATEGORY}
|
||||
</div>
|
||||
<div className='flex flex-wrap'>
|
||||
<div className='text-lg font-bold mb-2'>{locale.COMMON.CATEGORY}</div>
|
||||
<div className=''>
|
||||
{categoryOptions?.map(category => {
|
||||
const selected = currentCategory === category.name
|
||||
return (
|
||||
|
||||
@@ -9,12 +9,9 @@ export default function CategoryItem({ selected, category, categoryCount }) {
|
||||
(selected
|
||||
? ' bg-gray-600 text-white '
|
||||
: 'dark:text-gray-400 text-gray-900 ') +
|
||||
' hover:underline flex text-sm items-center duration-300 cursor-pointer py-1 whitespace-nowrap'
|
||||
'text-sm hover:underline flex text-md items-center duration-300 cursor-pointer py-1 whitespace-nowrap'
|
||||
}>
|
||||
<div>
|
||||
{/* <i
|
||||
className={`mr-2 fas ${selected ? 'fa-folder-open' : 'fa-folder'}`}
|
||||
/> */}
|
||||
{category} {categoryCount && `(${categoryCount})`}
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
@@ -16,14 +16,13 @@ const Footer = ({ title }) => {
|
||||
parseInt(since) < currentYear ? since + '-' + currentYear : currentYear
|
||||
const { siteInfo } = useGlobal()
|
||||
const MAGZINE_FOOTER_LINKS = siteConfig('MAGZINE_FOOTER_LINKS', [])
|
||||
console.log('菜单', MAGZINE_FOOTER_LINKS)
|
||||
|
||||
return (
|
||||
<footer className='z-10 bg-black text-white justify-center m-auto w-full p-6 relative'>
|
||||
<div className='max-w-screen-2xl w-full mx-auto '>
|
||||
<div className='max-w-screen-2xl w-full mx-auto '>
|
||||
{/* 信息与链接区块 */}
|
||||
<div className='w-full flex justify-between py-16'>
|
||||
<div className='gap-x-2 flex items-center'>
|
||||
<div className='w-full flex lg:flex-row flex-col justify-between py-16'>
|
||||
<div className='gap-x-2 py-6 flex items-center'>
|
||||
{/* 站长信息 */}
|
||||
<LazyImage
|
||||
src={siteInfo?.icon}
|
||||
@@ -43,11 +42,11 @@ const Footer = ({ title }) => {
|
||||
</div>
|
||||
|
||||
{/* 右侧链接区块 */}
|
||||
<div className='grid grid-cols-4 gap-16'>
|
||||
<div className='grid grid-cols-1 lg:grid-cols-4 lg:gap-16 gap-8'>
|
||||
{MAGZINE_FOOTER_LINKS?.map((group, index) => {
|
||||
return (
|
||||
<div key={index}>
|
||||
<div className='font-bold text-lg text-white pb-8'>
|
||||
<div className='font-bold text-lg text-white lg:pb-8 pb-4'>
|
||||
{group.name}
|
||||
</div>
|
||||
<div className='flex flex-col gap-y-2'>
|
||||
|
||||
@@ -2,6 +2,7 @@ import Collapse from '@/components/Collapse'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import throttle from 'lodash.throttle'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import CONFIG from '../config'
|
||||
import LogoBar from './LogoBar'
|
||||
@@ -18,8 +19,8 @@ export default function Header(props) {
|
||||
const [isOpen, changeShow] = useState(false)
|
||||
const collapseRef = useRef(null)
|
||||
const lastScrollY = useRef(0) // 用于存储上一次的滚动位置
|
||||
|
||||
const { locale } = useGlobal()
|
||||
const router = useRouter()
|
||||
|
||||
const defaultLinks = [
|
||||
{
|
||||
@@ -118,7 +119,7 @@ export default function Header(props) {
|
||||
{/* 导航栏菜单内容 */}
|
||||
<div
|
||||
id='top-navbar'
|
||||
className='flex w-full mx-auto max-w-screen-2xl h-20 transition-all duration-200 items-center justify-between'>
|
||||
className='px-2 lg:px-0 flex w-full mx-auto max-w-screen-2xl h-20 transition-all duration-200 items-center justify-between'>
|
||||
{/* 搜索栏 */}
|
||||
{showSearchInput && (
|
||||
<input
|
||||
@@ -141,7 +142,7 @@ export default function Header(props) {
|
||||
<div className='flex gap-x-8 h-full'>
|
||||
<LogoBar {...props} />
|
||||
{/* 桌面端顶部菜单 */}
|
||||
<div className='hidden md:flex items-center gap-x-2'>
|
||||
<div className='hidden md:flex items-center gap-x-3'>
|
||||
{links &&
|
||||
links?.map(link => (
|
||||
<MenuItemDrop key={link?.id} link={link} />
|
||||
@@ -153,6 +154,16 @@ export default function Header(props) {
|
||||
|
||||
{/* 右侧移动端折叠按钮 */}
|
||||
<div className='flex items-center gap-x-2'>
|
||||
{/* 搜索按钮 */}
|
||||
<div className='flex text-center items-center cursor-pointer'>
|
||||
<i
|
||||
className={
|
||||
showSearchInput
|
||||
? 'fa-regular fa-circle-xmark'
|
||||
: 'fa-solid fa-magnifying-glass' + ' align-middle'
|
||||
}
|
||||
onClick={toggleShowSearchInput}></i>
|
||||
</div>
|
||||
<div className='mr-1 flex md:hidden justify-end items-center text-lg space-x-4 font-serif dark:text-gray-200'>
|
||||
<div onClick={toggleMenuOpen} className='cursor-pointer'>
|
||||
{isOpen ? (
|
||||
@@ -162,17 +173,6 @@ export default function Header(props) {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 搜索按钮 */}
|
||||
<div className='text-center items-center cursor-pointer'>
|
||||
<i
|
||||
className={
|
||||
showSearchInput
|
||||
? 'fa-regular fa-circle-xmark'
|
||||
: 'fa-solid fa-magnifying-glass' + ' align-middle'
|
||||
}
|
||||
onClick={toggleShowSearchInput}></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// import { useGlobal } from '@/lib/global'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import Link from 'next/link'
|
||||
import BannerItem from './BannerItem'
|
||||
import PostItemCardTop from './PostItemCardTop'
|
||||
import PostItemCardWide from './PostItemCardWide'
|
||||
|
||||
@@ -14,41 +13,20 @@ const Hero = ({ posts }) => {
|
||||
const postTop = posts[0]
|
||||
const post1 = posts[1]
|
||||
const post2 = posts[2]
|
||||
// 首屏信息栏按钮文字
|
||||
const banner = siteConfig('MAGZINE_HOME_BANNER_ENABLE')
|
||||
const button = siteConfig('MAGZINE_HOME_BUTTON')
|
||||
const text = siteConfig('MAGZINE_HOME_BUTTON_TEXT')
|
||||
const url = siteConfig('MAGZINE_HOME_BUTTON_URL')
|
||||
const title = siteConfig('MAGZINE_HOME_TITLE')
|
||||
const description = siteConfig('MAGZINE_HOME_DESCRIPTION')
|
||||
const tips = siteConfig('MAGZINE_HOME_TIPS')
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='w-full mx-auto max-w-screen-2xl xl:flex justify-between'>
|
||||
<div className='w-full mx-auto max-w-screen-2xl xl:flex justify-between'>
|
||||
{/* 左侧一篇主要置顶文章 */}
|
||||
<div className='basis-1/2 mb-6'>
|
||||
<div className='basis-1/2 mb-6 px-2 lg:px-5'>
|
||||
<PostItemCardTop post={postTop} />
|
||||
</div>
|
||||
{/* 右侧 */}
|
||||
<div>
|
||||
{/* 首屏介绍 */}
|
||||
{banner && (
|
||||
<div className='flex flex-col p-5 gap-y-5 dark items-center justify-between w-full bg-black text-white'>
|
||||
{/* 首屏导航按钮 */}
|
||||
<h2 className='text-2xl font-semibold'>{title}</h2>
|
||||
<h3 className='text-sm'>{description}</h3>
|
||||
{button && (
|
||||
<div className='mt-2 text-center px-6 py-3 font-semibold rounded-3xl text-black bg-[#7BE986] hover:bg-[#62BA6B]'>
|
||||
<Link href={url}>{text}</Link>
|
||||
</div>
|
||||
)}
|
||||
<span className='text-xs'>{tips}</span>
|
||||
</div>
|
||||
)}
|
||||
<BannerItem />
|
||||
|
||||
{/* 两篇次要文章 */}
|
||||
<div className='py-4'>
|
||||
<div className='py-4 px-2 lg:px-5'>
|
||||
<hr className='mb-8' />
|
||||
<PostItemCardWide post={post1} />
|
||||
<hr className='mb-8' />
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import LazyImage from '@/components/LazyImage'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
|
||||
/**
|
||||
* 用户信息卡
|
||||
@@ -7,7 +8,7 @@ import { siteConfig } from '@/lib/config'
|
||||
* @returns
|
||||
*/
|
||||
const InfoCard = props => {
|
||||
const { siteInfo } = props
|
||||
const { siteInfo } = useGlobal()
|
||||
|
||||
return (
|
||||
<div id='info-card'>
|
||||
|
||||
34
themes/magzine/components/PostGroupArchive.js
Normal file
34
themes/magzine/components/PostGroupArchive.js
Normal file
@@ -0,0 +1,34 @@
|
||||
import PostItemCard from './PostItemCard'
|
||||
|
||||
/**
|
||||
* 博客归档列表
|
||||
* @param posts 所有文章
|
||||
* @param archiveTitle 归档标题
|
||||
* @returns {JSX.Element}
|
||||
* @constructor
|
||||
*/
|
||||
const PostGroupArchive = ({ posts = [], archiveTitle }) => {
|
||||
if (!posts || posts.length === 0) {
|
||||
return <></>
|
||||
}
|
||||
|
||||
return (
|
||||
<div className=''>
|
||||
{/* 分组标题 */}
|
||||
<div
|
||||
className='pb-4 text-2xl font-bold dark:text-gray-300'
|
||||
id={archiveTitle}>
|
||||
{archiveTitle}
|
||||
</div>
|
||||
|
||||
{/* 列表 */}
|
||||
<ul className='grid grid-cols-4 *:gap-4'>
|
||||
{posts?.map((p, index) => {
|
||||
return <PostItemCard key={index} post={p} />
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default PostGroupArchive
|
||||
66
themes/magzine/components/PostGroupLates.js
Normal file
66
themes/magzine/components/PostGroupLates.js
Normal file
@@ -0,0 +1,66 @@
|
||||
import LazyImage from '@/components/LazyImage'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
// import Image from 'next/image'
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
/**
|
||||
* 最新文章列表
|
||||
* @param posts 所有文章数据
|
||||
* @param sliceCount 截取展示的数量 默认6
|
||||
* @constructor
|
||||
*/
|
||||
const PostGroupLatest = props => {
|
||||
const { latestPosts } = props
|
||||
// 获取当前路径
|
||||
const currentPath = useRouter().asPath
|
||||
const { locale, siteInfo } = useGlobal()
|
||||
if (!latestPosts) {
|
||||
return <></>
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className=' mb-2 px-1 flex flex-nowrap justify-between'>
|
||||
<div className='font-bold text-lg'>{locale.COMMON.LATEST_POSTS}</div>
|
||||
</div>
|
||||
{latestPosts.map(post => {
|
||||
const selected =
|
||||
currentPath === `${siteConfig('SUB_PATH', '')}/${post.slug}`
|
||||
|
||||
const headerImage = post?.pageCoverThumbnail
|
||||
? post.pageCoverThumbnail
|
||||
: siteInfo?.pageCover
|
||||
|
||||
return (
|
||||
<Link
|
||||
key={post.id}
|
||||
title={post.title}
|
||||
href={`${siteConfig('SUB_PATH', '')}/${post.slug}`}
|
||||
passHref
|
||||
className={'my-3 flex'}>
|
||||
<div className='w-20 h-14 overflow-hidden relative'>
|
||||
<LazyImage
|
||||
src={`${headerImage}`}
|
||||
className='object-cover w-full h-full'
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={
|
||||
(selected ? ' text-green-400 ' : 'dark:text-gray-400 ') +
|
||||
' text-sm overflow-x-hidden hover:text-green-600 px-2 duration-200 w-full rounded ' +
|
||||
' hover:text-green-400 cursor-pointer items-center flex'
|
||||
}>
|
||||
<div>
|
||||
<div className='line-clamp-2 menu-link'>{post.title}</div>
|
||||
<div className='text-gray-500'>{post.lastEditedDay}</div>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
)
|
||||
})}
|
||||
</>
|
||||
)
|
||||
}
|
||||
export default PostGroupLatest
|
||||
@@ -9,12 +9,12 @@ import CategoryItem from './CategoryItem'
|
||||
* 普通的博客卡牌
|
||||
* 带封面图
|
||||
*/
|
||||
const PostItemCard = ({ post, showSummary }) => {
|
||||
const PostItemCard = ({ post }) => {
|
||||
const { siteInfo } = useGlobal()
|
||||
const cover = post?.pageCoverThumbnail || siteInfo?.pageCover
|
||||
return (
|
||||
<div key={post.id} className='mb-6 max-w-screen-2xl'>
|
||||
<div className='lg:py-8 py-4 flex flex-col w-full'>
|
||||
<div className='flex flex-col'>
|
||||
{siteConfig('MAGZINE_POST_LIST_COVER') && (
|
||||
<Link
|
||||
href={post?.href}
|
||||
|
||||
@@ -15,7 +15,7 @@ const PostItemCardSimple = ({ post, showSummary }) => {
|
||||
return (
|
||||
<div
|
||||
key={post.id}
|
||||
className='mb-6 max-w-screen-2xl border-t mr-8 py-2 gap-y-4 flex flex-col dark:border-gray-800 '>
|
||||
className='lg:mb-6 max-w-screen-2xl border-t mr-8 py-2 gap-y-4 flex flex-col dark:border-gray-800 '>
|
||||
<div className='flex mr-2 items-center'>
|
||||
{siteConfig('MAGZINE_POST_LIST_CATEGORY') && (
|
||||
<CategoryItem category={post.category} />
|
||||
|
||||
@@ -15,7 +15,7 @@ const PostListHorizontal = ({ title, href, posts, hasBg }) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={`w-full py-10 ${hasBg ? 'bg-[#F6F6F1]' : ''}`}>
|
||||
<div className={`w-full py-10 px-2 lg:px-0 ${hasBg ? 'bg-[#F6F6F1]' : ''}`}>
|
||||
<div className='max-w-screen-2xl w-full mx-auto'>
|
||||
{/* 标题 */}
|
||||
<div className='flex justify-between items-center py-6'>
|
||||
@@ -26,7 +26,7 @@ const PostListHorizontal = ({ title, href, posts, hasBg }) => {
|
||||
</Link>
|
||||
</div>
|
||||
{/* 列表 */}
|
||||
<ul className='flex gap-4'>
|
||||
<ul className='grid grid-cols-1 lg:grid-cols-4 gap-4'>
|
||||
{posts?.map((p, index) => {
|
||||
return <PostItemCard key={index} post={p} />
|
||||
})}
|
||||
|
||||
@@ -24,10 +24,12 @@ const PostListPage = ({ page = 1, posts = [], postCount }) => {
|
||||
return (
|
||||
<div className='w-full justify-center'>
|
||||
<div id='posts-wrapper'>
|
||||
{/* 文章列表 */}
|
||||
{posts?.map(post => (
|
||||
<PostItemCard key={post.id} post={post} />
|
||||
))}
|
||||
{/* 列表 */}
|
||||
<ul className='grid grid-cols-4 gap-4'>
|
||||
{posts?.map((p, index) => {
|
||||
return <PostItemCard key={index} post={p} />
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
<PaginationSimple page={page} totalPage={totalPage} />
|
||||
</div>
|
||||
|
||||
@@ -18,14 +18,14 @@ const PostListRecommend = ({ latestPosts, allNavPages }) => {
|
||||
const title = siteConfig('MAGZINE_RECOMMEND_POST_TITLE')
|
||||
|
||||
return (
|
||||
<div className={`w-full py-10 bg-[#F6F6F1]`}>
|
||||
<div className={`w-full py-10 px-2 bg-[#F6F6F1]`}>
|
||||
<div className='max-w-screen-2xl w-full mx-auto'>
|
||||
{/* 标题 */}
|
||||
<div className='flex justify-between items-center py-6'>
|
||||
<h3 className='text-4xl font-bold'>{title}</h3>
|
||||
</div>
|
||||
{/* 列表 */}
|
||||
<ul className='flex gap-4 overflow-x-scroll'>
|
||||
<ul className='flex flex-col lg:flex-row gap-4 lg:overflow-x-scroll'>
|
||||
{recommendPosts?.map(p => {
|
||||
return <PostItemCard key={p.id} post={p} />
|
||||
})}
|
||||
|
||||
@@ -14,7 +14,7 @@ const PostSimpleListHorizontal = ({ title, href, posts }) => {
|
||||
|
||||
return (
|
||||
<div className='w-full py-10 bg-[#F6F6F1]'>
|
||||
<div className='max-w-screen-2xl w-full mx-auto'>
|
||||
<div className='max-w-screen-2xl w-full mx-auto px-2'>
|
||||
{/* 标题 */}
|
||||
<div className='flex justify-between items-center py-6'>
|
||||
<h3 className='text-2xl'>{title}</h3>
|
||||
@@ -24,7 +24,7 @@ const PostSimpleListHorizontal = ({ title, href, posts }) => {
|
||||
</Link>
|
||||
</div>
|
||||
{/* 列表 */}
|
||||
<ul className='flex'>
|
||||
<ul className='flex flex-col lg:flex-row'>
|
||||
{posts?.map(p => {
|
||||
return <PostItemCardSimple key={p.id} post={p} />
|
||||
})}
|
||||
|
||||
39
themes/magzine/components/TouchMeCard.js
Normal file
39
themes/magzine/components/TouchMeCard.js
Normal file
@@ -0,0 +1,39 @@
|
||||
import FlipCard from '@/components/FlipCard'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import Link from 'next/link'
|
||||
|
||||
/**
|
||||
* 交流频道
|
||||
* @returns
|
||||
*/
|
||||
export default function TouchMeCard() {
|
||||
// 开关
|
||||
if (!siteConfig('MAGZINE_SOCIAL_CARD', null)) {
|
||||
return <></>
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={'relative h-32 text-black flex flex-col'}>
|
||||
<FlipCard
|
||||
className='cursor-pointer lg:py-8 px-4 py-4 border bg-[#7BE986] dark:bg-yellow-600 dark:border-gray-600'
|
||||
frontContent={
|
||||
<div className='h-full'>
|
||||
<h2 className='font-[1000] text-3xl'>
|
||||
{siteConfig('MAGZINE_SOCIAL_CARD_TITLE_1')}
|
||||
</h2>
|
||||
<h3 className='pt-2'>
|
||||
{siteConfig('MAGZINE_SOCIAL_CARD_TITLE_2')}
|
||||
</h3>
|
||||
</div>
|
||||
}
|
||||
backContent={
|
||||
<Link href={siteConfig('MAGZINE_SOCIAL_CARD_URL')}>
|
||||
<div className='font-[1000] text-xl h-full'>
|
||||
{siteConfig('MAGZINE_SOCIAL_CARD_TITLE_3')}
|
||||
</div>
|
||||
</Link>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -29,6 +29,13 @@ const CONFIG = {
|
||||
MAGZINE_POST_DETAIL_CATEGORY: true, // 文章显示分类
|
||||
MAGZINE_POST_DETAIL_TAG: true, // 文章显示标签
|
||||
|
||||
// 文章页面联系卡
|
||||
MAGZINE_SOCIAL_CARD: true, // 是否显示右侧,点击加入社群按钮
|
||||
MAGZINE_SOCIAL_CARD_TITLE_1: '交流频道',
|
||||
MAGZINE_SOCIAL_CARD_TITLE_2: '加入社群讨论分享',
|
||||
MAGZINE_SOCIAL_CARD_TITLE_3: '点击加入社群',
|
||||
MAGZINE_SOCIAL_CARD_URL: 'https://docs.tangly1024.com/article/chat-community',
|
||||
|
||||
// 页脚菜单
|
||||
MAGZINE_FOOTER_LINKS: [
|
||||
{
|
||||
|
||||
@@ -10,10 +10,9 @@ import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
import { createContext, useContext, useEffect, useState } from 'react'
|
||||
import Announcement from './components/Announcement'
|
||||
import ArchiveItem from './components/ArchiveItem'
|
||||
import ArticleAround from './components/ArticleAround'
|
||||
import ArticleInfo from './components/ArticleInfo'
|
||||
import { ArticleLock } from './components/ArticleLock'
|
||||
import BannerFullWidth from './components/BannerFullWidth'
|
||||
import Catalog from './components/Catalog'
|
||||
import CategoryGroup from './components/CategoryGroup'
|
||||
import CategoryItem from './components/CategoryItem'
|
||||
@@ -21,14 +20,16 @@ import Footer from './components/Footer'
|
||||
import Header from './components/Header'
|
||||
import Hero from './components/Hero'
|
||||
import PostBannerGroupByCategory from './components/PostBannerGroupByCategory'
|
||||
import PostGroupArchive from './components/PostGroupArchive'
|
||||
import PostGroupLatest from './components/PostGroupLates'
|
||||
import PostListPage from './components/PostListPage'
|
||||
import PostListRecommend from './components/PostListRecommend'
|
||||
import PostListScroll from './components/PostListScroll'
|
||||
import PostSimpleListHorizontal from './components/PostListSimpleHorizontal'
|
||||
import SearchInput from './components/SearchInput'
|
||||
import TagGroups from './components/TagGroups'
|
||||
import TagItemMini from './components/TagItemMini'
|
||||
import TocDrawer from './components/TocDrawer'
|
||||
import TouchMeCard from './components/TouchMeCard'
|
||||
import CONFIG from './config'
|
||||
import { Style } from './style'
|
||||
|
||||
@@ -118,14 +119,20 @@ const LayoutIndex = props => {
|
||||
* @returns
|
||||
*/
|
||||
const LayoutPostList = props => {
|
||||
// 当前筛选的分类或标签
|
||||
const { category, tag } = props
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className=' max-w-screen-2xl mx-auto w-full'>
|
||||
{/* 一个顶部条 */}
|
||||
<h2 className='py-8 text-2xl font-bold'>{category || tag}</h2>
|
||||
|
||||
{siteConfig('POST_LIST_STYLE') === 'page' ? (
|
||||
<PostListPage {...props} />
|
||||
) : (
|
||||
<PostListScroll {...props} />
|
||||
)}
|
||||
</>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -135,15 +142,9 @@ const LayoutPostList = props => {
|
||||
* @returns
|
||||
*/
|
||||
const LayoutSlug = props => {
|
||||
const { post, prev, next, lock, validPassword } = props
|
||||
const { post, recommendPosts, prev, next, lock, validPassword } = props
|
||||
const { locale } = useGlobal()
|
||||
const router = useRouter()
|
||||
const slotRight = post?.toc && post?.toc?.length >= 3 && (
|
||||
<div key={locale.COMMON.TABLE_OF_CONTENTS}>
|
||||
<Catalog toc={post?.toc} />
|
||||
</div>
|
||||
)
|
||||
console.log('post-文章', post)
|
||||
|
||||
useEffect(() => {
|
||||
// 404
|
||||
@@ -165,47 +166,102 @@ const LayoutSlug = props => {
|
||||
}, [post])
|
||||
|
||||
return (
|
||||
<div {...props} className='w-full mx-auto max-w-screen-2xl'>
|
||||
{/* 文章锁 */}
|
||||
{lock && <ArticleLock validPassword={validPassword} />}
|
||||
<>
|
||||
<div {...props} className='w-full mx-auto max-w-screen-2xl'>
|
||||
{/* 文章锁 */}
|
||||
{lock && <ArticleLock validPassword={validPassword} />}
|
||||
|
||||
{!lock && (
|
||||
<div>
|
||||
{/* 文章信息 */}
|
||||
<ArticleInfo {...props} />
|
||||
{!lock && (
|
||||
<div className='w-full max-w-screen-2xl mx-auto'>
|
||||
{/* 文章信息 */}
|
||||
<ArticleInfo {...props} />
|
||||
|
||||
{/* Notion文章主体 */}
|
||||
<article id='article-wrapper' className='px-1 max-w-4xl'>
|
||||
<NotionPage post={post} />
|
||||
</article>
|
||||
{/* 文章区块分为三列 */}
|
||||
<div className='grid grid-cols-1 lg:grid-cols-5 gap-8 py-12'>
|
||||
<div className='h-full lg:col-span-1'>
|
||||
<Catalog toc={post?.toc} className='sticky top-20' />
|
||||
</div>
|
||||
|
||||
{/* 文章底部区域 */}
|
||||
<section>
|
||||
{/* 分享 */}
|
||||
<ShareBar post={post} />
|
||||
{/* 文章分类和标签信息 */}
|
||||
<div className='flex justify-between'>
|
||||
{siteConfig('MAGZINE_POST_DETAIL_CATEGORY') && post?.category && (
|
||||
<CategoryItem category={post?.category} />
|
||||
)}
|
||||
<div>
|
||||
{siteConfig('MAGZINE_POST_DETAIL_TAG') &&
|
||||
post?.tagItems?.map(tag => (
|
||||
<TagItemMini key={tag.name} tag={tag} />
|
||||
))}
|
||||
{/* Notion文章主体 */}
|
||||
<article
|
||||
id='article-wrapper'
|
||||
className='max-w-3xl lg:col-span-3 w-full mx-auto'>
|
||||
<NotionPage post={post} />
|
||||
|
||||
{/* 文章底部区域 */}
|
||||
<section>
|
||||
{/* 分享 */}
|
||||
<ShareBar post={post} />
|
||||
{/* 文章分类和标签信息 */}
|
||||
<div className='flex justify-between'>
|
||||
{siteConfig('MAGZINE_POST_DETAIL_CATEGORY') &&
|
||||
post?.category && (
|
||||
<CategoryItem category={post?.category} />
|
||||
)}
|
||||
<div>
|
||||
{siteConfig('MAGZINE_POST_DETAIL_TAG') &&
|
||||
post?.tagItems?.map(tag => (
|
||||
<TagItemMini key={tag.name} tag={tag} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
{/* 评论区 */}
|
||||
<Comment frontMatter={post} />
|
||||
</section>
|
||||
</article>
|
||||
|
||||
<div className='lg:col-span-1 flex flex-col justify-between'>
|
||||
{/* meta信息 */}
|
||||
<section className='text-lg gap-y-6 '>
|
||||
<div className='text-gray-500 py-1 dark:text-gray-600'>
|
||||
{/* <div className='whitespace-nowrap'>
|
||||
<i className='far fa-calendar mr-2' />
|
||||
{post?.publishDay}
|
||||
</div> */}
|
||||
<div className='whitespace-nowrap mr-2'>
|
||||
<i className='far fa-calendar-check mr-2' />
|
||||
{post?.lastEditedDay}
|
||||
</div>
|
||||
<div className='hidden busuanzi_container_page_pv mr-2 whitespace-nowrap'>
|
||||
<i className='mr-1 fas fa-fire' />
|
||||
<span className='busuanzi_value_page_pv' />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* 最新文章区块 */}
|
||||
<div>
|
||||
<PostGroupLatest {...props} />
|
||||
</div>
|
||||
|
||||
{/* 文章分类区块 */}
|
||||
<div>
|
||||
<CategoryGroup {...props} />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<TouchMeCard />
|
||||
</div>
|
||||
|
||||
{/* 底部留白 */}
|
||||
<div></div>
|
||||
</div>
|
||||
</div>
|
||||
{/* 上一篇下一篇文章 */}
|
||||
{post?.type === 'Post' && <ArticleAround prev={prev} next={next} />}
|
||||
{/* 评论区 */}
|
||||
<Comment frontMatter={post} />
|
||||
</section>
|
||||
|
||||
{/* 移动端目录 */}
|
||||
<TocDrawer {...props} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{/* 移动端目录 */}
|
||||
<TocDrawer {...props} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{/* 广告醒图 */}
|
||||
<BannerFullWidth />
|
||||
{/* 最新文章区块 */}
|
||||
<PostSimpleListHorizontal
|
||||
title={locale.COMMON.RELATE_POSTS}
|
||||
href='/archive'
|
||||
posts={recommendPosts}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -234,11 +290,10 @@ const LayoutSearch = props => {
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='max-w-screen-2xl w-full mx-auto'>
|
||||
{/* 搜索导航栏 */}
|
||||
<div className='py-12'>
|
||||
<div className='pb-4 w-full'>{locale.NAV.SEARCH}</div>
|
||||
<SearchInput currentSearch={currentSearch} {...props} />
|
||||
{!currentSearch && (
|
||||
<>
|
||||
<TagGroups {...props} />
|
||||
@@ -257,7 +312,7 @@ const LayoutSearch = props => {
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -270,12 +325,12 @@ const LayoutArchive = props => {
|
||||
const { archivePosts } = props
|
||||
return (
|
||||
<>
|
||||
<div className='mb-10 pb-20 md:py-12 py-3 min-h-full'>
|
||||
<div className='w-full max-w-screen-2xl mx-auto mt-14 min-h-full'>
|
||||
{Object.keys(archivePosts)?.map(archiveTitle => (
|
||||
<ArchiveItem
|
||||
<PostGroupArchive
|
||||
key={archiveTitle}
|
||||
archiveTitle={archiveTitle}
|
||||
archivePosts={archivePosts}
|
||||
posts={archivePosts[archiveTitle]}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
@@ -307,10 +362,10 @@ const LayoutCategoryIndex = props => {
|
||||
const { categoryOptions } = props
|
||||
const { locale } = useGlobal()
|
||||
return (
|
||||
<>
|
||||
<div className='w-full max-w-screen-2xl mx-auto min-h-96'>
|
||||
<div className='bg-white dark:bg-gray-700 py-10'>
|
||||
<div className='dark:text-gray-200 mb-5'>
|
||||
<i className='mr-4 fas fa-th' />
|
||||
<div className='dark:text-gray-200 mb-5 text-2xl font-bold'>
|
||||
{/* <i className='mr-4 fas fa-th' /> */}
|
||||
{locale.COMMON.CATEGORY}:
|
||||
</div>
|
||||
<div id='category-list' className='duration-200 flex flex-wrap'>
|
||||
@@ -325,7 +380,7 @@ const LayoutCategoryIndex = props => {
|
||||
className={
|
||||
'hover:text-black dark:hover:text-white dark:text-gray-300 dark:hover:bg-gray-600 px-5 cursor-pointer py-2 hover:bg-gray-100'
|
||||
}>
|
||||
<i className='mr-4 fas fa-folder' />
|
||||
{/* <i className='mr-4 fas fa-folder' /> */}
|
||||
{category.name}({category.count})
|
||||
</div>
|
||||
</Link>
|
||||
@@ -333,7 +388,7 @@ const LayoutCategoryIndex = props => {
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -346,10 +401,10 @@ const LayoutTagIndex = props => {
|
||||
const { tagOptions } = props
|
||||
const { locale } = useGlobal()
|
||||
return (
|
||||
<>
|
||||
<div className='w-full max-w-screen-2xl mx-auto min-h-96'>
|
||||
<div className='bg-white dark:bg-gray-700 py-10'>
|
||||
<div className='dark:text-gray-200 mb-5'>
|
||||
<i className='mr-4 fas fa-tag' />
|
||||
<div className='dark:text-gray-200 mb-5 text-2xl font-bold'>
|
||||
{/* <i className='mr-4 fas fa-tag' /> */}
|
||||
{locale.COMMON.TAGS}:
|
||||
</div>
|
||||
<div id='tags-list' className='duration-200 flex flex-wrap'>
|
||||
@@ -362,7 +417,7 @@ const LayoutTagIndex = props => {
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user