Skip to content

Commit

Permalink
Port details page to ts, part 1 (#2679)
Browse files Browse the repository at this point in the history
* All but featured-resources have test coverage

* Get featured resources test coverage

* Use .nvmrc in build.yml
  • Loading branch information
RoyEJohnson authored Nov 8, 2024
1 parent c875d12 commit d6b22d0
Show file tree
Hide file tree
Showing 25 changed files with 731 additions and 494 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ jobs:
uses: actions/checkout@v2
-
name: "Setup NVM"
uses: dcodeIO/setup-node-nvm@master
uses: actions/setup-node@v3
with:
node-version: v16.20.2
node-version-file: .nvmrc
cache: yarn
-
name: "Setup environment"
run: ./script/setup
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import React from 'react';
import ResourceBoxes, {ResourceModel} from '../resource-box/resource-boxes';
import {FormattedMessage} from 'react-intl';
import './featured-resources.scss';

type ResourcesProps = {
header: string;
models: ResourceModel[];
'data-analytics-content-list': string;
};

function FeaturedResources({header, models, ...props}: ResourcesProps) {
const modResources = models.map((res) => {
const storageKey = `featured-resource-${res.heading}`;
const seenTimes = 1 + Number(window.localStorage[storageKey] || 0);
const model = Object.assign(
{
isNew: seenTimes <= 3
// There was an onClick defined here that nothing used
},
res
);

window.localStorage[storageKey] = seenTimes;

return model;
});

return (
<div className="card">
<div className="headline">{header}</div>
<div
data-analytics-content-list={
props['data-analytics-content-list']
}
className="resources"
>
<ResourceBoxes models={modResources} />
</div>
</div>
);
}

export default function FeaturedResourcesSection({
header,
models,
...props
}: ResourcesProps) {
return (
<div>
<div className="featured-resources">
<FeaturedResources header={header} models={models} {...props} />
</div>
<div className="divider">
<div className="line"></div>
<FormattedMessage
id="resources.additional"
defaultMessage="see additional resources below"
/>
<div className="line"></div>
</div>
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export default function GiveBeforeOther({
close: () => void;
data: DonationPopupData;
track?: string;
variant?: string;
variant: string;
onDownload?: (event: React.MouseEvent) => void;
id?: string;
}) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ function GiveBeforePdfAfterConditionals({
}: {
onThankYouClick: ReturnType<typeof useOnThankYouClick>['onThankYouClick'];
link: string;
track: string | undefined;
track?: string;
data: DonationPopupData;
close: () => void;
onDownload?: (event: React.MouseEvent) => void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,54 +2,67 @@ import React from 'react';
import useUserContext from '~/contexts/user';
import trackLink from '../../track-link';
import './thank-you-form.scss';
import {TrackedMouseEvent} from '~/components/shell/router-helpers/use-link-handler';

function FormWithAfterSubmit({
afterSubmit,
responseId = 'form-response',
children,
onSubmit: firstOnSubmit,
...formProps
}) {
const iframeRef = React.useRef();
}: React.PropsWithChildren<
{
afterSubmit: () => void;
responseId?: string;
} & React.FormHTMLAttributes<HTMLFormElement>
>) {
const iframeRef = React.useRef<HTMLIFrameElement>(null);
const onSubmit = React.useCallback(
(event) => {
if (firstOnSubmit) {
firstOnSubmit(event);
if (event.defaultPrevented) {
return;
}
}
() => {
const iframe = iframeRef.current;
const runAfterSubmit = () => {
afterSubmit();
iframe.removeEventListener('load', runAfterSubmit);
iframe?.removeEventListener('load', runAfterSubmit);
};

iframe.addEventListener('load', runAfterSubmit);
iframe?.addEventListener('load', runAfterSubmit);
},
[firstOnSubmit, afterSubmit]
[afterSubmit]
);

return (
<React.Fragment>
<iframe
name={responseId}
title={responseId}
id={responseId}
className='hidden'
src=''
width='0'
height='0'
tabIndex='-1'
className="hidden"
src=""
width="0"
height="0"
tabIndex={-1}
ref={iframeRef}
/>
<form target={responseId} {...formProps} onSubmit={onSubmit}>
<form target={responseId} {...formProps} onSubmit={onSubmit} name="thank-you form">
{children}
</form>
</React.Fragment>
);
}

export default function ThankYou({link, close, source, itemType='PDF', track, id}) {
export default function ThankYou({
link,
close,
source,
itemType = 'PDF',
track,
id
}: {
link: string;
close: () => void;
source: string;
itemType?: string;
track?: string;
id?: string;
}) {
const {userModel} = useUserContext();
const first = userModel?.first_name;
const last = userModel?.last_name;
Expand All @@ -59,7 +72,7 @@ export default function ThankYou({link, close, source, itemType='PDF', track, id
close();
}, [link, close]);
const trackDownload = React.useCallback(
(event) => {
(event: TrackedMouseEvent) => {
trackLink(event, id);
},
[id]
Expand All @@ -68,81 +81,83 @@ export default function ThankYou({link, close, source, itemType='PDF', track, id
return (
<FormWithAfterSubmit
action={`${process.env.API_ORIGIN}/apps/cms/api/donations/thankyounote/`}
method='post'
className='thank-you-form'
method="post"
className="thank-you-form"
afterSubmit={afterSubmit}
>
<input type='hidden' name='source' value={source} />
<input type="hidden" name="source" value={source} />
<h1>Send us a thank you note</h1>
<div className='instructions'>
<span className='asterisk' />
<div className="instructions">
<span className="asterisk" />
indicates required field
</div>
<label>
Your message <span className='asterisk' />
Your message <span className="asterisk" />
<textarea
name='thank_you_note'
rows='4'
placeholder='Start typing'
name="thank_you_note"
rows={4}
placeholder="Start typing"
required
/>
</label>
<div className='names'>
<div className="names">
<label>
First name <span className='asterisk' />
First name <span className="asterisk" />
<input
name='first_name'
type='text'
placeholder='Your first name'
name="first_name"
type="text"
placeholder="Your first name"
required
defaultValue={first}
/>
</label>
<label>
Last name <span className='asterisk' />
Last name <span className="asterisk" />
<input
name='last_name'
type='text'
placeholder='Your last name'
name="last_name"
type="text"
placeholder="Your last name"
required
defaultValue={last}
/>
</label>
<label>
Institution name <span className='asterisk' />
Institution name <span className="asterisk" />
<input
name='institution'
type='text'
placeholder='Your school'
name="institution"
type="text"
placeholder="Your school"
required
defaultValue={school}
/>
</label>
<label>
Email address
<input
name='contact_email_address'
type='email'
placeholder='Your email (optional)'
name="contact_email_address"
type="email"
placeholder="Your email (optional)"
/>
</label>
</div>
<div className='consent-checkbox'>
<div className="consent-checkbox">
<label>
Consent <span className='asterisk' />
Consent <span className="asterisk" />
</label>
<label className='cb-group'>
<label className="cb-group">
<input
type='checkbox'
name='consent_to_share_or_contact'
value='True'
type="checkbox"
name="consent_to_share_or_contact"
value="True"
/>
By clicking here I understand that OpenStax may include my
story in publications and distribution in printed,
electronic, and digital media.
</label>
</div>
<button className='primary'>Submit note and go to {itemType}</button>
<button className="primary">
Submit note and go to {itemType}
</button>
<a
className="never-mind"
href={link}
Expand All @@ -158,7 +173,7 @@ export default function ThankYou({link, close, source, itemType='PDF', track, id

export function useOnThankYouClick() {
const [showThankYou, setShowThankYou] = React.useState(false);
const onThankYouClick = React.useCallback((event) => {
const onThankYouClick = React.useCallback((event: React.MouseEvent) => {
event.preventDefault();
setShowThankYou(true);
}, []);
Expand Down
Loading

0 comments on commit d6b22d0

Please sign in to comment.