diff --git a/blog.config.js b/blog.config.js
index c6c9faea..76a161b7 100644
--- a/blog.config.js
+++ b/blog.config.js
@@ -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中的页面描述覆盖
diff --git a/components/HeroIcons.js b/components/HeroIcons.js
index 5578af5d..b4283aaf 100644
--- a/components/HeroIcons.js
+++ b/components/HeroIcons.js
@@ -14,4 +14,16 @@ const Sun = () => {
}
-export { Moon, Sun }
+
+const Home = ({ className }) => {
+ return
+
+
+}
+
+const User = ({ className }) => {
+ return
+
+
+}
+export { Moon, Sun, Home, User }
diff --git a/package.json b/package.json
index 18527c97..d9967502 100644
--- a/package.json
+++ b/package.json
@@ -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",
diff --git a/public/bg_image.jpg b/public/bg_image.jpg
old mode 100755
new mode 100644
index 191b9554..cb503374
Binary files a/public/bg_image.jpg and b/public/bg_image.jpg differ
diff --git a/public/images/features-bg.png b/public/images/features-bg.png
new file mode 100644
index 00000000..c2e77985
Binary files /dev/null and b/public/images/features-bg.png differ
diff --git a/public/images/features-element.png b/public/images/features-element.png
new file mode 100644
index 00000000..9f1bf79b
Binary files /dev/null and b/public/images/features-element.png differ
diff --git a/public/images/hero-image.png b/public/images/hero-image.png
new file mode 100644
index 00000000..522befe4
Binary files /dev/null and b/public/images/hero-image.png differ
diff --git a/public/images/testimonial.jpg b/public/images/testimonial.jpg
new file mode 100644
index 00000000..8eadf88e
Binary files /dev/null and b/public/images/testimonial.jpg differ
diff --git a/public/videos/video.mp4 b/public/videos/video.mp4
new file mode 100644
index 00000000..92686932
Binary files /dev/null and b/public/videos/video.mp4 differ
diff --git a/styles/globals.css b/styles/globals.css
index 042c7f28..fed2254d 100644
--- a/styles/globals.css
+++ b/styles/globals.css
@@ -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;
}
\ No newline at end of file
diff --git a/styles/notion.css b/styles/notion.css
index b9e10f4c..8e999ad6 100644
--- a/styles/notion.css
+++ b/styles/notion.css
@@ -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;
+}
+
diff --git a/themes/blank/index.js b/themes/blank/index.js
index e12ee9ba..92d3d9af 100644
--- a/themes/blank/index.js
+++ b/themes/blank/index.js
@@ -1,57 +1,1130 @@
/**
- * 这是一个空白主题的示例
+ * 这是一个空白主题,方便您用作创建新主题时的模板,从而开发出您自己喜欢的主题
+ * 1. 禁用了代码质量检查功能,提高了代码的宽容度;您可以使用标准的html写法
+ * 2. 内容大部分是在此文件中写死,notion数据从props参数中传进来
+ * 3. 您可在此网站找到更多喜欢的组件 https://www.tailwind-kit.com/
+ */
+/* eslint-disable*/
+import BLOG from '@/blog.config'
+import DarkModeButton from '@/components/DarkModeButton'
+import NotionPage from '@/components/NotionPage'
+import Link from 'next/link'
+import { useState } from 'react'
+
+/**
+ * 这是个配置文件,可以方便在此统一配置信息
*/
const THEME_CONFIG = { THEME: 'blank' }
+
+
/**
- * 主题框架
+ * 布局框架
+ * 作为一个基础框架使用,定义了整个主题每个页面必备的顶部导航栏和页脚
+ * 其它页面都嵌入到此框架中使用
* @param {*} props
* @returns
*/
const LayoutBase = (props) => {
- const { children } = props
- return
-
+ const { siteInfo, children } = props
+ return
+ {/* 顶部导航栏 */}
+
+
+ {/* 内容 */}
{children}
+ {/* 底部页脚 */}
+
}
+
/**
* 首页布局
* @param {*} props
* @returns
*/
const LayoutIndex = (props) => {
- return
- hero-page
-
+ const { siteInfo } = props
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ )
}
-const LayoutSearch = () => <>>
-const LayoutArchive = () => <>>
-const LayoutSlug = () => <>>
-const Layout404 = () => <>>
-const LayoutCategory = () => <>>
-const LayoutCategoryIndex = () => <>>
-const LayoutPage = () => <>>
-const LayoutTag = () => <>>
-const LayoutTagIndex = () => <>>
-export {
- THEME_CONFIG,
- LayoutIndex,
- LayoutSearch,
- LayoutArchive,
- LayoutSlug,
- Layout404,
- LayoutCategory,
- LayoutCategoryIndex,
- LayoutPage,
- LayoutTag,
- LayoutTagIndex
+/**
+ * 文章详情页布局
+ * @param {*} props
+ * @returns
+ */
+const LayoutSlug = (props) =>
+
+
+
+
+
+// 其他布局暂时留空
+const LayoutSearch = (props) =>
+const LayoutArchive = (props) =>
+const Layout404 = (props) =>
+const LayoutCategory = (props) =>
+const LayoutCategoryIndex = (props) =>
+const LayoutPage = (props) =>
+const LayoutTag = (props) =>
+const LayoutTagIndex = (props) =>
+
+/**
+ * 问题留言区域
+ * @param {*} props
+ * @returns
+ */
+const FAQ = (props) => {
+ return
+
+ FAQs
+
+
+
+
+ What is a home energy rating?
+
+
+
+ A home energy rating is an estimated calculation into a homes potential energy usage, which will determine the amount of heating and cooling required to make its occupants comfortable. It produces a star rating dependant on the amount of heating and cooling loads which will be required, from 0 to 10 stars.
+
+
+
+
+
+ Why do I need a 6 Star energy rating?
+
+
+
+ In most Australian states the government requires that all new homes and apartments (along with certain types of building extensions) built since 2010 be energy rated and achieve a minimum of 6 Stars.
+
+
+
+
+
+ What is the general cost of an energy rating?
+
+
+
+ Simple energy rating prices vary greatly on the size and type of building, generally an energy rating will cost somewhere between $130 to $700+.
+
+
+
+
+
+ What information do I need to supply for an energy rating to be completed??
+
+
+
+ The information required to complete a full and comprehensive energy report are the following final working drawings: Site Plan, Floor Plan, Elevations, Sections, Lighting layout and window schedule (including sizes of the existing windows).
+
+
+
+
+
+ Does building an extension need an energy rating?
+
+
+
+ Depended on the size of the extension you are building there is a chance that it too will need to be energy rated. It's always best to check first before going ahead with construction.
+
+
+
+
+
+ What is the general cost of an energy rating?
+
+
+
+ Depended on the size of the extension you are building there is a chance that it too will need to be energy rated. It's always best to check first before going ahead with construction.
+
+
+
+
+
+}
+
+/**
+ * 文章列表
+ */
+const PostList = (props) => {
+ const { latestPosts } = props
+ return
+
+
+
+ Lastest articles
+
+
+ All article are verified by 2 experts and valdiate by the CTO
+
+
+
+
+
+ {latestPosts?.map(post => (
+
+
+
+
+
+ {post.category}
+
+
+ {post.title}
+
+
+ {post.description}
+
+
+
+ {post.tags?.map(t => {
+ return
+ #{t}
+
+ })}
+
+
+
+
+ ))}
+
+
+
+}
+
+/**
+ * 产品大图
+ */
+const ProductInfo = () => {
+ return
+
+
+
+
+
+ Be on
+
+ Time
+
+
+
+ 这是一个空主题,很多数据在页面中写死,您可以在代码的 /themes/blank 中个性化您的页面
+
+
+
+
+
+
+
+
+
+}
+
+/**
+ * 多张对比的价格卡
+ */
+const PriceCardMulti = () => {
+ return
+
+
+
+
+ Entreprise
+
+
+ $0
+
+ / month
+
+
+
+ For most businesses that want to optimize web queries.
+
+
+
+
+
+
+
+ All illimited components
+
+
+
+
+
+
+ Own custom Tailwind styles
+
+
+
+
+
+
+ Unlimited Templates
+
+
+
+
+
+
+ Free premium dashboard
+
+
+
+
+
+
+ Best ranking
+
+
+
+
+
+
+ Prenium svg
+
+
+
+
+
+
+ My wife
+
+
+
+ Choose plan
+
+
+
+
+
+
+
+ Essential
+
+
+ For the basics tailwind
+
+
+ $99
+
+
+ Per agent per month
+
+
+ Request demo
+
+
+
+
+
+
+
+ All illimited components Tailwind
+
+
+
+
+
+
+ Own analitycs templates
+
+
+
+
+
+
+ 24/24 support link
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Best ranking
+
+
+
+
+
+
+
+
+ Chocolate and meel
+
+
+
+
+
+
+
+
+
+ Pro
+
+
+ $99
+
+ month
+
+
+
+
+ Plan include :
+
+
+
+
+
+
+
+ All illimited components
+
+
+
+
+
+
+ Own custom Tailwind styles
+
+
+
+
+
+
+ Unlimited Templates
+
+
+
+
+
+
+ Free premium dashboard
+
+
+
+
+
+
+ Best ranking
+
+
+
+
+
+
+ Prenium svg
+
+
+
+
+
+
+ My wife
+
+
+
+ Choose plan
+
+
+
+
+
+
+
+
+}
+
+
+/**
+ * 价格卡 单个
+ * @returns
+ */
+const PriceCardOne = () => {
+ return
+
+
+
+
+ Start selling online for free with all the features you need to launch your local delivery and pick-up service, nothing more. We don't charge commission or monthly fees, keep all your margin.
+
+
+
+
+ What's included
+
+
+
+
+
+
+
+
+ All illimited components
+
+
+
+
+
+ Own custom Tailwind styles
+
+
+
+
+
+ Unlimited Templates
+
+
+
+
+
+ Free premium dashboard
+
+
+
+
+
+ Best ranking
+
+
+
+
+
+ Prenium svg
+
+
+
+
+
+ My wife
+
+
+
+
+
+
+
+ & What's not
+
+
+
+
+
+
+ No Contracts. No monthly, setup, or additional payment processor fees
+
+
+
+
+
+ No 2-week on-boarding, it takes 20 minutes!
+
+
+
+
+
+
+
+ Free
+
+
+
+
+ Card payments:
+
+
+ 2.9% + 20p per transaction
+
+
+
+
+
+ Create your store
+
+
+
+
+
+
+
+}
+
+/**
+ * 一个网页抹胸信息
+ * @returns
+ */
+const BandeauInfo = () => {
+
+ return
+
+
+
+ Feel confident in choosing the best energy assessor for your energy rating.
+
+
+
+
+
+
+
+ Quotes on average
+
+
+
+
+
+ Average turnaround
+
+
+
+
+
+ Buy the kit
+
+
+
+
+}
+
+
+/**
+ * 团队介绍
+ * @returns
+ */
+const Teams = () => {
+
+ return
+
+
+
+
+
+ Jacky Pout
+
+
+ FullStack Engineer
+
+
+ He love caramel and he hate PHP
+
+
+ Jacky@poute.com
+
+
+
+
+
+
+
+ Damien Marley
+
+
+ CEO
+
+
+ He's fun and listen everyday Bob Marley
+
+
+ Damien@marley.com
+
+
+
+
+
+}
+
+/**
+* 导航栏
+* @param {*} param0
+* @returns
+*/
+const NavBar = ({ siteInfo }) => {
+ const [showMenu, setShowMenu] = useState(false)
+ const toggleMenu = () => {
+ setShowMenu(!showMenu)
+ }
+ return
+
+
+
+ {/* Logo菜单区域 */}
+
+
+
+
+
+
+
+ {/* 移动设备菜单 */}
+
+
+
+}
+
+/**
+ * 特性介绍
+ */
+const Features = () => {
+ return
+
+
+
+
+
+ Sed ac magna sit amet risus tristique interdum, at vel velit in hac habitasse platea dictumst.
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi sagittis, quam nec venenatis lobortis, mi risus tempus nulla, sed porttitor est nibh at nulla. Praesent placerat enim ut ex tincidunt vehicula. Fusce sit amet dui tellus.
+
+
+
+ See more
+
+
+
+
+
+
+
+
+
+ 1
+
+
+
+
+ Responsive Elements
+
+
+ All elements are responsive and provide the best display in all screen size. It's magic !
+
+
+
+
+
+
+ 2
+
+
+
+
+ Flexible Team
+
+
+ Flexibility is the key. All team is available 24/24 and joinable every day on our hotline.
+
+
+
+
+
+
+ 3
+
+
+
+
+ Ecologic Software
+
+
+ Our Software are ecologic and responsable. Green is not just a color, it's a way of life.
+
+
+
+
+
+
+
+
+
+
+}
+
+/**
+ * 页脚
+ * @param {*} param0
+ */
+const Footer = ({ siteInfo }) => {
+ return
+
+
+
+
+
+
+
+
+ Created by Charlie
+
+
+
+}
+
+/**
+ * 首版
+ * @param {*} param0
+* @returns
+*/
+const CTA = ({ siteInfo }) => {
+ return
+
+
+
+ The React Framework for Production
+
+
+ Next.js gives you the best developer experience with all the features you need for production: hybrid static & server rendering, TypeScript support, smart bundling, route pre-fetching, and more. No config needed.
+
+
+
+
+
+
+
+
+
+
+}
+export {
+ THEME_CONFIG,
+ LayoutIndex,
+ LayoutSearch,
+ LayoutArchive,
+ LayoutSlug,
+ Layout404,
+ LayoutCategory,
+ LayoutCategoryIndex,
+ LayoutPage,
+ LayoutTag,
+ LayoutTagIndex
}
diff --git a/themes/landing/components/Features.js b/themes/landing/components/Features.js
new file mode 100644
index 00000000..a2dd5d92
--- /dev/null
+++ b/themes/landing/components/Features.js
@@ -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 background (needs .relative class on parent and next sibling elements) */}
+
+
+
+
+
+
+ {/* Section header */}
+
+
Explore the solutions
+
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur excepteur sint occaecat cupidatat.
+
+
+ {/* Section content */}
+
+
+ {/* Content */}
+
+
+
Powerful suite of tools
+
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa.
+
+ {/* Tabs buttons */}
+
+
+
+ {/* Tabs items */}
+
+
+
+ {/* Item 1 */}
+
heightFix()}
+ unmount={false}
+ >
+
+
+
+
+
+ {/* Item 2 */}
+
heightFix()}
+ unmount={false}
+ >
+
+
+
+
+
+ {/* Item 3 */}
+
heightFix()}
+ unmount={false}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/themes/landing/components/FeaturesBlocks.js b/themes/landing/components/FeaturesBlocks.js
new file mode 100644
index 00000000..e5ec6864
--- /dev/null
+++ b/themes/landing/components/FeaturesBlocks.js
@@ -0,0 +1,125 @@
+export default function FeaturesBlocks() {
+ return (
+
+
+ {/* Section background (needs .relative class on parent and next sibling elements) */}
+
+
+
+
+
+
+ {/* Section header */}
+
+
Explore the solutions
+
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur excepteur sint occaecat cupidatat.
+
+
+ {/* Items */}
+
+
+ {/* 1st item */}
+
+
+
+
+
+
+
+
+
+
+
+
+
Headless CMS
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+
+
+ {/* 2nd item */}
+
+
+
+
+
+
+
+
+
+
+
+
Headless CMS
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+
+
+ {/* 3rd item */}
+
+
+
+
+
+
+
+
+
+
+
+
+
Headless CMS
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+
+
+ {/* 4th item */}
+
+
+
+
+
+
+
+
+
+
+
+
+
Headless CMS
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+
+
+ {/* 5th item */}
+
+
+
+
+
+
+
+
+
+
+
+
Headless CMS
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+
+
+ {/* 6th item */}
+
+
+
+
+
+
+
+
+
+
+
Headless CMS
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+
+
+
+
+
+
+
+ )
+}
diff --git a/themes/landing/components/Footer.js b/themes/landing/components/Footer.js
new file mode 100644
index 00000000..e5f4f1dc
--- /dev/null
+++ b/themes/landing/components/Footer.js
@@ -0,0 +1,149 @@
+import Logo from './Logo'
+
+export default function Footer() {
+ return (
+
+ )
+}
diff --git a/themes/landing/components/Header.js b/themes/landing/components/Header.js
new file mode 100644
index 00000000..bcb638eb
--- /dev/null
+++ b/themes/landing/components/Header.js
@@ -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 (
+
+
+
+
+ {/* Site branding */}
+
+
+
+
+ {/* Desktop navigation */}
+
+ {/* Desktop sign in links */}
+
+
+ Sign in
+
+
+
+ Sign up
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/themes/landing/components/Hero.js b/themes/landing/components/Hero.js
new file mode 100644
index 00000000..3223ed6d
--- /dev/null
+++ b/themes/landing/components/Hero.js
@@ -0,0 +1,60 @@
+import ModalVideo from './ModalVideo'
+
+export default function Hero() {
+ return (
+
+
+ {/* Illustration behind hero content */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* Hero content */}
+
+
+ {/* Section header */}
+
+
Make your website wonderful
+
+
Our landing page template works on all devices, so you only have to set it up once, and get beautiful results forever.
+
+
+
+
+ {/* Hero image */}
+
+
+
+
+
+
+ )
+}
diff --git a/themes/landing/components/Logo.js b/themes/landing/components/Logo.js
new file mode 100644
index 00000000..9b629104
--- /dev/null
+++ b/themes/landing/components/Logo.js
@@ -0,0 +1,18 @@
+import Link from 'next/link'
+
+export default function Logo() {
+ return (
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/themes/landing/components/MobileMenu.js b/themes/landing/components/MobileMenu.js
new file mode 100644
index 00000000..6a1c90e8
--- /dev/null
+++ b/themes/landing/components/MobileMenu.js
@@ -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 (
+
+ {/* Hamburger button */}
+
setMobileNavOpen(!mobileNavOpen)}
+ >
+ Menu
+
+
+
+
+
+
+
+ {/* Mobile navigation */}
+
+
+
+
+ setMobileNavOpen(false)}>Sign in
+
+
+ setMobileNavOpen(false)}>
+ Sign up
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/themes/landing/components/ModalVideo.js b/themes/landing/components/ModalVideo.js
new file mode 100644
index 00000000..9759caff
--- /dev/null
+++ b/themes/landing/components/ModalVideo.js
@@ -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 (
+
+
+ {/* Video thumbnail */}
+
+
+
+ {/* eslint-disable-next-line @next/next/no-img-element */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{ setModalOpen(true) }}>
+
+
+
+
+ Watch the full video (2 min)
+
+
+
+ {/* End: Video thumbnail */}
+
+
videoRef.current?.play()}>
+ setModalOpen(false)}>
+
+ {/* Modal backdrop */}
+
+ {/* End: Modal backdrop */}
+
+ {/* Modal dialog */}
+
+
+
+
+
+ Your browser does not support the video tag.
+
+
+
+
+ {/* End: Modal dialog */}
+
+
+
+
+
+ )
+}
diff --git a/themes/landing/components/Newsletter.js b/themes/landing/components/Newsletter.js
new file mode 100644
index 00000000..10d698b6
--- /dev/null
+++ b/themes/landing/components/Newsletter.js
@@ -0,0 +1,63 @@
+export default function Newsletter() {
+ return (
+
+
+
+
+ {/* CTA box */}
+
+
+ {/* Background illustration */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* CTA content */}
+
+
Want more tutorials & guides?
+
Lorem ipsum dolor sit amet consectetur adipisicing elit nemo expedita voluptas culpa sapiente.
+
+ {/* CTA form */}
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/themes/landing/components/Testimonials.js b/themes/landing/components/Testimonials.js
new file mode 100644
index 00000000..0e01f3cc
--- /dev/null
+++ b/themes/landing/components/Testimonials.js
@@ -0,0 +1,103 @@
+import Image from 'next/image'
+import TestimonialImage from '@/public/images/testimonial.jpg'
+
+export default function Testimonials() {
+ return (
+
+
+ {/* Illustration behind content */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* Section header */}
+
+
Trusted by over 20,000 companies all over the world
+
Arcu cursus vitae congue mauris rhoncus viverra nibh cras pulvinar mattis
+ blandit libero cursus mattis.
+
+
+ {/* Items */}
+
+
+ {/* Item */}
+
+
+ {/* Item */}
+
+
+ {/* Item */}
+
+
+ {/* Item */}
+
+
+ {/* Item */}
+
+
+
+
+ {/* Testimonials */}
+
+
+
+ {/* Testimonial */}
+
+
+
+ “ I love this product and would recommend it to anyone. Could be not easier to use, and our multiple websites are wonderful. We get nice comments all the time. “
+
+
Darya Finger
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/themes/landing/index.js b/themes/landing/index.js
new file mode 100644
index 00000000..b6df961b
--- /dev/null
+++ b/themes/landing/index.js
@@ -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
+ {/* 顶部导航栏 */}
+
+
+ {/* 内容 */}
+
+ {children}
+
+
+ {/* 底部页脚 */}
+
+
+}
+
+
+/**
+ * 首页布局
+ * @param {*} props
+ * @returns
+ */
+const LayoutIndex = (props) => {
+ const { siteInfo } = props
+ return (
+
+
+
+
+
+
+
+ )
+}
+
+/**
+ * 文章详情页布局
+ * @param {*} props
+ * @returns
+ */
+const LayoutSlug = (props) =>
+
+
+
+
+
+// 其他布局暂时留空
+const LayoutSearch = (props) =>
+const LayoutArchive = (props) =>
+const Layout404 = (props) =>
+const LayoutCategory = (props) =>
+const LayoutCategoryIndex = (props) =>
+const LayoutPage = (props) =>
+const LayoutTag = (props) =>
+const LayoutTagIndex = (props) =>
+
+export {
+ THEME_CONFIG,
+ LayoutIndex,
+ LayoutSearch,
+ LayoutArchive,
+ LayoutSlug,
+ Layout404,
+ LayoutCategory,
+ LayoutCategoryIndex,
+ LayoutPage,
+ LayoutTag,
+ LayoutTagIndex
+}