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).
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
| Prop | Type | Description |
|---|---|---|
report | ComplianceReport | Required. The report object from getComplianceScore(). |
title | string | Dashboard heading. Defaults to "NDPA Compliance Dashboard". |
showRecommendations | boolean | Toggle the recommendations section. Defaults to true. |
maxRecommendations | number | Cap on the rendered recommendations. Defaults to 5. |
classNames | NDPRDashboardClassNames | Per-slot class overrides (root, header, scoreCircle, moduleCard, etc.). |
unstyled | boolean | Strip 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'
}