From dcf25a027d86ed4b64b661898187d475fbdc8ac7 Mon Sep 17 00:00:00 2001 From: HARUMI JANG Date: Tue, 13 Dec 2022 19:26:41 -0500 Subject: [PATCH 1/7] WIP: Added updated webform to client side --- .../components/withCustomStyles.tsx | 28 +++++++ examples/example-webform/package.json | 3 +- .../example-webform/pages/client-side.tsx | 81 ++++++++++++++++++- yarn.lock | 39 ++------- 4 files changed, 116 insertions(+), 35 deletions(-) create mode 100644 examples/example-webform/components/withCustomStyles.tsx diff --git a/examples/example-webform/components/withCustomStyles.tsx b/examples/example-webform/components/withCustomStyles.tsx new file mode 100644 index 00000000..61e3b6ba --- /dev/null +++ b/examples/example-webform/components/withCustomStyles.tsx @@ -0,0 +1,28 @@ +const withCustomStyles = ( + EnhancedComponent, + fieldProps = {}, + labelProps = {}, + wrapperProps = {} +) => { + return function WebformElementWithCustomStyles(props) { + return ( + + ); + } +}; + +export default withCustomStyles; diff --git a/examples/example-webform/package.json b/examples/example-webform/package.json index 7ca374b6..f29c75fe 100644 --- a/examples/example-webform/package.json +++ b/examples/example-webform/package.json @@ -22,7 +22,8 @@ "react": "^17.0.2", "react-dom": "^17.0.2", "react-hook-form": "^7.25.3", - "yup": "^0.32.11" + "yup": "^0.32.11", + "nextjs-drupal-webform": "^1.0.0-alpha1" }, "devDependencies": { "@babel/core": "^7.12.9", diff --git a/examples/example-webform/pages/client-side.tsx b/examples/example-webform/pages/client-side.tsx index fe30142b..aa05c76e 100644 --- a/examples/example-webform/pages/client-side.tsx +++ b/examples/example-webform/pages/client-side.tsx @@ -7,14 +7,25 @@ import { useForm } from "react-hook-form" import * as yup from "yup" import { yupResolver } from "@hookform/resolvers/yup" import { contactFormSchema } from "../validations/contact" - +import { + resolveWebformContent, + Webform, + components, +} from "nextjs-drupal-webform" +import { drupal } from "basic-starter/lib/drupal" type FormData = yup.TypeOf +import classNames from "classnames" +import withCustomStyles from "../components/withCustomStyles" interface WebformPageProps { teams: DrupalTaxonomyTerm[] + webformObject: object } -export default function WebformPage({ teams }: WebformPageProps) { +export default function WebformPage({ + teams, + webformObject, +}: WebformPageProps) { const [status, setStatus] = React.useState<"error" | "success">() const { register, handleSubmit, formState, reset } = useForm({ resolver: yupResolver(contactFormSchema), @@ -45,6 +56,45 @@ export default function WebformPage({ teams }: WebformPageProps) { return setStatus("error") } + const labelProps = { + className: classNames(["block", "text-sm", "font-medium", "text-gray-700"]), + } + const fieldProps = { + className: classNames([ + "relative", + "block", + "w-full px-3", + "py-2 mt-1 text-gray-900", + "placeholder-gray-500", + "border border-gray-300", + "rounded-md appearance-none", + "focus:outline-none", + "focus:ring-black", + "focus:border-black", + "focus:z-10", + "sm:text-sm", + ]), + } + const wrapperProps = { + className: classNames(["space-y-3"]), + } + + const buttonProps = { + className: classNames([ + "flex", + "justify-center", + "px-4", + "py-2", + "text-sm font-medium", + "text-white", + "bg-black", + "border border-transparent", + "rounded-md", + "shadow-sm", + "hover:bg-black", + ]), + } + return ( <> @@ -61,6 +111,32 @@ export default function WebformPage({ teams }: WebformPageProps) { {" "} module to submit the form values directly to Drupal.

+ {console.log("webformObject", webformObject)} +
{status === "error" ? (
@@ -186,6 +262,7 @@ export async function getStaticProps(): Promise< // Load terms terms for the contact form. return { props: { + webformObject: await resolveWebformContent("contact", drupal), teams: await getResourceCollection("taxonomy_term--team"), }, } diff --git a/yarn.lock b/yarn.lock index 754f1b57..a6f713f6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3280,21 +3280,14 @@ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== -"@types/react-dom@17.0.2": +"@types/react-dom@17.0.2", "@types/react-dom@^18.0.9": version "17.0.2" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.2.tgz#35654cf6c49ae162d5bc90843d5437dc38008d43" integrity sha512-Icd9KEgdnFfJs39KyRyr0jQ7EKhq8U6CcHRMGAS45fp5qgUvxL3ujUCfWFttUK2UErqZNj97t9gsVPNAqcwoCg== dependencies: "@types/react" "*" -"@types/react-dom@^18.0.9": - version "18.0.9" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.9.tgz#ffee5e4bfc2a2f8774b15496474f8e7fe8d0b504" - integrity sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg== - dependencies: - "@types/react" "*" - -"@types/react@*", "@types/react@17.0.2", "@types/react@^17.0.0": +"@types/react@*", "@types/react@17.0.2", "@types/react@^17.0.0", "@types/react@^17.0.43", "@types/react@^18.0.26": version "17.0.2" resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.2.tgz#3de24c4efef902dd9795a49c75f760cbe4f7a5a8" integrity sha512-Xt40xQsrkdvjn1EyWe1Bc0dJLcil/9x2vAuW7ya+PuQip4UYUaXyhzWmAbwRsdMgwOFHpfp7/FFZebDU6Y8VHA== @@ -3302,24 +3295,6 @@ "@types/prop-types" "*" csstype "^3.0.2" -"@types/react@^17.0.43": - version "17.0.52" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.52.tgz#10d8b907b5c563ac014a541f289ae8eaa9bf2e9b" - integrity sha512-vwk8QqVODi0VaZZpDXQCmEmiOuyjEFPY7Ttaw5vjM112LOq37yz1CDJGrRJwA1fYEq4Iitd5rnjd1yWAc/bT+A== - dependencies: - "@types/prop-types" "*" - "@types/scheduler" "*" - csstype "^3.0.2" - -"@types/react@^18.0.26": - version "18.0.26" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.26.tgz#8ad59fc01fef8eaf5c74f4ea392621749f0b7917" - integrity sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug== - dependencies: - "@types/prop-types" "*" - "@types/scheduler" "*" - csstype "^3.0.2" - "@types/resolve@1.17.1": version "1.17.1" resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6" @@ -3327,11 +3302,6 @@ dependencies: "@types/node" "*" -"@types/scheduler@*": - version "0.16.2" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" - integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== - "@types/sinonjs__fake-timers@8.1.1": version "8.1.1" resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz#b49c2c70150141a15e0fa7e79cf1f92a72934ce3" @@ -10114,6 +10084,11 @@ next@^12.2.3: "@next/swc-win32-ia32-msvc" "12.2.3" "@next/swc-win32-x64-msvc" "12.2.3" +nextjs-drupal-webform@^1.0.0-alpha1: + version "1.0.0-alpha1" + resolved "https://registry.yarnpkg.com/nextjs-drupal-webform/-/nextjs-drupal-webform-1.0.0-alpha1.tgz#f4106207907c7a001ed8367edebc4c80218dc949" + integrity sha512-2eyXvp5mavu9QFSmLwWttSuYEon5CcPn3fIxUelVwicgo00OrKZ/9kaCKuEDNeWfYY8HrSQGtal4ANiJ5U908g== + node-abi@^3.3.0: version "3.22.0" resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.22.0.tgz#00b8250e86a0816576258227edbce7bbe0039362" From 59590d2a66bd75e88cc5b432711910c10c46b154 Mon Sep 17 00:00:00 2001 From: HARUMI JANG Date: Wed, 14 Dec 2022 10:51:42 -0500 Subject: [PATCH 2/7] Revert client-side file --- .../example-webform/pages/client-side.tsx | 81 +------------------ 1 file changed, 2 insertions(+), 79 deletions(-) diff --git a/examples/example-webform/pages/client-side.tsx b/examples/example-webform/pages/client-side.tsx index aa05c76e..fe30142b 100644 --- a/examples/example-webform/pages/client-side.tsx +++ b/examples/example-webform/pages/client-side.tsx @@ -7,25 +7,14 @@ import { useForm } from "react-hook-form" import * as yup from "yup" import { yupResolver } from "@hookform/resolvers/yup" import { contactFormSchema } from "../validations/contact" -import { - resolveWebformContent, - Webform, - components, -} from "nextjs-drupal-webform" -import { drupal } from "basic-starter/lib/drupal" + type FormData = yup.TypeOf -import classNames from "classnames" -import withCustomStyles from "../components/withCustomStyles" interface WebformPageProps { teams: DrupalTaxonomyTerm[] - webformObject: object } -export default function WebformPage({ - teams, - webformObject, -}: WebformPageProps) { +export default function WebformPage({ teams }: WebformPageProps) { const [status, setStatus] = React.useState<"error" | "success">() const { register, handleSubmit, formState, reset } = useForm({ resolver: yupResolver(contactFormSchema), @@ -56,45 +45,6 @@ export default function WebformPage({ return setStatus("error") } - const labelProps = { - className: classNames(["block", "text-sm", "font-medium", "text-gray-700"]), - } - const fieldProps = { - className: classNames([ - "relative", - "block", - "w-full px-3", - "py-2 mt-1 text-gray-900", - "placeholder-gray-500", - "border border-gray-300", - "rounded-md appearance-none", - "focus:outline-none", - "focus:ring-black", - "focus:border-black", - "focus:z-10", - "sm:text-sm", - ]), - } - const wrapperProps = { - className: classNames(["space-y-3"]), - } - - const buttonProps = { - className: classNames([ - "flex", - "justify-center", - "px-4", - "py-2", - "text-sm font-medium", - "text-white", - "bg-black", - "border border-transparent", - "rounded-md", - "shadow-sm", - "hover:bg-black", - ]), - } - return ( <> @@ -111,32 +61,6 @@ export default function WebformPage({ {" "} module to submit the form values directly to Drupal.

- {console.log("webformObject", webformObject)} -
{status === "error" ? (
@@ -262,7 +186,6 @@ export async function getStaticProps(): Promise< // Load terms terms for the contact form. return { props: { - webformObject: await resolveWebformContent("contact", drupal), teams: await getResourceCollection("taxonomy_term--team"), }, } From 7a9a211c2c03dd160844646683c659ebeedc02af Mon Sep 17 00:00:00 2001 From: HARUMI JANG Date: Wed, 14 Dec 2022 11:07:33 -0500 Subject: [PATCH 3/7] Add custom styling --- .../components/withCustomStyles.tsx | 6 +- examples/example-webform/package.json | 2 +- .../example-webform/pages/server-side.tsx | 300 +++++++++++------- yarn.lock | 15 +- 4 files changed, 207 insertions(+), 116 deletions(-) diff --git a/examples/example-webform/components/withCustomStyles.tsx b/examples/example-webform/components/withCustomStyles.tsx index 61e3b6ba..d417e5e6 100644 --- a/examples/example-webform/components/withCustomStyles.tsx +++ b/examples/example-webform/components/withCustomStyles.tsx @@ -21,8 +21,8 @@ const withCustomStyles = ( ...wrapperProps, }} /> - ); + ) } -}; +} -export default withCustomStyles; +export default withCustomStyles diff --git a/examples/example-webform/package.json b/examples/example-webform/package.json index f29c75fe..97853d73 100644 --- a/examples/example-webform/package.json +++ b/examples/example-webform/package.json @@ -23,7 +23,7 @@ "react-dom": "^17.0.2", "react-hook-form": "^7.25.3", "yup": "^0.32.11", - "nextjs-drupal-webform": "^1.0.0-alpha1" + "nextjs-drupal-webform": "^1.0.0-alpha2" }, "devDependencies": { "@babel/core": "^7.12.9", diff --git a/examples/example-webform/pages/server-side.tsx b/examples/example-webform/pages/server-side.tsx index 28afe26f..a32dd3bf 100644 --- a/examples/example-webform/pages/server-side.tsx +++ b/examples/example-webform/pages/server-side.tsx @@ -8,18 +8,65 @@ import * as yup from "yup" import { yupResolver } from "@hookform/resolvers/yup" import { contactFormSchema } from "../validations/contact" +import withCustomStyles from "../components/withCustomStyles" +import { + resolveWebformContent, + Webform, + components, + WebformProps, +} from "nextjs-drupal-webform" +import { drupal } from "basic-starter/lib/drupal" +import classNames from "classnames" type FormData = yup.TypeOf interface WebformPageProps { teams: DrupalTaxonomyTerm[] + webform: WebformProps } -export default function WebformPage({ teams }: WebformPageProps) { +export default function WebformPage({ teams, webform }: WebformPageProps) { const [status, setStatus] = React.useState<"error" | "success">() const { register, handleSubmit, formState, reset } = useForm({ resolver: yupResolver(contactFormSchema), }) + const labelProps = { + className: classNames(["block", "text-sm", "font-medium", "text-gray-700"]), + } + const fieldProps = { + className: classNames([ + "relative", + "block", + "w-full px-3", + "py-2 mt-1 text-gray-900", + "placeholder-gray-500", + "border border-gray-300", + "rounded-md appearance-none", + "focus:outline-none", + "focus:ring-black", + "focus:border-black", + "focus:z-10", + "sm:text-sm", + ]), + } + const wrapperProps = { + className: classNames(["space-y-3"]), + } + const buttonProps = { + className: classNames([ + "flex", + "justify-center", + "px-4", + "py-2", + "text-sm font-medium", + "text-white", + "bg-black", + "border border-transparent", + "rounded-md", + "shadow-sm", + "hover:bg-black", + ]), + } // This makes a POST to a custom API route. // The Drupal base URL and the webform_id are NOT exposed. @@ -58,113 +105,149 @@ export default function WebformPage({ teams }: WebformPageProps) { This is useful if we need to hide client IDs and secrets or our Drupal implementation.

-
- {status === "error" ? ( -
- An error occured. Please try again. -
- ) : null} - {status === "success" ? ( -
- Your message has been sent. Thank you. -
- ) : null} - {Object.values(formState.errors)?.length ? ( -
- {Object.values(formState.errors).map((error, index) => ( -

{error.message}

- ))} -
- ) : null} -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
- -
-
+ + {/*
*/} + {/* {status === "error" ? (*/} + {/*
*/} + {/* An error occured. Please try again.*/} + {/*
*/} + {/* ) : null}*/} + {/* {status === "success" ? (*/} + {/*
*/} + {/* Your message has been sent. Thank you.*/} + {/*
*/} + {/* ) : null}*/} + {/* {Object.values(formState.errors)?.length ? (*/} + {/*
*/} + {/* {Object.values(formState.errors).map((error, index) => (*/} + {/*

{error.message}

*/} + {/* ))}*/} + {/*
*/} + {/* ) : null}*/} + {/*
*/} + {/*
*/} + {/* */} + {/* Name*/} + {/* */} + {/* */} + {/*
*/} + {/*
*/} + {/* */} + {/* Email*/} + {/* */} + {/* */} + {/*
*/} + {/*
*/} + {/* */} + {/* Team*/} + {/* */} + {/* */} + {/* */} + {/* {teams.map((team) => (*/} + {/* */} + {/* ))}*/} + {/* */} + {/*
*/} + {/*
*/} + {/* */} + {/* Subject*/} + {/* */} + {/* */} + {/*
*/} + {/*
*/} + {/* */} + {/* Message*/} + {/* */} + {/* */} + {/*
*/} + {/* */} + {/* Submit*/} + {/* */} + {/* */} + {/*
*/}

Go back @@ -183,6 +266,7 @@ export async function getStaticProps(): Promise< return { props: { teams: await getResourceCollection("taxonomy_term--team"), + webform: await resolveWebformContent("contact", drupal), }, } } diff --git a/yarn.lock b/yarn.lock index a6f713f6..dbda8cd8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4623,6 +4623,11 @@ classnames@^2.3.1: resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== +classnames@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924" + integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw== + clean-stack@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" @@ -10084,10 +10089,12 @@ next@^12.2.3: "@next/swc-win32-ia32-msvc" "12.2.3" "@next/swc-win32-x64-msvc" "12.2.3" -nextjs-drupal-webform@^1.0.0-alpha1: - version "1.0.0-alpha1" - resolved "https://registry.yarnpkg.com/nextjs-drupal-webform/-/nextjs-drupal-webform-1.0.0-alpha1.tgz#f4106207907c7a001ed8367edebc4c80218dc949" - integrity sha512-2eyXvp5mavu9QFSmLwWttSuYEon5CcPn3fIxUelVwicgo00OrKZ/9kaCKuEDNeWfYY8HrSQGtal4ANiJ5U908g== +nextjs-drupal-webform@^1.0.0-alpha2: + version "1.0.0-alpha2" + resolved "https://registry.yarnpkg.com/nextjs-drupal-webform/-/nextjs-drupal-webform-1.0.0-alpha2.tgz#03f494b2f8a585ecff3c4bc0f55daeba08aedab9" + integrity sha512-O+AszzKB1qRT0wFmrqthb1EvCz6rOxE+lbZq1ycj5eW2ftPjWOaui6icKWYVYUH+hkxTD3FYVQbMv7qukpuzEw== + dependencies: + classnames "^2.3.2" node-abi@^3.3.0: version "3.22.0" From 02445aa6457ac8246815dd78b472154faa5cfc62 Mon Sep 17 00:00:00 2001 From: HARUMI JANG Date: Thu, 15 Dec 2022 10:53:33 -0500 Subject: [PATCH 4/7] Pass in data-cy to submit button --- .../example-webform/pages/server-side.tsx | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/examples/example-webform/pages/server-side.tsx b/examples/example-webform/pages/server-side.tsx index a32dd3bf..ff207b3a 100644 --- a/examples/example-webform/pages/server-side.tsx +++ b/examples/example-webform/pages/server-side.tsx @@ -66,23 +66,24 @@ export default function WebformPage({ teams, webform }: WebformPageProps) { "shadow-sm", "hover:bg-black", ]), + "data-cy": "btn-submit", } // This makes a POST to a custom API route. // The Drupal base URL and the webform_id are NOT exposed. - async function onSubmit(data: FormData) { - const response = await fetch(`/api/contact`, { - method: "POST", - body: JSON.stringify(data), - }) - - if (response.ok) { - reset() - return setStatus("success") - } - - return setStatus("error") - } + // async function onSubmit(data: FormData) { + // const response = await fetch(`/api/contact`, { + // method: "POST", + // body: JSON.stringify(data), + // }) + // + // if (response.ok) { + // reset() + // return setStatus("success") + // } + // + // return setStatus("error") + // } return ( <> @@ -140,6 +141,7 @@ export default function WebformPage({ teams, webform }: WebformPageProps) { wrapperProps ), }} + // className="space-y-6" /> {/*

*/} {/* {status === "error" ? (*/} From 13612b755d936c85302b9d5f723e7f066b2dbf89 Mon Sep 17 00:00:00 2001 From: HARUMI JANG Date: Wed, 21 Dec 2022 14:16:33 -0500 Subject: [PATCH 5/7] Update example and update text --- .../components/WebformButton.tsx | 17 ++ examples/example-webform/lib/drupal.ts | 17 ++ examples/example-webform/package.json | 2 +- examples/example-webform/pages/api/webform.ts | 10 + examples/example-webform/pages/index.tsx | 15 +- .../example-webform/pages/server-side.tsx | 232 ++++-------------- yarn.lock | 8 +- 7 files changed, 101 insertions(+), 200 deletions(-) create mode 100644 examples/example-webform/components/WebformButton.tsx create mode 100644 examples/example-webform/lib/drupal.ts create mode 100644 examples/example-webform/pages/api/webform.ts diff --git a/examples/example-webform/components/WebformButton.tsx b/examples/example-webform/components/WebformButton.tsx new file mode 100644 index 00000000..cb1050bd --- /dev/null +++ b/examples/example-webform/components/WebformButton.tsx @@ -0,0 +1,17 @@ +import { components } from "nextjs-drupal-webform" +import classNames from "classnames" + +const buttonDecorator = (DecoratedComponent) => { + return function WebformCustomTable(props) { + const fieldProps = props.fieldProps ?? {} + const additionalClasses = [] + if (props.element["#button_type"] === "primary") { + additionalClasses.push("bg-black hover:bg-black text-white") + } + fieldProps.className = classNames(fieldProps.className, additionalClasses) + + return + } +} + +export default buttonDecorator(components.button) diff --git a/examples/example-webform/lib/drupal.ts b/examples/example-webform/lib/drupal.ts new file mode 100644 index 00000000..cd653cc6 --- /dev/null +++ b/examples/example-webform/lib/drupal.ts @@ -0,0 +1,17 @@ +import { DrupalClient } from "next-drupal" + +export const drupal = new DrupalClient( + process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, + { + previewSecret: process.env.DRUPAL_PREVIEW_SECRET, + auth: { + clientId: process.env.DRUPAL_CLIENT_ID, + clientSecret: process.env.DRUPAL_CLIENT_SECRET, + scope: + "administrator developer site_builder content_administrator content_author content_editor user_administrator headless", + }, + // @see https://github.com/vercel/next.js/discussions/32238 + // @see https://github.com/vercel/next.js/blob/d895a50abbc8f91726daa2d7ebc22c58f58aabbb/packages/next/server/api-utils/node.ts#L504 + forceIframeSameSiteCookie: process.env.NODE_ENV === "development", + } +) diff --git a/examples/example-webform/package.json b/examples/example-webform/package.json index 97853d73..5cfeecc3 100644 --- a/examples/example-webform/package.json +++ b/examples/example-webform/package.json @@ -23,7 +23,7 @@ "react-dom": "^17.0.2", "react-hook-form": "^7.25.3", "yup": "^0.32.11", - "nextjs-drupal-webform": "^1.0.0-alpha2" + "nextjs-drupal-webform": "^1.0.0-beta1" }, "devDependencies": { "@babel/core": "^7.12.9", diff --git a/examples/example-webform/pages/api/webform.ts b/examples/example-webform/pages/api/webform.ts new file mode 100644 index 00000000..60889f25 --- /dev/null +++ b/examples/example-webform/pages/api/webform.ts @@ -0,0 +1,10 @@ +import { NextApiRequest, NextApiResponse } from "next" +import { drupal } from "../../lib/drupal" +import { WebformDefaultApiRoute } from "nextjs-drupal-webform" + +export default async function handler( + request: NextApiRequest, + response: NextApiResponse +) { + return WebformDefaultApiRoute(request, response, drupal) +} diff --git a/examples/example-webform/pages/index.tsx b/examples/example-webform/pages/index.tsx index 66147367..743c4be7 100644 --- a/examples/example-webform/pages/index.tsx +++ b/examples/example-webform/pages/index.tsx @@ -1,5 +1,6 @@ import Head from "next/head" import Link from "next/link" +import * as React from "react" export default function IndexPage() { return ( @@ -33,19 +34,15 @@ export default function IndexPage() { See Example

-

Server Side (API Route)

+

Server Side

- We submit the form values to a custom API route first. The API route - then submits the form to Drupal using the{" "} - - Webform REST + This example uses the{" "} + + Next.js Webform {" "} + library to render and submit forms built using the Drupal Webform module.

-

- This is useful if we need to hide client IDs and secrets or our - Drupal implementation. -

See Example diff --git a/examples/example-webform/pages/server-side.tsx b/examples/example-webform/pages/server-side.tsx index ff207b3a..0e318573 100644 --- a/examples/example-webform/pages/server-side.tsx +++ b/examples/example-webform/pages/server-side.tsx @@ -2,12 +2,6 @@ import * as React from "react" import { GetStaticPropsResult } from "next" import Head from "next/head" import Link from "next/link" -import { getResourceCollection, DrupalTaxonomyTerm } from "next-drupal" -import { useForm } from "react-hook-form" -import * as yup from "yup" -import { yupResolver } from "@hookform/resolvers/yup" - -import { contactFormSchema } from "../validations/contact" import withCustomStyles from "../components/withCustomStyles" import { resolveWebformContent, @@ -17,19 +11,13 @@ import { } from "nextjs-drupal-webform" import { drupal } from "basic-starter/lib/drupal" import classNames from "classnames" - -type FormData = yup.TypeOf +import WebformButton from "../components/WebformButton" interface WebformPageProps { - teams: DrupalTaxonomyTerm[] webform: WebformProps } -export default function WebformPage({ teams, webform }: WebformPageProps) { - const [status, setStatus] = React.useState<"error" | "success">() - const { register, handleSubmit, formState, reset } = useForm({ - resolver: yupResolver(contactFormSchema), - }) +export default function WebformPage({ webform }: WebformPageProps) { const labelProps = { className: classNames(["block", "text-sm", "font-medium", "text-gray-700"]), } @@ -54,8 +42,6 @@ export default function WebformPage({ teams, webform }: WebformPageProps) { } const buttonProps = { className: classNames([ - "flex", - "justify-center", "px-4", "py-2", "text-sm font-medium", @@ -69,22 +55,6 @@ export default function WebformPage({ teams, webform }: WebformPageProps) { "data-cy": "btn-submit", } - // This makes a POST to a custom API route. - // The Drupal base URL and the webform_id are NOT exposed. - // async function onSubmit(data: FormData) { - // const response = await fetch(`/api/contact`, { - // method: "POST", - // body: JSON.stringify(data), - // }) - // - // if (response.ok) { - // reset() - // return setStatus("success") - // } - // - // return setStatus("error") - // } - return ( <> @@ -95,161 +65,53 @@ export default function WebformPage({ teams, webform }: WebformPageProps) {

Next.js for Drupal

Webform Example - Server Side

- We submit the form values to a custom API route first. The API route - then submits the form to Drupal using the{" "} - - Webform REST + This example uses the{" "} + + Next.js Webform {" "} + library to render and submit forms built using the Drupal Webform module.

-

- This is useful if we need to hide client IDs and secrets or our - Drupal implementation. -

- - {/*
*/} - {/* {status === "error" ? (*/} - {/*
*/} - {/* An error occured. Please try again.*/} - {/*
*/} - {/* ) : null}*/} - {/* {status === "success" ? (*/} - {/*
*/} - {/* Your message has been sent. Thank you.*/} - {/*
*/} - {/* ) : null}*/} - {/* {Object.values(formState.errors)?.length ? (*/} - {/*
*/} - {/* {Object.values(formState.errors).map((error, index) => (*/} - {/*

{error.message}

*/} - {/* ))}*/} - {/*
*/} - {/* ) : null}*/} - {/*
*/} - {/*
*/} - {/* */} - {/* Name*/} - {/* */} - {/* */} - {/*
*/} - {/*
*/} - {/* */} - {/* Email*/} - {/* */} - {/* */} - {/*
*/} - {/*
*/} - {/* */} - {/* Team*/} - {/* */} - {/* */} - {/* */} - {/* {teams.map((team) => (*/} - {/* */} - {/* ))}*/} - {/* */} - {/*
*/} - {/*
*/} - {/* */} - {/* Subject*/} - {/* */} - {/* */} - {/*
*/} - {/*
*/} - {/* */} - {/* Message*/} - {/* */} - {/* */} - {/*
*/} - {/* */} - {/* Submit*/} - {/* */} - {/* */} - {/*
*/} +
+ +

Go back @@ -264,10 +126,8 @@ export default function WebformPage({ teams, webform }: WebformPageProps) { export async function getStaticProps(): Promise< GetStaticPropsResult > { - // Load terms terms for the contact form. return { props: { - teams: await getResourceCollection("taxonomy_term--team"), webform: await resolveWebformContent("contact", drupal), }, } diff --git a/yarn.lock b/yarn.lock index dbda8cd8..3610e973 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10089,10 +10089,10 @@ next@^12.2.3: "@next/swc-win32-ia32-msvc" "12.2.3" "@next/swc-win32-x64-msvc" "12.2.3" -nextjs-drupal-webform@^1.0.0-alpha2: - version "1.0.0-alpha2" - resolved "https://registry.yarnpkg.com/nextjs-drupal-webform/-/nextjs-drupal-webform-1.0.0-alpha2.tgz#03f494b2f8a585ecff3c4bc0f55daeba08aedab9" - integrity sha512-O+AszzKB1qRT0wFmrqthb1EvCz6rOxE+lbZq1ycj5eW2ftPjWOaui6icKWYVYUH+hkxTD3FYVQbMv7qukpuzEw== +nextjs-drupal-webform@^1.0.0-beta1: + version "1.0.0-beta1" + resolved "https://registry.yarnpkg.com/nextjs-drupal-webform/-/nextjs-drupal-webform-1.0.0-beta1.tgz#fbb7989856fa0f559b599c3859c0922f4c5f7bba" + integrity sha512-qdV0LVZvBS9+VEI3IwGp43HkY2z6WuMxRWEuoVC9thqRxTWvspoCGCNYqpdm37IqN9uUgafQyzpQa6eI08ejSA== dependencies: classnames "^2.3.2" From 89afc9562f04070c2a0e1c9ceeabb4f39896793c Mon Sep 17 00:00:00 2001 From: HARUMI JANG Date: Wed, 21 Dec 2022 14:34:36 -0500 Subject: [PATCH 6/7] Update confirmation msg in test --- examples/example-webform/cypress/integration/webform.spec.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/example-webform/cypress/integration/webform.spec.tsx b/examples/example-webform/cypress/integration/webform.spec.tsx index 78b838bf..47f6026c 100644 --- a/examples/example-webform/cypress/integration/webform.spec.tsx +++ b/examples/example-webform/cypress/integration/webform.spec.tsx @@ -30,7 +30,7 @@ context("server side webform", () => { cy.get("[name=message]").type("This is my message.") cy.get("[data-cy=btn-submit]").click() - cy.contains("Your message has been sent. Thank you.") + cy.contains("New submission added to Contact") }) }) From da29f76ad035984a7e55c0d69b5a4e736e0be63c Mon Sep 17 00:00:00 2001 From: HARUMI JANG Date: Wed, 21 Dec 2022 14:46:51 -0500 Subject: [PATCH 7/7] remove option from DrupalClient --- examples/example-webform/lib/drupal.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/examples/example-webform/lib/drupal.ts b/examples/example-webform/lib/drupal.ts index cd653cc6..a1e60835 100644 --- a/examples/example-webform/lib/drupal.ts +++ b/examples/example-webform/lib/drupal.ts @@ -10,8 +10,5 @@ export const drupal = new DrupalClient( scope: "administrator developer site_builder content_administrator content_author content_editor user_administrator headless", }, - // @see https://github.com/vercel/next.js/discussions/32238 - // @see https://github.com/vercel/next.js/blob/d895a50abbc8f91726daa2d7ebc22c58f58aabbb/packages/next/server/api-utils/node.ts#L504 - forceIframeSameSiteCookie: process.env.NODE_ENV === "development", } )