Skip to content

feat(b2b-analytics): add a Learner progress section to org/contract analytics - #4004

Open
daniellefrappier18 wants to merge 5 commits into
mainfrom
daniellef/b2b-learner-progress-section
Open

daniellefrappier18 wants to merge 5 commits into
mainfrom
daniellef/b2b-learner-progress-section

Conversation

@daniellefrappier18

@daniellefrappier18 daniellefrappier18 commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

What are the relevant tickets?

N/A — no mit-learn issue tracks this directly

Description (What does it do?)

Adds a "Learner progress" section to the org/contract analytics dashboard (AnalyticsContent), directly under "Contract utilization". Contract-scoped only — there's no org-wide equivalent endpoint, so the section is absent entirely on the org-wide aggregate page (same restriction as the existing "Learner analytics" link).

Four KPI tiles (Enrolled / Not started / In progress / Completed) plus a directly-labeled distribution row per status, each showing a proportional bar, count, and percent of total. passed and certified are folded into one "Completed" bucket/tile, matching the grouping the learner directory's Status filter already uses.

This matches the shape of Ferdi's prototype at mit-learn-prototypes.vercel.app/b2b-stats, but ships a deliberately smaller surface — only what a real backend field supports today. Compared to the prototype, this PR does not render:

  • The "Needs attention" tile — defined as not_started OR 30+ days since last activity. No such aggregate exists yet; last_active_on is hardcoded null on every row today. Tracked as follow-up backend work, not fabricated here.
  • Percentage-range bands (1–24%, 25–49%, 50–99%) — no field carries a learner's percent-complete today, only the coarser status enum. The distribution below renders the buckets the API can actually back.

Screenshots (if appropriate):

  • Desktop screenshots
  • Mobile width screenshots
Screenshot 2026-09-29 at 10 13 04 AM

Hover:
Screenshot 2026-09-29 at 10 12 56 AM

Screenshot 2026-09-29 at 10 13 47 AM

Using NVDA

learners_NVDA.mp4

How can this be tested?

This assumes you're running local dev for this branch on the Tilt/k3d stack (~/Desktop/work/ol-infrastructure), not docker compose.

Prerequisite: mitxonline manager access — this page won't resolve without a mitxonline user with is_manager=True on some org with at least one contract.

1. Confirm the analytics-api stub is running, and is the latest version. This section's data comes from a local-dev-only stub — not from anything set up in mitxonline. It needs the two most recent commits on daniellef/analytics-api-stub (ol-infrastructure, PR #5788): one adds completion_status_counts; the other reconciles the stub's course-level enrollment counts against the same learner fixture, so "Learner progress" and "Course performance" no longer show contradictory numbers for the same contract.

kubectl get pods -n mit-learn -l app=analytics-api

If nothing's running, or it's running an older copy, either check out/pull daniellef/analytics-api-stub and re-run tilt up, or apply the manifest below directly:

analytics-api-stub.yaml (kubectl apply -f -, then kubectl rollout restart deployment analytics-api -n mit-learn)
apiVersion: v1
kind: ConfigMap
metadata:
  name: analytics-api-stub-src
  namespace: mit-learn
  labels:
    app: analytics-api
data:
  stub_app.py: |
    <paste the current contents of ol-infrastructure's
    local-dev/apps/analytics-api/stub_app.py here>
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: analytics-api
  namespace: mit-learn
  labels:
    app: analytics-api
spec:
  replicas: 1
  selector:
    matchLabels:
      app: analytics-api
  template:
    metadata:
      labels:
        app: analytics-api
    spec:
      containers:
      - name: analytics-api
        image: python:3.13-slim
        imagePullPolicy: IfNotPresent
        command: ["python", "/app/stub_app.py"]
        ports:
        - containerPort: 8070
          name: http
        env:
        - name: PORT
          value: "8070"
        resources:
          requests: {cpu: 25m, memory: 32Mi}
          limits: {memory: 128Mi}
        readinessProbe:
          httpGet: {path: /health, port: 8070}
          initialDelaySeconds: 3
          periodSeconds: 10
        livenessProbe:
          httpGet: {path: /health, port: 8070}
          initialDelaySeconds: 5
          periodSeconds: 20
        volumeMounts:
        - name: stub-src
          mountPath: /app
          readOnly: true
      volumes:
      - name: stub-src
        configMap:
          name: analytics-api-stub-src
---
apiVersion: v1
kind: Service
metadata:
  name: analytics-api
  namespace: mit-learn
  labels:
    app: analytics-api
spec:
  selector:
    app: analytics-api
  ports:
  - name: http
    port: 8070
    targetPort: http

Enable the b2b-analytics-dashboard PostHog feature flag, sign in at https://learn.mit.dev, open an org you manage, and go to a contract's analytics page (/organization//contract//analytics).

  • Verify: "Learner progress" renders directly under "Contract utilization", with four tiles — Enrolled, Not started, In progress, Completed

Additional Context

@github-actions

github-actions Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

OpenAPI Changes

44 changes: 0 error, 24 warning, 20 info

View full changelog

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

@daniellefrappier18
daniellefrappier18 marked this pull request as ready for review September 29, 2026 14:13
@daniellefrappier18
daniellefrappier18 requested a review from a team as a code owner September 29, 2026 14:13
Copilot AI balanced review requested due to automatic review settings September 29, 2026 14:13

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Enrollment scope, API documentation, and touch-device link visibility need correction.

Review effort: Balanced
Findings: 2 Medium severity · 2 Low severity

Open (4)
What changed in this PR

Adds contract-scoped learner progress analytics to the B2B dashboard.

Changes:

  • Adds enrollment-status KPI tiles and distribution bars.
  • Extends analytics API types, exports, colors, and test factories.
  • Tests rendering, organization-level omission, links, and accessibility context.
File Description
AnalyticsContent.tsx Queries and renders learner progress.
AnalyticsContent.test.tsx Tests dashboard integration.
LearnerProgressCard.tsx Implements KPIs and distribution UI.
chartPalette.ts Adds progress-status colors.
types.ts Defines status-count response data.
factories.ts Generates status-count fixtures.
organizations/​index.ts Exports the new type.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread frontends/main/src/app-pages/DashboardPage/Analytics/LearnerProgressCard.tsx Outdated
Comment thread frontends/main/src/app-pages/DashboardPage/AnalyticsContent.tsx
Comment thread frontends/api/src/analytics/types.ts Outdated
Comment thread frontends/main/src/app-pages/DashboardPage/AnalyticsContent.tsx Outdated
daniellefrappier18 and others added 2 commits September 29, 2026 10:18
- keep the "View all learners" tile link visible on touch devices —
  opacity: 0 is now gated to @media (hover: hover), since there's no
  hover state to reveal it and no other way to discover the control
- fix CompletionStatusCounts' doc comment: the four buckets sum to
  total_count minus outcomes_withheld_count, not total_count itself
  (only looks otherwise today because outcomes_withheld_count is
  currently always zero)
- scope the section's copy and comment to active enrollments, matching
  include_inactive being deliberately left unset — a deactivated or
  refunded seat shouldn't count as "enrolled"

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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.

2 participants