Skip to content

Commit 2bdea92

Browse files
committed
Single request for all unit channel details
1 parent 0c46451 commit 2bdea92

File tree

3 files changed

+51
-62
lines changed

3 files changed

+51
-62
lines changed

frontends/main/src/app-pages/UnitsListingPage/UnitCard.tsx

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from "react"
2-
import type { LearningResourceOfferorDetail, OfferedByEnum } from "api"
2+
import type { OfferedByEnum } from "api"
3+
import type { UnitChannel } from "api/v0"
34
import {
45
Card,
56
Skeleton,
@@ -8,7 +9,6 @@ import {
89
theme,
910
UnitLogo,
1011
} from "ol-components"
11-
import { useChannelDetail } from "api/hooks/channels"
1212
import Link from "next/link"
1313

1414
const CardStyled = styled(Card)({
@@ -102,25 +102,23 @@ const CountsText = styled(Typography)(({ theme }) => ({
102102
}))
103103

104104
interface UnitCardsProps {
105-
units: LearningResourceOfferorDetail[] | undefined
105+
channels: UnitChannel[] | undefined
106106
courseCounts: Record<string, number>
107107
programCounts: Record<string, number>
108108
}
109109

110110
interface UnitCardProps {
111-
unit: LearningResourceOfferorDetail
111+
channel: UnitChannel
112112
courseCount: number
113113
programCount: number
114114
}
115115

116116
const UnitCard: React.FC<UnitCardProps> = (props) => {
117-
const { unit, courseCount, programCount } = props
118-
const channelDetailQuery = useChannelDetail("unit", unit.code)
119-
const channelDetail = channelDetailQuery.data
120-
const unitUrl = channelDetail?.channel_url
117+
const { channel, courseCount, programCount } = props
118+
const unit = channel.unit_detail.unit
121119

122-
if (!unitUrl) return null
123-
const href = unitUrl && new URL(unitUrl).pathname
120+
if (!channel.channel_url) return null
121+
const href = new URL(channel.channel_url).pathname
124122

125123
return (
126124
<CardStyled forwardClicksToLink data-testid={`unit-card-${unit.code}`}>
@@ -134,9 +132,7 @@ const UnitCard: React.FC<UnitCardProps> = (props) => {
134132
</LogoContainer>
135133
<CardBottom>
136134
<ValuePropContainer>
137-
<HeadingText>
138-
{channelDetail?.configuration?.heading}
139-
</HeadingText>
135+
<HeadingText>{channel?.configuration?.heading}</HeadingText>
140136
</ValuePropContainer>
141137
<CountsTextContainer>
142138
<CountsText data-testid={`course-count-${unit.code}`}>
@@ -174,17 +170,18 @@ export const UnitCardLoading = () => {
174170
}
175171

176172
export const UnitCards: React.FC<UnitCardsProps> = (props) => {
177-
const { units, courseCounts, programCounts } = props
173+
const { channels, courseCounts, programCounts } = props
178174
return (
179175
<>
180-
{units?.map((unit) => {
176+
{channels?.map((channel) => {
177+
const unit = channel.unit_detail.unit
181178
const courseCount = courseCounts[unit.code] || 0
182179
const programCount = programCounts[unit.code] || 0
183180

184181
return unit.value_prop ? (
185182
<UnitCard
186183
key={unit.code}
187-
unit={unit}
184+
channel={channel}
188185
courseCount={courseCount}
189186
programCount={programCount}
190187
/>

frontends/main/src/app-pages/UnitsListingPage/UnitsListingPage.tsx

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
"use client"
22

33
import React from "react"
4-
import { useChannelCounts } from "api/hooks/channels"
5-
import { useOfferorsList } from "api/hooks/learningResources"
4+
import { useChannelCounts, useChannelsList } from "api/hooks/channels"
65
import {
76
Banner,
87
Container,
@@ -14,23 +13,23 @@ import {
1413
import { backgroundSrcSetCSS } from "ol-utilities"
1514
import backgroundSteps from "@/public/images/backgrounds/background_steps.jpg"
1615
import { RiBookOpenLine, RiSuitcaseLine } from "@remixicon/react"
17-
import type { LearningResourceOfferorDetail } from "api"
16+
import type { Channel, UnitChannel } from "api/v0"
1817
import { HOME } from "@/common/urls"
1918
import { UnitCards, UnitCardLoading } from "./UnitCard"
2019
import { aggregateProgramCounts, aggregateCourseCounts } from "@/common/utils"
2120

2221
const DESKTOP_WIDTH = "1056px"
2322

24-
const sortUnits = (
25-
units: Array<LearningResourceOfferorDetail> | undefined,
23+
const sortUnitChannels = (
24+
channels: Array<Channel> | undefined,
2625
courseCounts: Record<string, number>,
2726
programCounts: Record<string, number>,
2827
) => {
29-
return units?.sort((a, b) => {
30-
const courseCountA = courseCounts[a.code] || 0
31-
const programCountA = programCounts[a.code] || 0
32-
const courseCountB = courseCounts[b.code] || 0
33-
const programCountB = programCounts[b.code] || 0
28+
return channels?.sort((a, b) => {
29+
const courseCountA = courseCounts[a.name] || 0
30+
const programCountA = programCounts[a.name] || 0
31+
const courseCountB = courseCounts[b.name] || 0
32+
const programCountB = programCounts[b.name] || 0
3433
const totalA = courseCountA + programCountA
3534
const totalB = courseCountB + programCountB
3635
return totalB - totalA
@@ -151,7 +150,7 @@ interface UnitSectionProps {
151150
icon: React.ReactNode
152151
title: string
153152
description: string
154-
units: LearningResourceOfferorDetail[] | undefined
153+
channels: UnitChannel[] | undefined
155154
courseCounts: Record<string, number>
156155
programCounts: Record<string, number>
157156
isLoading?: boolean
@@ -163,7 +162,7 @@ const UnitSection: React.FC<UnitSectionProps> = (props) => {
163162
icon,
164163
title,
165164
description,
166-
units,
165+
channels,
167166
courseCounts,
168167
programCounts,
169168
isLoading,
@@ -186,7 +185,7 @@ const UnitSection: React.FC<UnitSectionProps> = (props) => {
186185
.map((_null, i) => <UnitCardLoading key={`irrelevant-${i}`} />)
187186
) : (
188187
<UnitCards
189-
units={units}
188+
channels={channels}
190189
courseCounts={courseCounts}
191190
programCounts={programCounts}
192191
/>
@@ -197,8 +196,7 @@ const UnitSection: React.FC<UnitSectionProps> = (props) => {
197196
}
198197

199198
const UnitsListingPage: React.FC = () => {
200-
const unitsQuery = useOfferorsList()
201-
const units = unitsQuery.data?.results
199+
const channelsQuery = useChannelsList({ channel_type: "unit" })
202200
const channelCountQuery = useChannelCounts("unit")
203201

204202
const courseCounts = channelCountQuery.data
@@ -207,33 +205,41 @@ const UnitsListingPage: React.FC = () => {
207205
const programCounts = channelCountQuery.data
208206
? aggregateProgramCounts("name", channelCountQuery.data)
209207
: {}
210-
const academicUnits = sortUnits(
211-
units?.filter((unit) => unit.professional === false),
208+
209+
const channels = channelsQuery.data?.results
210+
const academicUnits = sortUnitChannels(
211+
channels?.filter(
212+
(channel) =>
213+
(channel as UnitChannel).unit_detail.unit.professional === false,
214+
),
212215
courseCounts,
213216
programCounts,
214217
)
215-
const professionalUnits = sortUnits(
216-
units?.filter((unit) => unit.professional === true),
218+
const professionalUnits = sortUnitChannels(
219+
channels?.filter(
220+
(channel) =>
221+
(channel as UnitChannel).unit_detail.unit.professional === true,
222+
),
217223
courseCounts,
218224
programCounts,
219225
)
220226

221-
const unitData = [
227+
const sections = [
222228
{
223229
id: "academic",
224230
icon: <AcademicIcon />,
225231
title: "Academic Units",
226232
description:
227233
"MIT's Academic courses, programs, and materials mirror MIT curriculum and residential programs, making these available to a global audience. Approved by faculty committees, Academic content furnishes a comprehensive foundation of knowledge, skills, and abilities for students pursuing their academic objectives. Renowned for their rigor and challenge, MIT's Academic offerings deliver an experience on par with the campus environment.",
228-
units: academicUnits,
234+
channels: academicUnits as UnitChannel[],
229235
},
230236
{
231237
id: "professional",
232238
icon: <ProfessionalIcon />,
233239
title: "Professional Units",
234240
description:
235241
"MIT's Professional courses and programs are tailored for working professionals seeking essential practical skills across various industries. Led by MIT faculty and maintaining challenging standards, Professional courses and programs prioritize real-world applications, emphasize practical skills and are directly relevant to today's workforce.",
236-
units: professionalUnits,
242+
channels: professionalUnits as UnitChannel[],
237243
},
238244
]
239245

@@ -266,17 +272,17 @@ const UnitsListingPage: React.FC = () => {
266272
</PageHeaderText>
267273
</PageHeaderContainerInner>
268274
</PageHeaderContainer>
269-
{unitData.map((unit) => (
275+
{sections.map((section) => (
270276
<UnitSection
271-
key={unit.id}
272-
id={unit.id}
273-
icon={unit.icon}
274-
title={unit.title}
275-
description={unit.description}
276-
units={unit.units}
277+
key={section.id}
278+
id={section.id}
279+
icon={section.icon}
280+
title={section.title}
281+
description={section.description}
282+
channels={section.channels}
277283
courseCounts={courseCounts}
278284
programCounts={programCounts}
279-
isLoading={unitsQuery.isLoading}
285+
isLoading={channelsQuery.isLoading}
280286
/>
281287
))}
282288
</PageContent>

frontends/main/src/app/units/page.tsx

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,19 @@ import { Metadata } from "next"
33
import { Hydrate } from "@tanstack/react-query"
44
import { prefetch } from "api/ssr/prefetch"
55
import { standardizeMetadata } from "@/common/metadata"
6-
import { learningResources } from "api/hooks/learningResources"
76
import { channels } from "api/hooks/channels"
8-
import type { PaginatedLearningResourceOfferorDetailList } from "api"
97
import UnitsListingPage from "@/app-pages/UnitsListingPage/UnitsListingPage"
108

119
export const metadata: Metadata = standardizeMetadata({
1210
title: "Units",
1311
})
1412

1513
const Page: React.FC = async () => {
16-
const { queryClient } = await prefetch([
17-
learningResources.offerors({}),
14+
const { dehydratedState } = await prefetch([
1815
channels.countsByType("unit"),
16+
channels.list({ channel_type: "unit" }),
1917
])
2018

21-
const units = queryClient
22-
.getQueryData<PaginatedLearningResourceOfferorDetailList>(
23-
learningResources.offerors({}).queryKey,
24-
)!
25-
.results.filter((unit) => !!unit.value_prop)
26-
.map((unit) => unit.code)
27-
28-
const { dehydratedState } = await prefetch(
29-
units.map((unit) => channels.detailByType("unit", unit)),
30-
queryClient,
31-
)
32-
3319
return (
3420
<Hydrate state={dehydratedState}>
3521
<UnitsListingPage />

0 commit comments

Comments
 (0)