Merge pull request #11 from acid-info/landing-page

feat: landing page
This commit is contained in:
jeangovil
2023-05-30 14:38:03 +03:30
committed by GitHub
63 changed files with 1375 additions and 653 deletions
@@ -36,6 +36,7 @@ const config = {
},
},
docs: {
routeBasePath: '/docs',
versions: {
current: {
label: 'current',
@@ -51,6 +52,22 @@ const config = {
themeConfig:
/** @type {import('@acid-info/logos-docusaurus-preset').ThemeConfig} */
({
navbar: {
items: [
{
label: 'Docs',
href: '/docs',
},
{
label: 'Features',
href: '#features',
},
{
label: 'Showcase',
href: '#showcase',
},
],
},
footer: {
copyright: 'Copyright @2023 Logos <br/> Built with Docusaurus.',
links: [
@@ -0,0 +1,90 @@
import {
Hero,
HeroTitle,
HeroDescription,
HeroActions,
HeroAction,
CallToActionSection,
FeatureList,
Showcase,
HeroModel,
} from '../components/mdx'
<Hero
size="large"
title="The web3 managing standard"
description="Waku is a decentralized communications network"
>
<HeroActions>
<HeroAction href="https://docs.waku.org" target="_blank">
Build on Waku
</HeroAction>
<HeroAction variant="filled" href="https://docs.waku.org" target="_blank">
Run Waku
</HeroAction>
</HeroActions>
<HeroModel modelUrl="/hero/bust-hi.glb" layout="floating" renderer="ascii" />
</Hero>
<FeatureList
id="features"
features={[
{
title: 'Private',
description:
'Waku leverages cutting-edge zero-knowledge encryption to ensure all messages and associated metadata benefit from rock-solid privacy guarantees.',
},
{
title: 'Runs anywhere',
description:
"Waku's modularity enables developers to integrate Waku protocols according to their use case and users' hardware restraints",
},
{
title: 'Scalable',
description:
'Waku aims to scale to support millions of users by dividing the flow of messages into shards—not every node needs to forward every message—while discovery protocols ensure users connect to the nodes serving relevant messages.',
},
{
title: 'Secure',
description:
"Waku's native incentivization mechanisms ensure a wide node distribution, making it highly secure and strengthening its privacy assurances.",
},
]}
/>
<CallToActionSection
title="User adoptions"
description="Waku has brought private, censorship-resistant communications to several notable web3 DApps, decentralizing their messaging components:"
label="Decentralize your DApp"
href="/join"
/>
<Showcase
id="showcase"
items={[
{
name: 'XMTP',
logo: '/showcase/xmtp-mark-white.svg',
description:
"Inter-blockchain account messaging protocol XMTP uses Waku's Go implementation to facilitate communication between nodes in its currently permissioned network.",
},
{
name: 'Status',
logo: '/showcase/status-mark-white.svg',
description:
"Waku powers many of the Status super app's features, including its private messaging.",
},
{
name: 'Railgun',
logo: '/showcase/railgun-mark-white.svg',
description:
'The privacy-focused DeFi protocol Railgun anonymizes Ethereum transactions with Waku. ',
},
]}
/>
<CallToActionSection
title="Join the community to discover what Waku can bring to your DApp"
label="Decentralize your DApp"
href="/join"
/>
Binary file not shown.
@@ -0,0 +1,4 @@
<svg width="58" height="58" viewBox="0 0 58 58" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="58" height="58" rx="29" fill="white"/>
<path d="M23 39V19H29.737C31.2013 19 32.4164 19.2669 33.3823 19.8008C34.3544 20.3346 35.0804 21.0736 35.5603 22.0176C36.0402 22.9551 36.2802 24.0391 36.2802 25.2695C36.2802 26.4935 36.0371 27.571 35.5511 28.502C35.0712 29.4264 34.3452 30.1458 33.3731 30.6602C32.4072 31.1745 31.192 31.4316 29.7278 31.4316H24.6243V28.834H29.4693C30.3922 28.834 31.1428 28.694 31.7212 28.4141C32.3056 28.1341 32.7332 27.7272 33.004 27.1934C33.2747 26.6595 33.41 26.0182 33.41 25.2695C33.41 24.5143 33.2716 23.86 32.9947 23.3066C32.724 22.7533 32.2964 22.3301 31.7119 22.0371C31.1336 21.7376 30.3738 21.5879 29.4324 21.5879H25.8517V39H23ZM32.3303 29.9766L37 39H33.7515L29.174 29.9766H32.3303Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 845 B

@@ -0,0 +1,3 @@
<svg width="58" height="58" viewBox="0 0 58 58" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M33.6479 28.7455C30.3452 28.9358 28.2754 28.1665 24.9723 28.3573C24.1531 28.4033 23.3396 28.522 22.5412 28.7121C23.0288 22.6037 27.3519 17.2602 33.2306 16.9205C36.8381 16.7123 40.4439 18.9397 40.6394 22.5555C40.8319 26.1094 38.1221 28.487 33.6483 28.7451L33.6479 28.7455ZM24.779 41.24C21.323 41.4352 17.8692 39.3501 17.6817 35.9665C17.4972 32.6404 20.0937 30.4152 24.3794 30.1736C27.543 29.9953 29.5261 30.7157 32.6897 30.5369C33.4741 30.4939 34.2533 30.3828 35.0186 30.2048C34.5523 35.9214 30.411 40.9226 24.779 41.24ZM28.9999 1.4449C13.7812 1.44446 1.44434 13.7812 1.44434 29C1.44434 44.2189 13.7812 56.5556 28.9999 56.5556C44.2186 56.5556 56.5554 44.2184 56.5554 29C56.5554 13.7816 44.2186 1.44446 28.9999 1.44446" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 885 B

@@ -0,0 +1,10 @@
<svg width="57" height="58" viewBox="0 0 57 58" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_603_7836)">
<path d="M0 29C0 12.9837 12.8112 0 28.6147 0C44.4079 0 56.61 12.7424 56.9815 28.8744C56.9815 34.0217 55.2473 38.3527 50.9119 42.4328C47.2482 45.8808 41.0019 46.3874 36.4191 43.8139C33.1479 41.9015 30.627 37.8289 28.4908 34.8377L24.5268 40.9892H15.9796L24.0314 28.8739L16.2274 16.948H25.0223L28.5528 23.0996L32.0211 16.948H40.8782L32.8265 28.8744C32.8265 28.8744 36.6665 34.8377 38.7722 37.1602C40.8782 39.4828 44.7182 39.5455 47.1955 37.0346C49.9195 34.274 50.5292 32.0759 50.5403 28.8744C50.5828 16.4828 40.8709 6.52813 28.6147 6.52813C16.3687 6.52813 6.44139 16.5891 6.44139 29C6.44139 41.4108 16.3687 51.472 28.6147 51.472C30.3085 51.472 31.932 51.3277 33.5077 50.9696L34.8704 57.3096C32.6282 57.819 30.8169 58 28.6147 58C12.8112 58 0 45.0162 0 29Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_603_7836">
<rect width="57" height="58" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1015 B

+6 -1
View File
@@ -21,7 +21,7 @@
},
"dependencies": {
"@acid-info/logos-docusaurus-preset": "^0.3.0",
"@acid-info/lsd-react": "^0.1.0-alpha.7",
"@acid-info/lsd-react": "^0.1.0-alpha.8",
"@docusaurus/core": "^2.4.1",
"@docusaurus/mdx-loader": "^2.4.1",
"@docusaurus/module-type-aliases": "^2.4.1",
@@ -38,6 +38,8 @@
"@emotion/react": "^11.11.0",
"@emotion/styled": "^11.11.0",
"@mdx-js/react": "^1.6.22",
"@react-three/drei": "8.20.2",
"@react-three/fiber": "6.2.3",
"@tryghost/content-api": "^1.11.4",
"clsx": "^1.2.1",
"copy-text-to-clipboard": "^3.0.1",
@@ -49,11 +51,14 @@
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-use": "^17.4.0",
"three": "^0.152.2",
"three-stdlib": "^2.23.4",
"utility-types": "^3.10.0"
},
"devDependencies": {
"@types/lodash": "^4.14.186",
"@types/mdx-js__react": "^1.5.5",
"@types/three": "^0.152.1",
"sass": "^1.55.0",
"tsc-alias": "^1.7.0",
"tsc-watch": "^5.0.3"
@@ -0,0 +1,22 @@
import React from 'react'
import { createPortal } from 'react-dom'
import { usePortal } from './usePortal'
interface PortalProps {
id?: string
containerId: string
}
export const Portal: React.FC<React.PropsWithChildren<PortalProps>> = ({
children,
containerId,
id,
}) => {
if (typeof window === 'undefined') {
return <></>
}
const portalElement = usePortal({ parentId: containerId })
return createPortal(children, portalElement, id)
}
@@ -0,0 +1 @@
export { Portal } from './Portal'
@@ -0,0 +1,26 @@
import { useEffect, useRef } from 'react'
import { settleSync } from '../../lib/settle'
interface Props {
parentId: string
}
export const usePortal = ({ parentId }: Props) => {
const elementRef = useRef<HTMLElement>()
if (!elementRef.current) {
elementRef.current = document.createElement('div')
}
useEffect(() => {
if (!elementRef.current) return
document.getElementById(parentId)?.appendChild(elementRef.current)
return () => {
const el = elementRef.current
el && settleSync(() => document.getElementById(parentId)?.removeChild(el))
}
}, [parentId, elementRef.current])
return elementRef.current
}
@@ -1,111 +0,0 @@
import React, { useEffect, useState } from 'react'
import clsx from 'clsx'
import styles from './style.module.scss'
import useDocusaurusContext from '@docusaurus/useDocusaurusContext'
// @ts-ignore
import GhostContentAPI from '@tryghost/content-api'
import { LinkButton } from '@logos-theme/components/Button/LinkButton'
type TProps = {
children: React.ReactNode
}
interface IGhostAuthor {
url: string
name: string
}
interface IGhostBlogPost {
title: string
excerpt: string
url: string
html: string
updated_at: string
authors: IGhostAuthor[]
}
const useGhostBlogPosts = (limit: number = 10) => {
const {
siteConfig: {
customFields: { ghostAPiKey },
},
} = useDocusaurusContext() as any
const [posts, setPosts] = useState<IGhostBlogPost[]>([])
useEffect(() => {
const api = new GhostContentAPI({
url: 'https://blog.codex.storage',
key: ghostAPiKey,
version: 'v2.0',
})
api.posts
.browse({ limit, include: 'tags,authors' })
.then((_posts: IGhostBlogPost[]) => {
setPosts(_posts)
})
.catch((err) => {
console.error(err)
})
}, [])
return posts
}
type TBlogPostProps = {
post: IGhostBlogPost
}
const BlogPost = ({ post }: TBlogPostProps) => (
<div className={clsx('card', styles.blogpost)}>
<h3 className={'sans'}>{post.title}</h3>
<p
className={''}
dangerouslySetInnerHTML={{
__html: `${post.html.split(' ').slice(0, 23).join(' ')}...`,
}}
/>
<div className={styles.blogpostMeta}>
<small className={'sans'}>
by{' '}
{post.authors.map((a, i) => (
<a href={a.url} key={`a-${i}`}>
{a.name}
</a>
))}
</small>
<small>
<time> - {formatDate(post.updated_at)}</time>
</small>
</div>
<a>
<LinkButton
className={'button--secondary'}
linkProps={{ href: post.url }}
>
Learn More
</LinkButton>
</a>
</div>
)
const formatDate = (dateString: string): string => {
const date = new Date(dateString)
const m = date.toLocaleString('default', { month: 'short' })
const d = date.getDay()
const y = date.getFullYear()
return `${m} ${d}, ${y}`
}
export const BlogPosts = ({ children }: TProps): JSX.Element => {
const posts = useGhostBlogPosts()
return (
<section className={styles.blogpostsWrapper}>
<div className={styles.blogposts}>
{posts.map((post, i) => (
<BlogPost key={`p-${i}`} post={post} />
))}
</div>
</section>
)
}
@@ -1 +0,0 @@
export * from './BlogPosts'
@@ -1,24 +0,0 @@
.blogpostsWrapper {
.blogposts {
.blogpost {
padding: 0 !important;
background: none;
//border: 1px solid var(--ifm-color-gray-200);
p {
color: var(--ifm-color-gray-500);
}
> p {
margin: 0;
}
.blogpostMeta {
margin-bottom: calc(var(--ifm-leading));
}
+ .blogpost {
margin-top: calc(2 * var(--ifm-leading));
}
}
}
}
@@ -0,0 +1,52 @@
@use '../../../css/utils';
.mdx-cta-section {
display: grid;
margin-top: 260px;
padding-top: 1.5rem;
border-top: 1px solid rgb(var(--lsd-border-primary));
}
.mdx-cta-section__title {
}
.mdx-cta-section__description {
}
.mdx-cta-section__link {
margin-top: 2rem;
button,
button span {
font-size: inherit;
line-height: inherit;
font-weight: inherit;
}
}
.mdx-cta-section--with-description {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(2, 1fr);
.mdx-cta-section__title {
grid-column: 1 / 2;
}
.mdx-cta-section__description {
grid-column: 2 / 3;
}
.mdx-cta-section__link {
grid-column: 2 / 3;
grid-row: 2 / 3;
}
}
@include utils.responsive('md', 'up') {
.mdx-cta-section:not(.mdx-cta-section--with-description) {
.mdx-cta-section__title {
max-width: 65%;
}
}
}
@@ -0,0 +1,65 @@
import { Button, Typography } from '@acid-info/lsd-react'
import clsx from 'clsx'
import React from 'react'
import './CallToActionSection.scss'
export type CallToActionSectionProps = Omit<
React.HTMLAttributes<HTMLDivElement>,
'title'
> & {
title?: React.ReactNode
description?: React.ReactNode
href?: string
label?: string
}
export const CallToActionSection: React.FC<CallToActionSectionProps> = ({
label,
href,
title = '',
description,
className,
children,
...props
}) => {
return (
<div
variant="h1"
component="h1"
className={clsx(
className,
'mdx-cta-section',
description && 'mdx-cta-section--with-description',
)}
{...(props as any)}
>
<Typography
variant={description ? 'h6' : 'h1'}
component="span"
className="mdx-cta-section__title"
>
{title}
</Typography>
{description && (
<Typography
variant="h4"
component="span"
className="mdx-cta-section__description"
>
{description}
</Typography>
)}
<Typography
className="mdx-cta-section__link"
variant="body1"
component="a"
href={href}
target="_blank"
>
<Button size="large" variant="filled">
{label}
</Button>
</Typography>
</div>
)
}
@@ -0,0 +1 @@
export * from './CallToActionSection'
@@ -1,50 +0,0 @@
import { clsx } from 'clsx'
import React from 'react'
import { LinkButtonWithIcon } from '../../Button/LinkButtonWithIcon'
import {
IconArrowRightCircle,
IconFolder,
IconFolderFilled,
IconGithub,
} from '../../Icon/Icon'
import styles from './style.module.scss'
type TProps = {
children: React.ReactNode
referenceType: 'github' | 'pdf'
linkUrl: string
linkText: string
}
export const ExternalReferenceCard = (props: TProps): JSX.Element => {
const { children, referenceType, linkText, linkUrl } = props
const icon = (() => {
switch (referenceType) {
case 'github':
return <IconGithub />
case 'pdf':
return <IconFolderFilled />
default:
return null
}
})()
return (
<div className={clsx('alert', styles.exref)}>
<div className={styles.exrefContainer}>
<div>{icon}</div>
<div className={styles.exrefText}>{children}</div>
<div className={styles.exrefButton}>
<LinkButtonWithIcon
icon={<IconArrowRightCircle />}
linkProps={{ href: linkUrl, target: '_black' }}
className={'button--secondary'}
>
{linkText}
</LinkButtonWithIcon>
</div>
</div>
</div>
)
}

Some files were not shown because too many files have changed in this diff Show More