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.
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
| 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'
}