theme-landing

This commit is contained in:
tangly1024
2023-07-02 20:54:34 +08:00
parent ea79f36f93
commit 95ace17914
23 changed files with 2180 additions and 44 deletions

View File

@@ -326,7 +326,7 @@ const BLOG = {
AVATAR: process.env.NEXT_PUBLIC_AVATAR || '/avatar.svg', // 作者头像被notion中的ICON覆盖。若无ICON则取public目录下的avatar.png
TITLE: process.env.NEXT_PUBLIC_TITLE || 'NotionNext BLOG', // 站点标题 被notion中的页面标题覆盖此处请勿留空白否则服务器无法编译
HOME_BANNER_IMAGE:
process.env.NEXT_PUBLIC_HOME_BANNER_IMAGE || './bg_image.jpg', // 首页背景大图, 会被notion中的封面图覆盖若无封面图则会使用代码中的 /public/bg_image.jpg 文件
process.env.NEXT_PUBLIC_HOME_BANNER_IMAGE || '/bg_image.jpg', // 首页背景大图, 会被notion中的封面图覆盖若无封面图则会使用代码中的 /public/bg_image.jpg 文件
DESCRIPTION:
process.env.NEXT_PUBLIC_DESCRIPTION || '这是一个由NotionNext生成的站点', // 站点描述被notion中的页面描述覆盖

View File

@@ -14,4 +14,16 @@ const Sun = () => {
<path strokeLinecap="round" strokeLinejoin="round" d="M12 3v2.25m6.364.386l-1.591 1.591M21 12h-2.25m-.386 6.364l-1.591-1.591M12 18.75V21m-4.773-4.227l-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0z" />
</svg>
}
export { Moon, Sun }
const Home = ({ className }) => {
return <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className={className}>
<path strokeLinecap="round" strokeLinejoin="round" d="M2.25 12l8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25" />
</svg>
}
const User = ({ className }) => {
return <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className={className}>
<path strokeLinecap="round" strokeLinejoin="round" d="M17.982 18.725A7.488 7.488 0 0012 15.75a7.488 7.488 0 00-5.982 2.975m11.963 0a9 9 0 10-11.963 0m11.963 0A8.966 8.966 0 0112 21a8.966 8.966 0 01-5.982-2.275M15 9.75a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
}
export { Moon, Sun, Home, User }

View File

@@ -22,6 +22,7 @@
},
"dependencies": {
"@giscus/react": "^2.2.6",
"@headlessui/react": "^1.7.15",
"@next/bundle-analyzer": "^12.1.1",
"@vercel/analytics": "^1.0.0",
"animate.css": "^4.1.1",

BIN
public/bg_image.jpg Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

BIN
public/videos/video.mp4 Normal file

Binary file not shown.

View File

@@ -333,18 +333,17 @@ a.avatar-wrapper {
}
}
.notion-external-title {
@apply dark:text-white !important;
/* Buttons */
.btn,
.btn-sm {
@apply font-medium inline-flex items-center justify-center border border-transparent rounded leading-snug transition duration-150 ease-in-out;
}
.notion-external-subtitle {
@apply dark:text-gray-400 !important;
.btn {
@apply px-8 py-3 shadow-lg;
}
.notion-external-block {
@apply dark:border-gray-200 !important;
}
.notion-external-image > svg > g > path{
@apply dark:fill-gray-200 !important;
.btn-sm {
@apply px-4 py-2 shadow;
}

View File

@@ -2026,3 +2026,20 @@ code.language-mermaid {
.notion-equation-inline .katex-display {
margin: 0 0 !important;
}
.notion-external-title {
@apply dark:text-white !important;
}
.notion-external-subtitle {
@apply dark:text-gray-400 !important;
}
.notion-external-block {
@apply dark:border-gray-200 !important;
}
.notion-external-image > svg > g > path{
@apply dark:fill-gray-200 !important;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,168 @@
'use client'
import { useState, useRef, useEffect } from 'react'
import { Transition } from '@headlessui/react'
import Image from 'next/image'
import FeaturesBg from '@/public/images/features-bg.png'
import FeaturesElement from '@/public/images/features-element.png'
export default function Features() {
const [tab, setTab] = useState(1)
const tabs = useRef(null)
const heightFix = () => {
if (tabs.current && tabs.current.parentElement) tabs.current.parentElement.style.height = `${tabs.current.clientHeight}px`
}
useEffect(() => {
heightFix()
}, [])
return (
<section className="relative">
{/* Section background (needs .relative class on parent and next sibling elements) */}
<div className="absolute inset-0 bg-gray-100 pointer-events-none mb-16" aria-hidden="true"></div>
<div className="absolute left-0 right-0 m-auto w-px p-px h-20 bg-gray-200 transform -translate-y-1/2"></div>
<div className="relative max-w-6xl mx-auto px-4 sm:px-6">
<div className="pt-12 md:pt-20">
{/* Section header */}
<div className="max-w-3xl mx-auto text-center pb-12 md:pb-16">
<h1 className="h2 mb-4">Explore the solutions</h1>
<p className="text-xl text-gray-600">Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur excepteur sint occaecat cupidatat.</p>
</div>
{/* Section content */}
<div className="md:grid md:grid-cols-12 md:gap-6">
{/* Content */}
<div className="max-w-xl md:max-w-none md:w-full mx-auto md:col-span-7 lg:col-span-6 md:mt-6" data-aos="fade-right">
<div className="md:pr-4 lg:pr-12 xl:pr-16 mb-8">
<h3 className="h3 mb-3">Powerful suite of tools</h3>
<p className="text-xl text-gray-600">Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa.</p>
</div>
{/* Tabs buttons */}
<div className="mb-8 md:mb-0">
<a
className={`flex items-center text-lg p-5 rounded border transition duration-300 ease-in-out mb-3 ${tab !== 1 ? 'bg-white shadow-md border-gray-200 hover:shadow-lg' : 'bg-gray-200 border-transparent'}`}
href="#0"
onClick={(e) => { e.preventDefault(); setTab(1) }}
>
<div>
<div className="font-bold leading-snug tracking-tight mb-1">Building the Simple ecosystem</div>
<div className="text-gray-600">Take collaboration to the next level with security and administrative features built for teams.</div>
</div>
<div className="flex justify-center items-center w-8 h-8 bg-white rounded-full shadow flex-shrink-0 ml-3">
<svg className="w-3 h-3 fill-current" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
<path d="M11.953 4.29a.5.5 0 00-.454-.292H6.14L6.984.62A.5.5 0 006.12.173l-6 7a.5.5 0 00.379.825h5.359l-.844 3.38a.5.5 0 00.864.445l6-7a.5.5 0 00.075-.534z" />
</svg>
</div>
</a>
<a
className={`flex items-center text-lg p-5 rounded border transition duration-300 ease-in-out mb-3 ${tab !== 2 ? 'bg-white shadow-md border-gray-200 hover:shadow-lg' : 'bg-gray-200 border-transparent'}`}
href="#0"
onClick={(e) => { e.preventDefault(); setTab(2) }}
>
<div>
<div className="font-bold leading-snug tracking-tight mb-1">Building the Simple ecosystem</div>
<div className="text-gray-600">Take collaboration to the next level with security and administrative features built for teams.</div>
</div>
<div className="flex justify-center items-center w-8 h-8 bg-white rounded-full shadow flex-shrink-0 ml-3">
<svg className="w-3 h-3 fill-current" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
<path d="M11.854.146a.5.5 0 00-.525-.116l-11 4a.5.5 0 00-.015.934l4.8 1.921 1.921 4.8A.5.5 0 007.5 12h.008a.5.5 0 00.462-.329l4-11a.5.5 0 00-.116-.525z" fillRule="nonzero" />
</svg>
</div>
</a>
<a
className={`flex items-center text-lg p-5 rounded border transition duration-300 ease-in-out mb-3 ${tab !== 3 ? 'bg-white shadow-md border-gray-200 hover:shadow-lg' : 'bg-gray-200 border-transparent'}`}
href="#0"
onClick={(e) => { e.preventDefault(); setTab(3) }}
>
<div>
<div className="font-bold leading-snug tracking-tight mb-1">Building the Simple ecosystem</div>
<div className="text-gray-600">Take collaboration to the next level with security and administrative features built for teams.</div>
</div>
<div className="flex justify-center items-center w-8 h-8 bg-white rounded-full shadow flex-shrink-0 ml-3">
<svg className="w-3 h-3 fill-current" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
<path d="M11.334 8.06a.5.5 0 00-.421-.237 6.023 6.023 0 01-5.905-6c0-.41.042-.82.125-1.221a.5.5 0 00-.614-.586 6 6 0 106.832 8.529.5.5 0 00-.017-.485z" fill="#191919" fillRule="nonzero" />
</svg>
</div>
</a>
</div>
</div>
{/* Tabs items */}
<div className="max-w-xl md:max-w-none md:w-full mx-auto md:col-span-5 lg:col-span-6 mb-8 md:mb-0 md:order-1">
<div className="transition-all">
<div className="relative flex flex-col text-center lg:text-right" data-aos="zoom-y-out" ref={tabs}>
{/* Item 1 */}
<Transition
show={tab === 1}
appear={true}
className="w-full"
enter="transition ease-in-out duration-700 transform order-first"
enterFrom="opacity-0 translate-y-16"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in-out duration-300 transform absolute"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 -translate-y-16"
beforeEnter={() => heightFix()}
unmount={false}
>
<div className="relative inline-flex flex-col">
<Image className="md:max-w-none mx-auto rounded" src={FeaturesBg} width={500} height="462" alt="Features bg" />
<Image className="md:max-w-none absolute w-full left-0 transform animate-float" src={FeaturesElement} width={500} height="44" alt="Element" style={{ top: '30%' }} />
</div>
</Transition>
{/* Item 2 */}
<Transition
show={tab === 2}
appear={true}
className="w-full"
enter="transition ease-in-out duration-700 transform order-first"
enterFrom="opacity-0 translate-y-16"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in-out duration-300 transform absolute"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 -translate-y-16"
beforeEnter={() => heightFix()}
unmount={false}
>
<div className="relative inline-flex flex-col">
<Image className="md:max-w-none mx-auto rounded" src={FeaturesBg} width={500} height="462" alt="Features bg" />
<Image className="md:max-w-none absolute w-full left-0 transform animate-float" src={FeaturesElement} width={500} height="44" alt="Element" style={{ top: '30%' }} />
</div>
</Transition>
{/* Item 3 */}
<Transition
show={tab === 3}
appear={true}
className="w-full"
enter="transition ease-in-out duration-700 transform order-first"
enterFrom="opacity-0 translate-y-16"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in-out duration-300 transform absolute"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 -translate-y-16"
beforeEnter={() => heightFix()}
unmount={false}
>
<div className="relative inline-flex flex-col">
<Image className="md:max-w-none mx-auto rounded" src={FeaturesBg} width={500} height="462" alt="Features bg" />
<Image className="md:max-w-none absolute w-full left-0 transform animate-float" src={FeaturesElement} width={500} height="44" alt="Element" style={{ top: '30%' }} />
</div>
</Transition>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
)
}

View File

@@ -0,0 +1,125 @@
export default function FeaturesBlocks() {
return (
<section className="relative">
{/* Section background (needs .relative class on parent and next sibling elements) */}
<div className="absolute inset-0 top-1/2 md:mt-24 lg:mt-0 bg-gray-900 pointer-events-none" aria-hidden="true"></div>
<div className="absolute left-0 right-0 bottom-0 m-auto w-px p-px h-20 bg-gray-200 transform translate-y-1/2"></div>
<div className="relative max-w-6xl mx-auto px-4 sm:px-6">
<div className="py-12 md:py-20">
{/* Section header */}
<div className="max-w-3xl mx-auto text-center pb-12 md:pb-20">
<h2 className="h2 mb-4">Explore the solutions</h2>
<p className="text-xl text-gray-600">Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur excepteur sint occaecat cupidatat.</p>
</div>
{/* Items */}
<div className="max-w-sm mx-auto grid gap-6 md:grid-cols-2 lg:grid-cols-3 items-start md:max-w-2xl lg:max-w-none">
{/* 1st item */}
<div className="relative flex flex-col items-center p-6 bg-white rounded shadow-xl">
<svg className="w-16 h-16 p-1 -mt-1 mb-2" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fillRule="evenodd">
<rect className="fill-current text-blue-600" width="64" height="64" rx="32" />
<g strokeWidth="2">
<path className="stroke-current text-blue-300" d="M34.514 35.429l2.057 2.285h8M20.571 26.286h5.715l2.057 2.285" />
<path className="stroke-current text-white" d="M20.571 37.714h5.715L36.57 26.286h8" />
<path className="stroke-current text-blue-300" strokeLinecap="square" d="M41.143 34.286l3.428 3.428-3.428 3.429" />
<path className="stroke-current text-white" strokeLinecap="square" d="M41.143 29.714l3.428-3.428-3.428-3.429" />
</g>
</g>
</svg>
<h4 className="text-xl font-bold leading-snug tracking-tight mb-1">Headless CMS</h4>
<p className="text-gray-600 text-center">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
{/* 2nd item */}
<div className="relative flex flex-col items-center p-6 bg-white rounded shadow-xl">
<svg className="w-16 h-16 p-1 -mt-1 mb-2" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fillRule="evenodd">
<rect className="fill-current text-blue-600" width="64" height="64" rx="32" />
<g strokeWidth="2" transform="translate(19.429 20.571)">
<circle className="stroke-current text-white" strokeLinecap="square" cx="12.571" cy="12.571" r="1.143" />
<path className="stroke-current text-white" d="M19.153 23.267c3.59-2.213 5.99-6.169 5.99-10.696C25.143 5.63 19.514 0 12.57 0 5.63 0 0 5.629 0 12.571c0 4.527 2.4 8.483 5.99 10.696" />
<path className="stroke-current text-blue-300" d="M16.161 18.406a6.848 6.848 0 003.268-5.835 6.857 6.857 0 00-6.858-6.857 6.857 6.857 0 00-6.857 6.857 6.848 6.848 0 003.268 5.835" />
</g>
</g>
</svg>
<h4 className="text-xl font-bold leading-snug tracking-tight mb-1">Headless CMS</h4>
<p className="text-gray-600 text-center">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
{/* 3rd item */}
<div className="relative flex flex-col items-center p-6 bg-white rounded shadow-xl">
<svg className="w-16 h-16 p-1 -mt-1 mb-2" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fillRule="evenodd">
<rect className="fill-current text-blue-600" width="64" height="64" rx="32" />
<g strokeWidth="2">
<path className="stroke-current text-blue-300" d="M34.743 29.714L36.57 32 27.43 43.429H24M24 20.571h3.429l1.828 2.286" />
<path className="stroke-current text-white" strokeLinecap="square" d="M34.743 41.143l1.828 2.286H40M40 20.571h-3.429L27.43 32l1.828 2.286" />
<path className="stroke-current text-blue-300" d="M36.571 32H40" />
<path className="stroke-current text-white" d="M24 32h3.429" strokeLinecap="square" />
</g>
</g>
</svg>
<h4 className="text-xl font-bold leading-snug tracking-tight mb-1">Headless CMS</h4>
<p className="text-gray-600 text-center">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
{/* 4th item */}
<div className="relative flex flex-col items-center p-6 bg-white rounded shadow-xl">
<svg className="w-16 h-16 p-1 -mt-1 mb-2" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fillRule="evenodd">
<rect className="fill-current text-blue-600" width="64" height="64" rx="32" />
<g strokeWidth="2">
<path className="stroke-current text-white" d="M32 37.714A5.714 5.714 0 0037.714 32a5.714 5.714 0 005.715 5.714" />
<path className="stroke-current text-white" d="M32 37.714a5.714 5.714 0 015.714 5.715 5.714 5.714 0 015.715-5.715M20.571 26.286a5.714 5.714 0 005.715-5.715A5.714 5.714 0 0032 26.286" />
<path className="stroke-current text-white" d="M20.571 26.286A5.714 5.714 0 0126.286 32 5.714 5.714 0 0132 26.286" />
<path className="stroke-current text-blue-300" d="M21.714 40h4.572M24 37.714v4.572M37.714 24h4.572M40 21.714v4.572" strokeLinecap="square" />
</g>
</g>
</svg>
<h4 className="text-xl font-bold leading-snug tracking-tight mb-1">Headless CMS</h4>
<p className="text-gray-600 text-center">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
{/* 5th item */}
<div className="relative flex flex-col items-center p-6 bg-white rounded shadow-xl">
<svg className="w-16 h-16 p-1 -mt-1 mb-2" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fillRule="evenodd">
<rect className="fill-current text-blue-600" width="64" height="64" rx="32" />
<g strokeWidth="2">
<path className="stroke-current text-white" d="M19.429 32a12.571 12.571 0 0021.46 8.89L23.111 23.11A12.528 12.528 0 0019.429 32z" />
<path className="stroke-current text-blue-300" d="M32 19.429c6.943 0 12.571 5.628 12.571 12.571M32 24a8 8 0 018 8" />
<path className="stroke-current text-white" d="M34.286 29.714L32 32" />
</g>
</g>
</svg>
<h4 className="text-xl font-bold leading-snug tracking-tight mb-1">Headless CMS</h4>
<p className="text-gray-600 text-center">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
{/* 6th item */}
<div className="relative flex flex-col items-center p-6 bg-white rounded shadow-xl">
<svg className="w-16 h-16 p-1 -mt-1 mb-2" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fillRule="evenodd">
<rect className="fill-current text-blue-600" width="64" height="64" rx="32" />
<g strokeWidth="2" strokeLinecap="square">
<path className="stroke-current text-white" d="M29.714 40.358l-4.777 2.51 1.349-7.865-5.715-5.57 7.898-1.147L32 21.13l3.531 7.155 7.898 1.147L40 32.775" />
<path className="stroke-current text-blue-300" d="M44.571 43.429H34.286M44.571 37.714H34.286" />
</g>
</g>
</svg>
<h4 className="text-xl font-bold leading-snug tracking-tight mb-1">Headless CMS</h4>
<p className="text-gray-600 text-center">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
</div>
</div>
</div>
</section>
)
}

View File

@@ -0,0 +1,149 @@
import Logo from './Logo'
export default function Footer() {
return (
<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">
{/* 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>
{/* 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>
{/* 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>
{/* 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>
{/* 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">
{/* 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">
<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>
{/* Copyrights note */}
<div className="text-sm text-gray-600 mr-4">&copy; Cruip.com. All rights reserved.</div>
</div>
</div>
</footer>
)
}

View File

@@ -0,0 +1,58 @@
'use client'
import { useState, useEffect } from 'react'
import Link from 'next/link'
import Logo from './Logo'
import MobileMenu from './MobileMenu'
export default function Header() {
const [top, setTop] = useState(true)
// detect whether user has scrolled the page down by 10px
const scrollHandler = () => {
window.pageYOffset > 10 ? setTop(false) : setTop(true)
}
useEffect(() => {
scrollHandler()
window.addEventListener('scroll', scrollHandler)
return () => window.removeEventListener('scroll', scrollHandler)
}, [top])
return (
<header className={`fixed w-full z-30 md:bg-opacity-90 transition duration-300 ease-in-out ${!top ? 'bg-white backdrop-blur-sm shadow-lg' : ''}`}>
<div className="max-w-6xl mx-auto px-5 sm:px-6">
<div className="flex items-center justify-between h-16 md:h-20">
{/* Site branding */}
<div className="shrink-0 mr-4">
<Logo />
</div>
{/* Desktop navigation */}
<nav className="hidden md:flex md:grow">
{/* Desktop sign in links */}
<ul className="flex grow justify-end flex-wrap items-center">
<li>
<Link href="/signin" className="font-medium text-gray-600 hover:text-gray-900 px-5 py-3 flex items-center transition duration-150 ease-in-out">Sign in</Link>
</li>
<li>
<Link href="/signup" className="btn-sm text-gray-200 bg-gray-900 hover:bg-gray-800 ml-3">
<span>Sign up</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" />
</svg>
</Link>
</li>
</ul>
</nav>
<MobileMenu />
</div>
</div>
</header>
)
}

View File

@@ -0,0 +1,60 @@
import ModalVideo from './ModalVideo'
export default function Hero() {
return (
<section className="relative">
{/* Illustration behind hero content */}
<div className="absolute left-1/2 transform -translate-x-1/2 bottom-0 pointer-events-none -z-1" aria-hidden="true">
<svg width="1360" height="578" viewBox="0 0 1360 578" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="illustration-01">
<stop stopColor="#FFF" offset="0%" />
<stop stopColor="#EAEAEA" offset="77.402%" />
<stop stopColor="#DFDFDF" offset="100%" />
</linearGradient>
</defs>
<g fill="url(#illustration-01)" fillRule="evenodd">
<circle cx="1232" cy="128" r="128" />
<circle cx="155" cy="443" r="64" />
</g>
</svg>
</div>
<div className="max-w-6xl mx-auto px-4 sm:px-6">
{/* Hero content */}
<div className="pt-32 pb-12 md:pt-40 md:pb-20">
{/* Section header */}
<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">Make your website <span className="bg-clip-text text-transparent bg-gradient-to-r from-blue-500 to-teal-400">wonderful</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">Our landing page template works on all devices, so you only have to set it up once, and get beautiful results forever.</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="#0">Start free trial</a>
</div>
<div>
<a className="btn text-white bg-gray-900 hover:bg-gray-800 w-full sm:w-auto sm:ml-4" href="#0">Learn more</a>
</div>
</div>
</div>
</div>
{/* Hero image */}
<ModalVideo
thumb={'/bg_image.jpg'}
thumbWidth={768}
thumbHeight={432}
thumbAlt="Modal video thumbnail"
video="/videos/video.mp4"
videoWidth={1920}
videoHeight={1080} />
</div>
</div>
</section>
)
}

View File

@@ -0,0 +1,18 @@
import Link from 'next/link'
export default function Logo() {
return (
<Link href="/" className="block" aria-label="Cruip">
<svg className="w-8 h-8" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient cx="21.152%" cy="86.063%" fx="21.152%" fy="86.063%" r="79.941%" id="footer-logo">
<stop stopColor="#4FD1C5" offset="0%" />
<stop stopColor="#81E6D9" offset="25.871%" />
<stop stopColor="#338CF5" offset="100%" />
</radialGradient>
</defs>
<rect width="32" height="32" rx="16" fill="url(#footer-logo)" fillRule="nonzero" />
</svg>
</Link>
)
}

View File

@@ -0,0 +1,83 @@
'use client'
import { useState, useRef, useEffect } from 'react'
import { Transition } from '@headlessui/react'
import Link from 'next/link'
export default function MobileMenu() {
const [mobileNavOpen, setMobileNavOpen] = useState(false)
const trigger = useRef(null)
const mobileNav = useRef(null)
// close the mobile menu on click outside
useEffect(() => {
const clickHandler = ({ target }) => {
if (!mobileNav.current || !trigger.current) return
if (!mobileNavOpen || mobileNav.current.contains(target) || trigger.current.contains(target)) return
setMobileNavOpen(false)
}
document.addEventListener('click', clickHandler)
return () => document.removeEventListener('click', clickHandler)
})
// close the mobile menu if the esc key is pressed
useEffect(() => {
const keyHandler = ({ keyCode }) => {
if (!mobileNavOpen || keyCode !== 27) return
setMobileNavOpen(false)
}
document.addEventListener('keydown', keyHandler)
return () => document.removeEventListener('keydown', keyHandler)
})
return (
<div className="flex md:hidden">
{/* Hamburger button */}
<button
ref={trigger}
className={`hamburger ${mobileNavOpen && 'active'}`}
aria-controls="mobile-nav"
aria-expanded={mobileNavOpen}
onClick={() => setMobileNavOpen(!mobileNavOpen)}
>
<span className="sr-only">Menu</span>
<svg className="w-6 h-6 fill-current text-gray-900" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<rect y="4" width="24" height="2" />
<rect y="11" width="24" height="2" />
<rect y="18" width="24" height="2" />
</svg>
</button>
{/* Mobile navigation */}
<div ref={mobileNav}>
<Transition
show={mobileNavOpen}
as="nav"
id="mobile-nav"
className="absolute top-full h-screen pb-16 z-20 left-0 w-full overflow-scroll bg-white"
enter="transition ease-out duration-200 transform"
enterFrom="opacity-0 -translate-y-2"
enterTo="opacity-100 translate-y-0"
leave="transition ease-out duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<ul className="px-5 py-2">
<li>
<Link href="/signin" className="flex font-medium w-full text-gray-600 hover:text-gray-900 py-2 justify-center" onClick={() => setMobileNavOpen(false)}>Sign in</Link>
</li>
<li>
<Link href="/signup" className="btn-sm text-gray-200 bg-gray-900 hover:bg-gray-800 w-full my-2" onClick={() => setMobileNavOpen(false)}>
<span>Sign up</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" fill="#999" fillRule="nonzero" />
</svg>
</Link>
</li>
</ul>
</Transition>
</div>
</div>
)
}

View File

@@ -0,0 +1,109 @@
'use client'
import { useState, useRef, Fragment } from 'react'
import { Dialog, Transition } from '@headlessui/react'
export default function ModalVideo({
thumb,
thumbWidth,
thumbHeight,
thumbAlt,
video,
videoWidth,
videoHeight
}) {
const [modalOpen, setModalOpen] = useState(false)
const videoRef = useRef(null)
return (
<div>
{/* Video thumbnail */}
<div>
<div className="relative flex justify-center mb-8" data-aos="zoom-y-out" data-aos-delay="450">
<div className="flex flex-col justify-center">
{/* eslint-disable-next-line @next/next/no-img-element */}
<img src={thumb} width={thumbWidth} height={thumbHeight} alt={thumbAlt} />
<svg className="absolute inset-0 max-w-full mx-auto md:max-w-none h-auto" width="768" height="432" viewBox="0 0 768 432" xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="hero-ill-a">
<stop stopColor="#FFF" offset="0%" />
<stop stopColor="#EAEAEA" offset="77.402%" />
<stop stopColor="#DFDFDF" offset="100%" />
</linearGradient>
<linearGradient x1="50%" y1="0%" x2="50%" y2="99.24%" id="hero-ill-b">
<stop stopColor="#FFF" offset="0%" />
<stop stopColor="#EAEAEA" offset="48.57%" />
<stop stopColor="#DFDFDF" stopOpacity="0" offset="100%" />
</linearGradient>
<radialGradient cx="21.152%" cy="86.063%" fx="21.152%" fy="86.063%" r="79.941%" id="hero-ill-e">
<stop stopColor="#4FD1C5" offset="0%" />
<stop stopColor="#81E6D9" offset="25.871%" />
<stop stopColor="#338CF5" offset="100%" />
</radialGradient>
<circle id="hero-ill-d" cx="384" cy="216" r="64" />
</defs>
<g fill="none" fillRule="evenodd">
<circle fillOpacity=".04" fill="url(#hero-ill-a)" cx="384" cy="216" r="128" />
<circle fillOpacity=".16" fill="url(#hero-ill-b)" cx="384" cy="216" r="96" />
<g fillRule="nonzero">
<use fill="#000" xlinkHref="#hero-ill-d" />
<use fill="url(#hero-ill-e)" xlinkHref="#hero-ill-d" />
</g>
</g>
</svg>
</div>
<button className="absolute top-full flex items-center transform -translate-y-1/2 bg-white rounded-full font-medium group p-4 shadow-lg" onClick={() => { setModalOpen(true) }}>
<svg className="w-6 h-6 fill-current text-gray-400 group-hover:text-blue-600 shrink-0" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10zm0 2C5.373 24 0 18.627 0 12S5.373 0 12 0s12 5.373 12 12-5.373 12-12 12z" />
<path d="M10 17l6-5-6-5z" />
</svg>
<span className="ml-3">Watch the full video (2 min)</span>
</button>
</div>
</div>
{/* End: Video thumbnail */}
<Transition show={modalOpen} as={Fragment} afterEnter={() => videoRef.current?.play()}>
<Dialog initialFocus={videoRef} onClose={() => setModalOpen(false)}>
{/* Modal backdrop */}
<Transition.Child
className="fixed inset-0 z-[99999] bg-black bg-opacity-75 transition-opacity"
enter="transition ease-out duration-200"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="transition ease-out duration-100"
leaveFrom="opacity-100"
leaveTo="opacity-0"
aria-hidden="true"
/>
{/* End: Modal backdrop */}
{/* Modal dialog */}
<Transition.Child
className="fixed inset-0 z-[99999] overflow-hidden flex items-center justify-center transform px-4 sm:px-6"
enter="transition ease-out duration-200"
enterFrom="opacity-0 scale-95"
enterTo="opacity-100 scale-100"
leave="ttransition ease-out duration-200"
leaveFrom="oopacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
<div className="max-w-6xl mx-auto h-full flex items-center">
<Dialog.Panel className="w-full max-h-full aspect-video bg-black overflow-hidden">
<video ref={videoRef} width={videoWidth} height={videoHeight} loop controls>
<source src={video} type="video/mp4" />
Your browser does not support the video tag.
</video>
</Dialog.Panel>
</div>
</Transition.Child>
{/* End: Modal dialog */}
</Dialog>
</Transition>
</div>
)
}

View File

@@ -0,0 +1,63 @@
export default function Newsletter() {
return (
<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">
{/* 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">
{/* CTA content */}
<div className="text-center lg:text-left lg:max-w-xl">
<h3 className="h3 text-white mb-2">Want more tutorials & guides?</h3>
<p className="text-gray-300 text-lg mb-6">Lorem ipsum dolor sit amet consectetur adipisicing elit nemo expedita voluptas culpa sapiente.</p>
{/* 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">No spam. You can unsubscribe at any time.</p>
</form>
</div>
</div>
</div>
</div>
</div>
</section>
)
}

File diff suppressed because one or more lines are too long

98
themes/landing/index.js Normal file
View File

@@ -0,0 +1,98 @@
/**
* 这是一个空白主题,方便您用作创建新主题时的模板,从而开发出您自己喜欢的主题
* 1. 禁用了代码质量检查功能提高了代码的宽容度您可以使用标准的html写法
* 2. 内容大部分是在此文件中写死notion数据从props参数中传进来
* 3. 您可在此网站找到更多喜欢的组件 https://www.tailwind-kit.com/
*/
/* eslint-disable*/
import NotionPage from '@/components/NotionPage'
import Header from './components/Header'
import Footer from './components/Footer'
import Hero from './components/Hero'
import Features from './components/Features'
import FeaturesBlocks from './components/FeaturesBlocks'
import Testimonials from './components/Testimonials'
import Newsletter from './components/Newsletter'
/**
* 这是个配置文件,可以方便在此统一配置信息
*/
const THEME_CONFIG = { THEME: 'landing' }
/**
* 布局框架
* 作为一个基础框架使用,定义了整个主题每个页面必备的顶部导航栏和页脚
* 其它页面都嵌入到此框架中使用
* @param {*} props
* @returns
*/
const LayoutBase = (props) => {
const { siteInfo, children } = props
return <div id='theme-blank' className="flex flex-col justify-between bg-white">
{/* 顶部导航栏 */}
<Header />
{/* 内容 */}
<div id='content-wrapper'>
{children}
</div>
{/* 底部页脚 */}
<Footer />
</div>
}
/**
* 首页布局
* @param {*} props
* @returns
*/
const LayoutIndex = (props) => {
const { siteInfo } = props
return (
<LayoutBase {...props}>
<Hero />
<Features />
<FeaturesBlocks />
<Testimonials />
<Newsletter />
</LayoutBase>
)
}
/**
* 文章详情页布局
* @param {*} props
* @returns
*/
const LayoutSlug = (props) => <LayoutBase {...props}>
<div className='p-12'>
<NotionPage {...props} />
</div>
</LayoutBase>
// 其他布局暂时留空
const LayoutSearch = (props) => <LayoutBase {...props}><Hero /></LayoutBase>
const LayoutArchive = (props) => <LayoutBase {...props}><Hero /></LayoutBase>
const Layout404 = (props) => <LayoutBase {...props}><Hero /></LayoutBase>
const LayoutCategory = (props) => <LayoutBase {...props}><Hero /></LayoutBase>
const LayoutCategoryIndex = (props) => <LayoutBase {...props}><Hero /></LayoutBase>
const LayoutPage = (props) => <LayoutBase {...props}><Hero /></LayoutBase>
const LayoutTag = (props) => <LayoutBase {...props}><Hero /></LayoutBase>
const LayoutTagIndex = (props) => <LayoutBase {...props}><Hero /></LayoutBase>
export {
THEME_CONFIG,
LayoutIndex,
LayoutSearch,
LayoutArchive,
LayoutSlug,
Layout404,
LayoutCategory,
LayoutCategoryIndex,
LayoutPage,
LayoutTag,
LayoutTagIndex
}