parent
ebeb481e50
commit
91b47f439d
@ -26,6 +26,7 @@
|
||||
"@types/lodash": "^4.14.182",
|
||||
"@types/marked": "^4.0.3",
|
||||
"clsx": "^1.1.1",
|
||||
"datocms-structured-text-to-html-string": "^2.0.4",
|
||||
"datocms-structured-text-to-plain-text": "^2.0.4",
|
||||
"graphql": "^16.3.0",
|
||||
"graphql-request": "^4.2.0",
|
||||
@ -46,7 +47,8 @@
|
||||
"react-merge-refs": "^1.1.0",
|
||||
"react-query": "^3.35.0",
|
||||
"react-use-measure": "^2.1.1",
|
||||
"sharp": "^0.30.4"
|
||||
"sharp": "^0.30.4",
|
||||
"tiny-json-http": "^7.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@graphql-codegen/cli": "^2.6.2",
|
||||
@ -55,6 +57,7 @@
|
||||
"@types/node": "^17.0.25",
|
||||
"@types/react": "^17.0.43",
|
||||
"@types/react-dom": "^17.0.14",
|
||||
"@types/tiny-json-http": "^7.3.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.20.0",
|
||||
"@typescript-eslint/parser": "^5.20.0",
|
||||
"cross-env": "^7.0.3",
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import clsx from 'clsx'
|
||||
import NextLink from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useCallback } from 'react'
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
|
||||
import { Calendar, Clock } from '~/components/icons/events'
|
||||
import Heading from '~/components/primitives/heading'
|
||||
@ -20,12 +20,33 @@ interface CardProps {
|
||||
}
|
||||
|
||||
const Card = ({ className, data, isNews = false }: CardProps) => {
|
||||
const [eventDate, setEventDate] = useState<string>()
|
||||
const [eventTime, setEventTime] = useState<string>()
|
||||
|
||||
useEffect(() => {
|
||||
setEventDate(
|
||||
new Date(data?.eventDatetime).toLocaleDateString('default', {
|
||||
year: '2-digit',
|
||||
month: '2-digit',
|
||||
day: '2-digit'
|
||||
})
|
||||
)
|
||||
setEventTime(
|
||||
new Date(data?.eventDatetime).toLocaleTimeString('default', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
})
|
||||
)
|
||||
}, [data?.eventDatetime])
|
||||
|
||||
return (
|
||||
<NextLink href={isNews ? `/blog/${data?.slug}` : data?.link}>
|
||||
<NextLink href={isNews ? `/blog/${data?.slug}` : data?.eventLink}>
|
||||
<div className={clsx(s['card'], className)}>
|
||||
<div className={s['card__header']}>
|
||||
{!isNews && (
|
||||
<span className={s.location}>{data?.location?.toUpperCase()}</span>
|
||||
<span className={s.location}>
|
||||
{data?.eventLocation?.toUpperCase()}
|
||||
</span>
|
||||
)}
|
||||
<div className={isNews ? s.is_news : ''}>
|
||||
{isNews && (
|
||||
@ -35,12 +56,12 @@ const Card = ({ className, data, isNews = false }: CardProps) => {
|
||||
)}
|
||||
<span className={s.date}>
|
||||
{!isNews && <Calendar />}
|
||||
{data?.date}
|
||||
{isNews ? data?.date : eventDate}
|
||||
</span>
|
||||
{!isNews && (
|
||||
<span className={s.hour}>
|
||||
<Clock />
|
||||
{data?.time} HS
|
||||
{eventTime} HS
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
@ -49,15 +70,15 @@ const Card = ({ className, data, isNews = false }: CardProps) => {
|
||||
<img
|
||||
alt={data?.title}
|
||||
loading="lazy"
|
||||
src={isNews ? data?.image.url : data?.imgSrc}
|
||||
src={isNews ? data?.image.url : data?.eventImage?.url}
|
||||
/>
|
||||
</div>
|
||||
<div className={s['content']}>
|
||||
<Heading as="h2" variant="sm" font="tthoves">
|
||||
{data?.title}
|
||||
{isNews ? data?.title : data?.eventTitle}
|
||||
</Heading>
|
||||
<p>{isNews ? getDescription(data) : data?.preview}</p>
|
||||
<Link href={isNews ? `/blog/${data?.slug}` : data?.link}>
|
||||
<p>{isNews ? getDescription(data) : data?.eventDesc}</p>
|
||||
<Link href={isNews ? `/blog/${data?.slug}` : data?.eventLink}>
|
||||
{isNews ? 'READ ARTICLE' : 'LEARN MORE'}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@ -7,7 +7,18 @@ import Link from '~/components/primitives/link'
|
||||
|
||||
import s from './hero.module.scss'
|
||||
|
||||
const Hero = () => {
|
||||
interface Props {
|
||||
data: {
|
||||
heroCtaLabel: string
|
||||
heroCtaLink: string
|
||||
heroDescB01: string
|
||||
heroDescB02: string
|
||||
heroHeading: string
|
||||
heroTitle: string
|
||||
}
|
||||
}
|
||||
|
||||
const Hero = ({ data }: Props) => {
|
||||
return (
|
||||
<Section className={s['section']} disableFadeIn>
|
||||
<div className={s['gradient']} />
|
||||
@ -34,35 +45,24 @@ const Hero = () => {
|
||||
<div className={s['body']}>
|
||||
<div className={s['header']}>
|
||||
<Heading as="h1" variant="xl">
|
||||
Accelerating Web3
|
||||
{data?.heroHeading}
|
||||
</Heading>
|
||||
<Arrow className={s['arrow']} />
|
||||
</div>
|
||||
<div className={s['content']}>
|
||||
<div>
|
||||
<Line className={s['line']} height={145} />
|
||||
<Heading as="h2" variant="sm">
|
||||
We’re materializing a decentralized and interoperable future,{' '}
|
||||
<b>now</b>
|
||||
</Heading>
|
||||
<Heading
|
||||
as="h2"
|
||||
variant="sm"
|
||||
dangerouslySetInnerHTML={{ __html: data?.heroTitle }}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<p>
|
||||
For blockchain to achieve true decentralization and wider
|
||||
adoption, we need to expand data access, verifiability, and
|
||||
control for decentralized application developers and end
|
||||
consumers around the world.
|
||||
</p>
|
||||
<p>
|
||||
Led by a globally renowned team of architects and core
|
||||
contributors across Ethereum, IPLD / IPFS, and Cosmos SDK, our
|
||||
mission is to accelerate blockchain development,
|
||||
interoperability, and adoption by providing decentralized
|
||||
application (DApp) developers and users with greater access to
|
||||
verifiable data.
|
||||
</p>
|
||||
<p>{data?.heroDescB01}</p>
|
||||
<p>{data?.heroDescB02}</p>
|
||||
<div>
|
||||
<Link href="https://docs.laconic.com/faq">FAQ</Link>
|
||||
<Link href={data?.heroCtaLink}>{data?.heroCtaLabel}</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -5,27 +5,43 @@ import Heading from '~/components/primitives/heading'
|
||||
|
||||
import Team from './team'
|
||||
import s from './team.module.scss'
|
||||
import { cercTeam, laconicTeam, xylmTeam } from './teams'
|
||||
|
||||
const TeamSection = () => {
|
||||
interface Props {
|
||||
data: {
|
||||
teamHeading: string
|
||||
teamDescB01: string
|
||||
teamDescB02: string
|
||||
}
|
||||
teamData: {
|
||||
memberGithub: string
|
||||
memberImage: {
|
||||
url: string
|
||||
}
|
||||
memberLinkedin: string
|
||||
memberName: string
|
||||
memberPosition: string
|
||||
memberTeam: string
|
||||
memberTwitter: string
|
||||
}[]
|
||||
}
|
||||
|
||||
const TeamSection = ({ teamData, data }: Props) => {
|
||||
const laconicTeam = teamData?.filter(
|
||||
(member) => member.memberTeam === 'Laconic'
|
||||
)
|
||||
const cercTeam = teamData?.filter((member) => member.memberTeam === 'Cerc')
|
||||
const xylmTeam = teamData?.filter((member) => member.memberTeam === 'Xylm')
|
||||
|
||||
return (
|
||||
<Section className={s['section']} id="team">
|
||||
<Container className={s['container']}>
|
||||
<Heading as="h2" variant="lg">
|
||||
Team
|
||||
{data?.teamHeading}
|
||||
</Heading>
|
||||
<div>
|
||||
<Arrow className={s['arrow']} />
|
||||
<p>
|
||||
Built over four years, Laconic is developed by platform experts
|
||||
across Ethereum, IPLD / IPFS, and Cosmos SDK. Our project
|
||||
organizations are led by Ethereum architects and developers who
|
||||
co-authored and contributed to EIP-1559.
|
||||
</p>
|
||||
<p>
|
||||
We’ve successfully launched startups, and built products and
|
||||
communities loved by millions of people around the world.
|
||||
</p>
|
||||
<p>{data?.teamDescB01}</p>
|
||||
<p>{data?.teamDescB02}</p>
|
||||
</div>
|
||||
<Team members={laconicTeam} teamName="Laconic LLC" teamNumber="01" />
|
||||
<Team
|
||||
|
||||
@ -12,12 +12,14 @@ import s from './team.module.scss'
|
||||
|
||||
type Team = {
|
||||
member: {
|
||||
fullName: string
|
||||
github: string
|
||||
image: string
|
||||
linkedin: string
|
||||
position: string
|
||||
twitter: string
|
||||
memberName: string
|
||||
memberPosition: string
|
||||
memberImage: {
|
||||
url: string
|
||||
}
|
||||
memberGithub: string
|
||||
memberTwitter: string
|
||||
memberLinkedin: string
|
||||
}
|
||||
className?: string
|
||||
}
|
||||
@ -25,24 +27,28 @@ type Team = {
|
||||
function MemberProfile({ member, className }: Team) {
|
||||
return (
|
||||
<div className={clsx(s['member'], className)}>
|
||||
<img alt={member.fullName} loading="lazy" src={member.image} />
|
||||
<img
|
||||
alt={member?.memberName}
|
||||
loading="lazy"
|
||||
src={member?.memberImage?.url}
|
||||
/>
|
||||
<div className={s['description']}>
|
||||
<span>{member.fullName}</span>
|
||||
<span>{member.position}</span>
|
||||
<span>{member?.memberName}</span>
|
||||
<span>{member?.memberPosition}</span>
|
||||
</div>
|
||||
<div className={s['socials']}>
|
||||
{member.twitter && (
|
||||
<a href={member.twitter} target="_blank" rel="noopener">
|
||||
{member?.memberTwitter && (
|
||||
<a href={member?.memberTwitter} target="_blank" rel="noopener">
|
||||
<Twitter />
|
||||
</a>
|
||||
)}
|
||||
{member.github && (
|
||||
<a href={member.github} target="_blank" rel="noopener">
|
||||
{member?.memberGithub && (
|
||||
<a href={member?.memberGithub} target="_blank" rel="noopener">
|
||||
<Github />
|
||||
</a>
|
||||
)}
|
||||
{member.linkedin && (
|
||||
<a href={member.linkedin} target="_blank" rel="noopener">
|
||||
{member?.memberLinkedin && (
|
||||
<a href={member?.memberLinkedin} target="_blank" rel="noopener">
|
||||
<Linkedin />
|
||||
</a>
|
||||
)}
|
||||
@ -53,12 +59,15 @@ function MemberProfile({ member, className }: Team) {
|
||||
|
||||
type Teams = {
|
||||
members: {
|
||||
fullName: string
|
||||
github: string
|
||||
image: string
|
||||
linkedin: string
|
||||
position: string
|
||||
twitter: string
|
||||
memberGithub: string
|
||||
memberImage: {
|
||||
url: string
|
||||
}
|
||||
memberLinkedin: string
|
||||
memberName: string
|
||||
memberPosition: string
|
||||
memberTeam: string
|
||||
memberTwitter: string
|
||||
}[]
|
||||
teamName: string
|
||||
teamNumber: string
|
||||
|
||||
@ -1,96 +0,0 @@
|
||||
export const laconicTeam = [
|
||||
{
|
||||
fullName: 'Rick Dudley',
|
||||
position: 'Chief Architect, Cerc',
|
||||
image: '/images/about/team/rick-dudley.jpg',
|
||||
github: 'https://github.com/AFDudley',
|
||||
linkedin: 'https://www.linkedin.com/in/afdudley/',
|
||||
twitter: 'https://twitter.com/AFDudley0'
|
||||
},
|
||||
{
|
||||
fullName: 'Maly Ly',
|
||||
position: 'Chief Executive, Cerc',
|
||||
image: '/images/about/team/maly-ly.jpg',
|
||||
github: '',
|
||||
linkedin: 'https://www.linkedin.com/in/malytly/',
|
||||
twitter: 'https://twitter.com/malytly'
|
||||
},
|
||||
{
|
||||
fullName: 'Boris Mann',
|
||||
position: 'CEO, Fission',
|
||||
image: '/images/about/team/boris-mann.jpg',
|
||||
github: 'https://github.com/bmann',
|
||||
linkedin: 'https://www.linkedin.com/in/boris/',
|
||||
twitter: 'https://twitter.com/bmann'
|
||||
},
|
||||
{
|
||||
fullName: 'Brooklyn Zelenka',
|
||||
position: 'CTO, Fission',
|
||||
image: '/images/about/team/brooklyn-zelenka.jpg',
|
||||
github: 'https://github.com/expede',
|
||||
linkedin: 'https://www.linkedin.com/in/brooklynzelenka/',
|
||||
twitter: 'https://twitter.com/expede'
|
||||
}
|
||||
]
|
||||
|
||||
export const cercTeam = [
|
||||
{
|
||||
fullName: 'Ashwin Phatak',
|
||||
position: 'VP of Engineering',
|
||||
image: '/images/about/team/ashwin-phatak.jpg',
|
||||
twitter: 'https://twitter.com/ashwinphatak',
|
||||
linkedin: 'https://www.linkedin.com/in/ashwinphatak/',
|
||||
github: 'https://github.com/ashwinphatak'
|
||||
},
|
||||
{
|
||||
fullName: 'Ian Norden',
|
||||
position: 'Engineering Lead',
|
||||
image: '/images/about/team/ian-norden.jpg',
|
||||
twitter: '',
|
||||
linkedin: 'https://www.linkedin.com/in/ian-s-norden/',
|
||||
github: 'https://github.com/i-norden'
|
||||
},
|
||||
{
|
||||
fullName: 'Leah Light',
|
||||
position: 'Operations Manager',
|
||||
image: '/images/about/team/leah-light.jpg',
|
||||
twitter: '',
|
||||
linkedin: 'https://www.linkedin.com/in/leah-light-a308535/',
|
||||
github: ''
|
||||
},
|
||||
{
|
||||
fullName: 'Erik Dies',
|
||||
position: 'Product Lead',
|
||||
image: '/images/about/team/erik-dies.jpg',
|
||||
twitter: 'https://twitter.com/thelesserdies',
|
||||
linkedin: '',
|
||||
github: 'https://github.com/erikdies'
|
||||
}
|
||||
]
|
||||
|
||||
export const xylmTeam = [
|
||||
{
|
||||
fullName: 'Robert Douglass',
|
||||
position: 'VP of Ecosystem',
|
||||
image: '/images/about/team/robert-douglass.jpg',
|
||||
twitter: 'https://twitter.com/robertDouglass',
|
||||
linkedin: 'https://www.linkedin.com/in/roberttdouglass/',
|
||||
github: ''
|
||||
},
|
||||
{
|
||||
fullName: 'Michael Gushansky',
|
||||
position: 'Head of Marketing',
|
||||
image: '/images/about/team/michael-gushansky.jpg',
|
||||
twitter: 'https://twitter.com/mikegushansky',
|
||||
linkedin: 'https://www.linkedin.com/in/michael-gushansky-08698384/',
|
||||
github: ''
|
||||
},
|
||||
{
|
||||
fullName: 'Olive Kimoto',
|
||||
position: 'Creative & Program Lead',
|
||||
image: '/images/about/team/olive-kimoto.jpg',
|
||||
twitter: 'https://twitter.com/olivekimoto',
|
||||
linkedin: 'https://www.linkedin.com/in/olive-kimoto-71433b138/',
|
||||
github: ''
|
||||
}
|
||||
]
|
||||
@ -1,42 +0,0 @@
|
||||
export const events = [
|
||||
{
|
||||
location: 'París, France',
|
||||
date: '04.13.22',
|
||||
time: '08:00',
|
||||
imgSrc: '/images/community/events/card01.png',
|
||||
title: 'Paris Blockchain Week',
|
||||
preview:
|
||||
'PBW is the flagship event of Paris Blockchain Week gathering more than 3000 attendees, 70 sponsors, 250 speakers and 100 media partners.',
|
||||
link: 'https://www.pbwsummit.com/'
|
||||
},
|
||||
{
|
||||
location: 'Amsterdam, Netherlands',
|
||||
date: '04.18.22',
|
||||
time: '09:00',
|
||||
imgSrc: '/images/community/events/card02.png',
|
||||
title: 'Devconnect',
|
||||
preview:
|
||||
'Devconnect is a week-long in-person gathering that will feature independent Ethereum events, each with a unique focus.',
|
||||
link: 'https://devconnect.org/'
|
||||
},
|
||||
{
|
||||
location: 'Austin, TX',
|
||||
date: '06.09.22',
|
||||
time: '09:00',
|
||||
imgSrc: '/images/community/events/card03.png',
|
||||
title: 'Consensus',
|
||||
preview:
|
||||
'Consensus, the most influential crypto & blockchain experience of the year since 2015, will return to an in-person format and be held in Austin, Texas, for the first time ever.',
|
||||
link: 'https://events.coindesk.com/consensus2022'
|
||||
},
|
||||
{
|
||||
location: 'Amsterdam, NL',
|
||||
date: '07.19.22',
|
||||
time: '19:30',
|
||||
imgSrc: '/images/community/events/card04.png',
|
||||
title: 'ETH CC',
|
||||
preview:
|
||||
'The Ethereum Community Conference (EthCC) is the largest annual European Ethereum event focused on technology and community.',
|
||||
link: 'https://ethcc.io/'
|
||||
}
|
||||
]
|
||||
@ -10,10 +10,27 @@ import { Container } from '~/components/layout/container'
|
||||
import Section from '~/components/layout/section'
|
||||
import Heading from '~/components/primitives/heading'
|
||||
|
||||
import { events } from './events'
|
||||
import s from './events.module.scss'
|
||||
|
||||
const Events = () => {
|
||||
interface Props {
|
||||
data: {
|
||||
eventsHeading: string
|
||||
eventsDescription: string
|
||||
}
|
||||
eventsData: {
|
||||
eventDatetime: string
|
||||
eventDesc: string
|
||||
eventImage: {
|
||||
url: string
|
||||
}
|
||||
eventLink: string
|
||||
eventLocation: string
|
||||
eventTitle: string
|
||||
id: string
|
||||
}[]
|
||||
}
|
||||
|
||||
const Events = ({ eventsData, data }: Props) => {
|
||||
const [loaded, setLoaded] = useState(false)
|
||||
|
||||
const [sliderRef, slider] = useKeenSlider<HTMLDivElement>({
|
||||
@ -39,11 +56,9 @@ const Events = () => {
|
||||
<Container className={s['container']}>
|
||||
<div className={s['header']}>
|
||||
<Heading as="h2" variant="lg">
|
||||
Events
|
||||
{data?.eventsHeading}
|
||||
</Heading>
|
||||
<span>
|
||||
We’d love to meet you in person. Find us at a conference near you:
|
||||
</span>
|
||||
<span>{data?.eventsDescription}</span>
|
||||
<div className={s['gradient']} />
|
||||
</div>
|
||||
</Container>
|
||||
@ -52,8 +67,8 @@ const Events = () => {
|
||||
className={clsx(s['events__container'], 'keen-slider')}
|
||||
ref={sliderRef}
|
||||
>
|
||||
{events.map((event, i) => (
|
||||
<Card key={i} data={event} className="keen-slider__slide" />
|
||||
{eventsData.map((event) => (
|
||||
<Card key={event?.id} data={event} className="keen-slider__slide" />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -5,7 +5,18 @@ import Heading from '~/components/primitives/heading'
|
||||
|
||||
import s from './hero.module.scss'
|
||||
|
||||
const Hero = () => {
|
||||
interface Props {
|
||||
data: {
|
||||
heroButton01: string
|
||||
heroButton02: string
|
||||
heroB01Link: string
|
||||
heroB02Link: string
|
||||
heroDescription: string
|
||||
heroHeading: string
|
||||
}
|
||||
}
|
||||
|
||||
const Hero = ({ data }: Props) => {
|
||||
return (
|
||||
<Section className={s['section']} disableFadeIn>
|
||||
<div className={s['gradient']}></div>
|
||||
@ -30,32 +41,29 @@ const Hero = () => {
|
||||
/>
|
||||
<div className={s['header']}>
|
||||
<Heading as="h1" variant="xl">
|
||||
Laconic Community
|
||||
{data?.heroHeading}
|
||||
</Heading>
|
||||
<Arrow className={s['arrow--mobile']} />
|
||||
</div>
|
||||
<div className={s['content']}>
|
||||
<Arrow className={s['arrow']} />
|
||||
<p>
|
||||
Join us as we accelerate blockchain development and interoperability
|
||||
by expanding access to verifiable data.
|
||||
</p>
|
||||
<p>{data?.heroDescription}</p>
|
||||
<div className={s['buttons__container']}>
|
||||
<ButtonLink
|
||||
variant="primary"
|
||||
size="large"
|
||||
className={s['button']}
|
||||
href="https://discord.com/invite/ukhbBemyxY"
|
||||
href={data?.heroB01Link}
|
||||
>
|
||||
CHAT WITH US
|
||||
{data?.heroButton01}
|
||||
</ButtonLink>
|
||||
<ButtonLink
|
||||
variant="primary"
|
||||
size="large"
|
||||
className={s['button']}
|
||||
href="https://laconic.community/"
|
||||
href={data?.heroB02Link}
|
||||
>
|
||||
GET STARTED
|
||||
{data?.heroButton02}
|
||||
</ButtonLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -17,7 +17,25 @@ import Heading from '~/components/primitives/heading'
|
||||
|
||||
import s from './socials.module.scss'
|
||||
|
||||
const Socials = () => {
|
||||
interface Props {
|
||||
data: {
|
||||
socialsHeading: string
|
||||
socialsLine: string
|
||||
socialsImage: {
|
||||
url: string
|
||||
}
|
||||
socialsTwitter: string
|
||||
socialsDiscord: string
|
||||
socialsDiscourse: string
|
||||
socialsReddit: string
|
||||
socialsTelegram: string
|
||||
socialsLinkedin: string
|
||||
socialsFacebook: string
|
||||
socialsInstagram: string
|
||||
}
|
||||
}
|
||||
|
||||
const Socials = ({ data }: Props) => {
|
||||
return (
|
||||
<Section className={s['section']}>
|
||||
<Container className={s['container']}>
|
||||
@ -25,59 +43,75 @@ const Socials = () => {
|
||||
alt="Planet"
|
||||
className={s['planet--image']}
|
||||
loading="lazy"
|
||||
src="/images/community/socials/planet.png"
|
||||
src={data?.socialsImage?.url}
|
||||
/>
|
||||
<div>
|
||||
<div className={s['header']}>
|
||||
<Heading as="h2" variant="xl" centered={false}>
|
||||
Connect With Us
|
||||
{data?.socialsHeading}
|
||||
</Heading>
|
||||
</div>
|
||||
<Line className={s['line']} height={144} />
|
||||
</div>
|
||||
<div className={s['icons__container']}>
|
||||
<span>GET IN TOUCH</span>
|
||||
<span>{data?.socialsLine}</span>
|
||||
<div className={s['grid']}>
|
||||
<Link href={`https://twitter.com/laconicnetwork`}>
|
||||
<a target="_blank">
|
||||
<Twitter />
|
||||
</a>
|
||||
</Link>
|
||||
<Link href={`https://discord.com/invite/ukhbBemyxY`}>
|
||||
<a target="_blank">
|
||||
<Discord />
|
||||
</a>
|
||||
</Link>
|
||||
<Link href={`https://laconic.community/`}>
|
||||
<a target="_blank">
|
||||
<Discourse />
|
||||
</a>
|
||||
</Link>
|
||||
<Link href={`https://www.reddit.com/r/LaconicNetwork/`}>
|
||||
<a target="_blank">
|
||||
<Reddit />
|
||||
</a>
|
||||
</Link>
|
||||
<Link href={`https://t.me/laconicnetwork`}>
|
||||
<a target="_blank">
|
||||
<Telegram />
|
||||
</a>
|
||||
</Link>
|
||||
<Link href={`https://www.linkedin.com/company/laconic-network/`}>
|
||||
<a target="_blank">
|
||||
<Linkedin />
|
||||
</a>
|
||||
</Link>
|
||||
<Link href={`https://www.facebook.com/laconicnetwork`}>
|
||||
<a target="_blank">
|
||||
<Facebook />
|
||||
</a>
|
||||
</Link>
|
||||
<Link href={`https://instagram.com/laconicnetwork`}>
|
||||
<a target="_blank">
|
||||
<Instagram />
|
||||
</a>
|
||||
</Link>
|
||||
{data?.socialsTwitter && (
|
||||
<Link href={data?.socialsTwitter}>
|
||||
<a target="_blank">
|
||||
<Twitter />
|
||||
</a>
|
||||
</Link>
|
||||
)}
|
||||
{data?.socialsDiscord && (
|
||||
<Link href={data?.socialsDiscord}>
|
||||
<a target="_blank">
|
||||
<Discord />
|
||||
</a>
|
||||
</Link>
|
||||
)}
|
||||
{data?.socialsDiscourse && (
|
||||
<Link href={data?.socialsDiscourse}>
|
||||
<a target="_blank">
|
||||
<Discourse />
|
||||
</a>
|
||||
</Link>
|
||||
)}
|
||||
{data?.socialsReddit && (
|
||||
<Link href={data?.socialsReddit}>
|
||||
<a target="_blank">
|
||||
<Reddit />
|
||||
</a>
|
||||
</Link>
|
||||
)}
|
||||
{data?.socialsTelegram && (
|
||||
<Link href={data?.socialsTelegram}>
|
||||
<a target="_blank">
|
||||
<Telegram />
|
||||
</a>
|
||||
</Link>
|
||||
)}
|
||||
{data?.socialsLinkedin && (
|
||||
<Link href={data?.socialsLinkedin}>
|
||||
<a target="_blank">
|
||||
<Linkedin />
|
||||
</a>
|
||||
</Link>
|
||||
)}
|
||||
{data?.socialsFacebook && (
|
||||
<Link href={data?.socialsFacebook}>
|
||||
<a target="_blank">
|
||||
<Facebook />
|
||||
</a>
|
||||
</Link>
|
||||
)}
|
||||
{data?.socialsInstagram && (
|
||||
<Link href={data?.socialsInstagram}>
|
||||
<a target="_blank">
|
||||
<Instagram />
|
||||
</a>
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Container>
|
||||
|
||||
@ -28,12 +28,43 @@ import {
|
||||
Icon12
|
||||
} from './icons'
|
||||
|
||||
const Benefits = () => {
|
||||
interface Props {
|
||||
data: {
|
||||
benefitsHeading: string
|
||||
benefitsDesc: string
|
||||
benefitsS01Desc: string
|
||||
benefitsS01Heading: string
|
||||
benefitsS01Item01: string
|
||||
benefitsS01Item02: string
|
||||
benefitsS01Item03: string
|
||||
benefitsS01Item04: string
|
||||
benefitsS01Item05: string
|
||||
benefitsS01Item06: string
|
||||
benefitsS02Desc: string
|
||||
benefitsS02Heading: string
|
||||
benefitsS02Item01: string
|
||||
benefitsS02Item02: string
|
||||
benefitsS02Item03: string
|
||||
benefitsS02Item04: string
|
||||
benefitsS02Item05: string
|
||||
benefitsS02Item06: string
|
||||
benefitsButton: string
|
||||
benefitsButtonLink: string
|
||||
}
|
||||
}
|
||||
|
||||
const Benefits = ({ data }: Props) => {
|
||||
const ballRef = React.useRef<HTMLDivElement>(null)
|
||||
const gridRef = React.useRef<HTMLDivElement>(null)
|
||||
const userRef = React.useRef<HTMLDivElement>(null)
|
||||
const isMobile = useMedia('(max-width: 768px)')
|
||||
|
||||
const [isMounted, setIsMounted] = React.useState(false)
|
||||
|
||||
React.useEffect(() => {
|
||||
setIsMounted(true)
|
||||
}, [])
|
||||
|
||||
useIsomorphicLayoutEffect(() => {
|
||||
if (isMobile || typeof isMobile === 'undefined') return
|
||||
if (!ballRef.current) return
|
||||
@ -61,24 +92,16 @@ const Benefits = () => {
|
||||
<Section className={s['section']}>
|
||||
<Container className={s['header']}>
|
||||
<Heading as="h2" variant="lg">
|
||||
Benefits
|
||||
{data?.benefitsHeading}
|
||||
</Heading>
|
||||
<div className={s['grid']}>
|
||||
<div className={s['ball']} ref={ballRef} />
|
||||
<div className={s['icon']}>
|
||||
<Arrow />
|
||||
</div>
|
||||
<p>
|
||||
For DApp developers and users, Laconic is the only solution that
|
||||
provides accurate, low-cost, multi-chain verifiable data, by
|
||||
leveraging cryptographic proofs and cutting edge data caching
|
||||
engineering. <br />
|
||||
<br />{' '}
|
||||
<b>
|
||||
Laconic is the only blockchain data querying solution that
|
||||
provides cross-chain cryptographic proofs.
|
||||
</b>
|
||||
</p>
|
||||
{isMounted && (
|
||||
<p dangerouslySetInnerHTML={{ __html: data?.benefitsDesc }} />
|
||||
)}
|
||||
</div>
|
||||
</Container>
|
||||
<img
|
||||
@ -97,32 +120,17 @@ const Benefits = () => {
|
||||
<span>01</span>
|
||||
<Line className={s['line']} height={144} />
|
||||
<Heading as="h3" variant="sm">
|
||||
For DApp Developers
|
||||
{data?.benefitsS01Heading}
|
||||
</Heading>
|
||||
<p>
|
||||
Quickly and easily build blockchain applications with the fastest,
|
||||
most accurate, and lowest cost multi-chain verifiable data
|
||||
solution.
|
||||
</p>
|
||||
<p>{data?.benefitsS01Desc}</p>
|
||||
</div>
|
||||
<ul>
|
||||
<Benefit icon={<Icon01 />}>
|
||||
Only solution providing Cryptographic proofs
|
||||
</Benefit>
|
||||
<Benefit icon={<Icon02 />}>
|
||||
Composable, supports broader use cases
|
||||
</Benefit>
|
||||
<Benefit icon={<Icon03 />}>
|
||||
From months to minutes. Quick automated setup
|
||||
</Benefit>
|
||||
<Benefit icon={<Icon04 />}>Broad cross-chain compatibility</Benefit>
|
||||
<Benefit icon={<Icon05 />}>
|
||||
Unparalleled flexibility. Supports hash-linked data including
|
||||
blockchain
|
||||
</Benefit>
|
||||
<Benefit icon={<Icon06 />}>
|
||||
Lower development and data costs. 100x of times less than market
|
||||
</Benefit>
|
||||
<Benefit icon={<Icon01 />}>{data?.benefitsS01Item01}</Benefit>
|
||||
<Benefit icon={<Icon02 />}>{data?.benefitsS01Item02}</Benefit>
|
||||
<Benefit icon={<Icon03 />}>{data?.benefitsS01Item03}</Benefit>
|
||||
<Benefit icon={<Icon04 />}>{data?.benefitsS01Item04}</Benefit>
|
||||
<Benefit icon={<Icon05 />}>{data?.benefitsS01Item05}</Benefit>
|
||||
<Benefit icon={<Icon06 />}>{data?.benefitsS01Item06}</Benefit>
|
||||
</ul>
|
||||
</Container>
|
||||
<img
|
||||
@ -141,37 +149,24 @@ const Benefits = () => {
|
||||
<span>02</span>
|
||||
<Line className={s['line']} height={112} />
|
||||
<Heading as="h3" variant="sm">
|
||||
For DApp Users
|
||||
{data?.benefitsS02Heading}
|
||||
</Heading>
|
||||
<p>
|
||||
Experience a higher quality of service and better uptime with
|
||||
Laconic.
|
||||
</p>
|
||||
<p>{data?.benefitsS02Desc}</p>
|
||||
</div>
|
||||
<ul>
|
||||
<Benefit icon={<Icon07 />}>
|
||||
Greater data access and control
|
||||
</Benefit>
|
||||
<Benefit icon={<Icon08 />}>
|
||||
In-browser local cache, without need for data availability layer
|
||||
</Benefit>
|
||||
<Benefit icon={<Icon09 />}>
|
||||
Optimal control of privacy levels
|
||||
</Benefit>
|
||||
<Benefit icon={<Icon10 />}>Self-Verify data accuracy</Benefit>
|
||||
<Benefit icon={<Icon11 />}>
|
||||
Higher quality of service and uptime
|
||||
</Benefit>
|
||||
<Benefit icon={<Icon12 />}>
|
||||
LNT rewards for network participation
|
||||
</Benefit>
|
||||
<Benefit icon={<Icon07 />}>{data?.benefitsS02Item01}</Benefit>
|
||||
<Benefit icon={<Icon08 />}>{data?.benefitsS02Item02}</Benefit>
|
||||
<Benefit icon={<Icon09 />}>{data?.benefitsS02Item03}</Benefit>
|
||||
<Benefit icon={<Icon10 />}>{data?.benefitsS02Item04}</Benefit>
|
||||
<Benefit icon={<Icon11 />}>{data?.benefitsS02Item05}</Benefit>
|
||||
<Benefit icon={<Icon12 />}>{data?.benefitsS02Item06}</Benefit>
|
||||
</ul>
|
||||
<ButtonLink
|
||||
className={s['button']}
|
||||
variant="primary"
|
||||
href="https://discord.com/invite/ukhbBemyxY"
|
||||
href={data?.benefitsButtonLink}
|
||||
>
|
||||
Get Started
|
||||
{data?.benefitsButton}
|
||||
</ButtonLink>
|
||||
</Container>
|
||||
</Container>
|
||||
|
||||
@ -5,12 +5,22 @@ import Line from '~/components/icons/line'
|
||||
import Section from '~/components/layout/section'
|
||||
import { ButtonLink } from '~/components/primitives/button'
|
||||
import Heading from '~/components/primitives/heading'
|
||||
import HighlightedText from '~/components/primitives/highlighted-text'
|
||||
import { useIsomorphicLayoutEffect } from '~/hooks/use-isomorphic-layout-effect'
|
||||
|
||||
import s from './hero.module.scss'
|
||||
|
||||
const Hero = () => {
|
||||
interface props {
|
||||
data: {
|
||||
heroHeading: string
|
||||
heroButton01: string
|
||||
heroB01Link: string
|
||||
heroButton02: string
|
||||
heroB02Link: string
|
||||
heroSlogan: any
|
||||
}
|
||||
}
|
||||
|
||||
const Hero = ({ data }: props) => {
|
||||
const videoRef = useRef<HTMLVideoElement>(null)
|
||||
|
||||
useIsomorphicLayoutEffect(() => {
|
||||
@ -38,36 +48,30 @@ const Hero = () => {
|
||||
>
|
||||
<source src="/videos/hero-grid.mp4" type="video/mp4" />
|
||||
</video>
|
||||
<Heading as="h1" variant="xl" centered>
|
||||
Build a <br className="hide-on-desktop" />{' '}
|
||||
<HighlightedText>
|
||||
Fast, Frictionless, <br /> & Provable
|
||||
</HighlightedText>{' '}
|
||||
Web3
|
||||
</Heading>
|
||||
|
||||
<Heading
|
||||
as="h1"
|
||||
variant="xl"
|
||||
centered
|
||||
dangerouslySetInnerHTML={{ __html: data?.heroHeading }}
|
||||
/>
|
||||
<Line className={s['line']} />
|
||||
<p>
|
||||
From months to minutes. Laconic’s multi-chain verifiable data <br />{' '}
|
||||
marketplace accelerates blockchain development, <br />
|
||||
interoperability, and adoption
|
||||
</p>
|
||||
<div dangerouslySetInnerHTML={{ __html: data?.heroSlogan }} />
|
||||
<div className={s['buttons__container']}>
|
||||
<ButtonLink
|
||||
variant="primary"
|
||||
size="large"
|
||||
className={s['button']}
|
||||
href="https://discord.com/invite/ukhbBemyxY"
|
||||
href={data?.heroB01Link}
|
||||
>
|
||||
JOIN US NOW
|
||||
{data?.heroButton01}
|
||||
</ButtonLink>
|
||||
<ButtonLink
|
||||
variant="default"
|
||||
size="large"
|
||||
className={s['button']}
|
||||
href="https://laconic.community/"
|
||||
href={data?.heroB02Link}
|
||||
>
|
||||
CHAT WITH US
|
||||
{data?.heroButton02}
|
||||
</ButtonLink>
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
@ -13,10 +13,13 @@ import s from './latest-news.module.scss'
|
||||
|
||||
// TODO
|
||||
export interface Props {
|
||||
data: any
|
||||
blogData: any
|
||||
data: {
|
||||
latestHeading: string
|
||||
}
|
||||
}
|
||||
|
||||
const LatestNews = ({ data }: Props) => {
|
||||
const LatestNews = ({ data, blogData }: Props) => {
|
||||
const [loaded, setLoaded] = useState(false)
|
||||
|
||||
const [sliderRef, slider] = useKeenSlider<HTMLDivElement>({
|
||||
@ -40,13 +43,15 @@ const LatestNews = ({ data }: Props) => {
|
||||
return (
|
||||
<Section className={s['section']}>
|
||||
<Container className={s.heading}>
|
||||
<Heading as="h2" variant="lg">
|
||||
Latest news <br /> from Laconic
|
||||
</Heading>
|
||||
<Heading
|
||||
as="h2"
|
||||
variant="lg"
|
||||
dangerouslySetInnerHTML={{ __html: data?.latestHeading }}
|
||||
/>
|
||||
</Container>
|
||||
<div className={s['slider__container']}>
|
||||
<div className={`${s.events__container} keen-slider`} ref={sliderRef}>
|
||||
{data.map((item: any, i: Key) => (
|
||||
{blogData.map((item: any, i: Key) => (
|
||||
<Card key={i} data={item} className={`keen-slider__slide`} isNews />
|
||||
))}
|
||||
</div>
|
||||
|
||||
@ -11,10 +11,24 @@ import Heading from '~/components/primitives/heading'
|
||||
import { CUSTOM_EASE, DURATION, gsap, Observer } from '~/lib/gsap'
|
||||
|
||||
import Item from './item'
|
||||
import { testimonials } from './testimonials'
|
||||
import s from './what-others-say.module.scss'
|
||||
|
||||
const WhatOthersSay = () => {
|
||||
interface Props {
|
||||
data: {
|
||||
othersHeading: string
|
||||
}
|
||||
testimonialsData: {
|
||||
id: string
|
||||
testimonialImage: {
|
||||
url: string
|
||||
}
|
||||
testimonialPosition: string
|
||||
testimonialText: string
|
||||
testimonialUsername: string
|
||||
}[]
|
||||
}
|
||||
|
||||
const WhatOthersSay = ({ data, testimonialsData }: Props) => {
|
||||
const carouselRef = useRef<HTMLDivElement>(null)
|
||||
const { vw } = useRealViewport()
|
||||
const [ref] = useKeenSlider<HTMLDivElement>({
|
||||
@ -78,25 +92,26 @@ const WhatOthersSay = () => {
|
||||
<Section className={s['section']}>
|
||||
<Container>
|
||||
<div className={s['header']}>
|
||||
<Heading as="h2" variant="md" centered>
|
||||
What <br className="hide-on-mobile" /> others say
|
||||
</Heading>
|
||||
<Heading
|
||||
as="h2"
|
||||
variant="md"
|
||||
centered
|
||||
dangerouslySetInnerHTML={{ __html: data?.othersHeading }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={s['carousel']} ref={carouselRef}>
|
||||
<div className={s['image']}>
|
||||
<img src="/images/head.png" loading="lazy" alt="Head" />
|
||||
</div>
|
||||
|
||||
{testimonials.map((testimonial, index) => {
|
||||
{testimonialsData.map((testimonial) => {
|
||||
return (
|
||||
<Item
|
||||
className="carousel__item"
|
||||
image={testimonial.image}
|
||||
key={index}
|
||||
name={testimonial.name}
|
||||
image={testimonial?.testimonialImage?.url}
|
||||
key={testimonial?.id}
|
||||
name={testimonial?.testimonialUsername}
|
||||
>
|
||||
{testimonial.text}
|
||||
{testimonial?.testimonialText}
|
||||
</Item>
|
||||
)
|
||||
})}
|
||||
@ -106,15 +121,15 @@ const WhatOthersSay = () => {
|
||||
<div className={s['image']}>
|
||||
<img src="/images/head.png" loading="lazy" alt="Head" />
|
||||
</div>
|
||||
{testimonials.map((testimonial, index) => {
|
||||
{testimonialsData.map((testimonial) => {
|
||||
return (
|
||||
<Item
|
||||
className="keen-slider__slide"
|
||||
image={testimonial.image}
|
||||
key={index}
|
||||
name={testimonial.name}
|
||||
image={testimonial?.testimonialImage?.url}
|
||||
key={testimonial?.id}
|
||||
name={testimonial?.testimonialUsername}
|
||||
>
|
||||
{testimonial.text}
|
||||
{testimonial?.testimonialText}
|
||||
</Item>
|
||||
)
|
||||
})}
|
||||
|
||||
@ -1,84 +0,0 @@
|
||||
import Square from '~/components/logos/square'
|
||||
|
||||
export const testimonials = [
|
||||
{
|
||||
image:
|
||||
'https://pbs.twimg.com/profile_images/1513509255302856718/I9DHE-BG_400x400.jpg',
|
||||
name: '@rickmanelius',
|
||||
position: 'CO-Founder',
|
||||
logo: <Square />,
|
||||
text: "If you love web3 infra layer tools/solutions, give @laconicnetwork a follow. I'm incredibly excited with what they have coming down the pipeline"
|
||||
},
|
||||
{
|
||||
image:
|
||||
'https://pbs.twimg.com/profile_images/1467983835627286529/eeb-wHtV_400x400.jpg',
|
||||
name: '@kumavis',
|
||||
position: 'CO-Founder',
|
||||
logo: <Square />,
|
||||
text: 'Running infura for free is actually extremely expensive, we pursued a light client before but it required a fresh implementation. hopefully @laconicnetwork solves this problem'
|
||||
},
|
||||
{
|
||||
image:
|
||||
'https://pbs.twimg.com/profile_images/1478264960581091330/I1PG8TSU_400x400.jpg',
|
||||
name: '@OnChainDreamer',
|
||||
position: 'CO-Founder',
|
||||
logo: <Square />,
|
||||
text: '@laconicnetwork > really smart ppl follows b4 launch'
|
||||
},
|
||||
{
|
||||
image:
|
||||
'https://pbs.twimg.com/profile_images/1510473579128893446/wkH_3gq3_400x400.jpg',
|
||||
name: '@GarretteDVF',
|
||||
position: 'CO-Founder',
|
||||
logo: <Square />,
|
||||
text: 'Will also need light clients. Gamer profiles will need some form of p2p gossip on their ranking over time, which makes a good case for composable state information (assuming games are settled on the chain). I would look to @laconicnetwork for some of that.'
|
||||
},
|
||||
{
|
||||
image:
|
||||
'https://pbs.twimg.com/profile_images/1502059383651549188/w1s1xEnA_400x400.jpg',
|
||||
name: '@Lifechart3',
|
||||
position: 'CO-Founder',
|
||||
logo: <Square />,
|
||||
text: 'Patiently waiting for @laconicnetwork Launch 😎'
|
||||
},
|
||||
{
|
||||
image:
|
||||
'https://pbs.twimg.com/profile_images/1513509255302856718/I9DHE-BG_400x400.jpg',
|
||||
name: '@rickmanelius',
|
||||
position: 'CO-Founder',
|
||||
logo: <Square />,
|
||||
text: "If you love web3 infra layer tools/solutions, give @laconicnetwork a follow. I'm incredibly excited with what they have coming down the pipeline"
|
||||
},
|
||||
{
|
||||
image:
|
||||
'https://pbs.twimg.com/profile_images/1467983835627286529/eeb-wHtV_400x400.jpg',
|
||||
name: '@kumavis',
|
||||
position: 'CO-Founder',
|
||||
logo: <Square />,
|
||||
text: 'Running infura for free is actually extremely expensive, we pursued a light client before but it required a fresh implementation. hopefully @laconicnetwork solves this problem'
|
||||
},
|
||||
{
|
||||
image:
|
||||
'https://pbs.twimg.com/profile_images/1478264960581091330/I1PG8TSU_400x400.jpg',
|
||||
name: '@OnChainDreamer',
|
||||
position: 'CO-Founder',
|
||||
logo: <Square />,
|
||||
text: '@laconicnetwork > really smart ppl follows b4 launch'
|
||||
},
|
||||
{
|
||||
image:
|
||||
'https://pbs.twimg.com/profile_images/1510473579128893446/wkH_3gq3_400x400.jpg',
|
||||
name: '@GarretteDVF',
|
||||
position: 'CO-Founder',
|
||||
logo: <Square />,
|
||||
text: 'Will also need light clients. Gamer profiles will need some form of p2p gossip on their ranking over time, which makes a good case for composable state information (assuming games are settled on the chain). I would look to @laconicnetwork for some of that.'
|
||||
},
|
||||
{
|
||||
image:
|
||||
'https://pbs.twimg.com/profile_images/1502059383651549188/w1s1xEnA_400x400.jpg',
|
||||
name: '@Lifechart3',
|
||||
position: 'CO-Founder',
|
||||
logo: <Square />,
|
||||
text: 'Patiently waiting for @laconicnetwork Launch 😎'
|
||||
}
|
||||
]
|
||||
@ -1,31 +1,39 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
import { Container } from '~/components/layout/container'
|
||||
import Section from '~/components/layout/section'
|
||||
import Heading from '~/components/primitives/heading'
|
||||
import s from '~/components/sections/terms/termsofuse/termsofuse.module.scss'
|
||||
import CustomStructuredText from '~/lib/renderer'
|
||||
|
||||
import { privacyPolicy } from './privacypolicy'
|
||||
interface Props {
|
||||
data: {
|
||||
privacyContent: any
|
||||
_updatedAt: string
|
||||
}
|
||||
}
|
||||
|
||||
const PrivacyPolicy = ({ data }: Props) => {
|
||||
const [updatedOnDate, setUpdatedOnDate] = useState<string>()
|
||||
|
||||
useEffect(() => {
|
||||
setUpdatedOnDate(
|
||||
new Date(data?._updatedAt).toLocaleDateString('default', {
|
||||
day: '2-digit',
|
||||
month: '2-digit',
|
||||
year: '2-digit'
|
||||
})
|
||||
)
|
||||
}, [data?._updatedAt])
|
||||
|
||||
const PrivacyPolicy = () => {
|
||||
return (
|
||||
<Section className={s['section']}>
|
||||
<div className={s['header']}>
|
||||
<span>LAST UPDATE</span>
|
||||
<span className={s['separator']}>—</span>
|
||||
<span>{privacyPolicy.updatedOn}</span>
|
||||
<span>{updatedOnDate}</span>
|
||||
</div>
|
||||
<Container className={s['container']}>
|
||||
<p>{privacyPolicy.text.block01.pg01}</p>
|
||||
<p>{privacyPolicy.text.block01.pg02}</p>
|
||||
<p>{privacyPolicy.text.block01.pg03}</p>
|
||||
<p>{privacyPolicy.text.block01.pg04}</p>
|
||||
<Heading as="h2" font="tthoves" variant="sm">
|
||||
{privacyPolicy.text.block02.title}
|
||||
</Heading>
|
||||
<p>{privacyPolicy.text.block02.pg01}</p>
|
||||
<Heading as="h2" font="tthoves" variant="sm">
|
||||
{privacyPolicy.text.block03.title}
|
||||
</Heading>
|
||||
<p>{privacyPolicy.text.block03.pg01}</p>
|
||||
<CustomStructuredText data={data?.privacyContent} />
|
||||
</Container>
|
||||
</Section>
|
||||
)
|
||||
|
||||
@ -1,21 +0,0 @@
|
||||
export const privacyPolicy = {
|
||||
updatedOn: '01.31.22',
|
||||
text: {
|
||||
block01: {
|
||||
pg01: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ornare aliquam pretium. Nullam id massa non augue suscipit porttitor quis quis dolor. Pellentesque porttitor sed turpis vitae pulvinar. Pellentesque a est venenatis, scelerisque lacus ac, vulputate lectus. Etiam porttitor sagittis nisi sit amet lacinia. Cras gravida ultricies porta. Curabitur semper nulla nisi, eget suscipit purus blandit porttitor. Fusce sagittis luctus sapien ut volutpat. Donec luctus, tellus nec gravida ullamcorper, ligula lacus sagittis lacus, ultrices ultricies dolor ligula vitae orci. Quisque a nisi nunc. Maecenas mattis dui id sem porta ultrices.',
|
||||
pg02: 'Duis quis leo non ex gravida placerat a ac urna. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus facilisis ipsum ut risus egestas ornare. Phasellus et leo eu purus hendrerit auctor. Nam accumsan enim nec massa semper, vel porttitor neque efficitur. Duis a convallis nulla, a mattis turpis. Mauris a blandit ex. Phasellus sit amet vestibulum purus. Maecenas rutrum pretium lectus ut tincidunt. Donec mollis quam sit amet condimentum lacinia.',
|
||||
|
||||
pg03: 'In elementum et felis in elementum. Maecenas nunc nisi, pretium a lobortis interdum, venenatis ut erat. Cras euismod dignissim molestie. Proin commodo nisl at risus gravida facilisis. Donec sit amet magna odio. Pellentesque posuere in risus nec vehicula. Etiam euismod risus eget congue placerat. Pellentesque nec orci ac velit finibus semper a egestas nunc. Integer venenatis, libero sed faucibus tincidunt, massa lorem ullamcorper lacus, quis dignissim libero dolor a nunc. Suspendisse eu accumsan nisi. Integer vitae maximus purus. Nam ut velit a eros tristique feugiat accumsan vitae ex. Pellentesque metus urna, varius non nisl non, molestie sodales diam. Proin sit amet ullamcorper justo. Mauris vehicula dictum imperdiet. Etiam laoreet diam at nunc consectetur sollicitudin.',
|
||||
|
||||
pg04: 'Pellentesque ante libero, pellentesque ac sodales et, consectetur a ipsum. Integer aliquam massa et mattis tristique. Praesent id egestas magna. Nam cursus, lectus ac ornare convallis, nisl metus euismod nibh, sed fermentum velit nulla eu neque. Quisque pulvinar enim vel metus aliquam congue. Aenean sit amet ex euismod, ultrices sem quis, dapibus leo. Ut luctus pellentesque orci, fermentum porttitor libero congue eu.'
|
||||
},
|
||||
block02: {
|
||||
title: '1. Lorem Ipsum',
|
||||
pg01: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
|
||||
},
|
||||
block03: {
|
||||
title: '2. Lorem Ipsum',
|
||||
pg01: 'Quisque id tristique quam, vitae feugiat orci. Nulla vel nulla et massa fringilla faucibus. Suspendisse semper arcu nec leo maximus fringilla. Praesent id elementum turpis. Cras sit amet nunc sed nunc tempus placerat vel ultrices urna. Aenean scelerisque porta massa, vel sodales turpis porta quis. Aliquam euismod neque ac eros dictum, ac dapibus risus convallis. Mauris risus orci, porttitor et semper eu, accumsan a tellus. Ut posuere venenatis urna sit amet laoreet. Curabitur id justo ut lacus pretium ultrices et in tortor. Phasellus dignissim, justo quis dapibus viverra, nulla justo faucibus sem, quis tristique nulla mi nec purus. Morbi dolor magna, congue ut tempor id, vestibulum et eros. Praesent at quam purus. Nam eget tincidunt tellus, non tristique quam. Vivamus nulla libero, placerat et orci ac.'
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -41,7 +41,7 @@
|
||||
|
||||
line-height: 1.35;
|
||||
font-size: tovw(30px, 'default', 18px);
|
||||
width: tovw(635px, 'default', 300px);
|
||||
width: tovw(585px, 'default', 300px);
|
||||
margin-top: tovw(62px, 'default', 30px);
|
||||
}
|
||||
}
|
||||
@ -61,7 +61,7 @@
|
||||
}
|
||||
|
||||
top: tovw(-250px);
|
||||
left: tovw(-400px);
|
||||
left: tovw(-350px);
|
||||
width: tovw(1060px, 'default', 300px);
|
||||
position: absolute;
|
||||
|
||||
|
||||
@ -4,31 +4,36 @@ import Heading from '~/components/primitives/heading'
|
||||
|
||||
import s from './app.module.scss'
|
||||
|
||||
const AppSection = () => {
|
||||
interface Props {
|
||||
data: {
|
||||
appDescription: string
|
||||
appHeading: string
|
||||
appImg: {
|
||||
url: string
|
||||
}
|
||||
appMobileImg: {
|
||||
url: string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const AppSection = ({ data }: Props) => {
|
||||
return (
|
||||
<Section className={s['section']} id="laconicapp">
|
||||
<Container className={s['container']}>
|
||||
<div>
|
||||
<img
|
||||
className={s.app__img}
|
||||
src="/images/products/app.png"
|
||||
alt="token"
|
||||
/>
|
||||
<img className={s.app__img} src={data?.appImg?.url} alt="app" />
|
||||
<img
|
||||
className={s.app__img__mobile}
|
||||
src="/images/products/app-mobile.jpg"
|
||||
alt="token"
|
||||
src={data?.appMobileImg?.url}
|
||||
alt="app"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Heading as="h2" variant="lg">
|
||||
Laconic App
|
||||
{data?.appHeading}
|
||||
</Heading>
|
||||
<p>
|
||||
Laconic Wallet leverages an in-browser IPFS payment channel,
|
||||
enabling users of the network to transact quickly and easily with
|
||||
LNT and ERC20 tokens.
|
||||
</p>
|
||||
<p>{data?.appDescription}</p>
|
||||
</div>
|
||||
</Container>
|
||||
</Section>
|
||||
|
||||
@ -7,7 +7,23 @@ import Heading from '~/components/primitives/heading'
|
||||
|
||||
import s from './hero.module.scss'
|
||||
|
||||
const Hero = () => {
|
||||
interface Props {
|
||||
data: {
|
||||
heroHeading: string
|
||||
heroDescription: string
|
||||
heroItem01: string
|
||||
heroItem02: string
|
||||
heroItem03: string
|
||||
heroItem04: string
|
||||
heroItem05: string
|
||||
heroS01Heading: string
|
||||
heroS01Desc: string
|
||||
heroS02Heading: string
|
||||
heroS02Desc: string
|
||||
}
|
||||
}
|
||||
|
||||
const Hero = ({ data }: Props) => {
|
||||
const heroVideoRef = useRef<HTMLVideoElement>(null)
|
||||
|
||||
// const loop = () => {
|
||||
@ -42,43 +58,31 @@ const Hero = () => {
|
||||
<div className={s.body}>
|
||||
<div>
|
||||
<Heading as="h1" variant="xl">
|
||||
Products
|
||||
{data?.heroHeading}
|
||||
</Heading>
|
||||
<Arrow className={s['arrow']} />
|
||||
</div>
|
||||
<div className={s.text__container}>
|
||||
<p>
|
||||
Laconic is the only data solution that provides accurate,
|
||||
low-cost, multi-chain, verifiable blockchain data by leveraging
|
||||
cryptographic proofs, cutting-edge data-caching engineering, and a
|
||||
secure verifiable data marketplace:
|
||||
</p>
|
||||
<p>{data?.heroDescription}</p>
|
||||
<div>
|
||||
<ol>
|
||||
<li>Laconic Watchers (SDK)</li>
|
||||
<li>Laconic Stack</li>
|
||||
<li>Laconic Network</li>
|
||||
<li>Laconic App</li>
|
||||
<li>Laconic Network Token (LNT)</li>
|
||||
<li>{data?.heroItem01}</li>
|
||||
<li>{data?.heroItem02}</li>
|
||||
<li>{data?.heroItem03}</li>
|
||||
<li>{data?.heroItem04}</li>
|
||||
<li>{data?.heroItem05}</li>
|
||||
</ol>
|
||||
<div>
|
||||
<Heading as="h2" variant="sm">
|
||||
DeFi
|
||||
{data?.heroS01Heading}
|
||||
</Heading>
|
||||
<p>
|
||||
Laconic enables simple and efficient DApp development, and the
|
||||
most flexible views of the Ethereum state.
|
||||
</p>
|
||||
<p>{data?.heroS01Desc}</p>
|
||||
</div>
|
||||
<div>
|
||||
<Heading as="h2" variant="sm">
|
||||
NFTs
|
||||
{data?.heroS02Heading}
|
||||
</Heading>
|
||||
<p>
|
||||
Laconic exposes cross-chain history and metadata associated
|
||||
with an NFT, enabling provably accurate data for DApps and
|
||||
Marketplaces.
|
||||
</p>
|
||||
<p>{data?.heroS02Desc}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -5,49 +5,54 @@ import Heading from '~/components/primitives/heading'
|
||||
|
||||
import s from './network.module.scss'
|
||||
|
||||
const Network = () => {
|
||||
interface Props {
|
||||
data: {
|
||||
networkHeading: string
|
||||
networkDesc: string
|
||||
networkListItem01: string
|
||||
networkListItem02: string
|
||||
networkListItem03: string
|
||||
networkImg: {
|
||||
url: string
|
||||
}
|
||||
networkMobileImg: {
|
||||
url: string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const Network = ({ data }: Props) => {
|
||||
return (
|
||||
<Section className={s['section']} id="laconicnetwork">
|
||||
<Container className={s['container']}>
|
||||
<div>
|
||||
<Heading as="h2" variant="lg">
|
||||
Laconic Network
|
||||
{data?.networkHeading}
|
||||
</Heading>
|
||||
<p>
|
||||
An open, interoperable, verifiable data marketplace and ecosystem of
|
||||
service providers, DApp operators, and data consumers providing
|
||||
low-cost, decentralized, and disintermediated horizontal scaling
|
||||
solutions for projects leveraging Laconic Stack.
|
||||
</p>
|
||||
<p>{data?.networkDesc}</p>
|
||||
<img
|
||||
className={s.network__img__mobile}
|
||||
src="/images/products/network-mobile.jpg"
|
||||
src={data?.networkMobileImg?.url}
|
||||
alt="network"
|
||||
/>
|
||||
<div className={s.features}>
|
||||
<div>
|
||||
<img src="/images/products/nw-01.png" alt="" />
|
||||
<p>
|
||||
Seamlessly connects DApps and bridges with data service
|
||||
providers
|
||||
</p>
|
||||
<p>{data?.networkListItem01}</p>
|
||||
</div>
|
||||
<div>
|
||||
<img src="/images/products/nw-02.png" alt="" />
|
||||
<p>Leverages state-channel-based payment infrastructure</p>
|
||||
<p>{data?.networkListItem02}</p>
|
||||
</div>
|
||||
<div>
|
||||
<img src="/images/products/nw-03.png" alt="" />
|
||||
<p>
|
||||
Provides highest quality services at the lowest prices via
|
||||
marketplace model
|
||||
</p>
|
||||
<p>{data?.networkListItem03}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<img
|
||||
className={s.network__img}
|
||||
src="/images/products/network.jpg"
|
||||
src={data?.networkImg?.url}
|
||||
alt="network"
|
||||
/>
|
||||
</Container>
|
||||
|
||||
@ -1,30 +1,44 @@
|
||||
// import { Arrow } from '~/components/icons/arrow'
|
||||
import Line from '~/components/icons/line'
|
||||
import { Container } from '~/components/layout/container'
|
||||
import Section from '~/components/layout/section'
|
||||
import Heading from '~/components/primitives/heading'
|
||||
|
||||
// import Link from '~/components/primitives/link'
|
||||
import { stackData } from './stack'
|
||||
import s from './stack.module.scss'
|
||||
|
||||
const Stack = () => {
|
||||
interface Props {
|
||||
data: {
|
||||
stackDescription: string
|
||||
stackHeading: string
|
||||
stackListData: {
|
||||
stackData: {
|
||||
title: string
|
||||
content: string
|
||||
}[]
|
||||
}
|
||||
stackImage: {
|
||||
url: string
|
||||
}
|
||||
stackSvgImg: {
|
||||
url: string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const Stack = ({ data }: Props) => {
|
||||
const stackData = data?.stackListData?.stackData
|
||||
|
||||
return (
|
||||
<Section className={s['section']} id="laconicstack">
|
||||
<Container className={s['container']}>
|
||||
<div className={s.header}>
|
||||
<Heading as="h2" variant="lg">
|
||||
Laconic Stack
|
||||
{data?.stackHeading}
|
||||
</Heading>
|
||||
<p>
|
||||
Laconic Stack is a set of essential and verifiable technologies and
|
||||
services that significantly simplify DApp development and make DApps
|
||||
accessible to a wider audience of developers.
|
||||
</p>
|
||||
<p>{data?.stackDescription}</p>
|
||||
</div>
|
||||
<div>
|
||||
<ol>
|
||||
{stackData.map((item) => (
|
||||
{stackData?.map((item) => (
|
||||
<li key={item.title}>
|
||||
<div>
|
||||
<Heading as="h3" variant="sm" font="arthemys">
|
||||
@ -40,12 +54,12 @@ const Stack = () => {
|
||||
<div>
|
||||
<img
|
||||
className={s.stack__img}
|
||||
src="/images/products/stack.png"
|
||||
src={data?.stackImage?.url}
|
||||
alt="stack"
|
||||
/>
|
||||
<img
|
||||
className={`${s.stack__img} ${s.stack__img__small}`}
|
||||
src="/images/products/diagram.svg"
|
||||
src={data?.stackSvgImg?.url}
|
||||
alt="stack"
|
||||
/>
|
||||
<div className={s.gradient} />
|
||||
|
||||
@ -5,48 +5,52 @@ import Heading from '~/components/primitives/heading'
|
||||
|
||||
import s from './token.module.scss'
|
||||
|
||||
const Token = () => {
|
||||
interface Props {
|
||||
data: {
|
||||
tokenHeading: string
|
||||
tokenDesc: string
|
||||
tokenItem01: string
|
||||
tokenItem02: string
|
||||
tokenItem03: string
|
||||
tokenImg: {
|
||||
url: string
|
||||
}
|
||||
tokenMobileImg: {
|
||||
url: string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const Token = ({ data }: Props) => {
|
||||
return (
|
||||
<Section className={s['section']} id="laconictoken">
|
||||
<Container className={s['container']}>
|
||||
<div>
|
||||
<Heading as="h2" variant="lg">
|
||||
Laconic Network Token
|
||||
{data?.tokenHeading}
|
||||
</Heading>
|
||||
<p>
|
||||
With a fixed total supply, Laconic Network Token (LNT) serves
|
||||
multiple functions in the Network design, most saliently by securing
|
||||
incentive alignment across network stakeholders. LNT also allows for
|
||||
seamless payments across services, regardless of blockchain or DApp.
|
||||
</p>
|
||||
<p>{data?.tokenDesc}</p>
|
||||
<img
|
||||
className={s.token__img__mobile}
|
||||
src="/images/products/token-mobile.jpg"
|
||||
src={data?.tokenMobileImg?.url}
|
||||
alt="token"
|
||||
/>
|
||||
<div className={s.features}>
|
||||
<div>
|
||||
<img src="/images/products/tk-01.png" alt="" />
|
||||
<p>Distribute rewards to staked users</p>
|
||||
<img src="/images/products/tk-01.png" alt="item" />
|
||||
<p>{data?.tokenItem01}</p>
|
||||
</div>
|
||||
<div>
|
||||
<img src="/images/products/tk-03.png" alt="" />
|
||||
<p>Provide service discounts</p>
|
||||
<img src="/images/products/tk-03.png" alt="item" />
|
||||
<p>{data?.tokenItem02}</p>
|
||||
</div>
|
||||
<div>
|
||||
<img src="/images/products/tk-04.png" alt="" />
|
||||
<p>
|
||||
Distribute funds to community participants for Network
|
||||
maintenance and development
|
||||
</p>
|
||||
<img src="/images/products/tk-04.png" alt="item" />
|
||||
<p>{data?.tokenItem03}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<img
|
||||
className={s.token__img}
|
||||
src="/images/products/token.jpg"
|
||||
alt="token"
|
||||
/>
|
||||
<img className={s.token__img} src={data?.tokenImg?.url} alt="token" />
|
||||
</Container>
|
||||
</Section>
|
||||
)
|
||||
|
||||
@ -5,64 +5,64 @@ import Heading from '~/components/primitives/heading'
|
||||
|
||||
import s from './watchers.module.scss'
|
||||
|
||||
const Watchers = () => {
|
||||
interface Props {
|
||||
data: {
|
||||
watchersHeading: string
|
||||
watchersImage: {
|
||||
url: string
|
||||
}
|
||||
watchersMobileImage: {
|
||||
url: string
|
||||
}
|
||||
watchersItem01: string
|
||||
watchersItem02: string
|
||||
watchersItem03: string
|
||||
watchersListHead: string
|
||||
watchersP01: string
|
||||
watchersP02: string
|
||||
}
|
||||
}
|
||||
|
||||
const Watchers = ({ data }: Props) => {
|
||||
return (
|
||||
<Section className={s['section']} id="laconicwatchers">
|
||||
<Container className={s['container']}>
|
||||
<div>
|
||||
<p>
|
||||
Developers can leverage the Laconic SDK to develop Watchers, which
|
||||
are the components of the Laconic Network that makes DApp
|
||||
development fast and frictionless. Watchers are custom caches of
|
||||
IPLD blocks. By providing proofs with our IPLD versions of Ethereum
|
||||
data, a DApp can be fully verifiable with hundreds of megabytes
|
||||
instead of the tens of terabytes an archive node requires,
|
||||
dramatically increasing speed and efficiency, and lowering costs.
|
||||
</p>
|
||||
<p>
|
||||
With the services of a Watcher, a DApp developer can exactly define
|
||||
and customize the API they need. The Watcher runs queries that are
|
||||
efficient and relevant to the DApp. Another key benefit of Watchers
|
||||
is that they are composable, enabling a developer to reference data
|
||||
previously derived from the Ethereum blockchain by means of another
|
||||
Watcher, within their Watcher.
|
||||
</p>
|
||||
<p>A Watcher serves three fundamental purposes:</p>
|
||||
<p>{data?.watchersP01}</p>
|
||||
<p>{data?.watchersP02}</p>
|
||||
<p>{data?.watchersListHead}</p>
|
||||
<img
|
||||
className={s.watchers__img__mobile}
|
||||
src="/images/products/watchers-mobile.jpg"
|
||||
src={data?.watchersMobileImage?.url}
|
||||
alt="network"
|
||||
/>
|
||||
<div className={s.features}>
|
||||
<ol>
|
||||
<li>
|
||||
<p>It queries precisely the data a DApp needs.</p>
|
||||
<p>{data?.watchersItem01}</p>
|
||||
<Line className={s['line']} height={45} />
|
||||
</li>
|
||||
<li>
|
||||
<p>
|
||||
It transforms the queried data to make it consumable to the
|
||||
DApp.
|
||||
</p>
|
||||
<p>{data?.watchersItem02}</p>
|
||||
<Line className={s['line']} height={45} />
|
||||
</li>
|
||||
<li>
|
||||
<p>It caches the data for fast and inexpensive access.</p>
|
||||
<p>{data?.watchersItem03}</p>
|
||||
<Line className={s['line']} height={45} />
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
<div className={s.heading}>
|
||||
<Heading as="h2" variant="lg">
|
||||
Laconic
|
||||
<br className="hide-on-mobile" /> Watchers
|
||||
<br />
|
||||
(SDK)
|
||||
</Heading>
|
||||
<Heading
|
||||
as="h2"
|
||||
variant="lg"
|
||||
dangerouslySetInnerHTML={{ __html: data?.watchersHeading }}
|
||||
/>
|
||||
|
||||
<img
|
||||
className={s.watchers__img}
|
||||
src="/images/products/watchers.jpg"
|
||||
src={data?.watchersImage?.url}
|
||||
alt="network"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -1,31 +1,40 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
import { Container } from '~/components/layout/container'
|
||||
import Section from '~/components/layout/section'
|
||||
import Heading from '~/components/primitives/heading'
|
||||
import CustomStructuredText from '~/lib/renderer'
|
||||
|
||||
import { termsOfUse } from './termsofuse'
|
||||
import s from './termsofuse.module.scss'
|
||||
|
||||
const TermsOfUse = () => {
|
||||
interface Props {
|
||||
data: {
|
||||
termsContent: any
|
||||
_updatedAt: string
|
||||
}
|
||||
}
|
||||
|
||||
const TermsOfUse = ({ data }: Props) => {
|
||||
const [updatedOnDate, setUpdatedOnDate] = useState<string>()
|
||||
|
||||
useEffect(() => {
|
||||
setUpdatedOnDate(
|
||||
new Date(data?._updatedAt).toLocaleDateString('default', {
|
||||
day: '2-digit',
|
||||
month: '2-digit',
|
||||
year: '2-digit'
|
||||
})
|
||||
)
|
||||
}, [data?._updatedAt])
|
||||
|
||||
return (
|
||||
<Section className={s['section']}>
|
||||
<div className={s['header']}>
|
||||
<span>LAST UPDATE</span>
|
||||
<span className={s['separator']}>—</span>
|
||||
<span>{termsOfUse.updatedOn}</span>
|
||||
<span>{updatedOnDate}</span>
|
||||
</div>
|
||||
<Container className={s['container']}>
|
||||
<p>{termsOfUse.text.block01.pg01}</p>
|
||||
<p>{termsOfUse.text.block01.pg02}</p>
|
||||
<p>{termsOfUse.text.block01.pg03}</p>
|
||||
<p>{termsOfUse.text.block01.pg04}</p>
|
||||
<Heading as="h2" font="tthoves" variant="sm">
|
||||
{termsOfUse.text.block02.title}
|
||||
</Heading>
|
||||
<p>{termsOfUse.text.block02.pg01}</p>
|
||||
<Heading as="h2" font="tthoves" variant="sm">
|
||||
{termsOfUse.text.block03.title}
|
||||
</Heading>
|
||||
<p>{termsOfUse.text.block03.pg01}</p>
|
||||
<CustomStructuredText data={data?.termsContent} />
|
||||
</Container>
|
||||
</Section>
|
||||
)
|
||||
|
||||
@ -1,21 +0,0 @@
|
||||
export const termsOfUse = {
|
||||
updatedOn: '01.31.22',
|
||||
text: {
|
||||
block01: {
|
||||
pg01: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ornare aliquam pretium. Nullam id massa non augue suscipit porttitor quis quis dolor. Pellentesque porttitor sed turpis vitae pulvinar. Pellentesque a est venenatis, scelerisque lacus ac, vulputate lectus. Etiam porttitor sagittis nisi sit amet lacinia. Cras gravida ultricies porta. Curabitur semper nulla nisi, eget suscipit purus blandit porttitor. Fusce sagittis luctus sapien ut volutpat. Donec luctus, tellus nec gravida ullamcorper, ligula lacus sagittis lacus, ultrices ultricies dolor ligula vitae orci. Quisque a nisi nunc. Maecenas mattis dui id sem porta ultrices.',
|
||||
pg02: 'Duis quis leo non ex gravida placerat a ac urna. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus facilisis ipsum ut risus egestas ornare. Phasellus et leo eu purus hendrerit auctor. Nam accumsan enim nec massa semper, vel porttitor neque efficitur. Duis a convallis nulla, a mattis turpis. Mauris a blandit ex. Phasellus sit amet vestibulum purus. Maecenas rutrum pretium lectus ut tincidunt. Donec mollis quam sit amet condimentum lacinia.',
|
||||
|
||||
pg03: 'In elementum et felis in elementum. Maecenas nunc nisi, pretium a lobortis interdum, venenatis ut erat. Cras euismod dignissim molestie. Proin commodo nisl at risus gravida facilisis. Donec sit amet magna odio. Pellentesque posuere in risus nec vehicula. Etiam euismod risus eget congue placerat. Pellentesque nec orci ac velit finibus semper a egestas nunc. Integer venenatis, libero sed faucibus tincidunt, massa lorem ullamcorper lacus, quis dignissim libero dolor a nunc. Suspendisse eu accumsan nisi. Integer vitae maximus purus. Nam ut velit a eros tristique feugiat accumsan vitae ex. Pellentesque metus urna, varius non nisl non, molestie sodales diam. Proin sit amet ullamcorper justo. Mauris vehicula dictum imperdiet. Etiam laoreet diam at nunc consectetur sollicitudin.',
|
||||
|
||||
pg04: 'Pellentesque ante libero, pellentesque ac sodales et, consectetur a ipsum. Integer aliquam massa et mattis tristique. Praesent id egestas magna. Nam cursus, lectus ac ornare convallis, nisl metus euismod nibh, sed fermentum velit nulla eu neque. Quisque pulvinar enim vel metus aliquam congue. Aenean sit amet ex euismod, ultrices sem quis, dapibus leo. Ut luctus pellentesque orci, fermentum porttitor libero congue eu.'
|
||||
},
|
||||
block02: {
|
||||
title: '1. Lorem Ipsum',
|
||||
pg01: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
|
||||
},
|
||||
block03: {
|
||||
title: '2. Lorem Ipsum',
|
||||
pg01: 'Quisque id tristique quam, vitae feugiat orci. Nulla vel nulla et massa fringilla faucibus. Suspendisse semper arcu nec leo maximus fringilla. Praesent id elementum turpis. Cras sit amet nunc sed nunc tempus placerat vel ultrices urna. Aenean scelerisque porta massa, vel sodales turpis porta quis. Aliquam euismod neque ac eros dictum, ac dapibus risus convallis. Mauris risus orci, porttitor et semper eu, accumsan a tellus. Ut posuere venenatis urna sit amet laoreet. Curabitur id justo ut lacus pretium ultrices et in tortor. Phasellus dignissim, justo quis dapibus viverra, nulla justo faucibus sem, quis tristique nulla mi nec purus. Morbi dolor magna, congue ut tempor id, vestibulum et eros. Praesent at quam purus. Nam eget tincidunt tellus, non tristique quam. Vivamus nulla libero, placerat et orci ac.'
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -102,6 +102,10 @@ p {
|
||||
font-size: tovw(24px, 'default', 18px);
|
||||
}
|
||||
|
||||
.highlight {
|
||||
color: var(--color-accent);
|
||||
}
|
||||
|
||||
.sr-only {
|
||||
position: absolute;
|
||||
border: 0;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
44
src/lib/cms/queries/about.js
Normal file
44
src/lib/cms/queries/about.js
Normal file
@ -0,0 +1,44 @@
|
||||
const AboutHero = {
|
||||
query: `
|
||||
{
|
||||
aboutPage {
|
||||
heroCtaLabel
|
||||
heroCtaLink
|
||||
heroDescB01
|
||||
heroDescB02
|
||||
heroHeading
|
||||
heroTitle
|
||||
}
|
||||
}`
|
||||
}
|
||||
|
||||
const AboutTeam = {
|
||||
query: `
|
||||
{
|
||||
aboutPage {
|
||||
teamHeading
|
||||
teamDescB01
|
||||
teamDescB02
|
||||
}
|
||||
}`
|
||||
}
|
||||
|
||||
const Teams = {
|
||||
query: `
|
||||
{
|
||||
allTeams(orderBy: [id_ASC]) {
|
||||
id
|
||||
memberGithub
|
||||
memberImage {
|
||||
url
|
||||
}
|
||||
memberLinkedin
|
||||
memberName
|
||||
memberPosition
|
||||
memberTeam
|
||||
memberTwitter
|
||||
}
|
||||
}`
|
||||
}
|
||||
|
||||
export { AboutHero, AboutTeam, Teams }
|
||||
65
src/lib/cms/queries/community.js
Normal file
65
src/lib/cms/queries/community.js
Normal file
@ -0,0 +1,65 @@
|
||||
const CommunityHero = {
|
||||
query: `
|
||||
{
|
||||
communityPage {
|
||||
heroButton01
|
||||
heroButton02
|
||||
heroDescription
|
||||
heroHeading
|
||||
heroB01Link
|
||||
heroB02Link
|
||||
}
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
const Events = {
|
||||
query: `
|
||||
{
|
||||
allEvents(orderBy: [eventDatetime_ASC]) {
|
||||
eventDatetime
|
||||
eventDesc
|
||||
eventImage {
|
||||
url
|
||||
}
|
||||
eventLink
|
||||
eventLocation
|
||||
eventTitle
|
||||
id
|
||||
}
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
const CommunityEvents = {
|
||||
query: `
|
||||
{
|
||||
communityPage {
|
||||
eventsHeading
|
||||
eventsDescription
|
||||
}
|
||||
}`
|
||||
}
|
||||
|
||||
const CommunitySocials = {
|
||||
query: `
|
||||
{
|
||||
communityPage {
|
||||
socialsHeading
|
||||
socialsLine
|
||||
socialsImage {
|
||||
url
|
||||
}
|
||||
socialsTwitter
|
||||
socialsDiscord
|
||||
socialsDiscourse
|
||||
socialsReddit
|
||||
socialsTelegram
|
||||
socialsLinkedin
|
||||
socialsFacebook
|
||||
socialsInstagram
|
||||
}
|
||||
}`
|
||||
}
|
||||
|
||||
export { CommunityEvents, CommunityHero, CommunitySocials, Events }
|
||||
81
src/lib/cms/queries/home.js
Normal file
81
src/lib/cms/queries/home.js
Normal file
@ -0,0 +1,81 @@
|
||||
const HomeHero = {
|
||||
query: `
|
||||
{
|
||||
homePage {
|
||||
heroHeading
|
||||
heroButton01
|
||||
heroB01Link
|
||||
heroButton02
|
||||
heroB02Link
|
||||
heroSlogan
|
||||
}
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
const HomeBenefits = {
|
||||
query: `
|
||||
{
|
||||
homePage {
|
||||
benefitsDesc
|
||||
benefitsHeading
|
||||
benefitsS01Desc
|
||||
benefitsS01Heading
|
||||
benefitsS01Item01
|
||||
benefitsS01Item02
|
||||
benefitsS01Item03
|
||||
benefitsS01Item04
|
||||
benefitsS01Item05
|
||||
benefitsS01Item06
|
||||
benefitsS02Desc
|
||||
benefitsS02Heading
|
||||
benefitsS02Item01
|
||||
benefitsS02Item02
|
||||
benefitsS02Item03
|
||||
benefitsS02Item04
|
||||
benefitsS02Item05
|
||||
benefitsS02Item06
|
||||
benefitsButton
|
||||
benefitsButtonLink
|
||||
}
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
const HomeOthers = {
|
||||
query: `
|
||||
{
|
||||
homePage {
|
||||
othersHeading
|
||||
}
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
const Testimonials = {
|
||||
query: `
|
||||
{
|
||||
allTestimonials {
|
||||
id
|
||||
testimonialImage {
|
||||
url
|
||||
}
|
||||
testimonialPosition
|
||||
testimonialText
|
||||
testimonialUsername
|
||||
}
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
const HomeLatest = {
|
||||
query: `
|
||||
{
|
||||
homePage {
|
||||
latestHeading
|
||||
}
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
export { HomeBenefits, HomeHero, HomeLatest, HomeOthers, Testimonials }
|
||||
27
src/lib/cms/queries/legal.js
Normal file
27
src/lib/cms/queries/legal.js
Normal file
@ -0,0 +1,27 @@
|
||||
const Terms = {
|
||||
query: `
|
||||
{
|
||||
termsPage {
|
||||
termsContent {
|
||||
value
|
||||
blocks
|
||||
}
|
||||
_updatedAt
|
||||
}
|
||||
}`
|
||||
}
|
||||
|
||||
const Privacy = {
|
||||
query: `
|
||||
{
|
||||
privacyPage {
|
||||
privacyContent {
|
||||
value
|
||||
blocks
|
||||
}
|
||||
_updatedAt
|
||||
}
|
||||
}`
|
||||
}
|
||||
|
||||
export { Privacy, Terms }
|
||||
125
src/lib/cms/queries/products.js
Normal file
125
src/lib/cms/queries/products.js
Normal file
@ -0,0 +1,125 @@
|
||||
const ProductsHero = {
|
||||
query: `
|
||||
{
|
||||
productsPage {
|
||||
heroDescription
|
||||
heroHeading
|
||||
heroItem01
|
||||
heroItem02
|
||||
heroItem03
|
||||
heroItem04
|
||||
heroItem05
|
||||
heroS01Desc
|
||||
heroS01Heading
|
||||
heroS02Desc
|
||||
heroS02Heading
|
||||
}
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
const ProductsWatchers = {
|
||||
query: `
|
||||
{
|
||||
productsPage {
|
||||
watchersHeading
|
||||
watchersImage {
|
||||
url
|
||||
}
|
||||
watchersMobileImage {
|
||||
url
|
||||
}
|
||||
watchersItem01
|
||||
watchersItem02
|
||||
watchersItem03
|
||||
watchersListHead
|
||||
watchersP01
|
||||
watchersP02
|
||||
}
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
const ProductsStack = {
|
||||
query: `
|
||||
{
|
||||
productsPage {
|
||||
stackDescription
|
||||
stackHeading
|
||||
stackListData
|
||||
stackImage {
|
||||
url
|
||||
}
|
||||
stackSvgImg {
|
||||
url
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
const ProductsNetwork = {
|
||||
query: `
|
||||
{
|
||||
productsPage {
|
||||
networkDesc
|
||||
networkHeading
|
||||
networkListItem01
|
||||
networkListItem02
|
||||
networkListItem03
|
||||
networkImg {
|
||||
url
|
||||
}
|
||||
networkMobileImg {
|
||||
url
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
const ProductsApp = {
|
||||
query: `
|
||||
{
|
||||
productsPage {
|
||||
appDescription
|
||||
appHeading
|
||||
appImg {
|
||||
url
|
||||
}
|
||||
appMobileImg {
|
||||
url
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
const ProductsToken = {
|
||||
query: `
|
||||
{
|
||||
productsPage {
|
||||
tokenHeading
|
||||
tokenDesc
|
||||
tokenImg {
|
||||
url
|
||||
}
|
||||
tokenItem01
|
||||
tokenItem02
|
||||
tokenItem03
|
||||
tokenMobileImg {
|
||||
url
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
export {
|
||||
ProductsApp,
|
||||
ProductsHero,
|
||||
ProductsNetwork,
|
||||
ProductsStack,
|
||||
ProductsToken,
|
||||
ProductsWatchers
|
||||
}
|
||||
33
src/lib/datocms.ts
Normal file
33
src/lib/datocms.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import tiny from 'tiny-json-http'
|
||||
|
||||
interface props {
|
||||
query: string
|
||||
variables?: string
|
||||
preview?: string
|
||||
}
|
||||
|
||||
export async function request({ query, variables, preview }: props) {
|
||||
let endpoint = 'https://graphql.datocms.com'
|
||||
|
||||
if (preview) {
|
||||
endpoint += `/preview`
|
||||
}
|
||||
|
||||
const { body } = await tiny.post({
|
||||
url: endpoint,
|
||||
headers: {
|
||||
authorization: `Bearer ${process.env.NEXT_PUBLIC_CMS_ACCESS_TOKEN}`
|
||||
},
|
||||
data: {
|
||||
query,
|
||||
variables
|
||||
}
|
||||
})
|
||||
|
||||
if (body.errors) {
|
||||
console.error('The query has errors!')
|
||||
throw body.errors
|
||||
}
|
||||
|
||||
return body.data
|
||||
}
|
||||
@ -9,6 +9,9 @@ import { PageLayout } from '~/components/layout/page'
|
||||
import Hero from '~/components/sections/about/hero'
|
||||
import Related from '~/components/sections/about/related'
|
||||
import Team from '~/components/sections/about/team'
|
||||
import { AboutHero, AboutTeam, Teams } from '~/lib/cms/queries/about'
|
||||
|
||||
import { request } from '../lib/datocms'
|
||||
|
||||
export const getStaticProps = async () => {
|
||||
const [allBlogPosts, categories] = await Promise.all([
|
||||
@ -18,12 +21,21 @@ export const getStaticProps = async () => {
|
||||
|
||||
const heroBlogPost = allBlogPosts.data[0]
|
||||
|
||||
const [heroData, teamsData, teamsPageData] = await Promise.all([
|
||||
request(AboutHero),
|
||||
request(Teams),
|
||||
request(AboutTeam)
|
||||
])
|
||||
|
||||
return {
|
||||
props: {
|
||||
initialBlogPosts: {
|
||||
pagination: allBlogPosts.pagination,
|
||||
data: allBlogPosts.data.slice(0, 3)
|
||||
},
|
||||
heroData: heroData?.aboutPage,
|
||||
teamsData: teamsData?.allTeams,
|
||||
teamsPageData: teamsPageData?.aboutPage,
|
||||
categories,
|
||||
page:
|
||||
{
|
||||
@ -35,7 +47,10 @@ export const getStaticProps = async () => {
|
||||
}
|
||||
|
||||
const About = ({
|
||||
initialBlogPosts
|
||||
initialBlogPosts,
|
||||
heroData,
|
||||
teamsData,
|
||||
teamsPageData
|
||||
}: InferGetStaticPropsType<typeof getStaticProps>) => {
|
||||
return (
|
||||
<PageLayout>
|
||||
@ -45,8 +60,8 @@ const About = ({
|
||||
{ href: '/videos/banner-about.webm', as: 'fetch' }
|
||||
]}
|
||||
/>
|
||||
<Hero />
|
||||
<Team />
|
||||
<Hero data={heroData} />
|
||||
<Team teamData={teamsData} data={teamsPageData} />
|
||||
<Related data={initialBlogPosts?.data} />
|
||||
</PageLayout>
|
||||
)
|
||||
|
||||
@ -1,12 +1,45 @@
|
||||
import { InferGetStaticPropsType } from 'next'
|
||||
|
||||
import { Meta } from '~/components/common/meta'
|
||||
import { PageLayout } from '~/components/layout/page'
|
||||
import Events from '~/components/sections/community/events'
|
||||
import Hero from '~/components/sections/community/hero'
|
||||
import Socials from '~/components/sections/community/socials'
|
||||
import {
|
||||
CommunityEvents,
|
||||
CommunityHero,
|
||||
CommunitySocials,
|
||||
Events as EventsQuery
|
||||
} from '~/lib/cms/queries/community'
|
||||
|
||||
import { Page } from './_app'
|
||||
import { request } from '../lib/datocms'
|
||||
|
||||
const Community: Page = () => {
|
||||
export const getStaticProps = async () => {
|
||||
const [heroData, eventsData, eventsSectionData, socialsData] =
|
||||
await Promise.all([
|
||||
request(CommunityHero),
|
||||
request(EventsQuery),
|
||||
request(CommunityEvents),
|
||||
request(CommunitySocials)
|
||||
])
|
||||
|
||||
return {
|
||||
props: {
|
||||
heroData: heroData?.communityPage,
|
||||
eventsData: eventsData?.allEvents,
|
||||
eventsSectionData: eventsSectionData?.communityPage,
|
||||
socialsData: socialsData?.communityPage
|
||||
},
|
||||
revalidate: 60
|
||||
}
|
||||
}
|
||||
|
||||
const Community = ({
|
||||
heroData,
|
||||
eventsData,
|
||||
eventsSectionData,
|
||||
socialsData
|
||||
}: InferGetStaticPropsType<typeof getStaticProps>) => {
|
||||
return (
|
||||
<PageLayout>
|
||||
<Meta
|
||||
@ -15,9 +48,9 @@ const Community: Page = () => {
|
||||
{ href: '/videos/banner-community.webm', as: 'fetch' }
|
||||
]}
|
||||
/>
|
||||
<Hero />
|
||||
<Events />
|
||||
<Socials />
|
||||
<Hero data={heroData} />
|
||||
<Events eventsData={eventsData} data={eventsSectionData} />
|
||||
<Socials data={socialsData} />
|
||||
</PageLayout>
|
||||
)
|
||||
}
|
||||
|
||||
@ -10,6 +10,15 @@ import Benefits from '~/components/sections/homepage/benefits'
|
||||
import Hero from '~/components/sections/homepage/hero'
|
||||
import LatestNews from '~/components/sections/homepage/latest-news'
|
||||
import WhatOthersSay from '~/components/sections/homepage/what-others-say'
|
||||
import {
|
||||
HomeBenefits,
|
||||
HomeHero,
|
||||
HomeLatest,
|
||||
HomeOthers,
|
||||
Testimonials
|
||||
} from '~/lib/cms/queries/home'
|
||||
|
||||
import { request } from '../lib/datocms'
|
||||
|
||||
export const getStaticProps = async () => {
|
||||
const [allBlogPosts, categories] = await Promise.all([
|
||||
@ -19,12 +28,26 @@ export const getStaticProps = async () => {
|
||||
|
||||
const heroBlogPost = allBlogPosts.data[0]
|
||||
|
||||
const [heroData, benefitsData, othersData, latestData, testimonialsData] =
|
||||
await Promise.all([
|
||||
request(HomeHero),
|
||||
request(HomeBenefits),
|
||||
request(HomeOthers),
|
||||
request(HomeLatest),
|
||||
request(Testimonials)
|
||||
])
|
||||
|
||||
return {
|
||||
props: {
|
||||
initialBlogPosts: {
|
||||
pagination: allBlogPosts.pagination,
|
||||
data: allBlogPosts.data.slice(0, 8)
|
||||
},
|
||||
heroData: heroData?.homePage,
|
||||
benefitsData: benefitsData?.homePage,
|
||||
othersData: othersData?.homePage,
|
||||
latestData: latestData?.homePage,
|
||||
testimonialsData: testimonialsData?.allTestimonials,
|
||||
categories,
|
||||
page:
|
||||
{
|
||||
@ -36,15 +59,20 @@ export const getStaticProps = async () => {
|
||||
}
|
||||
|
||||
const HomePage = ({
|
||||
initialBlogPosts
|
||||
initialBlogPosts,
|
||||
heroData,
|
||||
benefitsData,
|
||||
latestData,
|
||||
othersData,
|
||||
testimonialsData
|
||||
}: InferGetStaticPropsType<typeof getStaticProps>) => {
|
||||
return (
|
||||
<PageLayout>
|
||||
<Meta preload={[{ href: '/videos/hero-grid.mp4', as: 'fetch' }]} />
|
||||
<Hero />
|
||||
<Benefits />
|
||||
<LatestNews data={initialBlogPosts?.data} />
|
||||
<WhatOthersSay />
|
||||
<Hero data={heroData} />
|
||||
<Benefits data={benefitsData} />
|
||||
<LatestNews blogData={initialBlogPosts?.data} data={latestData} />
|
||||
<WhatOthersSay data={othersData} testimonialsData={testimonialsData} />
|
||||
</PageLayout>
|
||||
)
|
||||
}
|
||||
|
||||
@ -1,18 +1,34 @@
|
||||
import { InferGetStaticPropsType } from 'next'
|
||||
|
||||
import { Meta } from '~/components/common/meta'
|
||||
import { PageLayout } from '~/components/layout/page'
|
||||
import Hero from '~/components/sections/privacy/hero'
|
||||
import s from '~/components/sections/privacy/hero/hero.module.scss'
|
||||
import PrivacyPolicy from '~/components/sections/privacy/privacypolicy'
|
||||
import { Privacy as PrivacyQuery } from '~/lib/cms/queries/legal'
|
||||
|
||||
import { Page } from './_app'
|
||||
import { request } from '../lib/datocms'
|
||||
|
||||
const Privacy: Page = () => {
|
||||
export const getStaticProps = async () => {
|
||||
const [privacyData] = await Promise.all([request(PrivacyQuery)])
|
||||
|
||||
return {
|
||||
props: {
|
||||
privacyData: privacyData?.privacyPage
|
||||
},
|
||||
revalidate: 60
|
||||
}
|
||||
}
|
||||
|
||||
const Privacy = ({
|
||||
privacyData
|
||||
}: InferGetStaticPropsType<typeof getStaticProps>) => {
|
||||
return (
|
||||
<PageLayout>
|
||||
<div className={s.gradient}></div>
|
||||
<Meta />
|
||||
<Hero />
|
||||
<PrivacyPolicy />
|
||||
<PrivacyPolicy data={privacyData} />
|
||||
</PageLayout>
|
||||
)
|
||||
}
|
||||
|
||||
@ -13,6 +13,16 @@ import Network from '~/components/sections/products/network'
|
||||
import Stack from '~/components/sections/products/stack'
|
||||
import Token from '~/components/sections/products/token'
|
||||
import Watchers from '~/components/sections/products/watchers'
|
||||
import {
|
||||
ProductsApp,
|
||||
ProductsHero,
|
||||
ProductsNetwork,
|
||||
ProductsStack,
|
||||
ProductsToken,
|
||||
ProductsWatchers
|
||||
} from '~/lib/cms/queries/products'
|
||||
|
||||
import { request } from '../lib/datocms'
|
||||
|
||||
export const getStaticProps = async () => {
|
||||
const [allBlogPosts, categories] = await Promise.all([
|
||||
@ -22,12 +32,28 @@ export const getStaticProps = async () => {
|
||||
|
||||
const heroBlogPost = allBlogPosts.data[0]
|
||||
|
||||
const [heroData, watchersData, stackData, networkData, appData, tokenData] =
|
||||
await Promise.all([
|
||||
request(ProductsHero),
|
||||
request(ProductsWatchers),
|
||||
request(ProductsStack),
|
||||
request(ProductsNetwork),
|
||||
request(ProductsApp),
|
||||
request(ProductsToken)
|
||||
])
|
||||
|
||||
return {
|
||||
props: {
|
||||
initialBlogPosts: {
|
||||
pagination: allBlogPosts.pagination,
|
||||
data: allBlogPosts.data.slice(0, 3)
|
||||
},
|
||||
heroData: heroData?.productsPage,
|
||||
watchersData: watchersData?.productsPage,
|
||||
stackData: stackData?.productsPage,
|
||||
networkData: networkData?.productsPage,
|
||||
appData: appData?.productsPage,
|
||||
tokenData: tokenData?.productsPage,
|
||||
categories,
|
||||
page:
|
||||
{
|
||||
@ -39,7 +65,13 @@ export const getStaticProps = async () => {
|
||||
}
|
||||
|
||||
const Products = ({
|
||||
initialBlogPosts
|
||||
initialBlogPosts,
|
||||
heroData,
|
||||
watchersData,
|
||||
stackData,
|
||||
networkData,
|
||||
appData,
|
||||
tokenData
|
||||
}: InferGetStaticPropsType<typeof getStaticProps>) => {
|
||||
return (
|
||||
<PageLayout>
|
||||
@ -49,12 +81,12 @@ const Products = ({
|
||||
{ href: '/videos/banner-products.webm', as: 'fetch' }
|
||||
]}
|
||||
/>
|
||||
<Hero />
|
||||
<Watchers />
|
||||
<Stack />
|
||||
<Network />
|
||||
<AppSection />
|
||||
<Token />
|
||||
<Hero data={heroData} />
|
||||
<Watchers data={watchersData} />
|
||||
<Stack data={stackData} />
|
||||
<Network data={networkData} />
|
||||
<AppSection data={appData} />
|
||||
<Token data={tokenData} />
|
||||
<Related data={initialBlogPosts?.data} />
|
||||
</PageLayout>
|
||||
)
|
||||
|
||||
@ -1,18 +1,34 @@
|
||||
import { InferGetStaticPropsType } from 'next'
|
||||
|
||||
import { Meta } from '~/components/common/meta'
|
||||
import { PageLayout } from '~/components/layout/page'
|
||||
import Hero from '~/components/sections/terms/hero'
|
||||
import s from '~/components/sections/terms/hero/hero.module.scss'
|
||||
import TermsOfUse from '~/components/sections/terms/termsofuse'
|
||||
import { Terms as TermsQuery } from '~/lib/cms/queries/legal'
|
||||
|
||||
import { Page } from './_app'
|
||||
import { request } from '../lib/datocms'
|
||||
|
||||
const Terms: Page = () => {
|
||||
export const getStaticProps = async () => {
|
||||
const [termsData] = await Promise.all([request(TermsQuery)])
|
||||
|
||||
return {
|
||||
props: {
|
||||
termsData: termsData?.termsPage
|
||||
},
|
||||
revalidate: 60
|
||||
}
|
||||
}
|
||||
|
||||
const Terms = ({
|
||||
termsData
|
||||
}: InferGetStaticPropsType<typeof getStaticProps>) => {
|
||||
return (
|
||||
<PageLayout>
|
||||
<div className={s.gradient}></div>
|
||||
<Meta />
|
||||
<Hero />
|
||||
<TermsOfUse />
|
||||
<TermsOfUse data={termsData} />
|
||||
</PageLayout>
|
||||
)
|
||||
}
|
||||
|
||||
24
yarn.lock
24
yarn.lock
@ -1131,6 +1131,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39"
|
||||
integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==
|
||||
|
||||
"@types/tiny-json-http@^7.3.1":
|
||||
version "7.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/tiny-json-http/-/tiny-json-http-7.3.1.tgz#40339b990b7251689646b985823aa53487dcd77d"
|
||||
integrity sha512-mJwIwN1W9VLVM7FrGPuWabuEH5FqcOGZByqV4qOSNiwMKtEKym5+6Dyhx2v7vbR/4rSjjUgngmYimaDHQbZQsw==
|
||||
|
||||
"@types/websocket@^1.0.4":
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/websocket/-/websocket-1.0.5.tgz#3fb80ed8e07f88e51961211cd3682a3a4a81569c"
|
||||
@ -2116,6 +2121,15 @@ datocms-structured-text-generic-html-renderer@^2.0.1, datocms-structured-text-ge
|
||||
dependencies:
|
||||
datocms-structured-text-utils "^2.0.4"
|
||||
|
||||
datocms-structured-text-to-html-string@^2.0.4:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/datocms-structured-text-to-html-string/-/datocms-structured-text-to-html-string-2.0.4.tgz#8379040b3af3bbf72c0293ad8a00b30c93bee7b1"
|
||||
integrity sha512-ulet6wg3cxY4e4Edh0ilMfTfBK8VHeYZwhusx/fJSyk/3A1+PGiQ9EU2j2+OkOxvq+ePo0Iyzi7hgMEutSPRQQ==
|
||||
dependencies:
|
||||
datocms-structured-text-generic-html-renderer "^2.0.4"
|
||||
datocms-structured-text-utils "^2.0.4"
|
||||
vhtml "^2.2.0"
|
||||
|
||||
datocms-structured-text-to-plain-text@^2.0.4:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/datocms-structured-text-to-plain-text/-/datocms-structured-text-to-plain-text-2.0.4.tgz#9798c5ea06417e7da4b4b14d1ed3dd9c0d550944"
|
||||
@ -5832,6 +5846,11 @@ through@^2.3.6, through@^2.3.8:
|
||||
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
|
||||
|
||||
tiny-json-http@^7.4.2:
|
||||
version "7.4.2"
|
||||
resolved "https://registry.yarnpkg.com/tiny-json-http/-/tiny-json-http-7.4.2.tgz#2948d7a7f650d69df65f10982f126b5c5520ce3d"
|
||||
integrity sha512-+3ns4PfQTLaF69zGASkAfDoOEVmwYTXSDrU6VR93h317uFOW7evFzKa7Ih9JzPHiYSee3lUXHLAGhws2wFSexQ==
|
||||
|
||||
title-case@^3.0.3:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/title-case/-/title-case-3.0.3.tgz#bc689b46f02e411f1d1e1d081f7c3deca0489982"
|
||||
@ -6085,6 +6104,11 @@ value-or-promise@1.0.11, value-or-promise@^1.0.11:
|
||||
resolved "https://registry.yarnpkg.com/value-or-promise/-/value-or-promise-1.0.11.tgz#3e90299af31dd014fe843fe309cefa7c1d94b140"
|
||||
integrity sha512-41BrgH+dIbCFXClcSapVs5M6GkENd3gQOJpEfPDNa71LsUGMXDL0jMWpI/Rh7WhX+Aalfz2TTS3Zt5pUsbnhLg==
|
||||
|
||||
vhtml@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/vhtml/-/vhtml-2.2.0.tgz#369e6823ed6c32cbb9f6e33395bae7c65faa014c"
|
||||
integrity sha512-TPXrXrxBOslRUVnlVkiAqhoXneiertIg86bdvzionrUYhEuiROvyPZNiiP6GIIJ2Q7oPNVyEtIx8gMAZZE9lCQ==
|
||||
|
||||
wcwidth@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user