conflicts

This commit is contained in:
oriofir 2022-09-09 14:43:53 -07:00
commit 21b946f97c
13 changed files with 6021 additions and 2708 deletions

35
package-lock.json generated
View File

@ -38,6 +38,7 @@
"react-dom": "^18.2.0",
"react-fast-marquee": "^1.3.1",
"react-google-recaptcha": "^2.1.0",
"react-google-recaptcha-v3": "^1.10.0",
"react-hook-form": "^7.30.0",
"react-mailchimp-subscribe": "^2.1.3",
"react-merge-refs": "^1.1.0",
@ -82,7 +83,7 @@
"stylelint-config-standard": "^25.0.0",
"stylelint-config-standard-scss": "^3.0.0",
"stylelint-prettier": "^2.0.0",
"typescript": "^4.6.3"
"typescript": "^4.8.2"
},
"engines": {
"node": ">=14.x",
@ -9358,6 +9359,18 @@
"react": ">=16.4.1"
}
},
"node_modules/react-google-recaptcha-v3": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/react-google-recaptcha-v3/-/react-google-recaptcha-v3-1.10.0.tgz",
"integrity": "sha512-JBoqU107X8klQmS8tQSbQh1IMsT1fH3kVoArIqnia0rtn0rPNG9Ld+9rD/dHJMculIczSZpGvIJTXXwtsolMcg==",
"dependencies": {
"hoist-non-react-statics": "^3.3.2"
},
"peerDependencies": {
"react": "^17.0 || ^18.0",
"react-dom": "^17.0 || ^18.0"
}
},
"node_modules/react-hook-form": {
"version": "7.30.0",
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.30.0.tgz",
@ -11179,9 +11192,9 @@
}
},
"node_modules/typescript": {
"version": "4.6.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz",
"integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==",
"version": "4.8.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.2.tgz",
"integrity": "sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
@ -18672,6 +18685,14 @@
"react-async-script": "^1.1.1"
}
},
"react-google-recaptcha-v3": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/react-google-recaptcha-v3/-/react-google-recaptcha-v3-1.10.0.tgz",
"integrity": "sha512-JBoqU107X8klQmS8tQSbQh1IMsT1fH3kVoArIqnia0rtn0rPNG9Ld+9rD/dHJMculIczSZpGvIJTXXwtsolMcg==",
"requires": {
"hoist-non-react-statics": "^3.3.2"
}
},
"react-hook-form": {
"version": "7.30.0",
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.30.0.tgz",
@ -20000,9 +20021,9 @@
"dev": true
},
"typescript": {
"version": "4.6.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz",
"integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==",
"version": "4.8.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.2.tgz",
"integrity": "sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==",
"dev": true
},
"ua-parser-js": {

View File

@ -38,16 +38,17 @@
"keen-slider": "^6.6.9",
"lodash": "^4.17.21",
"marked": "^4.0.14",
"next": "^12.2.5",
"next": "^12.1.5",
"next-real-viewport": "^0.7.0",
"next-seo": "^5.4.0",
"next-themes": "^0.2.0",
"react": "^18.2.0",
"react": "^18.0.0",
"react-datocms": "^3.0.12",
"react-device-detect": "^2.2.2",
"react-dom": "^18.2.0",
"react-dom": "^18.0.0",
"react-fast-marquee": "^1.3.1",
"react-google-recaptcha": "^2.1.0",
"react-google-recaptcha-v3": "^1.0.0",
"react-hook-form": "^7.30.0",
"react-mailchimp-subscribe": "^2.1.3",
"react-merge-refs": "^1.1.0",
@ -66,7 +67,6 @@
"@types/node": "^17.0.25",
"@types/react": "^17.0.43",
"@types/react-dom": "^17.0.14",
"@types/react-google-recaptcha": "^2.1.5",
"@types/tiny-json-http": "^7.3.1",
"@typescript-eslint/eslint-plugin": "^5.20.0",
"@typescript-eslint/parser": "^5.20.0",
@ -92,7 +92,7 @@
"stylelint-config-standard": "^25.0.0",
"stylelint-config-standard-scss": "^3.0.0",
"stylelint-prettier": "^2.0.0",
"typescript": "^4.6.3"
"typescript": "^4.8.2"
},
"resolutions": {
"@types/react": "~17.0.43"

View File

@ -1,17 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/1.0" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
<url><loc>https://laconic.com</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-08-31T20:53:27.632Z</lastmod></url>
<url><loc>https://laconic.com/about</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-08-31T20:53:27.632Z</lastmod></url>
<url><loc>https://laconic.com/blog</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-08-31T20:53:27.632Z</lastmod></url>
<url><loc>https://laconic.com/careers</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-08-31T20:53:27.632Z</lastmod></url>
<url><loc>https://laconic.com/community</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-08-31T20:53:27.632Z</lastmod></url>
<url><loc>https://laconic.com/contact</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-08-31T20:53:27.632Z</lastmod></url>
<url><loc>https://laconic.com/partners</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-08-31T20:53:27.632Z</lastmod></url>
<url><loc>https://laconic.com/press</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-08-31T20:53:27.632Z</lastmod></url>
<url><loc>https://laconic.com/privacy-policy</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-08-31T20:53:27.632Z</lastmod></url>
<url><loc>https://laconic.com/products</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-08-31T20:53:27.632Z</lastmod></url>
<url><loc>https://laconic.com/terms-of-use</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-08-31T20:53:27.632Z</lastmod></url>
<url><loc>https://laconic.com/blog/how-laconic-network-uses-ipld</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-08-31T20:53:27.632Z</lastmod></url>
<url><loc>https://laconic.com/blog/introducing-laconic-network</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-08-31T20:53:27.632Z</lastmod></url>
<url><loc>https://laconic.com/blog/how-laconic-different</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-08-31T20:53:27.632Z</lastmod></url>
<url><loc>https://laconic.com</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-07-14T18:37:48.828Z</lastmod></url>
<url><loc>https://laconic.com/about</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-07-14T18:37:48.829Z</lastmod></url>
<url><loc>https://laconic.com/blog</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-07-14T18:37:48.829Z</lastmod></url>
<url><loc>https://laconic.com/careers</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-07-14T18:37:48.829Z</lastmod></url>
<url><loc>https://laconic.com/community</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-07-14T18:37:48.829Z</lastmod></url>
<url><loc>https://laconic.com/contact</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-07-14T18:37:48.829Z</lastmod></url>
<url><loc>https://laconic.com/partners</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-07-14T18:37:48.829Z</lastmod></url>
<url><loc>https://laconic.com/press</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-07-14T18:37:48.829Z</lastmod></url>
<url><loc>https://laconic.com/privacy-policy</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-07-14T18:37:48.829Z</lastmod></url>
<url><loc>https://laconic.com/products</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-07-14T18:37:48.829Z</lastmod></url>
<url><loc>https://laconic.com/terms-of-use</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-07-14T18:37:48.829Z</lastmod></url>
<url><loc>https://laconic.com/blog/introducing-laconic-network</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-07-14T18:37:48.829Z</lastmod></url>
<url><loc>https://laconic.com/blog/how-laconic-different</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-07-14T18:37:48.829Z</lastmod></url>
<url><loc>https://laconic.com/blog/how-laconic-network-uses-ipld</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-07-14T18:37:48.829Z</lastmod></url>
</urlset>

View File

@ -4,7 +4,7 @@ const SearchIcon = ({ className }: { className?: string }) => (
height={22}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...className}
{...(typeof className === 'object' ? className : {})}
>
<path
d="M9.313 16.625A7.312 7.312 0 1 0 9.313 2a7.312 7.312 0 0 0 0 14.625Z"

View File

@ -1,7 +1,10 @@
import { useState } from 'react'
import React, { useCallback, useState } from 'react'
// eslint-disable-next-line import/no-named-as-default
import ReCAPTCHA from 'react-google-recaptcha'
import { useGoogleReCaptcha } from 'react-google-recaptcha-v3'
import Select from 'react-select'
import { Container } from '~/components/layout/container'
import * as container from '~/components/layout/container'
import Section from '~/components/layout/section'
import { Button } from '~/components/primitives/button'
import Heading from '~/components/primitives/heading'
@ -39,8 +42,50 @@ const CustomForm = ({ data }: FormProps) => {
const [errorMsg, setErrorMsg] = useState('')
const [isFormSent, setIsFormSent] = useState(false)
const [isSending, setIsSending] = useState(false)
const [notification, setNotification] = useState('')
// const reRef = useRef<ReCAPTCHA>()
const { executeRecaptcha } = useGoogleReCaptcha()
function submitEnquiryForm(gReCaptchaToken: string) {
fetch('/api/inquiry', {
method: 'POST',
headers: {
Accept: 'application/json, text/plain, */*',
'Content-Type': 'application/json'
},
body: JSON.stringify({
gRecaptchaToken: gReCaptchaToken
})
})
.then((res) => res.json())
.then((res) => {
// console.log(res, 'response from backend')
if (res?.status === 'success') {
setNotification(res?.message)
} else {
setNotification(res?.message)
}
})
}
const handleSubmitForm = useCallback(
(e: any) => {
e.preventDefault()
if (!executeRecaptcha) {
// eslint-disable-next-line no-console
console.log('Execute recaptcha not yet available')
return
}
executeRecaptcha('enquiryFormSubmit').then((gReCaptchaToken) => {
// eslint-disable-next-line no-console
console.log(gReCaptchaToken, 'response Google reCaptcha server')
submitEnquiryForm(gReCaptchaToken)
})
},
[executeRecaptcha]
)
const handleSubmit = async (e: any) => {
e.preventDefault()
@ -60,8 +105,6 @@ const CustomForm = ({ data }: FormProps) => {
inquiry: selectedOption.value
}
// const token = await reRef.current.executeAsync()
await fetch(`${process.env.NEXT_PUBLIC_API}/api/contact`, {
method: 'POST',
mode: 'no-cors',
@ -126,10 +169,20 @@ const CustomForm = ({ data }: FormProps) => {
onChange={(e) => setText(e.target.value)}
></textarea>
</label>
<script
src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit"
async
defer
></script>
<ReCAPTCHA
className="recaptcha"
sitekey="6LcJ5LkhAAAAAJ841sJnn6LkwOg-5vt33X-wGEJW"
onSubmit={handleSubmitForm}
/>
<Button size="medium" variant="primary">
{data?.formLabelButton}
</Button>
{notification && <p>{notification}</p>}
</form>
</div>
)
@ -138,7 +191,7 @@ const CustomForm = ({ data }: FormProps) => {
const Form = ({ data }: DataProps) => {
return (
<Section className={s['section']} id="contactform">
<Container className={s['container']}>
<container.Container className={s['container']}>
<div className={s['header']}>
<Heading as="h2" variant="md">
{data?.formHeading}
@ -147,7 +200,7 @@ const Form = ({ data }: DataProps) => {
</div>
<CustomForm data={data} />
<div className={s['gradient']} />
</Container>
</container.Container>
</Section>
)
}

View File

@ -188,6 +188,12 @@
border: none;
color: var(--color-white);
}
.recaptcha {
display: flex;
flex-direction: column;
background-color: black;
}
}
select {

View File

@ -1,4 +1,8 @@
import { useState } from 'react'
import { useCallback, useState } from 'react'
// eslint-disable-next-line import/no-named-as-default
import ReCAPTCHA from 'react-google-recaptcha'
// eslint-disable-next-line import/no-unresolved
import { useGoogleReCaptcha } from 'react-google-recaptcha-v3'
import Select from 'react-select'
import Line from '~/components/icons/line'
@ -54,8 +58,51 @@ const CustomForm = ({ data }: FormProps) => {
const [errorMsg, setErrorMsg] = useState('')
const [isFormSent, setIsFormSent] = useState(false)
const [isSending, setIsSending] = useState(false)
const [notification, setNotification] = useState('')
// const reRef = useRef<ReCAPTCHA>()
const handleSubmit = async (e: any) => {
const { executeRecaptcha } = useGoogleReCaptcha()
function submitEnquiryForm(gReCaptchaToken: string) {
fetch('/api/inquiry', {
method: 'POST',
headers: {
Accept: 'application/json, text/plain, */*',
'Content-Type': 'application/json'
},
body: JSON.stringify({
gRecaptchaToken: gReCaptchaToken
})
})
.then((res) => res.json())
.then((res) => {
// console.log(res, 'response from backend')
if (res?.status === 'success') {
setNotification(res?.message)
} else {
setNotification(res?.message)
}
})
}
const handleSubmitForm = useCallback(
(e: any) => {
e.preventDefault()
if (!executeRecaptcha) {
// eslint-disable-next-line no-console
console.log('Execute recaptcha not yet available')
return
}
executeRecaptcha('enquiryFormSubmit').then((gReCaptchaToken) => {
// eslint-disable-next-line no-console
console.log(gReCaptchaToken, 'response Google reCaptcha server')
submitEnquiryForm(gReCaptchaToken)
})
},
[executeRecaptcha]
)
async function handleSubmit(e: any) {
e.preventDefault()
try {
@ -78,6 +125,7 @@ const CustomForm = ({ data }: FormProps) => {
role: role
}
// const token = await reRef.current.executeAsync()
await fetch(`${process.env.NEXT_PUBLIC_API}/api/inquiry`, {
method: 'POST',
mode: 'no-cors',
@ -190,9 +238,20 @@ const CustomForm = ({ data }: FormProps) => {
onChange={(e) => setText(e.target.value)}
></textarea>
</label>
<script
src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit"
async
defer
></script>
<ReCAPTCHA
className="recaptcha"
sitekey="6LcJ5LkhAAAAAJ841sJnn6LkwOg-5vt33X-wGEJW"
onSubmit={handleSubmitForm}
/>
<Button size="medium" variant="primary">
{data?.contactButtonLabel}
</Button>
{notification && <p>{notification}</p>}
</form>
</div>
)

View File

@ -151,7 +151,6 @@
> img {
object-fit: cover;
height: 100%;
width: 100%;
}
}

View File

@ -1,12 +0,0 @@
import type { NextRequest } from 'next/server'
import { NextResponse } from 'next/server'
// This function can be marked `async` if using `await` inside
export function middleware(request: NextRequest) {
return NextResponse.redirect(new URL('/about-2', request.url))
}
// See "Matching Paths" below to learn more
export const config = {
matcher: '/about/:path*'
}

1
src/ts/react-google-recaptcha.d.ts vendored Normal file
View File

@ -0,0 +1 @@
declare module 'react-google-recaptcha'

View File

@ -24,5 +24,5 @@
"incremental": true
},
"exclude": ["node_modules"],
"include": ["**/*.ts", "**/*.tsx", "src/middleware.js"]
"include": ["**/*.ts", "**/*.tsx"]
}

1
tsconfig.tsbuildinfo Normal file

File diff suppressed because one or more lines are too long

8501
yarn.lock

File diff suppressed because it is too large Load Diff