Skip to content

Conversation

@gumaerc
Copy link
Contributor

@gumaerc gumaerc commented Jan 5, 2026

What are the relevant tickets?

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

Description (What does it do?)

This PR reworks functionality in the dashboard surrounding b2b organizations / contracts:

  • Instead of a tab per organization the user is in, there is now a tab per contract. Organizations can have multiple contracts, but previously we were just selecting the first one.
  • The URL structure for dashboard contract pages is set up as /dashboard/organization/org-slug/contract/contract-slug
  • The OrganizationContent component was refactored / renamed to ContractContent and now requires a contract ID along with the org ID.

Screenshots (if appropriate):

image image

How can this be tested?

  • Follow the instructions in the readme to set up MITx Online locally and connect it to your instance of Learn. They need to be sharing the same instance of Keycloak / APISIX so your user is consistent in both apps.
  • In MITx Online:
    • Create a B2B organization
    • Add your user to the B2B organization
    • Create multiple B2B contracts tied to said org
    • Create multiple programs with courses, assigning some to the first contract and some to the second
  • Back in MIT Learn:
    • Visit the dashboard
    • Verify that you now see two tabs in the dashboard, one for the first contract and one for the second
    • Visit these pages by clicking on the tabs
    • Verify that the URL structure for each contract is correct (/dashboard/organization/org-slug/contract/contract-slug)
    • Verify that each contract displays the programs / courses you would expect based on what you added above

Checklist:

  • Set up redirects for the current org dashboards to go to the first contract available

@gumaerc gumaerc changed the title org dashboard contract refactor [WIP] org dashboard contract refactor Jan 5, 2026
@gumaerc gumaerc force-pushed the cg/org-dashboard-contract-refactor branch from f226648 to 9a2411b Compare January 6, 2026 17:09
@gumaerc gumaerc added Needs Review An open Pull Request that is ready for review and removed Work in Progress labels Jan 6, 2026
@gumaerc gumaerc changed the title [WIP] org dashboard contract refactor org dashboard contract refactor Jan 6, 2026
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
Copy link
Contributor

ChristopherChudzicki commented Jan 8, 2026

Checklist:

  • Set up redirects for the current org dashboards to go to the first contract available

Another thing we probably want to do is change some contract slugs. Currently it would be, e.g., https://learn.mit.edu/dashboard/organization/mit-universal-ai/contracts/contract-504-universal-ai for MIT UAI. The contract slugs aren't used for anything public right now, so it's a good opportunity to clean them up.

Copy link
Contributor

@ChristopherChudzicki ChristopherChudzicki left a comment

Choose a reason for hiding this comment

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

This is working well for me except the empty contract issue.

Suggestion: In the interest of caution, do you think we should leave /dashboard/organization/[orgSlug] route in place for now, rendering something like

<ContractContent // <-- modify to use first contract if contractSlug missing
  orgSlug={resolved.orgSlug}
  contractSlug={null}
/>

Edit: Alternatively, could add a nextjs redirect for organization/[slug] to /organization, which would then redirect to most recent org contract.

Comment on lines 444 to 447
if (!contract?.programs || contract.programs.length === 0) {
return true
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Blocking Question: What's the point of this filter? I currently have an org with 3 contracts, one of which is empty. The empty contract shows all org content (but in a kinda buggy way).

Separately: I think the contract filtering should ideally be done at the request level, though probably the APIs don't support that filter yet.

<Typography variant="subtitle2" component="span">
{org.name}
</Typography>
{` - ${contract?.name}`}
Copy link
Contributor

Choose a reason for hiding this comment

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

github suggestions seem to have disappeared for me...

But contract.name would be fine, it's not nullable.

@gumaerc
Copy link
Contributor Author

gumaerc commented Jan 9, 2026

This is working well for me except the empty contract issue.

Suggestion: In the interest of caution, do you think we should leave /dashboard/organization/[orgSlug] route in place for now, rendering something like

<ContractContent // <-- modify to use first contract if contractSlug missing
  orgSlug={resolved.orgSlug}
  contractSlug={null}
/>

Edit: Alternatively, could add a nextjs redirect for organization/[slug] to /organization, which would then redirect to most recent org contract.

In the last commit (a5149ad) I added this functionality you suggested. It either displays the first available contract or redirects to the dashboard home if none are found. What do you think?

@gumaerc gumaerc force-pushed the cg/org-dashboard-contract-refactor branch from a5149ad to e3d8e54 Compare January 9, 2026 22:19
Copy link
Contributor

@ChristopherChudzicki ChristopherChudzicki left a comment

Choose a reason for hiding this comment

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

One small request... I think you implemented what I suggested, but now that I try it, I realize we should redirect instead of displaying UI.

Copy link
Contributor

@ChristopherChudzicki ChristopherChudzicki left a comment

Choose a reason for hiding this comment

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

LGTM, but suggest we not merge until

is deployed

@gumaerc gumaerc force-pushed the cg/org-dashboard-contract-refactor branch from e140fc7 to 2b0e322 Compare January 13, 2026 16:08
@gumaerc gumaerc force-pushed the cg/org-dashboard-contract-refactor branch from 2b0e322 to ce02457 Compare January 13, 2026 19:22
@gumaerc gumaerc merged commit 2b892c5 into main Jan 13, 2026
13 checks passed
@gumaerc gumaerc deleted the cg/org-dashboard-contract-refactor branch January 13, 2026 19:42
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.

4 participants