Skip to content

Certificate page #2429

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Aug 19, 2025
Merged

Certificate page #2429

merged 15 commits into from
Aug 19, 2025

Conversation

jonkafton
Copy link
Contributor

@jonkafton jonkafton commented Aug 11, 2025

What are the relevant tickets?

Description (What does it do?)

Displays a course certificate according to the designs in Figma for desktop and mobile. Certificates are linked to from the dashboard organization page (e.g. /dashboard/organization/universityx)

Outstanding

We have a few needs and wants from the MITx Online certificate API in order to complete this task. The markup and styling is fully in place, so it will be a case of plugging in missing data. The links to the certificate page are on the organization dashboard page, which itself is feature flagged ("mitlearn-organization-dashboard"), so we are able to release this version to production while the flag is not enabled.

  • The certificate API only returns the course run ID, which is not sufficient to look up the parent for course level data. We'll also need the course ID.

  • A certificate can also apply to a program/series. For program cerificates we'll need a program ID. Are these supported on the API and in the MITx Online Django admin? We have a "Course run grade" screen - is there an equivalent for Program attainments.

  • Are these certificates currently always "Universal Artificial Intelligence"? I'm using the product_name for the "has successfully completed all requirements of the..." text and the course.title for the main line ("Foundations of Universal AI" in the design). Reading through the Figma comments, I should be hardcoding "Universal Artificial Intelligence", using product_name in the page and certificate title and not using course / program titles - to confirm.

  • The designs show e.g. "Series Certificate" on the page title and certificate badge. This PR uses course?.certificate_type from the MITx Online course API, but these should read "Module Certificate", "Series Certificate" or "Program Certificate". The type (next point) would be sufficient to map to these hard coded.

  • The achievement text reads e.g. "has successfully completed all requirements of the Universal Artificial Intelligence series". The "series" needs to be dynamic, so we need a simple certificate type = "module"|"series"|"program".

    • Are module and course equivalent?
    • Is series a type of program - how do we identify?
  • Program certificates need an additional program certificate type to drive "Series", "MicroMasters™" or "Program".

  • Course/program start/end dates - ideally we'd have definite certificate start/end on the API to avoid deriving across courses and programs.

  • Optionally all data to drive the certificate UI would be available on the certificate API. It's reasonable to make a subsequent request for the course or program data, though these are performance waterfall.

  • Question: The certificate page URL in this PR is https://learn.mit.edu/certificate/<uuid> Is this too broad, ie. are these certificates specific to MITx Online and will there be other certificates with IDs that are not global across properties to need additional specifier in the path e.g. https://learn.mit.edu/certificate/mitxonline/<uuid>?

    • If we have shareable public links with globally unique IDs, do we need a separate API scheme for certificates that are private / not shared.
  • @steven-hatch @mbilalmughal some design items:

    • Can you please provide a certificate badge SVG that either includes or omits the drop shadow - the SVG export from Figma clips it.

    • For the mobile version, should I replace the seal with the badge and move the certificate type onto the badge - please update the design.

    • Would be good to get high-density res signature images (though these are content managed in Wagtail).

Screenshots (if appropriate):

Desktop:
image



Tablet:
image



Mobile:
image



image

How can this be tested?

In order to test, you'll need mitxonline running locally and to have created a B2B organization, contract and courses, plus a certificate page and signatories in Wagtail to associate to a course run. For the certificate link to show on the org dashboard page, you will need to create a course run grade for your user in the mitxonline django admin. There is a fair amount of setup, but thankfully @gumaerc has provided good runbooks on previous PRs:

Once set up, navigate to your organization dashboard page, e.g. http://open.odl.local:8062/dashboard/organization/universityx

image
  • Follow the link to load the new certificate page and ensure the layout and styles are faithful to the Figma designs on desktop and mobile.


Additional Context

@pdpinch
Copy link
Member

pdpinch commented Aug 12, 2025

Sorry Jon. It looks like the desktop and mobile layouts weren't in sync. The mobile layout should not use the "MIT Seal" -- the circular graphic should match the one in the desktop view.

@pdpinch
Copy link
Member

pdpinch commented Aug 12, 2025

I'm not sure where the "Certificate of Completion" text over the seal is coming from in the screenshots. For UAI, that text should be one of "Module Certificate", "Series Certificate" or "Program Certificate"

If it's a course certificate, then the seal text should be "Module Certificate".

If it's a program certificate, then the seal text should be the program_type (either "Series", "MicroMasters™" or "Program") followed by the text " Certificate"

Copy link
Member

Choose a reason for hiding this comment

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

This seal should be removed.

@jonkafton
Copy link
Contributor Author

Thanks @pdpinch - I've updated the PR description with the outstanding items.

@sovsey
Copy link

sovsey commented Aug 12, 2025

@jonkafton Please update the "Product Name 1" text below the user's name to be hard-coded as "Universal Artificial Intelligence".

Screenshot 2025-08-12 at 9 38 35 AM

Also, Product Name 1 as you have it in the page title is correct. However, I also see something other than Product Name 1 in the screenshot below. Both of these fields should display the product_name.

Screenshot 2025-08-12 at 9 42 03 AM

Copy link

github-actions bot commented Aug 12, 2025

OpenAPI Changes

Show/hide No detectable change.

Unexpected changes? Ensure your branch is up-to-date with main (consider rebasing).

@mbilalmughal
Copy link

Can you please provide a certificate badge SVG that either includes or omits the drop shadow - the SVG export from Figma clips it.

For the mobile version, should I replace the seal with the badge and move the certificate type onto the badge - please update the design.

Would be good to get high-density res signature images (though these are content managed in Wagtail).


@jonkafton Attach the seal SVG for desktop and mobile , and I have removed the drop shadow as it was little nosiy

seal-desktop
seal-mobile

@mbilalmughal
Copy link

@pdpinch jon needs high res signature images idealy in PNG format

Jon's comment

Would be good to get high-density res signature images (though these are content managed in Wagtail).

Please share the signatures in good image quality, at least 1000 px wide, so they don’t appear blurred when printed on an A4 page.

Also, there’s one Figma comment from Carolyn that I don’t understand. I’ve attached a screenshot below.

image

@abeglova abeglova assigned abeglova and unassigned abeglova Aug 12, 2025
@gumaerc gumaerc self-assigned this Aug 12, 2025
@jonkafton jonkafton force-pushed the jk/8009-certificate-display branch from 67b04c1 to 22e540a Compare August 12, 2025 16:28
@jonkafton jonkafton requested a review from pdpinch August 12, 2025 16:56
@jonkafton
Copy link
Contributor Author

I've updated the PR description with screenshots for the mobile design changes.

Copy link
Contributor

@gumaerc gumaerc left a comment

Choose a reason for hiding this comment

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

In general, I think this looks good and we can merge it as-is with some follow-up PR's to optimize fetching data after some updates to the API. I did notice a few things design wise though:

image

Notice how the text wraps around in the "has successfully completed..." section. This is all on one line in Figma, and since this page is not responsive aside from the mobile layout, we should probably address that. I think the fact that there are no dates on my certificate has to do with bad test data, but maybe we should handle that a little better than having a big blank white space? I also assume we are leaving the download / share / print buttons for later?

Before we merge this we should organize your list of needs & wants into separate issues that can be closed later. I'm working on adding some of this information to the certificate API. The course and run ID should be fairly straightforward, but I'm a little confused on certificate_type. As you noted, this seems to be a user facing field with types like "Certificate of Completion" rather than some kind of unique key. I'm not sure where in MITx Online we would determine if it's a "Module / Series / Program" certificate. To answer your questions on that though, I believe "module" is what it's being called when a course is part of a B2B contract and I do believe series is a type of program. The programs API endpoint contains a program_type field that says either "Series" "Micromasters®" or "Program.' The course / program start and end dates should be easily integrated into the certificate API.

@jonkafton
Copy link
Contributor Author

Notice how the text wraps around in the "has successfully completed..." section. This is all on one line in Figma, and since this page is not responsive aside from the mobile layout, we should probably address that.

I've given the desktop layout some degree of responsiveness down to around 1250px, but the design doesn't hold below that without the text overlaying the ribbon motif until we get to the mobile breakpoint at 900px. I do think it's acceptable on desktop that the certificate overflows the screen with scroll, especially with the expectation that it is fixed and printable, though we'd need some additional design for it to render without scroll at all screen widths (900px > < 1230px), @steven-hatch @mbilalmughal.

Before we merge this we should organize your list of needs & wants into separate issues that can be closed later.

Agree. We can push to RC if anyone would like to see a preview, though this is incomplete until the API items are available.

@gumaerc
Copy link
Contributor

gumaerc commented Aug 12, 2025

@jonkafton I experimented with simply adding CourseRunWithCourseSerializer to serialize the entire course run and course in the certificate API response: mitodl/mitxonline#2875. It produces output like this: https://mitxonline.learn.c4103.com/api/v2/course_certificates/d360dc8a-ac65-4f08-8147-56fba0e1da80/. As far as the course / course run information this should be all you need yea? I think it's okay to serialize the entire thing for this endpoint, because we're only ever fetching one at a time and it doesn't really seem to affect performance.

@mbilalmughal
Copy link

Notice how the text wraps around in the "has successfully completed..." section. This is all on one line in Figma, and since this page is not responsive aside from the mobile layout, we should probably address that.

I've given the desktop layout some degree of responsiveness down to around 1250px, but the design doesn't hold below that without the text overlaying the ribbon motif until we get to the mobile breakpoint at 900px. I do think it's acceptable on desktop that the certificate overflows the screen with scroll, especially with the expectation that it is fixed and printable, though we'd need some additional design for it to render without scroll at all screen widths (900px > < 1230px), @steven-hatch @mbilalmughal.

Before we merge this we should organize your list of needs & wants into separate issues that can be closed later.

Agree. We can push to RC if anyone would like to see a preview, though this is incomplete until the API items are available.

@jonkafton Let me create a tablet view for the certificate design. That will fix the problem and provide you with the necessary font sizes and spacing.

@mbilalmughal
Copy link

@jonkafton Here is the tablet view, and I agree that the stamp was not adjusting properly on that screen size. So, I introduced the mobile stamp in the tablet view as well. This means the desktop stamp will only be visible on LG and XL screens; after that, the mobile stamp should be displayed to avoid text overlapping. I have adjusted the font sizes and spacing, so you’ll need to update those as well to fix all the content.

Screenshot
image

@gumaerc
Copy link
Contributor

gumaerc commented Aug 14, 2025

@sovsey @pdpinch: @jon Kafton and I were discussing certificate URLs coming in from MITx Online and how we should route them on the frontend in Learn. Currently due to the way we've configured Wagtail to handle the URLs, it looks like:

/certificates/uuid - Course run certificate
/certificates/programs/uuid - Program / Series certificate

There is a bit of technical complexity that comes with replicating this routing in NextJS, with programs at the same level as capturing a UUID for a course certificate. We want to route them as:

/certificates/courses/uuid - Course run certificate
/certificates/programs/uuid - Program / Series certificate

There are a couple ways we could accomplish this, starting with the most simple:

  • We could simply capture r"/certificates/([a-f0-9]{8}-[a-f0-9]{4}-[0-5][a-f0-9]{3}-[089ab][a-f0-9]{3}-[0-9a-f]{12})" in transform.ts while the API response is being pulled in in the Learn frontend, and rewrite that to be /certificates/courses/${uuid}, with the routing in NextJS set up as we described. The downside to this is that if the URLs ever change in MITx Online, this will break. It's a somewhat fragile solution.
  • We could change the routing in Wagtail in MITx Online. This is potentially more problematic? I'm not sure but I imagine those certificate URLs have been saved by a bunch of users, so we would have to set up redirects.

@pdpinch
Copy link
Member

pdpinch commented Aug 14, 2025

I knew I would regret that choice...

High level question: Is there a quick-to-implement choice, and then a more robust, slower-to-implement choice we can do later?

Detail question: Wagtail has some built-in support for redirects. Does that help at all?

@gumaerc
Copy link
Contributor

gumaerc commented Aug 14, 2025

High level question: Is there a quick-to-implement choice, and then a more robust, slower-to-implement choice we can do later?

@pdpinch that's kind of the first option we're proposing there, rewriting the URL as it's fetched in the frontend here in Learn. Once we retire the MITx Online frontend, the Wagtail URL will not matter at that point and I think we will probably have to set up a redirect anyway. It's unclear to me from the Wagtail documentation if it supports regex or some kind of pattern matching, but my only concern there would be Wagtail redirects supporting redirecting /certificates/uuid to certificates/courses/uuid. I know how I could do that in nginx or apache, but I'm not certain the Wagtail redirects support that. I may just be missing something though, and I haven't tried it yet. Assuming you can redirect in the manner we need, I think maybe it's prudent to set up the frontend handling in Learn for now, and then once we retire the MITx Online frontend set up said wholesale redirect and change the routing?

@gumaerc
Copy link
Contributor

gumaerc commented Aug 14, 2025

@jonkafton re: the failing JS tests, some things seem to have changed name upstream in the Axios package. I committed some changes to this PR to adapt to the new names: #2422

@pdpinch
Copy link
Member

pdpinch commented Aug 14, 2025 via email

@gumaerc
Copy link
Contributor

gumaerc commented Aug 15, 2025

Ok. Should we consider a /certificates/series route as well, or is that mixing things up too much?

We could do that potentially, although as far as I understand a series is just a type of program? One of the points of separating courses and programs is so we know which API endpoint to hit, and don't have to hit the API to determine the type of certificate and subsequently query the certificate data. As long as we know it's a program the API should return that its program_type is "Series" as far as I know.

@jonkafton
Copy link
Contributor Author

PR remains open for now as we're in need of mitodl/mitxonline#2875 to be published with the next MITx Online release, currently held up.

@sovsey
Copy link

sovsey commented Aug 18, 2025

@jonkafton I took a look at the latest screenshots and they're generally looking good to me.

Curious what the current logic is for the start/end dates, and what API you're using?

Screenshot 2025-08-18 at 1 55 08 PM

@pdpinch in this Figma thread we had mentioned that it's not obvious how this should be calculated for programs/self-paced courses. Did Tim/CS have any feedback? What do you think we should do in the short term?

@jonkafton
Copy link
Contributor Author

Curious what the current logic is for the start/end dates, and what API you're using?

We get these explicitly on the course run or program attached to the certificate APIs.

@pdpinch
Copy link
Member

pdpinch commented Aug 19, 2025

@pdpinch in this Figma thread we had mentioned that it's not obvious how this should be calculated for programs/self-paced courses. Did Tim/CS have any feedback? What do you think we should do in the short term?

I haven't heard from Tim, but I think we need to base this on the learner's experience, not the course metadata. In the future, perhaps we should capture that on the certificate record at the time of creation.

This isn't the best place to write this down, but I don't want to forget it.

For a course, the first date should be the learner's enrollment date. The second date should be the certificate creation date.

For a program (or series), the first date should be the earliest date amongst all the course enrollment dates. The second date should be the certificate creation date.

@jonkafton jonkafton merged commit 3ace170 into main Aug 19, 2025
13 checks passed
@jonkafton jonkafton deleted the jk/8009-certificate-display branch August 19, 2025 17:30
This was referenced Aug 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants