MailChimp

This commit is contained in:
tangly1024.com
2023-07-04 12:39:18 +08:00
parent 26f6b2d85f
commit 194cd7ac7d
57 changed files with 361 additions and 235 deletions

View File

@@ -14,7 +14,7 @@ const LayoutSearch = props => {
useEffect(() => {
setTimeout(() => {
const container = isBrowser() && document.getElementById('container')
const container = isBrowser() && document.getElementById('posts-wrapper')
if (container && container.innerHTML) {
const re = new RegExp(keyword, 'gim')
const instance = new Mark(container)

View File

@@ -17,7 +17,7 @@ export const LayoutSlug = props => {
{lock && <ArticleLock validPassword={validPassword} />}
{!lock && <div id="notion-article" className="px-2">
{!lock && <div id="article-wrapper" className="px-2">
{post && <>
<ArticleInfo post={post} />
<NotionPage post={post} />

View File

@@ -22,7 +22,7 @@ export const BlogListPage = props => {
return (
<div className={`w-full ${showPageCover ? 'md:pr-2' : 'md:pr-12'}} mb-12`}>
<div id="container">
<div id="posts-wrapper">
{posts?.map(post => (
<BlogPostCard key={post.id} post = {post}/>
))}

View File

@@ -47,7 +47,7 @@ export const BlogListScroll = props => {
return (
<div className={`w-full ${showPageCover ? 'md:pr-2' : 'md:pr-12'}} mb-12`} ref={targetRef}>
<div id='posts-wrapper' className={`w-full ${showPageCover ? 'md:pr-2' : 'md:pr-12'}} mb-12`} ref={targetRef}>
{postsToShow?.map(post => (
<BlogPostCard key={post.id} post={post} />

View File

@@ -13,7 +13,7 @@ export const LayoutSearch = (props) => {
const currentSearch = keyword || router?.query?.s
useEffect(() => {
setTimeout(() => {
const container = isBrowser() && document.getElementById('container')
const container = isBrowser() && document.getElementById('posts-wrapper')
if (container && container.innerHTML) {
const re = new RegExp(currentSearch, 'gim')
const instance = new Mark(container)

View File

@@ -86,7 +86,7 @@ export default function ArticleDetail(props) {
</header>
{/* Notion文章主体 */}
<section id='notion-article' className='px-1'>
<section id='article-wrapper' className='px-1'>
{post && <NotionPage post={post} />}
</section>

View File

@@ -52,7 +52,7 @@ const BlogListPage = ({ page = 1, posts = [], postCount, siteInfo }) => {
return (
<div>
{/* 文章列表 */}
<div id="container" className='grid-container'>
<div id="posts-wrapper" className='grid-container'>
{filterPosts?.map(post => (
<div key={post.id} className='grid-item justify-center flex' style={{ breakInside: 'avoid' }}>
<BlogCard index={posts.indexOf(post)} key={post.id} post={post} siteInfo={siteInfo} />

View File

@@ -55,7 +55,7 @@ const BlogListScroll = props => {
return <BlogPostListEmpty />
} else {
return (
<div id="container" ref={targetRef} className='grid-container' >
<div id="posts-wrapper" ref={targetRef} className='grid-container' >
{/* 文章列表 */}
{postsToShow?.map(post => (
<div key={post.id} className='grid-item justify-center flex' style={{ breakInside: 'avoid' }}>

View File

@@ -19,7 +19,7 @@ export const LayoutSearch = (props) => {
useEffect(() => {
setTimeout(() => {
const container = isBrowser() && document.getElementById('container')
const container = isBrowser() && document.getElementById('posts-wrapper')
if (container && container.innerHTML) {
const re = new RegExp(currentSearch, 'gim')
const instance = new Mark(container)

View File

@@ -25,7 +25,7 @@ export const LayoutSlug = (props) => {
<h1 className="text-3xl pt-12 dark:text-gray-300">{post?.title}</h1>
{/* Notion文章主体 */}
{post && (<section id="notion-article" className="px-1">
{post && (<section id="article-wrapper" className="px-1">
<NotionPage post={post} />
</section>)}

View File

@@ -20,7 +20,7 @@ const BlogPostListPage = ({ page = 1, posts = [], postCount }) => {
return (
<div className='w-full justify-center'>
<div id='container'>
<div id='posts-wrapper'>
{/* 文章列表 */}
{posts?.map(post => (
<BlogPostCard key={post.id} post={post} />

View File

@@ -36,7 +36,7 @@ const NavPostList = (props) => {
if (!filteredPosts || filteredPosts.length === 0) {
return <NavPostListEmpty currentSearch={currentSearch} />
} else {
return <div className='w-full'>
return <div id='posts-wrapper' className='w-full'>
{/* 文章列表 */}
{filteredPosts?.map((group, index) => <NavPostItem key={index} group={group} onHeightChange={props.onHeightChange}/>)}
</div>

View File

@@ -10,7 +10,7 @@ const Progress = ({ targetRef, showPercent = true }) => {
const currentRef = targetRef?.current || targetRef
const [percent, changePercent] = useState(0)
const scrollListener = () => {
const target = currentRef || (isBrowser() && document.getElementById('container'))
const target = currentRef || (isBrowser() && document.getElementById('posts-wrapper'))
if (target) {
const clientHeight = target.clientHeight
const scrollY = window.pageYOffset

View File

@@ -7,7 +7,7 @@ export const Layout404 = props => {
useEffect(() => {
// 延时3秒如果加载失败就返回首页
setTimeout(() => {
const article = typeof document !== 'undefined' && document.getElementById('container')
const article = typeof document !== 'undefined' && document.getElementById('notion-article')
if (!article) {
router.push('/').then(() => {
// console.log('找不到页面', router.asPath)

View File

@@ -26,7 +26,7 @@ export const LayoutSlug = props => {
></LayoutBase>
}
const targetRef = isBrowser() ? document.getElementById('container') : null
const targetRef = isBrowser() ? document.getElementById('article-wrapper') : null
const floatSlot = <>
{post?.toc?.length > 1 && <div className="block lg:hidden">
@@ -50,11 +50,11 @@ export const LayoutSlug = props => {
<div className="w-full lg:hover:shadow lg:border rounded-t-xl lg:rounded-xl lg:px-2 lg:py-4 bg-white dark:bg-hexo-black-gray dark:border-black article">
{lock && <ArticleLock validPassword={validPassword} />}
{!lock && <div id="container" className="overflow-x-auto flex-grow mx-auto md:w-full md:px-5 ">
{!lock && <div id="article-wrapper" className="overflow-x-auto flex-grow mx-auto md:w-full md:px-5 ">
<article itemScope itemType="https://schema.org/Movie" className="subpixel-antialiased overflow-y-hidden" >
{/* Notion文章主体 */}
<section id='notion-article' className='px-5 justify-center mx-auto max-w-2xl lg:max-w-full'>
<section className='px-5 justify-center mx-auto max-w-2xl lg:max-w-full'>
{post && <NotionPage post={post} />}
</section>

View File

@@ -10,7 +10,7 @@ const Progress = ({ targetRef, showPercent = true }) => {
const currentRef = targetRef?.current || targetRef
const [percent, changePercent] = useState(0)
const scrollListener = () => {
const target = currentRef || (isBrowser() && document.getElementById('container'))
const target = currentRef || (isBrowser() && document.getElementById('article-wrapper'))
if (target) {
const clientHeight = target.clientHeight
const scrollY = window.pageYOffset

View File

@@ -31,7 +31,7 @@ export default function Features() {
{/* Section header */}
<div className="max-w-3xl mx-auto text-center pb-12 md:pb-16">
<h1 className="h2 mb-4">探索解决方案</h1>
<p className="text-xl text-gray-600">个人或小企业有什么方法可以快速搭建自己的站塑造一个品牌展示中心<br/>以前它是<strong className='font-bold'>繁重</strong>Wordpress<strong className='font-bold'></strong>Hexo<strong className='font-bold'></strong>Notion</p>
<p className="text-xl text-gray-600">如何搭建自己的门户网塑造一个品牌展示中心<br/>以前它是系统<strong className='font-bold'>繁重</strong>Wordpress<strong className='font-bold'></strong>Hexo<strong className='font-bold'></strong>Notion</p>
</div>
{/* Section content */}

View File

@@ -1,149 +1,174 @@
import { subscribeToNewsletter } from '@/lib/mailchimp'
import { useEffect, useRef, useState } from 'react'
import Logo from './Logo'
export default function Footer() {
const formRef = useRef()
const [success, setSuccess] = useState(false)
useEffect(() => {
const form = formRef.current
const handleSubmit = (e) => {
e.preventDefault()
const email = document.querySelector('#newsletter').value
subscribeToNewsletter(email).then(response => {
console.log('Subscription succeeded:', response)
// 在此处添加成功订阅后的操作
setSuccess(true)
})
.catch(error => {
console.error('Subscription failed:', error)
// 在此处添加订阅失败后的操作
})
}
form.addEventListener('submit', handleSubmit)
return () => {
form.removeEventListener('submit', handleSubmit)
}
}, [subscribeToNewsletter])
return (
<footer>
<div className="max-w-6xl mx-auto px-4 sm:px-6">
<footer>
<div className="max-w-6xl mx-auto px-4 sm:px-6">
{/* Top area: Blocks */}
<div className="grid sm:grid-cols-12 gap-8 py-8 md:py-12 border-t border-gray-200">
{/* Top area: Blocks */}
<div className="grid sm:grid-cols-12 gap-8 py-8 md:py-12 border-t border-gray-200">
{/* 1st block */}
<div className="sm:col-span-12 lg:col-span-3">
<div className="mb-2">
<Logo />
</div>
<div className="text-sm text-gray-600">
<a href="#0" className="text-gray-600 hover:text-gray-900 hover:underline transition duration-150 ease-in-out">Terms</a> · <a href="#0" className="text-gray-600 hover:text-gray-900 hover:underline transition duration-150 ease-in-out">Privacy Policy</a>
</div>
</div>
{/* 1st block */}
<div className="sm:col-span-12 lg:col-span-3">
<div className="mb-2">
<Logo />
</div>
<div className="text-sm text-gray-600">
<a href="#0" className="text-gray-600 hover:text-gray-900 hover:underline transition duration-150 ease-in-out">服务条款</a> · <a href="#0" className="text-gray-600 hover:text-gray-900 hover:underline transition duration-150 ease-in-out"></a>
</div>
</div>
{/* 2nd block */}
<div className="sm:col-span-6 md:col-span-3 lg:col-span-2">
<h6 className="text-gray-800 font-medium mb-2">Products</h6>
<ul className="text-sm">
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">Web Studio</a>
</li>
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">DynamicBox Flex</a>
</li>
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">Programming Forms</a>
</li>
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">Integrations</a>
</li>
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">Command-line</a>
</li>
</ul>
</div>
{/* 2nd block */}
<div className="sm:col-span-6 md:col-span-3 lg:col-span-2">
<h6 className="text-gray-800 font-medium mb-2">产品</h6>
<ul className="text-sm">
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">NotionNext</a>
</li>
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">Vercel</a>
</li>
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">Github</a>
</li>
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">Notion</a>
</li>
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">NextJs</a>
</li>
</ul>
</div>
{/* 3rd block */}
<div className="sm:col-span-6 md:col-span-3 lg:col-span-2">
<h6 className="text-gray-800 font-medium mb-2">Resources</h6>
<ul className="text-sm">
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">Documentation</a>
</li>
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">Tutorials & Guides</a>
</li>
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">Blog</a>
</li>
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">Support Center</a>
</li>
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">Partners</a>
</li>
</ul>
</div>
{/* 3rd block */}
<div className="sm:col-span-6 md:col-span-3 lg:col-span-2">
<h6 className="text-gray-800 font-medium mb-2">资源</h6>
<ul className="text-sm">
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">技术文档</a>
</li>
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">教程指南</a>
</li>
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">博客</a>
</li>
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">支持中心</a>
</li>
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">合作方</a>
</li>
</ul>
</div>
{/* 4th block */}
<div className="sm:col-span-6 md:col-span-3 lg:col-span-2">
<h6 className="text-gray-800 font-medium mb-2">Company</h6>
<ul className="text-sm">
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">Home</a>
</li>
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">About us</a>
</li>
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">Company values</a>
</li>
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">Pricing</a>
</li>
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">Privacy Policy</a>
</li>
</ul>
</div>
{/* 4th block */}
<div className="sm:col-span-6 md:col-span-3 lg:col-span-2">
<h6 className="text-gray-800 font-medium mb-2">企业</h6>
<ul className="text-sm">
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">主页</a>
</li>
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">关于我们</a>
</li>
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">公司价值观</a>
</li>
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">价格</a>
</li>
<li className="mb-2">
<a href="#0" className="text-gray-600 hover:text-gray-900 transition duration-150 ease-in-out">隐私政策</a>
</li>
</ul>
</div>
{/* 5th block */}
<div className="sm:col-span-6 md:col-span-3 lg:col-span-3">
<h6 className="text-gray-800 font-medium mb-2">Subscribe</h6>
<p className="text-sm text-gray-600 mb-4">Get the latest news and articles to your inbox every month.</p>
<form ref={formRef}>
<div className="flex flex-wrap mb-4">
<div className="w-full">
<label className="block text-sm sr-only" htmlFor="newsletter">Email</label>
<div className="relative flex items-center max-w-xs">
<input disabled={success} id="newsletter" type="email" className="form-input w-full text-gray-800 px-3 py-2 pr-12 text-sm" placeholder="Your email" required />
<button disabled={success} type="submit" className="absolute inset-0 left-auto" aria-label="Subscribe">
<span className="absolute inset-0 right-auto w-px -ml-px my-2 bg-gray-300" aria-hidden="true"></span>
<svg className="w-3 h-3 fill-current text-blue-600 mx-3 shrink-0" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
<path d="M11.707 5.293L7 .586 5.586 2l3 3H0v2h8.586l-3 3L7 11.414l4.707-4.707a1 1 0 000-1.414z" fillRule="nonzero" />
</svg>
</button>
</div>
{/* Success message */}
{success && <p className="mt-2 text-green-600 text-sm">Thanks for subscribing!</p>}
</div>
</div>
</form>
</div>
{/* 5th block */}
<div className="sm:col-span-6 md:col-span-3 lg:col-span-3">
<h6 className="text-gray-800 font-medium mb-2">Subscribe</h6>
<p className="text-sm text-gray-600 mb-4">Get the latest news and articles to your inbox every month.</p>
<form>
<div className="flex flex-wrap mb-4">
<div className="w-full">
<label className="block text-sm sr-only" htmlFor="newsletter">Email</label>
<div className="relative flex items-center max-w-xs">
<input id="newsletter" type="email" className="form-input w-full text-gray-800 px-3 py-2 pr-12 text-sm" placeholder="Your email" required />
<button type="submit" className="absolute inset-0 left-auto" aria-label="Subscribe">
<span className="absolute inset-0 right-auto w-px -ml-px my-2 bg-gray-300" aria-hidden="true"></span>
<svg className="w-3 h-3 fill-current text-blue-600 mx-3 shrink-0" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
<path d="M11.707 5.293L7 .586 5.586 2l3 3H0v2h8.586l-3 3L7 11.414l4.707-4.707a1 1 0 000-1.414z" fillRule="nonzero" />
</svg>
</button>
</div>
{/* Success message */}
{/* <p className="mt-2 text-green-600 text-sm">Thanks for subscribing!</p> */}
</div>
</div>
</form>
</div>
</div>
{/* Bottom area */}
<div className="md:flex md:items-center md:justify-between py-4 md:py-8 border-t border-gray-200">
{/* Bottom area */}
<div className="md:flex md:items-center md:justify-between py-4 md:py-8 border-t border-gray-200">
{/* Social as */}
<ul className="flex mb-4 md:order-1 md:ml-4 md:mb-0">
<li>
{/* Social as */}
<ul className="flex mb-4 md:order-1 md:ml-4 md:mb-0">
{/* <li>
<a href="#0" className="flex justify-center items-center text-gray-600 hover:text-gray-900 bg-white hover:bg-white-100 rounded-full shadow transition duration-150 ease-in-out" aria-label="Twitter">
<svg className="w-8 h-8 fill-current" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<path d="M24 11.5c-.6.3-1.2.4-1.9.5.7-.4 1.2-1 1.4-1.8-.6.4-1.3.6-2.1.8-.6-.6-1.5-1-2.4-1-1.7 0-3.2 1.5-3.2 3.3 0 .3 0 .5.1.7-2.7-.1-5.2-1.4-6.8-3.4-.3.5-.4 1-.4 1.7 0 1.1.6 2.1 1.5 2.7-.5 0-1-.2-1.5-.4 0 1.6 1.1 2.9 2.6 3.2-.3.1-.6.1-.9.1-.2 0-.4 0-.6-.1.4 1.3 1.6 2.3 3.1 2.3-1.1.9-2.5 1.4-4.1 1.4H8c1.5.9 3.2 1.5 5 1.5 6 0 9.3-5 9.3-9.3v-.4c.7-.5 1.3-1.1 1.7-1.8z" />
</svg>
</a>
</li>
<li className="ml-4">
<a href="#0" className="flex justify-center items-center text-gray-600 hover:text-gray-900 bg-white hover:bg-white-100 rounded-full shadow transition duration-150 ease-in-out" aria-label="Github">
<svg className="w-8 h-8 fill-current" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<path d="M16 8.2c-4.4 0-8 3.6-8 8 0 3.5 2.3 6.5 5.5 7.6.4.1.5-.2.5-.4V22c-2.2.5-2.7-1-2.7-1-.4-.9-.9-1.2-.9-1.2-.7-.5.1-.5.1-.5.8.1 1.2.8 1.2.8.7 1.3 1.9.9 2.3.7.1-.5.3-.9.5-1.1-1.8-.2-3.6-.9-3.6-4 0-.9.3-1.6.8-2.1-.1-.2-.4-1 .1-2.1 0 0 .7-.2 2.2.8.6-.2 1.3-.3 2-.3s1.4.1 2 .3c1.5-1 2.2-.8 2.2-.8.4 1.1.2 1.9.1 2.1.5.6.8 1.3.8 2.1 0 3.1-1.9 3.7-3.7 3.9.3.4.6.9.6 1.6v2.2c0 .2.1.5.6.4 3.2-1.1 5.5-4.1 5.5-7.6-.1-4.4-3.7-8-8.1-8z" />
</svg>
</a>
</li>
<li className="ml-4">
</li> */}
<li className="ml-4">
<a href="#0" className="flex justify-center items-center text-gray-600 hover:text-gray-900 bg-white hover:bg-white-100 rounded-full shadow transition duration-150 ease-in-out" aria-label="Github">
<svg className="w-8 h-8 fill-current" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<path d="M16 8.2c-4.4 0-8 3.6-8 8 0 3.5 2.3 6.5 5.5 7.6.4.1.5-.2.5-.4V22c-2.2.5-2.7-1-2.7-1-.4-.9-.9-1.2-.9-1.2-.7-.5.1-.5.1-.5.8.1 1.2.8 1.2.8.7 1.3 1.9.9 2.3.7.1-.5.3-.9.5-1.1-1.8-.2-3.6-.9-3.6-4 0-.9.3-1.6.8-2.1-.1-.2-.4-1 .1-2.1 0 0 .7-.2 2.2.8.6-.2 1.3-.3 2-.3s1.4.1 2 .3c1.5-1 2.2-.8 2.2-.8.4 1.1.2 1.9.1 2.1.5.6.8 1.3.8 2.1 0 3.1-1.9 3.7-3.7 3.9.3.4.6.9.6 1.6v2.2c0 .2.1.5.6.4 3.2-1.1 5.5-4.1 5.5-7.6-.1-4.4-3.7-8-8.1-8z" />
</svg>
</a>
</li>
{/* <li className="ml-4">
<a href="#0" className="flex justify-center items-center text-gray-600 hover:text-gray-900 bg-white hover:bg-white-100 rounded-full shadow transition duration-150 ease-in-out" aria-label="Facebook">
<svg className="w-8 h-8 fill-current" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<path d="M14.023 24L14 17h-3v-3h3v-2c0-2.7 1.672-4 4.08-4 1.153 0 2.144.086 2.433.124v2.821h-1.67c-1.31 0-1.563.623-1.563 1.536V14H21l-1 3h-2.72v7h-3.257z" />
</svg>
</a>
</li>
</ul>
</li> */}
</ul>
{/* Copyrights note */}
<div className="text-sm text-gray-600 mr-4">&copy; NotionNext. All rights reserved.</div>
{/* Copyrights note */}
<div className="text-sm text-gray-600 mr-4">&copy; NotionNext. All rights reserved.</div>
</div>
</div>
</div>
</footer>
</div>
</footer>
)
}

View File

@@ -35,12 +35,12 @@ export default function Header() {
{/* Desktop sign in links */}
<ul className="flex grow justify-end flex-wrap items-center">
<li>
<Link href="https://github.com/tangly1024/NotionNext" className="font-medium hover:font-bold text-gray-600 hover:text-gray-900 px-5 py-3 flex items-center transition duration-150 ease-in-out">
<i className='fab fa-github mr-1'></i><div>Github</div>
<Link href="https://github.com/tangly1024/NotionNext" target='_blank' className="font-medium hover:font-bold text-gray-600 hover:text-gray-900 px-5 py-3 flex items-center transition duration-150 ease-in-out">
<i className='fab fa-github mr-1'></i><div>Github</div>
</Link>
</li>
<li>
<Link href="https://blog.tangly1024.com/" className="btn-sm text-gray-200 bg-gray-900 hover:bg-gray-800 ml-3">
<Link href="https://blog.tangly1024.com/" target='_blank' className="btn-sm text-gray-200 bg-gray-900 hover:bg-gray-800 ml-3">
<span>我的博客</span>
<svg className="w-3 h-3 fill-current text-gray-400 shrink-0 ml-2 -mr-1" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
<path d="M11.707 5.293L7 .586 5.586 2l3 3H0v2h8.586l-3 3L7 11.414l4.707-4.707a1 1 0 000-1.414z" fillRule="nonzero" />

View File

@@ -30,7 +30,7 @@ export default function Hero() {
<div className="text-center pb-12 md:pb-16">
<h1 className="text-5xl md:text-6xl font-extrabold leading-tighter tracking-tighter mb-4" data-aos="zoom-y-out"><span className="bg-clip-text text-transparent bg-gradient-to-r from-blue-500 to-teal-400">NotionNext</span></h1>
<div className="max-w-3xl mx-auto">
<p className="text-xl text-gray-600 mb-8" data-aos="zoom-y-out" data-aos-delay="150">只需一个Notion笔记就可以搭建各种网站这也许是成本最低最快的建站方案</p>
<p className="text-xl text-gray-600 mb-8" data-aos="zoom-y-out" data-aos-delay="150">一个笔记软件一个脚本工具建站从未如此简单</p>
<div className="max-w-xs mx-auto sm:max-w-none sm:flex sm:justify-center" data-aos="zoom-y-out" data-aos-delay="300">
<div>
<a className="btn text-white bg-blue-600 hover:bg-blue-700 w-full mb-4 sm:w-auto sm:mb-0" href="https://docs.tangly1024.com/article/vercel-deploy-notion-next">开始体验</a>

View File

@@ -1,63 +1,89 @@
import { subscribeToNewsletter } from '@/lib/mailchimp'
import { useEffect, useRef, useState } from 'react'
export default function Newsletter() {
const formRef = useRef()
const [success, setSuccess] = useState(false)
useEffect(() => {
const form = formRef.current
const handleSubmit = (e) => {
e.preventDefault()
const email = document.querySelector('#newsletter').value
subscribeToNewsletter(email).then(response => {
console.log('Subscription succeeded:', response)
// 在此处添加成功订阅后的操作
setSuccess(true)
})
.catch(error => {
console.error('Subscription failed:', error)
// 在此处添加订阅失败后的操作
})
}
form.addEventListener('submit', handleSubmit)
return () => {
form.removeEventListener('submit', handleSubmit)
}
}, [subscribeToNewsletter])
return (
<section>
<div className="max-w-6xl mx-auto px-4 sm:px-6">
<div className="pb-12 md:pb-20">
<section>
<div className="max-w-6xl mx-auto px-4 sm:px-6">
<div className="pb-12 md:pb-20">
{/* CTA box */}
<div className="relative bg-gray-900 rounded py-10 px-8 md:py-16 md:px-12 shadow-2xl overflow-hidden" data-aos="zoom-y-out">
{/* CTA box */}
<div className="relative bg-gray-900 rounded py-10 px-8 md:py-16 md:px-12 shadow-2xl overflow-hidden" data-aos="zoom-y-out">
{/* Background illustration */}
<div className="absolute right-0 bottom-0 pointer-events-none hidden lg:block" aria-hidden="true">
<svg width="428" height="328" xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient cx="35.542%" cy="34.553%" fx="35.542%" fy="34.553%" r="96.031%" id="ni-a">
<stop stopColor="#DFDFDF" offset="0%" />
<stop stopColor="#4C4C4C" offset="44.317%" />
<stop stopColor="#333" offset="100%" />
</radialGradient>
</defs>
<g fill="none" fillRule="evenodd">
<g fill="#FFF">
<ellipse fillOpacity=".04" cx="185" cy="15.576" rx="16" ry="15.576" />
<ellipse fillOpacity=".24" cx="100" cy="68.402" rx="24" ry="23.364" />
<ellipse fillOpacity=".12" cx="29" cy="251.231" rx="29" ry="28.231" />
<ellipse fillOpacity=".64" cx="29" cy="251.231" rx="8" ry="7.788" />
<ellipse fillOpacity=".12" cx="342" cy="31.303" rx="8" ry="7.788" />
<ellipse fillOpacity=".48" cx="62" cy="126.811" rx="2" ry="1.947" />
<ellipse fillOpacity=".12" cx="78" cy="7.072" rx="2" ry="1.947" />
<ellipse fillOpacity=".64" cx="185" cy="15.576" rx="6" ry="5.841" />
</g>
<circle fill="url(#ni-a)" cx="276" cy="237" r="200" />
</g>
</svg>
</div>
{/* Background illustration */}
<div className="absolute right-0 bottom-0 pointer-events-none hidden lg:block" aria-hidden="true">
<svg width="428" height="328" xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient cx="35.542%" cy="34.553%" fx="35.542%" fy="34.553%" r="96.031%" id="ni-a">
<stop stopColor="#DFDFDF" offset="0%" />
<stop stopColor="#4C4C4C" offset="44.317%" />
<stop stopColor="#333" offset="100%" />
</radialGradient>
</defs>
<g fill="none" fillRule="evenodd">
<g fill="#FFF">
<ellipse fillOpacity=".04" cx="185" cy="15.576" rx="16" ry="15.576" />
<ellipse fillOpacity=".24" cx="100" cy="68.402" rx="24" ry="23.364" />
<ellipse fillOpacity=".12" cx="29" cy="251.231" rx="29" ry="28.231" />
<ellipse fillOpacity=".64" cx="29" cy="251.231" rx="8" ry="7.788" />
<ellipse fillOpacity=".12" cx="342" cy="31.303" rx="8" ry="7.788" />
<ellipse fillOpacity=".48" cx="62" cy="126.811" rx="2" ry="1.947" />
<ellipse fillOpacity=".12" cx="78" cy="7.072" rx="2" ry="1.947" />
<ellipse fillOpacity=".64" cx="185" cy="15.576" rx="6" ry="5.841" />
</g>
<circle fill="url(#ni-a)" cx="276" cy="237" r="200" />
</g>
</svg>
</div>
<div className="relative flex flex-col lg:flex-row justify-between items-center">
<div className="relative flex flex-col lg:flex-row justify-between items-center">
{/* CTA content */}
<div className="text-center lg:text-left lg:max-w-xl">
<h3 className="h3 text-white mb-2">需要更多的教程和帮助?</h3>
<p className="text-gray-300 text-lg mb-6">请留下您的电子邮件我会第一时间与您取得联系</p>
{/* CTA content */}
<div className="text-center lg:text-left lg:max-w-xl">
<h3 className="h3 text-white mb-2">需要更多的教程和帮助?</h3>
<p className="text-gray-300 text-lg mb-6">请留下您的电子邮件我会第一时间与您取得联系</p>
{/* CTA form */}
<form ref={formRef} className="w-full lg:w-auto">
<div className="flex flex-col sm:flex-row justify-center max-w-xs mx-auto sm:max-w-md lg:mx-0">
<input disabled={success} type="email" className="form-input w-full appearance-none bg-gray-800 border border-gray-700 focus:border-gray-600 rounded-sm px-4 py-3 mb-2 sm:mb-0 sm:mr-2 placeholder-gray-500" placeholder="Your email…" aria-label="Your email…" required />
<button disabled={success} type='submit' className={`btn text-white shadow ${success ? 'bg-green-600 hover:bg-green-700' : 'bg-blue-600 hover:bg-blue-700'}`} href="#0">{success ? 'Subscribed' : 'Subscribe'}</button>
</div>
{/* Success message */}
{success && <p className="text-sm text-gray-400 mt-3">感谢您的订阅!</p>}
{!success && <p className="text-sm text-gray-400 mt-3">没有垃圾邮件您可以随时取消订阅</p>}
</form>
</div>
</div>
{/* CTA form */}
<form className="w-full lg:w-auto">
<div className="flex flex-col sm:flex-row justify-center max-w-xs mx-auto sm:max-w-md lg:mx-0">
<input type="email" className="form-input w-full appearance-none bg-gray-800 border border-gray-700 focus:border-gray-600 rounded-sm px-4 py-3 mb-2 sm:mb-0 sm:mr-2 text-white placeholder-gray-500" placeholder="Your email…" aria-label="Your email…" />
<a className="btn text-white bg-blue-600 hover:bg-blue-700 shadow" href="#0">Subscribe</a>
</div>
{/* Success message */}
{/* <p className="text-sm text-gray-400 mt-3">Thanks for subscribing!</p> */}
<p className="text-sm text-gray-400 mt-3">没有垃圾邮件您可以随时取消订阅</p>
</form>
</div>
</div>
</div>
</div>
</div>
</section>
</section>
)
}

View File

@@ -28,7 +28,7 @@ const THEME_CONFIG = { THEME: 'landing' }
* @returns
*/
const LayoutBase = (props) => {
const { siteInfo, children } = props
const { children } = props
return <div id='theme-blank' className="flex flex-col justify-between bg-white">
{/* 顶部导航栏 */}
<Header />
@@ -50,7 +50,6 @@ const LayoutBase = (props) => {
* @returns
*/
const LayoutIndex = (props) => {
const { siteInfo } = props
return (
<LayoutBase {...props}>
<Hero />
@@ -68,7 +67,7 @@ const LayoutIndex = (props) => {
* @returns
*/
const LayoutSlug = (props) => <LayoutBase {...props}>
<div className='p-12'>
<div id='container-inner' className='mx-auto max-w-screen-lg p-12'>
<NotionPage {...props} />
</div>
</LayoutBase>

View File

@@ -7,7 +7,7 @@ export const Layout404 = props => {
useEffect(() => {
// 延时3秒如果加载失败就返回首页
setTimeout(() => {
const article = typeof document !== 'undefined' && document.getElementById('container')
const article = typeof document !== 'undefined' && document.getElementById('notion-article')
if (!article) {
router.push('/').then(() => {
// console.log('找不到页面', router.asPath)

View File

@@ -54,7 +54,7 @@ const LayoutBase = props => {
<main id="wrapper" className={`${CONFIG_MATERY.HOME_BANNER_ENABLE ? '' : 'pt-16'} flex-1 w-full py-8 md:px-8 lg:px-24 relative`}>
{/* 嵌入区域 */}
<div id="container-slot" className={`w-full max-w-6xl ${props?.post && ' lg:max-w-3xl 2xl:max-w-4xl '} mt-6 px-3 mx-auto lg:flex lg:space-x-4 justify-center relative z-10`}>
<div id="container-slot" className={`w-full max-w-6xl ${props?.post && ' lg:max-w-3xl 2xl:max-w-4xl '} mt-6 px-3 mx-auto lg:flex lg:space-x-4 justify-center relative z-10`}>
{props.containerSlot}
</div>

View File

@@ -89,7 +89,7 @@ export const LayoutSearch = props => {
</>}
{currentSearch && <>
<div id="container">
<div id="posts-wrapper">
{BLOG.POST_LIST_STYLE === 'page' ? <BlogPostListPage {...props} /> : <BlogPostListScroll {...props} />}
</div>
</>}

View File

@@ -54,7 +54,7 @@ export const LayoutSlug = props => {
<div className="-mt-32 transition-all duration-300 rounded-md mx-3 lg:border lg:rounded-xl lg:py-4 bg-white dark:bg-hexo-black-gray dark:border-black">
{lock && <ArticleLock validPassword={validPassword} />}
{!lock && <div id="container" className="overflow-x-auto md:w-full px-3 ">
{!lock && <div id="article-wrapper" className="overflow-x-auto md:w-full px-3 ">
{post?.type && post?.type === 'Post' && <>
<div
data-aos="fade-down"
@@ -70,7 +70,7 @@ export const LayoutSlug = props => {
<div className='lg:px-10 subpixel-antialiased'>
<article itemScope >
{/* Notion文章主体 */}
<section id='notion-article' className='justify-center mx-auto max-w-2xl lg:max-w-full'>
<section className='justify-center mx-auto max-w-2xl lg:max-w-full'>
{post && <NotionPage post={post} />}
</section>

View File

@@ -5,7 +5,7 @@ const NotionPage = dynamic(() => import('@/components/NotionPage'))
const Announcement = ({ notice }) => {
const { locale } = useGlobal()
if (!notice) {
if (!notice || Object.keys(notice).length === 0) {
return <></>
}
return <div className="px-3 w-full">

View File

@@ -28,7 +28,7 @@ export const ArticleLock = props => {
passwordInputRef.current.focus()
}, [])
return <div id='container' className='w-full flex justify-center items-center h-96 '>
return <div id='article-wrapper' className='w-full flex justify-center items-center h-96 '>
<div className='text-center space-y-3 dark:text-gray-300 text-black'>
<div className='font-bold'>{locale.COMMON.ARTICLE_LOCK_TIPS}</div>
<div className='flex mx-4'>

View File

@@ -18,7 +18,7 @@ const BlogPostListPage = ({ page = 1, posts = [], postCount, siteInfo }) => {
return <BlogPostListEmpty />
} else {
return (
<div id="container" className='w-full'>
<div className='w-full'>
<div className='pt-6'></div>
{/* 文章列表 */}
<div className="pt-4 flex flex-wrap pb-12" >

View File

@@ -11,7 +11,7 @@ const Progress = ({ targetRef, showPercent = true }) => {
const [percent, changePercent] = useState(0)
const scrollListener = () => {
requestAnimationFrame(() => {
const target = currentRef || (isBrowser() && document.getElementById('container'))
const target = currentRef || (isBrowser() && document.getElementById('article-wrapper'))
if (target) {
const clientHeight = target.clientHeight
const scrollY = window.pageYOffset

View File

@@ -19,7 +19,7 @@ export const LayoutSearch = (props) => {
useEffect(() => {
setTimeout(() => {
const container = isBrowser() && document.getElementById('container')
const container = isBrowser() && document.getElementById('posts-wrapper')
if (container && container.innerHTML) {
const re = new RegExp(currentSearch, 'gim')
const instance = new Mark(container)

View File

@@ -39,7 +39,7 @@ export const LayoutSlug = props => {
{/* 文章锁 */}
{lock && <ArticleLock validPassword={validPassword} />}
{!lock && <div id='container'>
{!lock && <div id='article-wrapper'>
{/* title */}
<h1 className="text-3xl pt-12 dark:text-gray-300">{post?.title}</h1>
@@ -67,7 +67,7 @@ export const LayoutSlug = props => {
</section>
{/* Notion文章主体 */}
<section id="notion-article" className="px-1 max-w-4xl">
<section className="px-1 max-w-4xl">
{post && (<NotionPage post={post} />)}
</section>

View File

@@ -20,7 +20,7 @@ const BlogPostListPage = ({ page = 1, posts = [], postCount }) => {
return (
<div className='w-full justify-center'>
<div id='container'>
<div id='posts-wrapper'>
{/* 文章列表 */}
{posts?.map(post => (
<BlogPostCard key={post.id} post={post} />

View File

@@ -61,7 +61,7 @@ const BlogPostListScroll = ({ posts = [], currentSearch }) => {
if (!postsToShow || postsToShow.length === 0) {
return <BlogPostListEmpty currentSearch={currentSearch} />
} else {
return <div id='container' ref={targetRef} className='w-full'>
return <div id='posts-wrapper' ref={targetRef} className='w-full'>
{/* 文章列表 */}
<div className='space-y-1 lg:space-y-4'>

View File

@@ -10,7 +10,7 @@ const Progress = ({ targetRef, showPercent = true }) => {
const currentRef = targetRef?.current || targetRef
const [percent, changePercent] = useState(0)
const scrollListener = () => {
const target = currentRef || (isBrowser() && document.getElementById('container'))
const target = currentRef || (isBrowser() && document.getElementById('article-wrapper'))
if (target) {
const clientHeight = target.clientHeight
const scrollY = window.pageYOffset

View File

@@ -8,7 +8,7 @@ export const Layout404 = props => {
useEffect(() => {
// 延时3秒如果加载失败就返回首页
setTimeout(() => {
const article = isBrowser() && document.getElementById('container')
const article = isBrowser() && document.getElementById('article-wrapper')
if (!article) {
router.push('/').then(() => {
// console.log('找不到页面', router.asPath)

View File

@@ -11,7 +11,7 @@ export const LayoutSearch = (props) => {
const { locale } = useGlobal()
const { posts, keyword } = props
setTimeout(() => {
const container = isBrowser() && document.getElementById('container')
const container = isBrowser() && document.getElementById('posts-wrapper')
if (container && container.innerHTML) {
const re = new RegExp(keyword, 'gim')
const instance = new Mark(container)

View File

@@ -12,7 +12,7 @@ import { isBrowser } from '@/lib/utils'
export const LayoutSlug = (props) => {
const { post, latestPosts, lock, validPassword } = props
const drawerRight = useRef(null)
const targetRef = isBrowser() ? document.getElementById('container') : null
const targetRef = isBrowser() ? document.getElementById('article-wrapper') : null
const floatSlot = post?.toc?.length > 1
? <div className='block lg:hidden'><TocDrawerButton onClick={() => {
drawerRight?.current?.handleSwitchVisible()

View File

@@ -25,7 +25,7 @@ export default function ArticleDetail(props) {
const showArticleInfo = CONFIG_NEXT.ARTICLE_INFO
return (
<div id="container"
<div id="article-wrapper"
className="shadow md:hover:shadow-2xl overflow-x-auto flex-grow mx-auto w-screen md:w-full ">
<div itemScope itemType="https://schema.org/Movie"
data-aos="fade-down"
@@ -77,7 +77,7 @@ export default function ArticleDetail(props) {
</header>}
{/* Notion内容主体 */}
<article id='notion-article' className='px-1 max-w-3xl mx-auto'>
<article className='px-1 max-w-3xl mx-auto'>
{post && (<NotionPage post={post} />)}
</article>

View File

@@ -30,7 +30,7 @@ export const ArticleLock = props => {
}, [])
return (
<div id='container' className="shadow md:hover:shadow-2xl overflow-x-auto flex-grow mx-auto w-screen md:w-full py-10 px-5 lg:pt-24 md:px-24 min-h-screen dark:border-gray-700 bg-white dark:bg-gray-800 duration-200">
<div id='article-wrapper' className="shadow md:hover:shadow-2xl overflow-x-auto flex-grow mx-auto w-screen md:w-full py-10 px-5 lg:pt-24 md:px-24 min-h-screen dark:border-gray-700 bg-white dark:bg-gray-800 duration-200">
<div className="w-full flex justify-center items-center h-96 font-sans">
<div className="text-center space-y-3 dark:text-gray-300 text-black">
<div className='font-bold'>{locale.COMMON.ARTICLE_LOCK_TIPS}</div>

View File

@@ -20,7 +20,7 @@ const BlogPostListPage = ({ page = 1, posts = [], postCount }) => {
return (
<div>
{/* 文章列表 */}
<div id="container" className="flex flex-wrap lg:space-y-4 space-y-1">
<div id="posts-wrapper" className="flex flex-wrap lg:space-y-4 space-y-1">
{posts?.map(post => (
<BlogPostCard key={post.id} post={post} />
))}

View File

@@ -55,7 +55,7 @@ const BlogPostListScroll = ({ posts = [], currentSearch, showSummary = CONFIG_NE
return <div ref={targetRef}>
{/* 文章列表 */}
<div id='container' className='flex flex-wrap space-y-1 lg:space-y-4'>
<div id='posts-wrapper' className='flex flex-wrap space-y-1 lg:space-y-4'>
{postsToShow.map(post => (
<BlogPostCard key={post.id} post={post} showSummary={showSummary} />
))}

View File

@@ -10,7 +10,7 @@ const Progress = ({ targetRef, showPercent = true }) => {
const currentRef = targetRef?.current || targetRef
const [percent, changePercent] = useState(0)
const scrollListener = () => {
const target = currentRef || (isBrowser() && document.getElementById('container'))
const target = currentRef || (isBrowser() && document.getElementById('article-wrapper'))
if (target) {
const clientHeight = target.clientHeight
const scrollY = window.pageYOffset

View File

@@ -15,7 +15,7 @@ export const LayoutSearch = props => {
useEffect(() => {
setTimeout(() => {
const container = isBrowser() && document.getElementById('container')
const container = isBrowser() && document.getElementById('posts-wrapper')
if (container && container.innerHTML) {
const re = new RegExp(keyword, 'gim')
const instance = new Mark(container)

View File

@@ -18,7 +18,7 @@ export const LayoutSlug = props => {
{lock && <ArticleLock validPassword={validPassword} />}
{!lock && <div id="notion-article" className="px-2">
{!lock && <div id="article-wrapper" className="px-2">
<>
<ArticleInfo post={post} />
<NotionPage post={post} />

View File

@@ -19,7 +19,7 @@ export const BlogListPage = props => {
return (
<div className="w-full md:pr-12 mb-12">
<div id="container">
<div id="posts-wrapper">
{posts?.map(post => (
<BlogPost key={post.id} post={post}/>
))}

View File

@@ -44,7 +44,7 @@ export const BlogListScroll = props => {
})
return (
<div id="container" className="w-full md:pr-12 mb-12" ref={targetRef}>
<div id="posts-wrapper" className="w-full md:pr-12 mb-12" ref={targetRef}>
{postsToShow.map(p => (
<article key={p.id} className="mb-12" >
<h2 className="mb-4">
@@ -78,5 +78,5 @@ export const BlogListScroll = props => {
</div>
</div>
);
)
}

View File

@@ -13,7 +13,7 @@ export const LayoutSearch = props => {
useEffect(() => {
setTimeout(() => {
const container = isBrowser() && document.getElementById('container')
const container = isBrowser() && document.getElementById('posts-wrapper')
if (container && container.innerHTML) {
const re = new RegExp(keyword, 'gim')
const instance = new Mark(container)

View File

@@ -15,7 +15,7 @@ export const LayoutSlug = props => {
{lock && <ArticleLock validPassword={validPassword} />}
<div id="notion-article" className="px-2 xl:max-w-4xl 2xl:max-w-6xl ">
<div id="article-wrapper" className="px-2 xl:max-w-4xl 2xl:max-w-6xl ">
<ArticleInfo post={post} />

View File

@@ -18,7 +18,7 @@ export const BlogListPage = props => {
return (
<div className="w-full md:pr-8 mb-12">
<div id="container">
<div id="posts-wrapper">
{posts?.map((p, index) => (<div key={p.id}>
{(index + 1) % 3 === 0 && <AdSlot type='in-article' />}
{ (index + 1) === 4 && <AdSlot type='flow'/>}

View File

@@ -44,7 +44,7 @@ export const BlogListScroll = props => {
})
return (
<div id="container" className="w-full md:pr-8 mb-12" ref={targetRef}>
<div id="posts-wrapper" className="w-full md:pr-8 mb-12" ref={targetRef}>
{postsToShow.map(p => (
<BlogItem key={p.id} post={p}/>
))}