@@ -11,11 +11,12 @@ | |||
"dependencies": { | |||
"@tesseract-design/viewfinder-base": "0.0.1", | |||
"@tesseract-design/viewfinder-react": "0.0.1", | |||
"@tesseract-design/web-action-react": "^0.2.0", | |||
"@tesseract-design/web-formatted-react": "^0.2.0", | |||
"@tesseract-design/web-freeform-react": "^0.2.0", | |||
"@tesseract-design/web-navigation-react": "^0.2.0", | |||
"@theoryofnekomata/formxtra": "^1.0.3", | |||
"@tesseract-design/web-action-react": "0.2.0", | |||
"@tesseract-design/web-formatted-react": "0.2.1", | |||
"@tesseract-design/web-freeform-react": "0.2.1", | |||
"@tesseract-design/web-navigation-react": "0.2.1", | |||
"@theoryofnekomata/formxtra": "../../../formxtra", | |||
"@modal-sh/iceform-next": "0.0.0", | |||
"@types/node": "20.6.0", | |||
"@types/react": "18.2.21", | |||
"@types/react-dom": "18.2.7", | |||
@@ -25,8 +26,6 @@ | |||
"eslint-config-next": "13.4.19", | |||
"next": "13.4.19", | |||
"postcss": "8.4.29", | |||
"react": "18.2.0", | |||
"react-dom": "18.2.0", | |||
"tailwindcss": "3.3.3", | |||
"typescript": "5.2.2" | |||
} | |||
@@ -5,6 +5,9 @@ settings: | |||
excludeLinksFromLockfile: false | |||
dependencies: | |||
'@modal-sh/iceform-next': | |||
specifier: 0.0.0 | |||
version: 0.0.0(next@13.4.19)(react-dom@18.2.0)(react@18.2.0) | |||
'@tesseract-design/viewfinder-base': | |||
specifier: 0.0.1 | |||
version: 0.0.1 | |||
@@ -12,20 +15,20 @@ dependencies: | |||
specifier: 0.0.1 | |||
version: 0.0.1(react-dom@18.2.0)(react@18.2.0) | |||
'@tesseract-design/web-action-react': | |||
specifier: ^0.2.0 | |||
specifier: 0.2.0 | |||
version: 0.2.0(react-dom@18.2.0)(react@18.2.0) | |||
'@tesseract-design/web-formatted-react': | |||
specifier: ^0.2.0 | |||
specifier: 0.2.1 | |||
version: 0.2.1(react-dom@18.2.0)(react@18.2.0) | |||
'@tesseract-design/web-freeform-react': | |||
specifier: ^0.2.0 | |||
specifier: 0.2.1 | |||
version: 0.2.1(react-dom@18.2.0)(react@18.2.0) | |||
'@tesseract-design/web-navigation-react': | |||
specifier: ^0.2.0 | |||
specifier: 0.2.1 | |||
version: 0.2.1(react-dom@18.2.0)(react@18.2.0) | |||
'@theoryofnekomata/formxtra': | |||
specifier: ^1.0.3 | |||
version: 1.0.3 | |||
specifier: ../../../formxtra | |||
version: link:../../../formxtra | |||
'@types/node': | |||
specifier: 20.6.0 | |||
version: 20.6.0 | |||
@@ -53,12 +56,6 @@ dependencies: | |||
postcss: | |||
specifier: 8.4.29 | |||
version: 8.4.29 | |||
react: | |||
specifier: 18.2.0 | |||
version: 18.2.0 | |||
react-dom: | |||
specifier: 18.2.0 | |||
version: 18.2.0(react@18.2.0) | |||
tailwindcss: | |||
specifier: 3.3.3 | |||
version: 3.3.3 | |||
@@ -179,6 +176,23 @@ packages: | |||
'@jridgewell/sourcemap-codec': 1.4.15 | |||
dev: false | |||
/@modal-sh/iceform-next@0.0.0(next@13.4.19)(react-dom@18.2.0)(react@18.2.0): | |||
resolution: {integrity: sha512-/FoVjAtY0PCAPOLLN53vLjlJs3mIMmmy5r+Iqg7dp5csburzkGtLpYRpzMAVYNj4ttV0j+YaJxSBYWNtT+PaUQ==} | |||
engines: {node: '>=12'} | |||
peerDependencies: | |||
next: 13.4.19 | |||
react: ^16.8 || ^17.0 || ^18.0 | |||
react-dom: ^16.8 || ^17.0 || ^18.0 | |||
dependencies: | |||
'@theoryofnekomata/formxtra': 1.0.3 | |||
busboy: 1.6.0 | |||
next: 13.4.19(react-dom@18.2.0)(react@18.2.0) | |||
node-cache: 5.1.2 | |||
react: 18.2.0 | |||
react-dom: 18.2.0(react@18.2.0) | |||
seroval: 0.10.4 | |||
dev: false | |||
/@modal-sh/react-utils@0.0.0(react-dom@18.2.0)(react@18.2.0): | |||
resolution: {integrity: sha512-aqbD221Zhsucxnr2ZJqS2sZQbI4/xcb703GvcXLew+2zqFhZOwfRdclwTralB/TXBmrrIh3aHeOisQ+DLlmC3w==} | |||
engines: {node: '>=12'} | |||
@@ -826,6 +840,11 @@ packages: | |||
resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} | |||
dev: false | |||
/clone@2.1.2: | |||
resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} | |||
engines: {node: '>=0.8'} | |||
dev: false | |||
/clsx@1.2.1: | |||
resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} | |||
engines: {node: '>=6'} | |||
@@ -2159,6 +2178,13 @@ packages: | |||
- babel-plugin-macros | |||
dev: false | |||
/node-cache@5.1.2: | |||
resolution: {integrity: sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==} | |||
engines: {node: '>= 8.0.0'} | |||
dependencies: | |||
clone: 2.1.2 | |||
dev: false | |||
/node-releases@2.0.14: | |||
resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} | |||
dev: false | |||
@@ -2603,6 +2629,11 @@ packages: | |||
lru-cache: 6.0.0 | |||
dev: false | |||
/seroval@0.10.4: | |||
resolution: {integrity: sha512-TdaE9JkoATjKu+vjwllieX8zWyBTUVxbgWDnOsDJFfmKbM7vLSukuCXuD3pO3kkCtX4daywOW8ps2VCdPhS8/w==} | |||
engines: {node: '>=10'} | |||
dev: false | |||
/set-function-length@1.2.2: | |||
resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} | |||
engines: {node: '>= 0.4'} | |||
@@ -1,4 +1,5 @@ | |||
import * as React from 'react'; | |||
import * as Iceform from '@modal-sh/iceform-next'; | |||
import {Layouts} from '@tesseract-design/viewfinder-react'; | |||
import * as WebNavigationReact from '@tesseract-design/web-navigation-react'; | |||
import * as WebFreeformReact from '@tesseract-design/web-freeform-react'; | |||
@@ -10,12 +11,14 @@ export interface ContactCtaBannerProps { | |||
onSubmit?: React.FormEventHandler<HTMLFormElement>; | |||
visible?: boolean; | |||
hasBrand?: boolean; | |||
iceformProps?: Partial<ReturnType<typeof Iceform.useResponse>>; | |||
} | |||
export const ContactCtaBanner: React.FC<ContactCtaBannerProps> = ({ | |||
onSubmit, | |||
visible: visibleProp = false, | |||
hasBrand = false, | |||
iceformProps = {}, | |||
}) => { | |||
const [visible, setVisible] = React.useState<boolean>(); | |||
const autofocusRef = React.useRef<HTMLInputElement>(null); | |||
@@ -76,12 +79,14 @@ export const ContactCtaBanner: React.FC<ContactCtaBannerProps> = ({ | |||
</div> | |||
</div> | |||
{visible !== false && ( | |||
<form | |||
<Iceform.Form | |||
{...iceformProps} | |||
className="mt-8" | |||
aria-label="Contact Form" | |||
onSubmit={onSubmit} | |||
method="post" | |||
action="/a/contact" | |||
clientAction="/api/contact" | |||
> | |||
<fieldset className="contents"> | |||
<legend className="sr-only"> | |||
@@ -131,7 +136,7 @@ export const ContactCtaBanner: React.FC<ContactCtaBannerProps> = ({ | |||
</div> | |||
</div> | |||
</fieldset> | |||
</form> | |||
</Iceform.Form> | |||
)} | |||
</Layouts.Basic.ContentContainer> | |||
</div> | |||
@@ -1,4 +1,5 @@ | |||
import * as React from 'react'; | |||
import * as Iceform from '@modal-sh/iceform-next'; | |||
import {Layouts} from '@tesseract-design/viewfinder-react'; | |||
import {MainLandingSection, MainLandingSectionProps} from '@/components/molecules/MainLandingSection'; | |||
import {MakeSection, MakeSectionProps} from '@/components/molecules/MakeSection'; | |||
@@ -17,6 +18,7 @@ export interface IndexLayoutProps { | |||
contactVisible?: boolean; | |||
hasMainLandingSection?: boolean; | |||
contactHasBrand?: boolean; | |||
iceformProps?: Partial<ReturnType<typeof Iceform.useResponse>> | |||
} | |||
export const IndexLayout: React.FC<IndexLayoutProps> = ({ | |||
@@ -28,6 +30,7 @@ export const IndexLayout: React.FC<IndexLayoutProps> = ({ | |||
contactVisible = false, | |||
hasMainLandingSection = false, | |||
contactHasBrand = false, | |||
iceformProps, | |||
}) => ( | |||
<Layouts.Basic.Root className="contents"> | |||
<div | |||
@@ -65,6 +68,7 @@ export const IndexLayout: React.FC<IndexLayoutProps> = ({ | |||
onSubmit={onSubmit} | |||
visible={contactVisible} | |||
hasBrand={contactHasBrand} | |||
iceformProps={iceformProps} | |||
/> | |||
<Footer/> | |||
</Layouts.Basic.Root> | |||
@@ -0,0 +1,5 @@ | |||
import { NextApiHandler } from 'next'; | |||
export const receiveContactEntry: NextApiHandler = async (req, res) => { | |||
res.status(200).json(req.body); | |||
}; |
@@ -0,0 +1,14 @@ | |||
import { NextPage } from 'next'; | |||
import * as Iceform from '@modal-sh/iceform-next'; | |||
import { receiveContactEntry } from '@/handlers/contact'; | |||
const ActionContactPage: NextPage = () => null; | |||
const getServerSideProps = Iceform.action.getServerSideProps({ | |||
fn: receiveContactEntry, | |||
}); | |||
export { | |||
getServerSideProps, | |||
ActionContactPage as default, | |||
}; |
@@ -0,0 +1,11 @@ | |||
import * as Iceform from '@modal-sh/iceform-next'; | |||
import { receiveContactEntry } from '@/handlers/contact'; | |||
const handler = Iceform.action.wrapApiHandler({ fn: receiveContactEntry }); | |||
const config = Iceform.action.getApiConfig(); | |||
export { | |||
config, | |||
handler as default, | |||
}; |
@@ -1,13 +0,0 @@ | |||
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction | |||
import type { NextApiRequest, NextApiResponse } from 'next' | |||
type Data = { | |||
name: string | |||
} | |||
export default function handler( | |||
req: NextApiRequest, | |||
res: NextApiResponse<Data> | |||
) { | |||
res.status(200).json({ name: 'John Doe' }) | |||
} |
@@ -1,8 +1,8 @@ | |||
import {NextPage} from 'next'; | |||
import {useHuePulsate} from '@/hooks/effects'; | |||
import * as config from '@/config'; | |||
import * as React from 'react'; | |||
import * as Iceform from '@modal-sh/iceform-next'; | |||
import * as config from '@/config'; | |||
import {IndexLayout} from '@/components/organisms/IndexLayout'; | |||
import {useHuePulsate} from '@/hooks/effects'; | |||
const IMAGE_CHOICES = [ | |||
'/images/3cd237361eada7fd30eb96d42d55ec00.jpg', | |||
@@ -20,7 +20,18 @@ const IMAGE_CHOICES = [ | |||
'/images/fe3050a31d3fb86accf26cc4bebec102.png', | |||
]; | |||
const ContactPage: NextPage = () => { | |||
const ContactPage: Iceform.NextPage = ({ | |||
req, | |||
res, | |||
}) => { | |||
const { | |||
response, | |||
loading, | |||
...iceformProps | |||
} = Iceform.useResponse({ | |||
res, | |||
}); | |||
useHuePulsate(config.effects.huePulsate); | |||
return ( | |||
@@ -28,8 +39,11 @@ const ContactPage: NextPage = () => { | |||
backgroundImages={IMAGE_CHOICES} | |||
contactVisible | |||
contactHasBrand | |||
iceformProps={iceformProps} | |||
/> | |||
) | |||
}; | |||
export const getServerSideProps = Iceform.destination.getServerSideProps(); | |||
export default ContactPage; |
@@ -4,6 +4,7 @@ import {useHuePulsate} from '@/hooks/effects'; | |||
import {useContactForm} from '@/hooks/contact'; | |||
import {IndexLayout} from '@/components/organisms/IndexLayout'; | |||
import * as config from '@/config'; | |||
import * as Iceform from '@modal-sh/iceform-next'; | |||
const IMAGE_CHOICES = [ | |||
'/images/3cd237361eada7fd30eb96d42d55ec00.jpg', | |||
@@ -122,21 +123,31 @@ const featuredProjectData = [ | |||
}, | |||
]; | |||
const IndexPage: NextPage = () => { | |||
const IndexPage: Iceform.NextPage = ({ | |||
req, | |||
res, | |||
}) => { | |||
const { | |||
response, | |||
loading, | |||
...iceformProps | |||
} = Iceform.useResponse({ | |||
res, | |||
}); | |||
useHuePulsate(config.effects.huePulsate); | |||
const { processContactForm } = useContactForm(); | |||
return ( | |||
<IndexLayout | |||
backgroundImages={IMAGE_CHOICES} | |||
makeSectionData={makeSectionData} | |||
envisionSectionData={envisionSectionData} | |||
featuredProjectData={featuredProjectData} | |||
onSubmit={processContactForm} | |||
hasMainLandingSection | |||
iceformProps={iceformProps} | |||
/> | |||
); | |||
}; | |||
export const getServerSideProps = Iceform.destination.getServerSideProps(); | |||
export default IndexPage; |