diff --git a/src/app/components/shell/shell.tsx b/src/app/components/shell/shell.tsx index 896516657..74c5e63a9 100644 --- a/src/app/components/shell/shell.tsx +++ b/src/app/components/shell/shell.tsx @@ -23,7 +23,7 @@ function AppContext({children}: React.PropsWithChildren) { ); } -const importContact = () => import('~/pages/contact/contact.js'); +const importContact = () => import('~/pages/contact/embedded.js'); function EmbeddedApp() { return ( diff --git a/src/app/pages/contact/contact.scss b/src/app/pages/contact/contact.scss index d8ab70d85..ded56ee5b 100644 --- a/src/app/pages/contact/contact.scss +++ b/src/app/pages/contact/contact.scss @@ -60,34 +60,6 @@ form { color: os-color(blue); - - textarea { - height: auto; - resize: none; - } - - > .form-content > label { - display: block; - height: $form-element-height; - margin-bottom: $form-element-height; - - &.auto-height { - height: auto; - } - } - } - - .btn { - @include button(); - margin-bottom: $form-element-height; - } - - [type="submit"] { - @extend %primary; - - float: none; - margin: 0; - padding: 0 5rem; } address { diff --git a/src/app/pages/contact/embedded.js b/src/app/pages/contact/embedded.js new file mode 100644 index 000000000..784e9d2c2 --- /dev/null +++ b/src/app/pages/contact/embedded.js @@ -0,0 +1,43 @@ +import React from 'react'; +import Form from './form'; +import './embedded.scss'; + +// File is js because it is dynamically imported (and minimal) +export default function EmbeddedForm() { + const [submitted, setSubmitted] = React.useState(false); + + if (submitted) { + return ; + } + + return ( +
+

Report an issue

+
+ Need to suggest a content correction instead? Fill out the{' '} + + errata form + + . +
+
+
+ ); +} + +function ThankYou() { + const signalDone = React.useCallback( + () => window.parent.postMessage('contact form submitted', '*'), + [] + ); + + return ( +
+

Thanks for contacting us.

+
Someone from our team will follow up with you soon.
+ +
+ ); +} diff --git a/src/app/pages/contact/embedded.scss b/src/app/pages/contact/embedded.scss new file mode 100644 index 000000000..dfa70c9f3 --- /dev/null +++ b/src/app/pages/contact/embedded.scss @@ -0,0 +1,30 @@ +@import 'pattern-library/core/pattern-library/headers'; + +.embedded-contact { + max-width: calc(100vw - 6rem); + width: $text-content-max; + margin: 3rem auto; + display: flex; + flex-direction: column; + gap: 2rem; + + h1 { + @include set-font(h3); + margin: 0; + } + + form { + @include wider-than($tablet-max) { + padding-left: 4rem; + } + } + + button { + @include button(); + + &.primary { + @extend %primary; + align-self: flex-start; + } + } +} \ No newline at end of file diff --git a/src/app/pages/contact/form.js b/src/app/pages/contact/form.js index cb6867b56..4ef29bad0 100644 --- a/src/app/pages/contact/form.js +++ b/src/app/pages/contact/form.js @@ -4,6 +4,7 @@ import DropdownSelect from '~/components/select/drop-down/drop-down'; import {useNavigate, useLocation} from 'react-router-dom'; import { FileButton } from '../errata-form/form/FileUploader'; import useUserContext from '~/contexts/user'; +import './form.scss'; const options = [ 'General', @@ -20,8 +21,6 @@ const options = [ 'OpenStax Polska' ].map((s) => ({label: s, value: s})); -options[0].selected = true; - const assignableOptions = [ 'Getting Started', 'Assignment', @@ -59,29 +58,57 @@ function LabeledInputWithInvalidMessage({ ); } -function useAfterSubmit() { - const navigate = useNavigate(); +function useIsEmbedded() { const {pathname} = useLocation(); + return pathname.includes('embedded'); +} + +function useAfterSubmit(setSubmitted) { + const navigate = useNavigate(); + const isEmbedded = useIsEmbedded(); + return React.useCallback( () => { - if (pathname.includes('embedded')) { - window.parent.postMessage('contact form submitted', '*'); + if (isEmbedded) { + setSubmitted(true); } else { navigate('/confirmation/contact'); } }, - [navigate, pathname] + [navigate, isEmbedded, setSubmitted] ); } +function useSubjectWithInitialization() { + const isEmbedded = useIsEmbedded(); + const initialValue = isEmbedded ? 'OpenStax Assignable' : 'General'; + const subjectState = useState(initialValue); + + // useEffect runs too late + React.useMemo( + () => { + for (const o of options) { + if (o.value === initialValue) { + o.selected = true; + } else { + delete o.selected; + } + } + }, + [initialValue] + ); + + return subjectState; +} + // This is an interim site; normally we can leave postTo null and the default // in the salesforceForm will be right. const newPostSite = 'https://hooks.zapier.com/hooks/catch/175480/3n62dhe/'; -export default function ContactForm() { +export default function ContactForm({setSubmitted}) { const [showInvalidMessages, setShowInvalidMessages] = useState(false); - const [subject, setSubject] = useState('General'); + const [subject, setSubject] = useSubjectWithInitialization(); const assignableSelected = React.useMemo( () => subject === 'OpenStax Assignable', [subject] @@ -94,15 +121,11 @@ export default function ContactForm() { () => (subject === 'OpenStax Polska') ? '/apps/cms/api/mail/send_mail' : newPostSite, [subject] ); - const onChangeSubject = React.useCallback( - (value) => setSubject(value), - [] - ); const beforeSubmit = React.useCallback( () => setShowInvalidMessages(true), [setShowInvalidMessages] ); - const afterSubmit = useAfterSubmit(); + const afterSubmit = useAfterSubmit(setSubmitted); const searchParams = new window.URLSearchParams(window.location.search); const bodyParams = searchParams.getAll('body').join('\n'); const {userStatus} = useUserContext(); @@ -115,33 +138,48 @@ export default function ContactForm() { { - assignableSelected &&