Skip to content

Commit

Permalink
Merge pull request #148 from OperationSpark/142-display-signup-short-…
Browse files Browse the repository at this point in the history
…url-on-sign-up-form

Display short url on sign up form after successful signup
  • Loading branch information
ptbarnum4 committed Mar 29, 2024
2 parents 93a9af3 + 9c1fc59 commit 2058b8f
Show file tree
Hide file tree
Showing 7 changed files with 236 additions and 92 deletions.
2 changes: 1 addition & 1 deletion data/gradShowcase.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"startDateTime": "3/28/2024 18:00",
"cohortName": "Golf",
"eventbriteUrl": "https://showcase.operationspark.org/opspark%20website",
"isActive": true
"isActive": false
}
5 changes: 3 additions & 2 deletions pages/api/infoSession/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,16 @@ export default async function handleInfoSessionForm(req: ISessionUser, res: Next
try {
const payload: ISessionSignup = formatPayload(req.body);

await runCloudFunction({
type SignupResult = { url: string };
const result = await runCloudFunction<ISessionSignup, SignupResult>({
url: SIGNUP_API_ENDPOINT,
body: payload,
headers: {
'X-Greenlight-Signup-Api-Key': GREENLIGHT_API_TOKEN,
},
});

res.status(200).end();
res.status(200).json(result.data);
} catch (error) {
console.error('Could not POST to signup service', error);
res.status(500).end();
Expand Down
31 changes: 29 additions & 2 deletions pages/programs/workforce/infoSession.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { Content, Main, Section } from '@this/components/layout';
import { TOption } from '@this/data/types/bits';
import useKeyCombo from '@this/hooks/useKeyCombo';
import { getStaticAsset } from '@this/pages-api/static/[asset]';
import { referencedByOptions } from '@this/src/Forms/formData/referenceOptions';
import { getFormattedDateTime } from '@this/src/helpers/timeUtils';
import useInfoSession from '@this/src/hooks/useInfoSession';
import { cardShadow, cardShadowLtr, cardShadowRtl } from '@this/src/theme/styled/mixins/shadows';
Expand All @@ -34,9 +35,35 @@ const InfoSession: NextPage<InfoSessionProps> = ({ commonQuestions, logos }) =>

useEffect(() => {
const { referred_by = '' } = router.query;
if (!referred_by || typeof referred_by !== 'string' || referred_by.toLowerCase() !== 'snap')
const referredByStr = Array.isArray(referred_by) ? referred_by[0] : referred_by;
if (!referredByStr) return;
const [referredType, referredValue] = referredByStr.split('@');
const defaultOption = {
name: 'Other Advertising',
value: 'other-advertising',
additionalInfoLabel: 'Where did you hear about us?',
additionalInfo: referredType,
};
const referredByOption = referencedByOptions.find(
(option) => option.value === referredType.toLowerCase(),
);

if (!referredByOption) {
setReferredBy(defaultOption);
return;
setReferredBy({ name: 'SNAP', value: 'snap' });
}

if (referredByOption.additionalInfo) {
referredValue &&
setReferredBy({
...referredByOption,
additionalInfoLabel: referredByOption.additionalInfo,
additionalInfo: referredValue,
});
return;
}

setReferredBy(referredByOption);
}, [router.query]);

return (
Expand Down
226 changes: 143 additions & 83 deletions src/Forms/Form.Workforce.tsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,48 @@
import axios from 'axios';
import moment from 'moment';
import { Fragment, useEffect, useState } from 'react';
import { AiOutlineInfoCircle } from 'react-icons/ai';
import styled from 'styled-components';

import { AiOutlineInfoCircle } from 'react-icons/ai';
import { IoMdCloseCircleOutline as CloseIcon } from 'react-icons/io';
import { MdOpenInNew as NewTabIcon } from 'react-icons/md';

import Button from '@this/components/Elements/Button';
import { Form, Input, useForm } from '@this/components/Form';
import { TOption } from '@this/data/types/bits';
import { IInfoSessionFormValues } from '@this/data/types/infoSession';
import { pixel } from '@this/lib/pixel';
import { ISessionDates } from '@this/pages-api/infoSession/dates';
import { FormDataSignup } from '@this/pages-api/infoSession/user';
import Spinner from '../components/Elements/Spinner';
import { getStateFromZipCode } from '../components/Form/helpers';
import useKeyCombo from '../hooks/useKeyCombo';
import { referencedByOptions } from './formData/referenceOptions';

interface WorkforceFormProps {
sessionDates: ISessionDates[];
referredBy?: { name: string; value: string };
referredBy?: TOption;
}

const WorkforceForm = ({ sessionDates, referredBy }: WorkforceFormProps) => {
const form = useForm<IInfoSessionFormValues>();
const [isSubmitting, setIsSubmitting] = useState(false);
const [renderUrl, setRenderUrl] = useState<string | null>(null);

const [locationMessage, setLocationMessage] = useState('');

const isKeyComboActive = useKeyCombo('o', 's');

const currentValues = form.values();

const handleSubmit = () => {
const handleSubmit = async () => {
if (isSubmitting) return;
setIsSubmitting(true);
const hasErrors = form.hasErrors();

if (hasErrors) {
setIsSubmitting(false);
return form.toggleShowErrors();
}

setIsSubmitting(true);
const { sessionDate, userLocation, firstName, lastName, ...values } = form.values();

userLocation.value = userLocation.name;
Expand Down Expand Up @@ -64,21 +70,34 @@ const WorkforceForm = ({ sessionDates, referredBy }: WorkforceFormProps) => {
sessionTime: session?.times?.start?.dateTime || null,
});

axios
.post('/api/infoSession/user', body)
.then(() => {
try {
const { data } = await axios.post('/api/infoSession/user', body);

const textMessage = currentValues.smsOptIn === 'true' ? ' and text message' : '';

if (currentValues.sessionDate.value === 'future') {
form.notifySuccess({
msg: 'Info session registration for submitted. You should receive an email and text message shortly.',
});
form.clear();
})
.catch(() => {
form.notifyError({
title: 'Error',
msg: 'There was an error signing you up\nPlease reach out to us at "admissions@operationspark.org" or give us a call at 504-233-3838',
msg: `Thank you for signing up! We will reach out soon. You will receive an email ${textMessage} shortly.`,
});
})
.finally(() => setIsSubmitting(false));
setRenderUrl(data.url);
return setIsSubmitting(false);
}

const sessionDate = currentValues.sessionDate.name;

form.notifySuccess({
msg: `You have successfully registered for an info session on ${sessionDate}. You will receive an email ${textMessage} shortly.`,
});

setRenderUrl(data.url);
} catch (error) {
form.notifyError({
title: 'Error',
msg: 'There was an error signing you up\nPlease reach out to us at "admissions@operationspark.org" or give us a call at 504-233-3838',
});
} finally {
setIsSubmitting(false);
}
};
const getLocationType = (session: ISessionDates) => {
const locationType = session.locationType
Expand All @@ -104,6 +123,11 @@ const WorkforceForm = ({ sessionDates, referredBy }: WorkforceFormProps) => {
},
];

const closeDetails = () => {
setRenderUrl(null);
form.clear();
};

useEffect(() => {
const zipChange = form.onSelectChange('userLocation');
const zipCode = Number(currentValues.zipCode);
Expand Down Expand Up @@ -171,23 +195,27 @@ const WorkforceForm = ({ sessionDates, referredBy }: WorkforceFormProps) => {
}, [currentValues.sessionDate, currentValues.attendingLocation, sessionDates]);

useEffect(() => {
if (referredBy) {
form.onSelectChange('referencedBy')({
option: referredBy,
isValid: true,
});
}
if (!referredBy) return;
form.onSelectChange('referencedBy')({
option: referredBy,
additionalInfo: referredBy.additionalInfo,
additionalInfoLabel: referredBy.additionalInfoLabel,
isValid: true,
});

// eslint-disable-next-line react-hooks/exhaustive-deps -- Ignore form change
}, [referredBy]);

return (
<WorkforceFormStyles>
<Form onSubmit={handleSubmit}>
{isSubmitting ? (
<div className='form-overlay'>
<Spinner text='Submitting' />
</div>
) : null}
<Form
onSubmit={handleSubmit}
onEnter={(e) => {
e.preventDefault();
e.stopPropagation();
handleSubmit();
}}
>
{workforceFormInputs.map((field, i) => (
<field.Element
key={field.name}
Expand Down Expand Up @@ -350,6 +378,41 @@ const WorkforceForm = ({ sessionDates, referredBy }: WorkforceFormProps) => {
>
Register!
</Button>

{isSubmitting ? (
<div className='form-overlay'>
<Spinner text='Submitting' />
</div>
) : null}
{renderUrl && !isSubmitting ? (
<div className='form-overlay'>
<div className='form-complete-response'>
<h2>Success!</h2>
{currentValues.sessionDate.value === 'future' ? (
<p>
Thank you for signing up! We will reach out soon. You will receive an email{' '}
{currentValues.smsOptIn === 'true' ? 'and text message' : ''} shortly.
</p>
) : (
<p>
You have successfully registered for an info session on{' '}
<b className='primary-secondary'>{currentValues.sessionDate.name}</b>. You will
receive an email {currentValues.smsOptIn === 'true' ? 'and text message' : ''}{' '}
shortly.
</p>
)}
<a href={renderUrl} className='anchor' target='_blank' rel='noreferrer'>
{currentValues.sessionDate.value === 'future'
? 'View details'
: 'View your registration details'}
<NewTabIcon />
</a>
<button onClick={closeDetails}>
<CloseIcon className='close-button' />
</button>
</div>
</div>
) : null}
</Form>
</WorkforceFormStyles>
);
Expand All @@ -361,13 +424,61 @@ const WorkforceFormStyles = styled.div`
.form-overlay {
position: absolute;
inset: 0;
z-index: 10;
z-index: 100;
backdrop-filter: blur(1.5px);
background: rgba(125, 125, 125, 0.2);
display: flex;
align-items: center;
justify-content: center;
}
.form-complete-response {
position: relative;
display: flex;
flex-flow: column;
align-items: center;
justify-content: center;
background: ${({ theme }) => theme.bg};
padding: 1.5rem;
border-radius: 0.5rem;
max-width: 90%;
text-align: center;
h2 {
font-size: 2rem;
font-weight: 600;
margin-bottom: 1rem;
}
p {
font-size: 1.1rem;
font-weight: 300;
margin-bottom: 1rem;
}
a {
display: flex;
align-items: center;
font-weight: 600;
margin-top: 1rem;
gap: 0.5rem;
}
.close-button {
position: absolute;
top: 0.5rem;
right: 0.5rem;
font-size: 1.5rem;
cursor: pointer;
color: ${({ theme }) => theme.red[300]};
transition: all 225ms;
:hover {
color: ${({ theme }) => theme.red[500]};
transform: scale(1.1);
}
:active {
transform: scale(0.9);
}
}
}
.user-location-row {
display: flex;
width: 100%;
Expand Down Expand Up @@ -445,54 +556,3 @@ const workforceFormInputs = [
required: true,
},
];

const referencedByOptions = [
{
value: 'google',
name: 'Google',
},
{
value: 'facebook',
name: 'Facebook',
},
{
value: 'instagram',
name: 'Instagram',
},
{
value: 'flyer',
name: 'Flyer',
},
{
value: 'radio',
name: 'Radio Advertising',
},
{
value: 'tv-streaming',
name: 'T.V. or Streaming Service',
},
{
value: 'snap',
name: 'SNAP',
},
{
value: 'other-advertising',
name: 'Other Advertising',
additionalInfo: 'Where did you hear about us?',
},
{
value: 'verbal',
name: 'Word of mouth',
additionalInfo: 'Who told you about us?',
},
{
value: 'event',
name: 'Community Event',
additionalInfo: 'Which event?',
},
{
value: 'organization',
name: 'Community Organization',
additionalInfo: 'Which organization?',
},
];
Loading

0 comments on commit 2058b8f

Please sign in to comment.