From 1a6fe2e63a783fd4d5d48f0664a808f62fa8142f Mon Sep 17 00:00:00 2001 From: VarunVAshrit Date: Mon, 7 Oct 2024 11:58:55 +0530 Subject: [PATCH 1/3] :sparkles: Create a new contact form for Equinor pension --- FeatureFlags.js | 5 +- sanityv3/schemas/objects/form.tsx | 4 + sanityv3/schemas/textSnippets.ts | 93 ++++++ web/pageComponents/topicPages/Form/Form.tsx | 4 + .../topicPages/Form/PensionForm.tsx | 297 ++++++++++++++++++ web/pages/api/forms/service-now-pension.ts | 61 ++++ web/types/types.ts | 2 +- 7 files changed, 464 insertions(+), 2 deletions(-) create mode 100644 web/pageComponents/topicPages/Form/PensionForm.tsx create mode 100644 web/pages/api/forms/service-now-pension.ts diff --git a/FeatureFlags.js b/FeatureFlags.js index a7bfdf73f..079f56ce1 100644 --- a/FeatureFlags.js +++ b/FeatureFlags.js @@ -44,6 +44,7 @@ const CAREERS_CONTACT_FORM = [...GLOBAL_PROD, ...GLOBAL_DEV] const CONTACT_EQUINOR_FORM = [...GLOBAL_PROD, ...GLOBAL_DEV] const ORDER_REPORT_FORM = [...GLOBAL_PROD, ...GLOBAL_DEV] const CAREER_FAIR_AND_VISITS_FORM = [...GLOBAL_PROD, ...GLOBAL_DEV, 'brazil'] +const PENSION_FORM = [...GLOBAL_PROD, ...GLOBAL_DEV] const FANCY_MENU = [...GLOBAL_PROD, ...GLOBAL_DEV] /* LANDING_PAGE requires FANCY_MENU to work */ @@ -73,13 +74,15 @@ export default (dataset) => ({ CAREER_FAIR_AND_VISITS_FORM.includes(dataset) || CONTACT_EQUINOR_FORM.includes(dataset) || ORDER_REPORT_FORM.includes(dataset) || - SUBSCRIBE_FORM.includes(dataset), + SUBSCRIBE_FORM.includes(dataset) || + PENSION_FORM.includes(dataset), HAS_SUBSCRIBE_FORM: SUBSCRIBE_FORM.includes(dataset), HAS_CAREERS_CONTACT_FORM: CAREERS_CONTACT_FORM.includes(dataset), HAS_CAREER_FAIR_AND_VISITS_FORM: CAREER_FAIR_AND_VISITS_FORM.includes(dataset), HAS_ORDER_REPORT_FORM: ORDER_REPORT_FORM.includes(dataset), HAS_CONTACT_EQUINOR_FORM: CONTACT_EQUINOR_FORM.includes(dataset), + HAS_PENSION_FORM: PENSION_FORM.includes(dataset), HAS_FANCY_MENU: FANCY_MENU.includes(dataset), /* LANDING_PAGE requires FANCY_MENU to work */ diff --git a/sanityv3/schemas/objects/form.tsx b/sanityv3/schemas/objects/form.tsx index 1b6e264fb..3eb7ea0d4 100644 --- a/sanityv3/schemas/objects/form.tsx +++ b/sanityv3/schemas/objects/form.tsx @@ -22,6 +22,7 @@ type FormType = | 'careersContactForm' | 'orderReportsForm' | 'careerFairAndVisitsForm' + | 'pensionForm' const ingressContentType = configureBlockContent({ h2: false, @@ -67,6 +68,7 @@ export default { title: 'Career fairs and visits', value: 'careerFairAndVisitsForm', }, + Flags.HAS_PENSION_FORM && { title: 'Pension form', value: 'pensionForm' }, ].filter((e) => e), layout: 'dropdown', }, @@ -110,6 +112,8 @@ export default { return 'Careers contact form' } else if (type == 'orderReportsForm') { return 'Order reports' + } else if(type == 'pensionForm') { + return 'Pension form' } return 'Career fairs and visits' } diff --git a/sanityv3/schemas/textSnippets.ts b/sanityv3/schemas/textSnippets.ts index fc1bfdbfb..3da074493 100644 --- a/sanityv3/schemas/textSnippets.ts +++ b/sanityv3/schemas/textSnippets.ts @@ -10,6 +10,7 @@ export const groups = { contactForm: { title: 'Contact form', hidden: !Flags.HAS_CONTACT_EQUINOR_FORM }, careerContactForm: { title: 'Careers Contact Form', hidden: !Flags.HAS_CAREERS_CONTACT_FORM }, orderAnnualReportsForm: { title: 'Order annual reports form', hidden: !Flags.HAS_ORDER_REPORT_FORM }, + pensionForm: { title: 'Pension form', hidden: !Flags.HAS_PENSION_FORM }, form: { title: 'Form', hidden: !Flags.HAS_FORMS }, cookie: { title: 'Cookie' }, others: { title: 'Others' }, @@ -304,6 +305,98 @@ const snippets: textSnippet = { defaultValue: 'Submit form', group: groups.contactForm, }, + pension_form_name: { + title: 'Name', + defaultValue: 'Name *', + group: groups.pensionForm, + }, + pension_form_name_placeholder: { + title: 'Name Placeholder', + defaultValue: 'Jane Doe', + group: groups.pensionForm, + }, + pension_form_name_validation: { + title: 'Name validation', + defaultValue: 'Please fill out your name', + group: groups.pensionForm, + }, + + pension_form_email: { + title: 'Email', + defaultValue: 'Email *', + group: groups.pensionForm, + }, + pension_form_email_validation: { + title: 'Email validation', + defaultValue: 'Please fill out a valid email address', + group: groups.pensionForm, + }, + + pension_form_phone: { + title: 'Phone', + defaultValue: 'Phone *', + group: groups.pensionForm, + }, + pension_form_phone_placeholder: { + title: 'Phone Placeholder', + defaultValue: '123-456-7890', + group: groups.pensionForm, + }, + pension_form_phone_validation: { + title: 'Phone validation', + defaultValue: 'Please fill out your phone number', + group: groups.pensionForm, + }, + + pension_form_category: { + title: 'Category', + defaultValue: 'Category', + group: groups.pensionForm, + }, + pension_form_category_pension: { + title: 'Pension Category', + defaultValue: 'Pension', + group: groups.pensionForm, + }, + pension_form_category_travel_insurance: { + title: 'Travel Insurance Category', + defaultValue: 'Travel Insurance', + group: groups.pensionForm, + }, + pension_form_category_other: { + title: 'Other Pension/Insurance Related Category', + defaultValue: 'Other Pension/Insurance Related', + group: groups.pensionForm, + }, + + pension_form_what_is_your_request: { + title: 'What is your request?', + defaultValue: 'What is your request?', + group: groups.pensionForm, + }, + pension_form_what_is_your_request_placeholder: { + title: `Requests Placeholder`, + defaultValue: `Please don't enter any personal information`, + group: groups.pensionForm, + }, + pension_form_what_is_your_request_validation: { + title: 'Requests Validation', + defaultValue: 'Please let us know how we may help you', + group: groups.pensionForm, + }, + + pension_form_submit: { + title: 'Submit Button Text', + defaultValue: 'Submit Form', + group: groups.pensionForm, + }, + + pension_form_all_fields_mandatory: { + title: 'All fields with * are mandatory', + defaultValue: 'All fields with * are mandatory', + group: groups.pensionForm, + }, + career_fair_form_organisation: { title: 'Organisation', defaultValue: 'School / Organisation', diff --git a/web/pageComponents/topicPages/Form/Form.tsx b/web/pageComponents/topicPages/Form/Form.tsx index 0a83018b7..ff59cb26e 100644 --- a/web/pageComponents/topicPages/Form/Form.tsx +++ b/web/pageComponents/topicPages/Form/Form.tsx @@ -9,6 +9,8 @@ import CareersContactForm from './careersContactForm/CareersContactForm' import type { FormData } from '../../../types/types' import { twMerge } from 'tailwind-merge' import CallToActions from '@sections/CallToActions' +import PensionForm from './PensionForm' +import React from 'react' const StyledHeading = styled(TitleText)` padding: 0 0 var(--space-large) 0; @@ -32,6 +34,8 @@ const Form = ({ data, anchor, className }: { data: FormData; anchor?: string; cl return case 'careersContactForm': return + case 'pensionForm': + return case 'orderReportsForm': return ( <> diff --git a/web/pageComponents/topicPages/Form/PensionForm.tsx b/web/pageComponents/topicPages/Form/PensionForm.tsx new file mode 100644 index 000000000..ce64512d4 --- /dev/null +++ b/web/pageComponents/topicPages/Form/PensionForm.tsx @@ -0,0 +1,297 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { Icon } from '@equinor/eds-core-react' +import { useForm, Controller } from 'react-hook-form' +import { error_filled } from '@equinor/eds-icons' +import { FormattedMessage, useIntl } from 'react-intl' +import { FormButton, FormTextField, FormSelect, FormSubmitSuccessBox, FormSubmitFailureBox } from '@components' +import { BaseSyntheticEvent, useState } from 'react' +import FriendlyCaptcha from './FriendlyCaptcha' +import { PensionFormCatalogType } from '../../../types' +import React from 'react' + +type PensionFormValues = { + name: string + email: string + phone: string + pensionCategory: string + requests: string +} + +const PensionForm = () => { + const intl = useIntl() + const [submitButtonEnabled, setSubmitButtonEnabled] = useState(false) + const [isServerError, setServerError] = useState(false) + const [isSuccessfullySubmitted, setSuccessfullySubmitted] = useState(false) + + const onSubmit = async (data: PensionFormValues, event?: BaseSyntheticEvent) => { + const res = await fetch('/api/forms/service-now-pension', { + body: JSON.stringify({ + data, + frcCaptchaSolution: (event?.target as any)['frc-captcha-solution'].value, + catalogType: getCatalog(data.pensionCategory), + }), + headers: { + 'Content-Type': 'application/json', + }, + method: 'POST', + }) + + setServerError(res.status != 200) + setSuccessfullySubmitted(res.status == 200) + } + + const getCatalog = (category: string): PensionFormCatalogType | null => { + if (category.includes(intl.formatMessage({ id: 'pension_form_pension', defaultMessage: 'Pension' }))) + return 'pension' + else if ( + category.includes(intl.formatMessage({ id: 'pension_form_travel_insurance', defaultMessage: 'Travel Insurance' })) + ) + return 'travelInsurance' + else if ( + category.includes( + intl.formatMessage({ + id: 'pension_form_other_pension_insurance_related', + defaultMessage: 'Other Pension/Insurance Related', + }), + ) + ) + return 'otherPensionInsuranceRelated' + else return null + } + + const { + handleSubmit, + control, + reset, + formState: { isSubmitted, isSubmitting, isSubmitSuccessful }, + } = useForm({ + defaultValues: { + name: '', + email: '', + phone: '', + pensionCategory: intl.formatMessage({id: 'pension_form_select_topic', defaultMessage: 'Select topic'}), + requests: '', + }, + }) + + return ( + <> +
{ + reset() + setSubmitButtonEnabled(false) + setSuccessfullySubmitted(false) + }} + > + {!isSuccessfullySubmitted && !isServerError && ( + <> + {/* Name field */} + { + const { name } = props + return ( + : undefined} + helperText={error?.message} + {...(invalid && { variant: 'error' })} + /> + ) + }} + /> + + {/* Email field */} + { + const { name } = props + return ( + : undefined} + helperText={error?.message} + aria-required="true" + {...(invalid && { variant: 'error' })} + /> + ) + }} + /> + + {/* Phone field */} + { + const { name } = props + return ( + : undefined} + helperText={error?.message} + {...(invalid && { variant: 'error' })} + /> + ) + }} + /> + + {/* Pension Category field */} + { + const { name } = props + return ( + + + + + + + ) + }} + /> + + {/* requests field */} + { + const { name } = props + return ( + : undefined} + helperText={error?.message} + {...(invalid && { variant: 'error' })} + /> + ) + }} + /> + +
+ +
+ + { + setSubmitButtonEnabled(true) + }} + errorCallback={(error: any) => { + console.error('FriendlyCaptcha encountered an error', error) + setSubmitButtonEnabled(true) + }} + /> + + + {isSubmitting ? ( + + ) : ( + + )} + + + )} + + {isSubmitSuccessful && } + {isServerError && } + + + ) +} + +export default PensionForm diff --git a/web/pages/api/forms/service-now-pension.ts b/web/pages/api/forms/service-now-pension.ts new file mode 100644 index 000000000..17e3ad7ce --- /dev/null +++ b/web/pages/api/forms/service-now-pension.ts @@ -0,0 +1,61 @@ +import { NextApiRequest, NextApiResponse } from 'next' +import { PensionFormCatalogType } from '../../../types' +import { sendRequestToServiceNow } from './service-now-base' +import { validateFormRequest } from './validateFormRequest' + +const getCatalogIdentifier = (catalogType: PensionFormCatalogType | null) => { + console.log(catalogType) + switch (catalogType) { + case 'pension': + return '6777904f938a2950eaf1f4527cba1048'; + case 'travelInsurance': + return '1818180393ca2950eaf1f4527cba101d'; + case 'otherPensionInsuranceRelated': + return '6777904f938a2950eaf1f4527cba1048'; + default: + return '6777904f938a2950eaf1f4527cba1048'; + } + }; + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + const result = await validateFormRequest(req, 'pension form') + if (result.status !== 200) { + return res.status(result.status).json({ msg: result.message }) + } + + const catalogIdentifier = getCatalogIdentifier(req.body.catalogType) + + const data = req.body.data + const email = encodeURI(data.email) + const category = encodeURI(data.category) + const requests = encodeURI(data.message) + const name = encodeURI(data.name) + + const urlString = + process.env.SERVICE_NOW_FORM_URL + + '/api/stasa/statoildotcomproject/ContactUs/' + + process.env.SERVICE_NOW_FORM_CATALOG_ITEM + + '/' + + catalogIdentifier + + '?Email=' + + email + + '&Category=' + + category + + '&Requests=' + + requests + + '&Name=' + + name + + await sendRequestToServiceNow(urlString) + .then((response) => { + if (JSON.parse(response).status == 'failure' || JSON.parse(response).Status?.includes('Failure')) { + console.log('Failed to create ticket in service-now') + res.status(500).end() + } + res.status(200).end() + }) + .catch((error) => { + console.log('Error occured while sending request to ServiceNow', error) + res.status(500).end() + }) +} diff --git a/web/types/types.ts b/web/types/types.ts index a7c6b1660..c4a4b2bfd 100644 --- a/web/types/types.ts +++ b/web/types/types.ts @@ -813,7 +813,7 @@ export type IframeCarouselData = { export type ContactFormCatalogType = 'humanRightsInformationRequest' | 'loginIssues' export type CareersContactFormCatalogType = 'suspectedRecruitmentScamRequest' | 'emergingTalentsQueries' | 'others' - +export type PensionFormCatalogType= 'pension'|'travelInsurance'|'otherPensionInsuranceRelated'; export type KeyNumberItemData = { type: 'keyNumberItem' id: string From c8a56cf2e812b56077738a4c82c2d1627308ab49 Mon Sep 17 00:00:00 2001 From: VarunVAshrit Date: Fri, 11 Oct 2024 13:02:31 +0530 Subject: [PATCH 2/3] :sparkles: Create a new form for Equinor pension(removed phone field) #2528 --- sanityv3/schemas/textSnippets.ts | 19 +---------- .../topicPages/Form/PensionForm.tsx | 34 ------------------- 2 files changed, 1 insertion(+), 52 deletions(-) diff --git a/sanityv3/schemas/textSnippets.ts b/sanityv3/schemas/textSnippets.ts index 3da074493..76fcd6674 100644 --- a/sanityv3/schemas/textSnippets.ts +++ b/sanityv3/schemas/textSnippets.ts @@ -330,24 +330,7 @@ const snippets: textSnippet = { title: 'Email validation', defaultValue: 'Please fill out a valid email address', group: groups.pensionForm, - }, - - pension_form_phone: { - title: 'Phone', - defaultValue: 'Phone *', - group: groups.pensionForm, - }, - pension_form_phone_placeholder: { - title: 'Phone Placeholder', - defaultValue: '123-456-7890', - group: groups.pensionForm, - }, - pension_form_phone_validation: { - title: 'Phone validation', - defaultValue: 'Please fill out your phone number', - group: groups.pensionForm, - }, - + }, pension_form_category: { title: 'Category', defaultValue: 'Category', diff --git a/web/pageComponents/topicPages/Form/PensionForm.tsx b/web/pageComponents/topicPages/Form/PensionForm.tsx index ce64512d4..f14ae0208 100644 --- a/web/pageComponents/topicPages/Form/PensionForm.tsx +++ b/web/pageComponents/topicPages/Form/PensionForm.tsx @@ -157,40 +157,6 @@ const PensionForm = () => { }} /> - {/* Phone field */} - { - const { name } = props - return ( - : undefined} - helperText={error?.message} - {...(invalid && { variant: 'error' })} - /> - ) - }} - /> - {/* Pension Category field */} Date: Mon, 14 Oct 2024 17:37:28 +0530 Subject: [PATCH 3/3] :sparkles: Cleaned up the log #2528 --- web/pages/api/forms/service-now-pension.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/web/pages/api/forms/service-now-pension.ts b/web/pages/api/forms/service-now-pension.ts index 17e3ad7ce..e1ee8e299 100644 --- a/web/pages/api/forms/service-now-pension.ts +++ b/web/pages/api/forms/service-now-pension.ts @@ -4,7 +4,6 @@ import { sendRequestToServiceNow } from './service-now-base' import { validateFormRequest } from './validateFormRequest' const getCatalogIdentifier = (catalogType: PensionFormCatalogType | null) => { - console.log(catalogType) switch (catalogType) { case 'pension': return '6777904f938a2950eaf1f4527cba1048';