NDPRDashboard

Read-only compliance dashboard. Visualises a ComplianceReport from getComplianceScore() with an overall ring, per-module cards, and a prioritised recommendations list.

Overview

NDPRDashboardis a presentational component for the toolkit's compliance scoring engine. Pass it a ComplianceReport — the typed object produced by getComplianceScore(input) — and it renders:

  • An overall score ring (0–100) with a coloured rating badge (excellent / good / needs-work / critical).
  • A 2×4 grid of per-module cards (consent, DSR, DPIA, breach, policy, lawful basis, cross-border, ROPA) each with a score and gap count.
  • A prioritised recommendations list, capped at maxRecommendations (default 5).

Production Readiness

Use this checklist when moving NDPRDashboard from demo mode into a customer-facing workflow. Pair the UI package with the source templates in @tantainnovative/ndpr-recipes so validation, persistence, and audit behavior live in your own backend.

Import path
Use
Production role
@tantainnovative/ndpr-toolkit
NDPRDashboard, getComplianceScore
Render a reviewed ComplianceReport or compute one from trusted compliance inputs.
@tantainnovative/ndpr-toolkit/presets
NDPRComplianceDashboard
Compute and render the dashboard from raw ComplianceInput in one component.
@tantainnovative/ndpr-toolkit/server
getComplianceScore
Server-side score computation for DPO dashboards and scheduled reports.
@tantainnovative/ndpr-recipes
src/nextjs/app-router/api/compliance/route.ts
Reference route for computing compliance scores from production records.

Implementation checklist

  • Feed the dashboard from reviewed source-of-record data, not hand-entered status guesses.
  • Show the scoring timestamp, source period, and owner where the dashboard is used operationally.
  • Decide which recommendations create tickets, alerts, or management review actions.
  • Restrict internal dashboards when scores reveal security gaps, incident posture, or vendor risk.
  • Document how each compliance input maps to consent, DSR, DPIA, breach, policy, lawful basis, transfer, and ROPA evidence.

Backend notes

  • Use the recipes compliance route as the starting point for collecting module status from backend tables.
  • Run getComplianceScore server-side for scheduled snapshots and executive reporting.
  • Store historical scores so improvements and regressions can be explained over time.
  • Avoid letting client-side users override raw inputs unless the change is reviewed and persisted.

Testing notes

  • Test excellent, needs-work, and critical input sets and confirm score bands and recommendations.
  • Verify stale policy dates, late DSR timelines, missing breach records, and transfer gaps affect the expected modules.
  • Check dashboard access control for DPO, admin, auditor, and ordinary user roles.
  • Compare dashboard values with underlying module records before relying on reports externally.

Common mistakes

  • Treating the score as certification rather than an operational health indicator.
  • Feeding the dashboard from static sample data after production records exist.
  • Publishing internal remediation recommendations to public users.
  • Ignoring historical score snapshots, which makes regressions difficult to explain.

Quickstart

import { NDPRDashboard, getComplianceScore } from '@tantainnovative/ndpr-toolkit';
import type { ComplianceInput } from '@tantainnovative/ndpr-toolkit';

const input: ComplianceInput = {
  consent: {
    hasConsentMechanism: true,
    hasPurposeSpecification: true,
    hasWithdrawalMechanism: true,
    hasMinorProtection: false,
    consentRecordsRetained: true,
  },
  dsr: {
    hasRequestMechanism: true,
    supportsAccess: true,
    supportsRectification: true,
    supportsErasure: true,
    supportsPortability: false,
    supportsObjection: true,
    responseTimelineDays: 30,
  },
  dpia: {
    conductedForHighRisk: true,
    documentedRisks: true,
    mitigationMeasures: false,
  },
  breach: {
    hasNotificationProcess: true,
    notifiesWithin72Hours: true,
    hasRiskAssessment: true,
    hasRecordKeeping: false,
  },
  policy: {
    hasPrivacyPolicy: true,
    isPubliclyAccessible: true,
    lastUpdated: '2025-01-15',
    coversAllSections: true,
  },
  lawfulBasis: {
    documentedForAllProcessing: true,
    hasLegitimateInterestAssessment: false,
  },
  crossBorder: {
    hasTransferMechanisms: true,
    adequacyAssessed: false,
    ndpcApprovalObtained: false,
  },
  ropa: {
    maintained: true,
    includesAllProcessing: true,
    lastReviewed: '2025-03-01',
  },
};

const report = getComplianceScore(input);

export default function CompliancePage() {
  return (
    <NDPRDashboard
      report={report}
      title="Acme Compliance Overview"
      showRecommendations
      maxRecommendations={5}
    />
  );
}

Preset wrapper: NDPRComplianceDashboard

If you don't want to call getComplianceScore() yourself, use the preset wrapper from /presets. It accepts the raw ComplianceInput, computes the report internally, and delegates rendering to NDPRDashboard:

import { NDPRComplianceDashboard } from '@tantainnovative/ndpr-toolkit/presets';

<NDPRComplianceDashboard
  input={{
    consent: {
      hasConsentMechanism: true,
      hasPurposeSpecification: true,
      hasWithdrawalMechanism: true,
      hasMinorProtection: false,
      consentRecordsRetained: true,
    },
    dsr: {
      hasRequestMechanism: true,
      supportsAccess: true,
      supportsRectification: true,
      supportsErasure: true,
      supportsPortability: false,
      supportsObjection: true,
      responseTimelineDays: 30,
    },
    // …dpia, breach, policy, lawfulBasis, crossBorder, ropa
  }}
  title="Compliance overview"
/>

Same visual surface; the only difference is whether the score computation lives in the preset or in your code.

Props

PropTypeDescription
reportComplianceReportRequired. The report object from getComplianceScore().
titlestringDashboard heading. Defaults to "NDPA Compliance Dashboard".
showRecommendationsbooleanToggle the recommendations section. Defaults to true.
maxRecommendationsnumberCap on the rendered recommendations. Defaults to 5.
classNamesNDPRDashboardClassNamesPer-slot class overrides (root, header, scoreCircle, moduleCard, etc.).
unstyledbooleanStrip all default classes for a true blank slate.

Recommendation shape

Each Recommendation carries enough context to drive a follow-up action: the NDPA section it traces back to, a priority bucket, and an effort estimate.

interface Recommendation {
  module: string;                  // 'consent' | 'dsr' | ...
  key: string;
  label: string;                   // short title
  recommendation: string;          // body
  priority: 'critical' | 'high' | 'medium' | 'low';
  effort: EffortLevel;
  ndpaSection: string;             // e.g. 'Section 25'
}