Skip to content

Commit 15caea9

Browse files
OpenStaxClaudeclaudeRoyEJohnson
authored
CORE-1287: Port remaining book details page modules from JS to TS (#2786)
* Port remaining book details page modules from JS to TS Converted all remaining JavaScript files in src/app/pages/details to TypeScript: Desktop view modules: - desktop-view.js → desktop-view.tsx - details-tab.js → details-tab.tsx - videos-tab.js → videos-tab.tsx - partners.js → partners.tsx - import-*.js → import-*.ts Phone view modules: - phone-view.js → phone-view.tsx - details-pane.js → details-pane.tsx - student-resources-pane.js → student-resources-pane.tsx - instructor-resources-pane.js → instructor-resources-pane.tsx All conversions follow TypeScript best practices: - Avoided using 'any' type - Preferred 'type' to 'interface' - Used type inference where possible - Inline type definitions for function parameters - Line lengths kept under 120 characters 🤖 Generated with [Claude Code](https://claude.com/claude-code) Port remaining book details page modules from JS to TS Converted all remaining JavaScript files in src/app/pages/details to TypeScript: Desktop view modules: - desktop-view.js → desktop-view.tsx - details-tab.js → details-tab.tsx - videos-tab.js → videos-tab.tsx - partners.js → partners.tsx - import-*.js → import-*.ts Phone view modules: - phone-view.js → phone-view.tsx - details-pane.js → details-pane.tsx - student-resources-pane.js → student-resources-pane.tsx - instructor-resources-pane.js → instructor-resources-pane.tsx All conversions follow TypeScript best practices: - Avoided using 'any' type - Preferred 'type' to 'interface' - Used type inference where possible - Inline type definitions for function parameters - Line lengths kept under 120 characters 🤖 Generated with [Claude Code](https://claude.com/claude-code) Revert to JS (loaders) Co-Authored-By: Claude <noreply@anthropic.com> * Lint clean * Test coverage --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Roy Johnson <roy.e.johnson@rice.edu>
1 parent 1e67deb commit 15caea9

File tree

28 files changed

+737
-443
lines changed

28 files changed

+737
-443
lines changed

src/app/components/accordion-group/accordion-group.tsx

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,9 @@ function Item({
109109

110110
type ItemType = {
111111
title: string;
112-
inline?: React.ReactNode;
113112
contentComponent: React.ReactNode;
113+
} | {
114+
inline: React.ReactNode;
114115
};
115116

116117
export default function AccordionGroup({
@@ -161,16 +162,15 @@ export default function AccordionGroup({
161162
preExpanded={preExpandedUuids}
162163
data-analytics-nav={analyticsNav}
163164
>
164-
{items.map(
165-
(item) =>
166-
item.inline || (
167-
<Item
168-
analytics={!!analyticsNav}
169-
key={item.title}
170-
{...item}
171-
checkChevronDirection={chevronDirection}
172-
/>
173-
)
165+
{items.filter((i) => 'title' in i).map(
166+
(item) => (
167+
<Item
168+
analytics={!!analyticsNav}
169+
key={item.title}
170+
{...item}
171+
checkChevronDirection={chevronDirection}
172+
/>
173+
)
174174
)}
175175
</Accordion>
176176
</div>

src/app/pages/details/common/get-this-title-files/options.tsx

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ export function WebviewOption({model}: {model: Model}) {
121121
const {GiveDialog, openGiveDialog} = useOpenGiveDialog();
122122
const trackDownload = React.useCallback(
123123
(event: TrackedMouseEvent) => {
124-
trackLink(event, model.id);
124+
trackLink(event, model.id.toString());
125125
},
126126
[model.id]
127127
);
@@ -140,10 +140,10 @@ export function WebviewOption({model}: {model: Model}) {
140140
<GiveDialog
141141
link={webviewLink}
142142
variant="View online"
143-
warning={model.contentWarningText}
143+
warning={model.contentWarningText ?? undefined}
144144
track="Online"
145145
onDownload={trackDownload}
146-
id={model.id}
146+
id={model.id.toString()}
147147
/>
148148
{showCallout && (
149149
<div className="callout recommended-callout">
@@ -173,12 +173,12 @@ export function PdfOption({model}: {model: Model}) {
173173
const {GiveDialog, openGiveDialog} = useOpenGiveDialog();
174174
const trackDownload = React.useCallback(
175175
(event: TrackedMouseEvent) => {
176-
trackLink(event, model.id);
176+
trackLink(event, model.id.toString());
177177
},
178178
[model.id]
179179
);
180180

181-
return (
181+
return pdfLink ? (
182182
<React.Fragment>
183183
<SimpleLinkOption
184184
link={pdfLink}
@@ -190,11 +190,11 @@ export function PdfOption({model}: {model: Model}) {
190190
link={pdfLink}
191191
track="PDF"
192192
onDownload={trackDownload}
193-
id={model.id}
194-
warning={model.contentWarningText}
193+
id={model.id.toString()}
194+
warning={model.contentWarningText ?? undefined}
195195
/>
196196
</React.Fragment>
197-
);
197+
) : null;
198198
}
199199

200200
export function usePrintCopyDialog() {
@@ -254,8 +254,8 @@ export function KindleOption({model}: {model: Model}) {
254254

255255
export function CheggOption({model}: {model: Model}) {
256256
return (
257-
<Option condition={model.cheggLink}>
258-
<a href={model.cheggLink} data-track="Chegg Reader">
257+
<Option condition={model.cheggLink ?? false}>
258+
<a href={model.cheggLink as string} data-track="Chegg Reader">
259259
<img
260260
className="logo-img"
261261
src="/dist/images/icons/Chegglogo.svg"

src/app/pages/details/common/get-this-title.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import './get-this-title-files/get-this-title.scss';
1414
import trackLink from './track-link';
1515

1616
export type Model = {
17-
id: string;
17+
id: number;
1818
slug: string;
1919
bookState: string;
2020
comingSoon: boolean;
@@ -23,13 +23,13 @@ export type Model = {
2323
kindleLink: string;
2424
webviewRexLink: string;
2525
webviewLink: string;
26-
contentWarningText?: string;
26+
contentWarningText: string | null;
2727
rexCalloutTitle?: string;
2828
rexCalloutBlurb?: string;
29-
highResolutionPdfUrl: string;
30-
lowResolutionPdfUrl: string;
31-
cheggLink: string; // These may not be supported at all anymore,
32-
cheggLinkText: string; // but the CMS is still serving them.
29+
highResolutionPdfUrl: string | null;
30+
lowResolutionPdfUrl: string | null;
31+
cheggLink: string | null; // These may not be supported at all anymore,
32+
cheggLinkText: string | null; // but the CMS is still serving them.
3333
};
3434
type ModelKey = 'bookshareLink' | 'kindleLink';
3535
type TrackedMouseEvent = Parameters<typeof trackLink>[0];
@@ -50,7 +50,7 @@ export default function GetThisTitle({model}: {model: Model}) {
5050
const [expanded, toggleExpanded] = useToggle(additionalOptions < 1);
5151
const interceptLinkClicks = React.useCallback<React.MouseEventHandler>(
5252
(event: TrackedMouseEvent) => {
53-
trackLink(event, model.id);
53+
trackLink(event, model.id.toString());
5454
},
5555
[model.id]
5656
);

src/app/pages/details/common/hooks.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ type PartnerData = {
4646
}
4747

4848
export function usePartnerFeatures(bookAbbreviation: string) {
49-
const [blurbs, setBlurbs] = useState<object[]>([]);
49+
const [blurbs, setBlurbs] = useState<ReturnType<typeof toBlurb>[]>([]);
5050
const [includePartners, setIncludePartners] = useState('');
5151

5252
useEffect(() => {
@@ -64,5 +64,5 @@ export function usePartnerFeatures(bookAbbreviation: string) {
6464
});
6565
}, [bookAbbreviation]);
6666

67-
return [blurbs, includePartners];
67+
return [blurbs, includePartners] as const;
6868
}

src/app/pages/details/common/publication-info.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import useDetailsContext, {ContextValues, IsbnType} from '../context';
77

88
function PdfUpdateInfo({updateDate, url}: {
99
updateDate?: string | null;
10-
url?: string;
10+
url: string | null;
1111
}) {
1212
if (!updateDate) {
1313
return null;
@@ -209,8 +209,8 @@ function LabeledDate({label, date, className}: {
209209
);
210210
}
211211

212-
export default function PublicationInfo({url, polish}: {
213-
url: string;
212+
export default function PublicationInfo({url = null, polish}: {
213+
url?: string | null;
214214
polish?: boolean;
215215
}) {
216216
const model = useDetailsContext();

src/app/pages/details/common/resource-box/left-content.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ function LeftButton({model}: {model: ResourceModel & LinkIsSet}) {
103103
const trackDownloadClick = React.useCallback(
104104
(event: TrackedMouseEvent) => {
105105
if (userStatus?.isInstructor) {
106-
trackLink(event, model.bookModel?.id.toString());
106+
trackLink(event, model.bookModel.id.toString());
107107
}
108108
},
109109
[model.bookModel, userStatus]

src/app/pages/details/common/resource-box/resource-box-utils.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ function encodeLocation(search: string) {
1818
}
1919

2020
export type ResourceData = {
21-
linkExternal: string;
22-
linkDocumentUrl: string;
21+
linkExternal?: string;
22+
linkDocumentUrl?: string;
2323
linkDocument?: {
2424
file: string;
2525
};
@@ -29,17 +29,18 @@ export type ResourceData = {
2929
heading: string;
3030
resourceCategory: string;
3131
resourceUnlocked: boolean;
32-
creatorFestResource: boolean;
32+
creatorFestResource?: boolean;
3333
description: string;
34+
comingSoonText?: string;
3435
};
3536
comingSoonText: string | null;
3637
videoReferenceNumber?: number | null;
3738
k12?: boolean;
3839
printLink: string | null;
39-
resourceUnlocked: boolean;
40+
resourceUnlocked?: boolean;
4041
lockedText?: string;
41-
resourceHeading: string;
42-
resourceDescription: string;
42+
resourceHeading?: string;
43+
resourceDescription?: string;
4344
featured?: boolean;
4445
};
4546

src/app/pages/details/context.tsx renamed to src/app/pages/details/context.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {useState} from 'react';
22
import buildContext from '~/components/jsx-helpers/build-context';
33
import type {ResourceData} from './common/resource-box/resource-box-utils';
44
import type {PromoteData} from './desktop-view/promo';
5+
import type {Model as GetThisTitleModel} from './common/get-this-title';
56

67
export type LocaleType = {
78
locale: string;
@@ -24,7 +25,7 @@ type StuffContent = {
2425
heading: string;
2526
};
2627
};
27-
type VideoContent = {
28+
export type VideoContent = {
2829
title: string;
2930
description: string;
3031
embed: string;
@@ -37,13 +38,14 @@ type Author = {
3738

3839
export type IsbnType = 'print' | 'printSoftcover' | 'digital' | 'assignable';
3940

40-
export type ContextValues = {
41+
export type ContextValues = GetThisTitleModel & {
4142
id: number;
4243
slug: string;
4344
translations: Array<TranslationType>;
4445
bookState: string;
4546
comingSoon: boolean;
4647
coverColor: string;
48+
description: string;
4749
meta: LocaleType;
4850
reverseGradient: boolean;
4951
title: string;
@@ -59,7 +61,7 @@ export type ContextValues = {
5961
webinarContent?: WebinarContent;
6062
freeStuffStudent: StuffContent;
6163
freeStuffInstructor: StuffContent;
62-
videos: VideoContent[];
64+
videos: [VideoContent[]] | never[];
6365
setUseCardBackground?: React.Dispatch<React.SetStateAction<boolean>>;
6466
authors: Author[];
6567
created: string;

src/app/pages/details/desktop-view/desktop-view.js

Lines changed: 0 additions & 109 deletions
This file was deleted.

0 commit comments

Comments
 (0)