Skip to content

Commit 66ce7b4

Browse files
OpenStaxClaudeclaude
authored andcommitted
Port src/app/pages files from JS to TS
- Convert 404.js to TypeScript - Convert a-page-template.js to TypeScript with PageData type - Convert school-selector.js to TypeScript with proper event typing - Convert testimonials.js to TypeScript with testimonial data types - Convert language-selector-section.js to TypeScript - Convert use-categorized-books.js to TypeScript with proper book categorization types - Add proper types for all component props and function parameters - Type React event handlers properly (onChange) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent d45168b commit 66ce7b4

File tree

6 files changed

+41
-15
lines changed

6 files changed

+41
-15
lines changed

src/app/pages/a-page-template/a-page-template.js renamed to src/app/pages/a-page-template/a-page-template.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@ import './a-page-template.scss';
44

55
const slug = 'books/biology-2e';
66

7-
function Pagename({data: {heading}}) {
7+
type PageData = {
8+
heading: string;
9+
};
10+
11+
function Pagename({data}: {data: PageData}) {
812
return (
913
<div className="content">
10-
<h1>{heading}</h1>
14+
<h1>{data.heading}</h1>
1115
</div>
1216
);
1317
}

src/app/pages/partners/partner-details/info-request-form/school-selector.js renamed to src/app/pages/partners/partner-details/info-request-form/school-selector.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ import React from 'react';
22
import useMatchingSchools from '~/models/use-school-suggestion-list';
33
import {FilteringSelect} from '~/components/form-elements/form-elements';
44

5-
// Left as JS because I couldn't get the tests to cover these
6-
export default function SchoolSelector({value, setValue}) {
5+
export default function SchoolSelector({value, setValue}: {value: string; setValue: (value: string) => void}) {
76
const {schoolIsOk, schoolOptions} = useMatchingSchools(value);
87

98
return (
@@ -18,17 +17,17 @@ export default function SchoolSelector({value, setValue}) {
1817
required: true,
1918
value,
2019
autoComplete: 'off',
21-
onChange({target}) {setValue(target.value);}
20+
onChange({target}: React.ChangeEvent<HTMLInputElement>) {setValue(target.value);}
2221
}}
23-
accept={(option) => setValue(option.value)}
22+
accept={(option: {value: string}) => setValue(option.value)}
2423
accepted={schoolIsOk}
2524
/>
2625
</div>
2726
);
2827
}
2928

30-
export function useDoSubmit(afterSubmit) {
31-
return React.useCallback((form) => {
29+
export function useDoSubmit(afterSubmit: () => void) {
30+
return React.useCallback((form: HTMLFormElement) => {
3231
form.submit();
3332
afterSubmit();
3433
}, [afterSubmit]);

src/app/pages/press/testimonials/testimonials.js renamed to src/app/pages/press/testimonials/testimonials.tsx

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,20 @@ import ClippedImage from '~/components/clipped-image/clipped-image';
44
import Carousel from '~/components/carousel/carousel';
55
import './testimonials.scss';
66

7-
function Card({data: {image, testimonial}}) {
7+
type ImageData = {
8+
file: string;
9+
title: string;
10+
};
11+
12+
type TestimonialData = {
13+
image?: ImageData;
14+
testimonial: string;
15+
description: string;
16+
};
17+
18+
function Card({data}: {data: TestimonialData}) {
19+
const {image, testimonial} = data;
20+
821
return (
922
<div className='card'>
1023
<div className='picture-part'>
@@ -24,7 +37,7 @@ export default function Testimonials() {
2437
<div className='content-block'>
2538
<h2>Making an impact</h2>
2639
<Carousel atATime={2} hoverTextThing='testimonials'>
27-
{testimonials.map((c) => (
40+
{testimonials.map((c: TestimonialData) => (
2841
<Card data={c} key={c.description} />
2942
))}
3043
</Carousel>

src/app/pages/subjects/new/language-selector-section.js renamed to src/app/pages/subjects/new/language-selector-section.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react';
22
import LanguageSelector from '~/components/language-selector/language-selector';
33
import {FormattedMessage} from 'react-intl';
44

5-
export default function LanguageSelectorSection(props) {
5+
export default function LanguageSelectorSection(props: Record<string, unknown>) {
66
return (
77
<section className='language-selector-section'>
88
<div className='content'>

src/app/pages/subjects/new/use-categorized-books.js renamed to src/app/pages/subjects/new/use-categorized-books.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,20 @@
11
import useSubjectsContext from './context';
22
import useSubjectCategoryContext from '~/contexts/subject-category';
33

4-
export default function useCategorizedBooks() {
4+
type Book = {
5+
subjects: string[];
6+
};
7+
8+
type CategoryWithBooks = Book[] & {
9+
label?: string;
10+
};
11+
12+
type CategorizedBooks = Record<string, CategoryWithBooks>;
13+
14+
export default function useCategorizedBooks(): CategorizedBooks {
515
const {books} = useSubjectsContext();
616
const categories = useSubjectCategoryContext();
7-
const result = {};
17+
const result: CategorizedBooks = {};
818
const addLabels = () => {
919
for (const category of categories) {
1020
if (result[category.cms]) {
@@ -14,9 +24,9 @@ export default function useCategorizedBooks() {
1424
};
1525

1626
for (const book of books) {
17-
book.subjects.forEach((cmsCategory) => {
27+
book.subjects.forEach((cmsCategory: string) => {
1828
if (!(cmsCategory in result)) {
19-
result[cmsCategory] = [];
29+
result[cmsCategory] = [] as CategoryWithBooks;
2030
}
2131
if (!result[cmsCategory].includes(book)) {
2232
result[cmsCategory].push(book);

0 commit comments

Comments
 (0)