conflicts
This commit is contained in:
commit
21b946f97c
35
package-lock.json
generated
35
package-lock.json
generated
@ -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": {
|
||||
|
||||
10
package.json
10
package.json
@ -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"
|
||||
|
||||
@ -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>
|
||||
@ -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"
|
||||
|
||||
@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
@ -188,6 +188,12 @@
|
||||
border: none;
|
||||
color: var(--color-white);
|
||||
}
|
||||
|
||||
.recaptcha {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: black;
|
||||
}
|
||||
}
|
||||
|
||||
select {
|
||||
|
||||
@ -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>
|
||||
)
|
||||
|
||||
@ -151,7 +151,6 @@
|
||||
|
||||
> img {
|
||||
object-fit: cover;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
1
src/ts/react-google-recaptcha.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
declare module 'react-google-recaptcha'
|
||||
@ -24,5 +24,5 @@
|
||||
"incremental": true
|
||||
},
|
||||
"exclude": ["node_modules"],
|
||||
"include": ["**/*.ts", "**/*.tsx", "src/middleware.js"]
|
||||
"include": ["**/*.ts", "**/*.tsx"]
|
||||
}
|
||||
|
||||
1
tsconfig.tsbuildinfo
Normal file
1
tsconfig.tsbuildinfo
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user