From d84774bc650e4d4adda5c7b9621fbb588ca09fc6 Mon Sep 17 00:00:00 2001 From: tangly1024 Date: Wed, 27 Apr 2022 13:10:38 +0800 Subject: [PATCH 1/2] =?UTF-8?q?example=E4=B8=BB=E9=A2=98=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- themes/example/Layout404.js | 9 +- themes/example/LayoutArchive.js | 8 +- themes/example/LayoutBase.js | 145 +++++-------------- themes/example/LayoutCategory.js | 55 ++++--- themes/example/LayoutCategoryIndex.js | 2 +- themes/example/LayoutIndex.js | 69 +-------- themes/example/LayoutSearch.js | 70 ++++++--- themes/example/LayoutSlug.js | 62 ++------ themes/example/LayoutTag.js | 50 ++++--- themes/example/LayoutTagIndex.js | 29 ++-- themes/example/components/ArticleInfo.js | 46 ++++++ themes/example/components/BlogList.js | 55 +++++++ themes/example/components/Footer.js | 49 +++++++ themes/example/components/Header.js | 21 +++ themes/example/components/JumpToTopButton.js | 19 +++ themes/example/components/Nav.js | 34 +++++ themes/example/components/SideBar.js | 44 ++++++ themes/example/components/Title.js | 19 +++ 18 files changed, 472 insertions(+), 314 deletions(-) create mode 100644 themes/example/components/ArticleInfo.js create mode 100644 themes/example/components/BlogList.js create mode 100644 themes/example/components/Footer.js create mode 100644 themes/example/components/Header.js create mode 100644 themes/example/components/JumpToTopButton.js create mode 100644 themes/example/components/Nav.js create mode 100644 themes/example/components/SideBar.js create mode 100644 themes/example/components/Title.js diff --git a/themes/example/Layout404.js b/themes/example/Layout404.js index cd28a607..5f92f0cc 100644 --- a/themes/example/Layout404.js +++ b/themes/example/Layout404.js @@ -1,6 +1,7 @@ +import LayoutBase from './LayoutBase' -export const Layout404 = () => { - return
- 404 Not found. -
+export const Layout404 = (props) => { + return + 404 Not found. + } diff --git a/themes/example/LayoutArchive.js b/themes/example/LayoutArchive.js index 9edb9c24..a7657b12 100644 --- a/themes/example/LayoutArchive.js +++ b/themes/example/LayoutArchive.js @@ -24,15 +24,13 @@ export const LayoutArchive = props => { }) return ( -
+
{Object.keys(archivePosts).map(archiveTitle => (
-
+
{archiveTitle}
+
    {archivePosts[archiveTitle].map(post => (
  • { - const { children, meta, customNav, siteInfo } = props - const { locale } = useGlobal() - const d = new Date() - const currentYear = d.getFullYear() - const startYear = BLOG.SINCE && BLOG.SINCE !== currentYear && BLOG.SINCE + '-' - - let links = [ - { icon: 'fas fa-search', name: locale.NAV.SEARCH, to: '/search' }, - { icon: 'fas fa-archive', name: locale.NAV.ARCHIVE, to: '/archive' }, - { icon: 'fas fa-folder', name: locale.COMMON.CATEGORY, to: '/category' }, - { icon: 'fas fa-tag', name: locale.COMMON.TAGS, to: '/tag' } - ] - - if (customNav) { - links = links.concat(customNav) - } - + const { children, meta } = props return ( -
    - - {/* 导航菜单 */} -
    -
    -
    - - - -
    {siteInfo.title}
    -
    - -
    - -
    -
    +
    + + {/* 顶栏LOGO */} +
    - {/* 内容主体 */} -
    -
    {children}
    -
    -
    - -
    -
    -
    + {/* 菜单 */} +
    + {/* 主体 */} +
    + + + + <div className="container max-w-4xl mx-auto md:flex items-start py-8 px-12 md:px-0"> + + <div className='px-2 w-full flex-grow'>{children}</div> + + <SideBar {...props} /> + + </div> + + </div> + + <Footer {...props} /> + + <div className='fixed right-4 bottom-4'> + <JumpToTopButton /> + </div> + </div> ) } diff --git a/themes/example/LayoutCategory.js b/themes/example/LayoutCategory.js index 85d399f6..ef344ea2 100644 --- a/themes/example/LayoutCategory.js +++ b/themes/example/LayoutCategory.js @@ -23,26 +23,39 @@ export const LayoutCategory = props => { updatePage(page + 1) } - return ( - <LayoutBase {...props}> - Category - {category} - {postsToShow.map(p => ( - <div key={p.id} className="border my-12"> - <Link href={`/article/${p.slug}`}> - <a className="underline cursor-pointer">{p.title}</a> - </Link> - <div>{p.summary}</div> + return <LayoutBase {...props}> + <div className='w-full'> + <div className='pb-12'>{category}</div> + + {postsToShow.map(p => ( + <article key={p.id} className="mb-12" > + <h2 className="mb-4"> + <Link href={`/article/${p.slug}`}> + <a className="text-black text-xl md:text-2xl no-underline hover:underline"> {p.title}</a> + </Link> + </h2> + + <div className="mb-4 text-sm text-gray-700"> + by <a href="#" className="text-gray-700">{BLOG.AUTHOR}</a> on {p.date?.start_date || p.createdTime} + <span className="font-bold mx-1"> | </span> + <a href="#" className="text-gray-700">{p.category}</a> + <span className="font-bold mx-1"> | </span> + {/* <a href="#" className="text-gray-700">2 Comments</a> */} + </div> + + <p className="text-gray-700 leading-normal"> + {p.summary} + </p> + </article> + ))} + + <div + onClick={handleGetMore} + className="w-full my-4 py-4 text-center cursor-pointer " + > + {' '} + {hasMore ? locale.COMMON.MORE : `${locale.COMMON.NO_MORE} 😰`}{' '} + </div> </div> - ))} - <div> - <div - onClick={handleGetMore} - className="w-full my-4 py-4 text-center cursor-pointer " - > - {' '} - {hasMore ? locale.COMMON.MORE : `${locale.COMMON.NO_MORE} 😰`}{' '} - </div> - </div> - </LayoutBase> - ) + </LayoutBase > } diff --git a/themes/example/LayoutCategoryIndex.js b/themes/example/LayoutCategoryIndex.js index b748b140..77a3fcc1 100644 --- a/themes/example/LayoutCategoryIndex.js +++ b/themes/example/LayoutCategoryIndex.js @@ -6,7 +6,7 @@ export const LayoutCategoryIndex = (props) => { const { categories } = props const { locale } = useGlobal() return <LayoutBase {...props}> - <div className=' p-10'> + <div className=' p-10 w-full'> <div className='dark:text-gray-200 mb-5'> <i className='mr-4 fas fa-th' />{locale.COMMON.CATEGORY}: </div> diff --git a/themes/example/LayoutIndex.js b/themes/example/LayoutIndex.js index 11da972e..6a28d455 100644 --- a/themes/example/LayoutIndex.js +++ b/themes/example/LayoutIndex.js @@ -1,74 +1,11 @@ -import BLOG from '@/blog.config' -import { useGlobal } from '@/lib/global' -import Link from 'next/link' -import { useRouter } from 'next/router' + +import { BlogList } from './components/BlogList' import LayoutBase from './LayoutBase' export const LayoutIndex = props => { - const { posts, postCount } = props - - const { locale } = useGlobal() - const router = useRouter() - const totalPage = Math.ceil(postCount / BLOG.POSTS_PER_PAGE) - - const page = 1 - const showNext = - page < totalPage && - posts.length === BLOG.POSTS_PER_PAGE && - posts.length < postCount - - const currentPage = +page return ( <LayoutBase {...props}> - {posts.map(p => ( - <div - key={p.id} - className="border dark:border-hexo-black-gray p-4 my-12" - > - <Link href={`/article/${p.slug}`}> - <a className="underline cursor-pointer">{p.title}</a> - </Link> - <div>{p.summary}</div> - </div> - ))} - - <div className="my-10 flex justify-between font-medium text-black dark:text-gray-100 space-x-2"> - <Link - href={{ - pathname: - currentPage === 2 - ? `${BLOG.SUB_PATH || '/'}` - : `/page/${currentPage - 1}`, - query: router.query.s ? { s: router.query.s } : {} - }} - passHref - > - <a - rel="prev" - className={`${ - currentPage === 1 ? 'invisible' : 'visible' - } text-center w-full duration-200 px-4 py-2 hover:border-black border-b-2 hover:font-bold`} - > - ← {locale.PAGINATION.PREV} - </a> - </Link> - <Link - href={{ - pathname: `/page/${currentPage + 1}`, - query: router.query.s ? { s: router.query.s } : {} - }} - passHref - > - <a - rel="next" - className={`${ - showNext ? 'visible' : 'invisible' - } text-center w-full duration-200 px-4 py-2 hover:border-black border-b-2 hover:font-bold`} - > - {locale.PAGINATION.NEXT} → - </a> - </Link> - </div> + <BlogList {...props} /> </LayoutBase> ) } diff --git a/themes/example/LayoutSearch.js b/themes/example/LayoutSearch.js index fec11e52..528c7976 100644 --- a/themes/example/LayoutSearch.js +++ b/themes/example/LayoutSearch.js @@ -33,28 +33,58 @@ export const LayoutSearch = props => { if (!hasMore) return updatePage(page + 1) } + useEffect(() => { + setTimeout(() => { + if (keyword) { + const targets = document.getElementsByClassName('replace') + for (const container of targets) { + if (container && container.innerHTML) { + const re = new RegExp(`${keyword}`, 'gim') + container.innerHTML = container.innerHTML.replace( + re, + `<span class='text-red-500 border-b border-dashed'>${keyword}</span>` + ) + } + } + } + }, 100) + }, []) - return ( - <LayoutBase {...props}> - <h2>Search - {keyword}</h2> - <SearchInput {...props} /> - {postsToShow?.map(p => ( - <div key={p.id} className="border my-12"> - <Link href={`/article/${p.slug}`}> - <a className="underline cursor-pointer">{p.title}</a> - </Link> - <div>{p.summary}</div> + return <LayoutBase {...props}> + <div className='py-2'> + <SearchInput {...props} /> </div> - ))} - <div> - <div - onClick={handleGetMore} - className="w-full my-4 py-4 text-center cursor-pointer " - > - {' '} - {hasMore ? locale.COMMON.MORE : `${locale.COMMON.NO_MORE} 😰`}{' '} + + {postsToShow.map(p => ( + <article key={p.id} className="mb-12" > + <h2 className="mb-4"> + <Link href={`/article/${p.slug}`}> + <a className="text-black text-xl md:text-2xl no-underline hover:underline replace"> {p.title}</a> + </Link> + </h2> + + <div className="mb-4 text-sm text-gray-700"> + by <a href="#" className="text-gray-700">{BLOG.AUTHOR}</a> on {p.date?.start_date || p.createdTime} + <span className="font-bold mx-1"> | </span> + <a href="#" className="text-gray-700">{p.category}</a> + <span className="font-bold mx-1"> | </span> + {/* <a href="#" className="text-gray-700">2 Comments</a> */} + </div> + + <p className="text-gray-700 leading-normal replace"> + {p.summary} + </p> + </article> + ))} + + <div> + <div + onClick={handleGetMore} + className="w-full my-4 py-4 text-center cursor-pointer " + > + {' '} + {hasMore ? locale.COMMON.MORE : `${locale.COMMON.NO_MORE} 😰`}{' '} + </div> </div> - </div> </LayoutBase> - ) } diff --git a/themes/example/LayoutSlug.js b/themes/example/LayoutSlug.js index 91b11d80..1f7fd409 100644 --- a/themes/example/LayoutSlug.js +++ b/themes/example/LayoutSlug.js @@ -2,9 +2,8 @@ import { getPageTableOfContents } from 'notion-utils' import LayoutBase from './LayoutBase' import { ArticleLock } from './components/ArticleLock' import NotionPage from '@/components/NotionPage' -import Link from 'next/link' -import { useGlobal } from '@/lib/global' -import formatDate from '@/lib/formatDate' +import { ArticleInfo } from './components/ArticleInfo' +import Comment from '@/components/Comment' export const LayoutSlug = props => { const { post, lock, validPassword } = props @@ -18,57 +17,20 @@ export const LayoutSlug = props => { post.toc = getPageTableOfContents(post, post.blockMap) } - const { locale } = useGlobal() - const date = formatDate(post?.date?.start_date || post?.createdTime, locale.LOCALE) - return ( - <LayoutBase {...props}> - <div> - <h2>{post?.title}</h2> + <LayoutBase {...props}> - {lock && <ArticleLock password={post.password} validPassword={validPassword} />} + {lock && <ArticleLock password={post.password} validPassword={validPassword} />} - {!lock && <section id="notion-article" className="px-1"> - <section className="flex-wrap flex mt-2 text-gray-400 dark:text-gray-400 font-light leading-8"> - <div> - <Link href={`/category/${post.category}`} passHref> - <a className="cursor-pointer text-md mr-2 hover:text-black dark:hover:text-white border-b dark:border-gray-500 border-dashed"> - <i className="mr-1 fas fa-folder-open" /> - {post.category} - </a> - </Link> - <span className='mr-2'>|</span> + {!lock && <div id="notion-article" className="px-2"> - {post?.type[0] !== 'Page' && (<> - <Link - href={`/archive#${post?.date?.start_date?.substr(0, 7)}`} - passHref - > - <a className="pl-1 mr-2 cursor-pointer hover:text-gray-700 dark:hover:text-gray-200 border-b dark:border-gray-500 border-dashed"> - {date} - </a> - </Link> - <span className='mr-2'>|</span> - <span className='mx-2 text-gray-400 dark:text-gray-500'> - {locale.COMMON.LAST_EDITED_TIME}: {post.lastEditedTime} - </span> - <span className='mr-2'>|</span> + {post && <> + <ArticleInfo post={post} /> + <NotionPage post={post} /> + <Comment frontMatter={post}/> + </>} + </div>} - </>)} - - <span className="hidden busuanzi_container_page_pv font-light mr-2"> - <i className='mr-1 fas fa-eye' /> -   - <span className="mr-2 busuanzi_value_page_pv" /> - </span> - </div> - - </section> - - {post && <NotionPage post={post} />} - </section>} - - </div> - </LayoutBase> + </LayoutBase> ) } diff --git a/themes/example/LayoutTag.js b/themes/example/LayoutTag.js index e1a549f4..e9809123 100644 --- a/themes/example/LayoutTag.js +++ b/themes/example/LayoutTag.js @@ -5,7 +5,7 @@ import { useState } from 'react' import LayoutBase from './LayoutBase' export const LayoutTag = props => { - const { tag, posts } = props + const { posts } = props const { locale } = useGlobal() const [page, updatePage] = useState(1) @@ -24,26 +24,36 @@ export const LayoutTag = props => { updatePage(page + 1) } - return ( - <LayoutBase> - Tag - {tag} - {postsToShow.map(p => ( - <div key={p.id} className="border my-12"> - <Link href={`/article/${p.slug}`}> - <a className="underline cursor-pointer">{p.title}</a> - </Link> - <div>{p.summary}</div> - </div> - ))} - <div> + return <LayoutBase> + {postsToShow.map(p => ( + <article key={p.id} className="mb-12" > + <h2 className="mb-4"> + <Link href={`/article/${p.slug}`}> + <a className="text-black text-xl md:text-2xl no-underline hover:underline"> {p.title}</a> + </Link> + </h2> + + <div className="mb-4 text-sm text-gray-700"> + by <a href="#" className="text-gray-700">{BLOG.AUTHOR}</a> on {p.date?.start_date || p.createdTime} + <span className="font-bold mx-1"> | </span> + <a href="#" className="text-gray-700">{p.category}</a> + <span className="font-bold mx-1"> | </span> + {/* <a href="#" className="text-gray-700">2 Comments</a> */} + </div> + + <p className="text-gray-700 leading-normal"> + {p.summary} + </p> + </article> + ))} + <div - onClick={handleGetMore} - className="w-full my-4 py-4 text-center cursor-pointer " + onClick={handleGetMore} + className="w-full my-4 py-4 text-center cursor-pointer " > - {' '} - {hasMore ? locale.COMMON.MORE : `${locale.COMMON.NO_MORE} 😰`}{' '} + {' '} + {hasMore ? locale.COMMON.MORE : `${locale.COMMON.NO_MORE} 😰`}{' '} </div> - </div> - </LayoutBase> - ) + + </LayoutBase > } diff --git a/themes/example/LayoutTagIndex.js b/themes/example/LayoutTagIndex.js index 3fb41c9f..249e1639 100644 --- a/themes/example/LayoutTagIndex.js +++ b/themes/example/LayoutTagIndex.js @@ -1,24 +1,21 @@ -import { useGlobal } from '@/lib/global' import Link from 'next/link' import LayoutBase from './LayoutBase' export const LayoutTagIndex = (props) => { const { tags } = props - const { locale } = useGlobal() return <LayoutBase {...props}> - <div className='p-10'> - <div className='dark:text-gray-200 mb-5'><i className='mr-4 fas fa-tag'/>{locale.COMMON.TAGS}:</div> - <div id='tags-list' className='duration-200 flex flex-wrap'> - { tags.map(tag => { - return <div key={tag.name} className='p-2'> - <Link key={tag} href={`/tag/${encodeURIComponent(tag.name)}`} passHref> - <a className={`cursor-pointer inline-block rounded hover:bg-gray-500 hover:text-white duration-200 + <div className='p-10'> + <div id='tags-list' className='duration-200 flex flex-wrap'> + {tags.map(tag => { + return <div key={tag.name} className='p-2'> + <Link key={tag} href={`/tag/${encodeURIComponent(tag.name)}`} passHref> + <a className={`cursor-pointer inline-block rounded hover:bg-gray-500 hover:text-white duration-200 mr-2 py-1 px-2 text-xs whitespace-nowrap dark:hover:text-white text-gray-600 hover:shadow-xl dark:border-gray-400 notion-${tag.color}_background dark:bg-gray-800`}> - <div className='font-light dark:text-gray-400'><i className='mr-1 fas fa-tag'/> {tag.name + (tag.count ? `(${tag.count})` : '')} </div> - </a> - </Link> - </div> - }) } - </div> - </div> </LayoutBase> + <div className='font-light dark:text-gray-400'><i className='mr-1 fas fa-tag' /> {tag.name + (tag.count ? `(${tag.count})` : '')} </div> + </a> + </Link> + </div> + })} + </div> + </div> </LayoutBase> } diff --git a/themes/example/components/ArticleInfo.js b/themes/example/components/ArticleInfo.js new file mode 100644 index 00000000..a0a5c365 --- /dev/null +++ b/themes/example/components/ArticleInfo.js @@ -0,0 +1,46 @@ +import Link from 'next/link' +import { useGlobal } from '@/lib/global' +import formatDate from '@/lib/formatDate' + +export const ArticleInfo = (props) => { + const { post } = props + + const { locale } = useGlobal() + const date = formatDate(post?.date?.start_date || post?.createdTime, locale.LOCALE) + + return <section className="flex-wrap flex mt-2 text-gray-400 dark:text-gray-400 font-light leading-8"> + <div> + <Link href={`/category/${post.category}`} passHref> + <a className="cursor-pointer text-md mr-2 hover:text-black dark:hover:text-white border-b dark:border-gray-500 border-dashed"> + <i className="mr-1 fas fa-folder-open" /> + {post.category} + </a> + </Link> + <span className='mr-2'>|</span> + + {post?.type[0] !== 'Page' && (<> + <Link + href={`/archive#${post?.date?.start_date?.substr(0, 7)}`} + passHref + > + <a className="pl-1 mr-2 cursor-pointer hover:text-gray-700 dark:hover:text-gray-200 border-b dark:border-gray-500 border-dashed"> + {date} + </a> + </Link> + <span className='mr-2'>|</span> + <span className='mx-2 text-gray-400 dark:text-gray-500'> + {locale.COMMON.LAST_EDITED_TIME}: {post.lastEditedTime} + </span> + <span className='mr-2'>|</span> + + </>)} + + <span className="hidden busuanzi_container_page_pv font-light mr-2"> + <i className='mr-1 fas fa-eye' /> +   + <span className="mr-2 busuanzi_value_page_pv" /> + </span> + </div> + + </section> +} diff --git a/themes/example/components/BlogList.js b/themes/example/components/BlogList.js new file mode 100644 index 00000000..057d45ef --- /dev/null +++ b/themes/example/components/BlogList.js @@ -0,0 +1,55 @@ + +import BLOG from '@/blog.config' +import { useGlobal } from '@/lib/global' +import { useRouter } from 'next/router' +import Link from 'next/link' + +export const BlogList = (props) => { + const { posts, postCount } = props + + const { locale } = useGlobal() + const router = useRouter() + const totalPage = Math.ceil(postCount / BLOG.POSTS_PER_PAGE) + + const page = 1 + const showNext = + page < totalPage && + posts.length === BLOG.POSTS_PER_PAGE && + posts.length < postCount + + const currentPage = +page + + return <div className="w-full md:pr-12 mb-12"> + + {posts.map(p => ( + <article key={p.id} className="mb-12" > + <h2 className="mb-4"> + <Link href={`/article/${p.slug}`}> + <a className="text-black text-xl md:text-2xl no-underline hover:underline"> {p.title}</a> + </Link> + </h2> + + <div className="mb-4 text-sm text-gray-700"> + by <a href="#" className="text-gray-700">{BLOG.AUTHOR}</a> on {p.date?.start_date || p.createdTime} + <span className="font-bold mx-1"> | </span> + <a href="#" className="text-gray-700">{p.category}</a> + <span className="font-bold mx-1"> | </span> + {/* <a href="#" className="text-gray-700">2 Comments</a> */} + </div> + + <p className="text-gray-700 leading-normal"> + {p.summary} + </p> + </article> + ))} + + <div className="flex justify-between text-xs"> + <Link href="/"> + <a className={`${currentPage > 1 ? 'bg-black ' : 'bg-gray '} text-white no-underline py-2 px-3 rounded`}>{locale.PAGINATION.PREV}</a> + </Link> + <Link href={{ pathname: `/page/${currentPage + 1}`, query: router.query.s ? { s: router.query.s } : {} }}> + <a className={`${showNext ? 'bg-black ' : 'bg-gray '} text-white no-underline py-2 px-3 rounded`}>{locale.PAGINATION.NEXT}</a> + </Link> + </div> + </div> +} diff --git a/themes/example/components/Footer.js b/themes/example/components/Footer.js new file mode 100644 index 00000000..86f0b9cb --- /dev/null +++ b/themes/example/components/Footer.js @@ -0,0 +1,49 @@ +import BLOG from '@/blog.config' + +export const Footer = (props) => { + const d = new Date() + const currentYear = d.getFullYear() + const startYear = BLOG.SINCE && BLOG.SINCE !== currentYear && BLOG.SINCE + '-' + + // {/* 页脚 */} + // <footer className="font-sans dark:bg-gray-900 flex-shrink-0 justify-center text-center m-auto w-full leading-6 text-sm p-6"> + // <i className="fas fa-copyright" /> {`${startYear}${currentYear}`}{' '} + + // <br /> + // <span className="hidden busuanzi_container_site_pv"> + // <i className="fas fa-eye" /> + // <span className="px-1 busuanzi_value_site_pv"> </span>{' '} + // </span> + // <span className="pl-2 hidden busuanzi_container_site_uv"> + // <i className="fas fa-users" />{' '} + // <span className="px-1 busuanzi_value_site_uv"> </span>{' '} + // </span> + // <br /> + // <h1>{meta?.title || siteInfo.title}</h1> + // <span className='text-xs font-serif'> + // Powered by{' '} + // <a + // href="https://github.com/tangly1024/NotionNext" + // className="underline dark:text-gray-300" + // > + // NotionNext {BLOG.VERSION} + // </a> + // . + // </span> + // </footer> + + return <footer className="w-full bg-white px-6 border-t"> + <div className="container mx-auto max-w-4xl py-6 flex flex-wrap md:flex-no-wrap justify-between items-center text-sm"> + ©{`${startYear}${currentYear}`} {BLOG.AUTHOR}. All rights reserved. + <div className="pt-4 md:p-0 text-center md:text-right text-xs"> + {/* 右侧链接 */} + {/* <a href="#" className="text-black no-underline hover:underline">Privacy Policy</a> */} + {BLOG.BEI_AN && (<a href="https://beian.miit.gov.cn/" className="text-black no-underline hover:underline ml-4">{BLOG.BEI_AN} </a>)} + <span className='text-black no-underline ml-4'> + Powered by + <a href="https://github.com/tangly1024/NotionNext" className=' hover:underline'> NotionNext {BLOG.VERSION} </a> + </span> + </div> + </div> + </footer> +} diff --git a/themes/example/components/Header.js b/themes/example/components/Header.js new file mode 100644 index 00000000..399fb5b7 --- /dev/null +++ b/themes/example/components/Header.js @@ -0,0 +1,21 @@ +import Link from 'next/link' + +/** + * 网站顶部 + * @returns + */ +export const Header = (props) => { + const { siteInfo } = props + + return <header className="w-full px-6 bg-white"> + <div className="container mx-auto max-w-4xl md:flex justify-between items-center"> + <Link href='/'> + <a className="py-6 w-full text-center md:text-left md:w-auto text-gray-dark no-underline flex justify-center items-center"> + {siteInfo?.title} + </a></Link> + <div className="w-full md:w-auto text-center md:text-right"> + {/* 右侧文字 */} + </div> + </div> + </header> +} diff --git a/themes/example/components/JumpToTopButton.js b/themes/example/components/JumpToTopButton.js new file mode 100644 index 00000000..30e684a8 --- /dev/null +++ b/themes/example/components/JumpToTopButton.js @@ -0,0 +1,19 @@ +import { useGlobal } from '@/lib/global' +import React from 'react' + +/** + * 跳转到网页顶部 + * 当屏幕下滑500像素后会出现该控件 + * @param targetRef 关联高度的目标html标签 + * @param showPercent 是否显示百分比 + * @returns {JSX.Element} + * @constructor + */ +const JumpToTopButton = () => { + const { locale } = useGlobal() + return <div title={locale.POST.TOP} className='cursor-pointer p-2 text-center' onClick={() => window.scrollTo({ top: 0, behavior: 'smooth' })} + ><i className='fas fa-angle-up text-2xl' /> + </div> +} + +export default JumpToTopButton diff --git a/themes/example/components/Nav.js b/themes/example/components/Nav.js new file mode 100644 index 00000000..10449dbb --- /dev/null +++ b/themes/example/components/Nav.js @@ -0,0 +1,34 @@ +import { useGlobal } from '@/lib/global' + +/** + * 菜单导航 + * @param {*} props + * @returns + */ +export const Nav = (props) => { + const { customNav } = props + const { locale } = useGlobal() + let links = [ + { icon: 'fas fa-search', name: locale.NAV.SEARCH, to: '/search' }, + { icon: 'fas fa-archive', name: locale.NAV.ARCHIVE, to: '/archive' }, + { icon: 'fas fa-folder', name: locale.COMMON.CATEGORY, to: '/category' }, + { icon: 'fas fa-tag', name: locale.COMMON.TAGS, to: '/tag' } + ] + + if (customNav) { + links = links.concat(customNav) + } + + return <nav className="w-full bg-white md:pt-0 px-6 relative z-20 border-t border-b border-gray-light"> + <div className="container mx-auto max-w-4xl md:flex justify-between items-center text-sm md:text-md md:justify-start"> + <div className="w-full md:w-2/3 text-center md:text-left py-4 flex flex-wrap justify-center items-stretch md:justify-start md:items-start"> + {links.map(link => { + return link && <a href={link.to} className="px-2 md:pl-0 md:mr-3 md:pr-3 text-gray-700 no-underline md:border-r border-gray-light">{link.name}</a> + })} + </div> + <div className="w-full md:w-1/3 text-center md:text-right"> + {/* <!-- extra links --> */} + </div> + </div> + </nav> +} diff --git a/themes/example/components/SideBar.js b/themes/example/components/SideBar.js new file mode 100644 index 00000000..b082bc6d --- /dev/null +++ b/themes/example/components/SideBar.js @@ -0,0 +1,44 @@ +import Live2D from '@/components/Live2D' +import { useGlobal } from '@/lib/global' +import Link from 'next/link' + +export const SideBar = (props) => { + const { locale } = useGlobal() + const { latestPosts, categories } = props + return <div className="w-full md:w-64 sticky top-8"> + + <aside className="rounded shadow overflow-hidden mb-6"> + <h3 className="text-sm bg-gray-100 text-gray-700 py-3 px-4 border-b">{locale.COMMON.CATEGORY}</h3> + + <div className="p-4"> + <ul className="list-reset leading-normal"> + {categories?.map(category => { + return <Link key={category.name} href={`/category/${category.name}`} passHref> + <li> <a href="#" className="text-gray-darkest text-sm">{category.name}({category.count})</a></li> + </Link> + })} + </ul> + </div> + + </aside> + + <aside className="rounded shadow overflow-hidden mb-6"> + <h3 className="text-sm bg-gray-100 text-gray-700 py-3 px-4 border-b">{locale.COMMON.LATEST_POSTS}</h3> + + <div className="p-4"> + <ul className="list-reset leading-normal"> + {latestPosts?.map(p => { + return <Link key={p.id} href={`/article/${p.slug}`} passHref> + <li> <a href="#" className="text-gray-darkest text-sm">{p.title}</a></li> + </Link> + })} + </ul> + </div> + </aside> + + <aside className="rounded overflow-hidden mb-6"> + <Live2D /> + </aside> + + </div> +} diff --git a/themes/example/components/Title.js b/themes/example/components/Title.js new file mode 100644 index 00000000..b0535341 --- /dev/null +++ b/themes/example/components/Title.js @@ -0,0 +1,19 @@ +import BLOG from '@/blog.config' + +/** + * 标题栏 + * @param {*} props + * @returns + */ +export const Title = (props) => { + const { siteInfo, post } = props + const title = post?.title || siteInfo?.description + const description = post?.description || BLOG.AUTHOR + + return <div className="text-center px-6 py-12 mb-6 bg-gray-100 border-b"> + <h1 className=" text-xl md:text-4xl pb-4">{title}</h1> + <p className="leading-loose text-gray-dark"> + {description} + </p> + </div> +} From 23880a63e5bc812efdb32c27302dc026e22aedd9 Mon Sep 17 00:00:00 2001 From: tangly1024 <tlyong1992@hotmail.com> Date: Wed, 27 Apr 2022 13:16:54 +0800 Subject: [PATCH 2/2] =?UTF-8?q?example=20=E4=B8=BB=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- blog.config.js | 2 +- themes/example/components/ArticleInfo.js | 62 ++++++++++++------------ themes/example/components/Nav.js | 7 ++- 3 files changed, 39 insertions(+), 32 deletions(-) diff --git a/blog.config.js b/blog.config.js index 6693a752..ed42761d 100644 --- a/blog.config.js +++ b/blog.config.js @@ -18,7 +18,7 @@ const BLOG = { FACEBOOK_PAGE_ID: process.env.NEXT_PUBLIC_FACEBOOK_PAGE_ID || '', // Facebook Page ID 來啟用 messenger 聊天功能 FACEBOOK_APP_ID: process.env.NEXT_PUBLIC_FACEBOOK_APP_ID || '', // Facebook App ID 來啟用 messenger 聊天功能 获取: https://developers.facebook.com/ - THEME: process.env.NEXT_PUBLIC_THEME || 'next', // 主题, 支持 ['next','hexo',"fukasawa','medium'] + THEME: process.env.NEXT_PUBLIC_THEME || 'next', // 主题, 支持 ['next','hexo',"fukasawa','medium','example'] @see https://preview.tangly1024.com THEME_SWITCH: process.env.NEXT_PUBLIC_THEME_SWITCH || false, // 是否显示切换主题按钮 LANG: 'zh-CN', // e.g 'zh-CN','en-US' see /lib/lang.js for more. HOME_BANNER_IMAGE: './bg_image.jpg', // 首页背景大图,默认文件:/public/bg_image.jpg 。会被Notion中的封面图覆盖。 diff --git a/themes/example/components/ArticleInfo.js b/themes/example/components/ArticleInfo.js index a0a5c365..7e92e254 100644 --- a/themes/example/components/ArticleInfo.js +++ b/themes/example/components/ArticleInfo.js @@ -9,38 +9,40 @@ export const ArticleInfo = (props) => { const date = formatDate(post?.date?.start_date || post?.createdTime, locale.LOCALE) return <section className="flex-wrap flex mt-2 text-gray-400 dark:text-gray-400 font-light leading-8"> - <div> - <Link href={`/category/${post.category}`} passHref> - <a className="cursor-pointer text-md mr-2 hover:text-black dark:hover:text-white border-b dark:border-gray-500 border-dashed"> - <i className="mr-1 fas fa-folder-open" /> - {post.category} - </a> - </Link> - <span className='mr-2'>|</span> + <div> + {post?.type[0] !== 'Page' && <> + <Link href={`/category/${post.category}`} passHref> + <a className="cursor-pointer text-md mr-2 hover:text-black dark:hover:text-white border-b dark:border-gray-500 border-dashed"> + <i className="mr-1 fas fa-folder-open" /> + {post.category} + </a> + </Link> + <span className='mr-2'>|</span> + </>} - {post?.type[0] !== 'Page' && (<> - <Link - href={`/archive#${post?.date?.start_date?.substr(0, 7)}`} - passHref - > - <a className="pl-1 mr-2 cursor-pointer hover:text-gray-700 dark:hover:text-gray-200 border-b dark:border-gray-500 border-dashed"> - {date} - </a> - </Link> - <span className='mr-2'>|</span> - <span className='mx-2 text-gray-400 dark:text-gray-500'> - {locale.COMMON.LAST_EDITED_TIME}: {post.lastEditedTime} - </span> - <span className='mr-2'>|</span> + {post?.type[0] !== 'Page' && (<> + <Link + href={`/archive#${post?.date?.start_date?.substr(0, 7)}`} + passHref + > + <a className="pl-1 mr-2 cursor-pointer hover:text-gray-700 dark:hover:text-gray-200 border-b dark:border-gray-500 border-dashed"> + {date} + </a> + </Link> + <span className='mr-2'>|</span> + <span className='mx-2 text-gray-400 dark:text-gray-500'> + {locale.COMMON.LAST_EDITED_TIME}: {post.lastEditedTime} + </span> + <span className='mr-2'>|</span> - </>)} + </>)} - <span className="hidden busuanzi_container_page_pv font-light mr-2"> - <i className='mr-1 fas fa-eye' /> -   - <span className="mr-2 busuanzi_value_page_pv" /> - </span> - </div> + <span className="hidden busuanzi_container_page_pv font-light mr-2"> + <i className='mr-1 fas fa-eye' /> +   + <span className="mr-2 busuanzi_value_page_pv" /> + </span> + </div> - </section> + </section> } diff --git a/themes/example/components/Nav.js b/themes/example/components/Nav.js index 10449dbb..4c3217c0 100644 --- a/themes/example/components/Nav.js +++ b/themes/example/components/Nav.js @@ -1,4 +1,5 @@ import { useGlobal } from '@/lib/global' +import Link from 'next/link' /** * 菜单导航 @@ -23,7 +24,11 @@ export const Nav = (props) => { <div className="container mx-auto max-w-4xl md:flex justify-between items-center text-sm md:text-md md:justify-start"> <div className="w-full md:w-2/3 text-center md:text-left py-4 flex flex-wrap justify-center items-stretch md:justify-start md:items-start"> {links.map(link => { - return link && <a href={link.to} className="px-2 md:pl-0 md:mr-3 md:pr-3 text-gray-700 no-underline md:border-r border-gray-light">{link.name}</a> + return link && <Link href={link.to}> + <a className="px-2 md:pl-0 md:mr-3 md:pr-3 text-gray-700 no-underline md:border-r border-gray-light"> + {link.name} + </a> + </Link> })} </div> <div className="w-full md:w-1/3 text-center md:text-right">