Skip to content

Conversation

ChristopherChudzicki
Copy link
Contributor

@ChristopherChudzicki ChristopherChudzicki commented Sep 30, 2025

What are the relevant tickets?

Closes https://github.com/mitodl/hq/issues/8715

Description (What does it do?)

Adds program pages at /program/{readable_id}.

Screenshots (if appropriate):

Desktop:
desktop_1

Mobile:
mobile_1
mobile_2

How can this be tested?

Prerequisites:

  • I will assume you have integrated MITxOnline and Learn locally. If not, see directions in, e.g., redirect attach to org dashboard #2498 (comment)
    • alternatively, mock API responses as described below. Even if you have MITxOnline integrated, mocking some API responses might be desirable.
  • Using local posthog, set up a feature flag named product-page-course.
  • Set up data as described below.

Setting up course data: To set up mock data:

To set up real local data:

  • Create a program with ./manage.py create_courseware; Use --help for details.
    • ⚠️ : Some mitxonline functionality expets readable ids for programs start with program-
  • Create a corresponding courseware CMS page with ./manage.py create_courseware_page; use --help option for details.
  • Navigate to http://mitxonline.odl.local:8013/cms/ and find your programpage. Fill in relevant fields.
    • You will need to create instructor pages, too.

Testing Steps:

  1. Visit http://learn.odl.local:8062/programs/readable-id, where readable_id is like program-v1:MITx+DEDP.
    • With feature flag ON, the page should be visible.
    • With feature flag OFF, the page should be empty
    • In all cases, the page should have a noindex tag.
  2. Designs should roughly match those in https://github.com/mitodl/hq/issues/8414, though some things are not implemented as part of this PR:
    • no courses carousels
    • no summary card
    • no enrollment dialog
  3. Check the "About" section:
    • If the about section includes multiple HTML elements, a "Show More" / "Show Less" button should appear.
    • If it includes only one HTML element, no "Show More" / "Show less" button should appear.
  4. Click instructors. That should open a dialog with details.
    • Instructors section will not show if instructors list is empty

@@ -1,5 +1,3 @@
"use client"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Marking all of ol-utilities with "use client" means that none of it can be used in server components. In particular, DEFAULT_RESOURCE_IMG constant couldn't be used in server components.

@ChristopherChudzicki ChristopherChudzicki changed the title Cc/program page Program Page basic layout Sep 30, 2025
@ChristopherChudzicki ChristopherChudzicki added the Needs Review An open Pull Request that is ready for review label Sep 30, 2025
Copy link
Contributor

@jonkafton jonkafton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An excellent addition to the site! I left some questions/observations.

<Component
className={classnames("raw-html", className)}
data-testid="raw"
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(html) }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not in this PR directly, but I notice the mitxonline API / Wagtail escapes html, including the list tags we're styling for.

<h2>Key Points</h2>
<ul>
<li>Ut enim ad minim veniam</li>
<li>Quis nostrud exercitation ullamco laboris</li>
<li><strong>Nisi ut aliquip ex ea commodo consequat</strong></li>
</ul>

is sanitized/escaped to:

<p data-block-key="6pl3h">&lt;h2&gt;Key Points&lt;/h2&gt;</p><p data-block-key="cjts8">  &lt;ul&gt;</p><p data-block-key="133r9">    &lt;li&gt;Ut enim ad minim veniam&lt;/li&gt;</p><p data-block-key="9163i">    &lt;li&gt;Quis nostrud exercitation ullamco laboris&lt;/li&gt;</p><p data-block-key="4pdjt">    &lt;li&gt;&lt;strong&gt;Nisi ut aliquip ex ea commodo consequat&lt;/strong&gt;&lt;/li&gt;</p><p data-block-key="bn25k">  &lt;/ul&gt;</p>

and rendered:

image

Copy link
Contributor Author

@ChristopherChudzicki ChristopherChudzicki Oct 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should be able to use the editor's rich text menu / markdown-like shortcuts to produce HTML lists, links, bold, etc (probably more styles than we want to allow, frankly):

Screenshot 2025-10-02 at 4 22 25 PM

If you paste HTML characters in directly, I'd expect what you showed. It's a WYSIWYG editor

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file now deserving of a rename, ProductSummary.tsx?

<BottomContainer>
<SidebarCol>
<SidebarImageWrapper>
<SidebarImage width={410} height={230} src={imageSrc} alt="" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Observation that locally this image (page.program_details.page.feature_image_src) does not load. We get a URL for the Learn backend on the programs list API:

http://open.odl.local:8065/media/original_images/IMG_20250928_135213707.jpg

The image loads correctly from:

http://mitxonline.odl.local:8065/media/original_images/IMG_20250928_135213707.jpg

I'm not sure if this is an issue with my local environment setup / API gateway routing or if it's something we need to handle.

Same issue for the instructor image from the programs detail, items[0].faculty[0].feature_image_src.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be fixed on a more recent version of mitxonline (after mitodl/mitxonline#2946 + mitodl/mitxonline#2950). I shouldve mentioned to up-to-date main branch of that...should fix some potential permission issues, too.

.then((res) => res.data)
},
}),
programsDetail: (readableId: string) =>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we rename this programPageDetail to match the key. I had some moments of confusion as to why neighboring programsQueries.programDetail() was not being called. Same for courseDetail from previous.

Copy link
Contributor Author

@ChristopherChudzicki ChristopherChudzicki Oct 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to change the keys and the queries to coursePages and programPages. They are listing endpoints, though we only use them to fetch 1 entry.

I considered originally trying to fake the detail endpoint and returning only a single object from the query, but decided to leave it as explicitly returning the list—I thought a proper detail endpoint should return 404 for missing objects, and trying to simulate a 404 with an AxiosError seemed like too much shenanigans.

So, since they are listings, coursePages and programPages seemed more accurate

@pdpinch
Copy link
Member

pdpinch commented Oct 2, 2025

Just confirming: this is a product page for a program, suitable as a landing page for marketing campaigns? Can you give me an example of the route?

@ChristopherChudzicki
Copy link
Contributor Author

@pdpinch

Just confirming: this is a product page for a program, suitable as a landing page for marketing campaigns? Can you give me an example of the route?

Yep (once it's done).

Example routes:

# For programs
https://learn.mit.edu/programs/program-v1:MITx+DEDP/
https://learn.mit.edu/programs/program-v1:MITxT+18.01x/
# For courses (previous PR)
https://learn.mit.edu/courses/course-v1:MITxT+10.50.CH04x

Copy link
Contributor

@jonkafton jonkafton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@ChristopherChudzicki ChristopherChudzicki merged commit f824eec into main Oct 3, 2025
13 checks passed
@ChristopherChudzicki ChristopherChudzicki deleted the cc/program-page branch October 3, 2025 15:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Needs Review An open Pull Request that is ready for review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants