feat: Initial Mediusa Clinic OS practice management platform ('Jane App But Better')

This commit is contained in:
2026-09-05 14:12:19 -07:00
parent 441e5eb57d
commit deb5197e53
17 changed files with 4675 additions and 71 deletions
+178
View File
@@ -0,0 +1,178 @@
import jsPDF from 'jspdf';
import { Superbill } from '@/types/clinical';
export function generateSuperbillPdf(superbill: Superbill) {
const doc = new jsPDF({
orientation: 'portrait',
unit: 'pt',
format: 'letter',
});
const margin = 40;
let y = margin;
// Header Banner
doc.setFillColor(15, 23, 42); // Slate 900
doc.rect(0, 0, doc.internal.pageSize.getWidth(), 80, 'F');
doc.setFont('helvetica', 'bold');
doc.setTextColor(255, 255, 255);
doc.setFontSize(20);
doc.text('MEDICAL SUPERBILL & STATEMENT', margin, 42);
doc.setFont('helvetica', 'normal');
doc.setFontSize(10);
doc.setTextColor(148, 163, 184); // Slate 400
doc.text('Comprehensive Out-of-Network Insurance Reimbursement Form', margin, 60);
doc.setTextColor(255, 255, 255);
doc.text(`Invoice #: ${superbill.invoiceNumber}`, doc.internal.pageSize.getWidth() - margin - 150, 42);
doc.text(`Date of Service: ${superbill.dateOfService}`, doc.internal.pageSize.getWidth() - margin - 150, 60);
y = 110;
// Two columns: Clinic (Billing Provider) & Patient Details
doc.setFont('helvetica', 'bold');
doc.setFontSize(11);
doc.setTextColor(15, 23, 42);
doc.text('BILLING PROVIDER & CLINIC', margin, y);
doc.text('PATIENT INFORMATION', 320, y);
doc.setDrawColor(226, 232, 240);
doc.line(margin, y + 6, 280, y + 6);
doc.line(320, y + 6, doc.internal.pageSize.getWidth() - margin, y + 6);
y += 22;
doc.setFont('helvetica', 'normal');
doc.setFontSize(9);
doc.setTextColor(51, 65, 85);
// Clinic Info
doc.text(superbill.clinicName, margin, y);
doc.text(superbill.clinicAddress, margin, y + 14);
doc.text(`Billing Provider: ${superbill.providerName}`, margin, y + 28);
doc.text(`Provider NPI: ${superbill.providerNpi} | Tax ID: ${superbill.clinicTaxId}`, margin, y + 42);
doc.text(`Place of Service (POS): ${superbill.posCode}`, margin, y + 56);
// Patient Info
doc.text(`Name: ${superbill.patientName}`, 320, y);
doc.text(`DOB: ${superbill.patientDob}`, 320, y + 14);
doc.text(`Address: ${superbill.patientAddress}`, 320, y + 28);
doc.text(`Payment Status: ${superbill.paymentMethod} (PAID IN FULL)`, 320, y + 42);
y += 85;
// Diagnosis (ICD-10) Section
doc.setFont('helvetica', 'bold');
doc.setFontSize(11);
doc.setTextColor(15, 23, 42);
doc.text('DIAGNOSIS CODES (ICD-10-CM)', margin, y);
doc.line(margin, y + 6, doc.internal.pageSize.getWidth() - margin, y + 6);
y += 20;
doc.setFont('helvetica', 'normal');
doc.setFontSize(9);
doc.setTextColor(51, 65, 85);
superbill.icd10Codes.forEach((icd, idx) => {
doc.setFont('helvetica', 'bold');
doc.text(`(${idx + 1}) ${icd.code}`, margin, y);
doc.setFont('helvetica', 'normal');
doc.text(` - ${icd.description}`, margin + 65, y);
y += 15;
});
y += 15;
// Procedure Line Items Table
doc.setFont('helvetica', 'bold');
doc.setFontSize(11);
doc.setTextColor(15, 23, 42);
doc.text('PROCEDURES & SERVICES (CPT CODES)', margin, y);
doc.line(margin, y + 6, doc.internal.pageSize.getWidth() - margin, y + 6);
y += 18;
// Table Header
doc.setFillColor(241, 245, 249);
doc.rect(margin, y, doc.internal.pageSize.getWidth() - (margin * 2), 22, 'F');
doc.setFont('helvetica', 'bold');
doc.setFontSize(9);
doc.setTextColor(71, 85, 105);
doc.text('CPT CODE', margin + 8, y + 15);
doc.text('DESCRIPTION', margin + 80, y + 15);
doc.text('UNITS', 400, y + 15);
doc.text('RATE', 450, y + 15);
doc.text('TOTAL', 505, y + 15);
y += 24;
doc.setFont('helvetica', 'normal');
doc.setFontSize(9);
doc.setTextColor(30, 41, 59);
superbill.items.forEach((item) => {
doc.text(item.cptCode, margin + 8, y + 14);
doc.text(item.description, margin + 80, y + 14);
doc.text(String(item.units), 405, y + 14);
doc.text(`$${item.rate.toFixed(2)}`, 450, y + 14);
doc.text(`$${item.total.toFixed(2)}`, 505, y + 14);
doc.setDrawColor(241, 245, 249);
doc.line(margin, y + 20, doc.internal.pageSize.getWidth() - margin, y + 20);
y += 22;
});
y += 20;
// Summary Totals Box
const summaryX = 350;
doc.setFillColor(248, 250, 252);
doc.rect(summaryX, y, doc.internal.pageSize.getWidth() - margin - summaryX, 70, 'F');
doc.rect(summaryX, y, doc.internal.pageSize.getWidth() - margin - summaryX, 70, 'S');
doc.setFont('helvetica', 'normal');
doc.text('Total Charges:', summaryX + 15, y + 20);
doc.text(`$${superbill.totalAmount.toFixed(2)}`, 505, y + 20);
doc.text('Patient Amount Paid:', summaryX + 15, y + 38);
doc.text(`$${superbill.patientPaid.toFixed(2)}`, 505, y + 38);
doc.setFont('helvetica', 'bold');
doc.text('Balance Due:', summaryX + 15, y + 56);
doc.text(`$${superbill.balanceDue.toFixed(2)}`, 505, y + 56);
y += 95;
// Practitioner Attestation & Signature
doc.setFont('helvetica', 'bold');
doc.setFontSize(9);
doc.setTextColor(15, 23, 42);
doc.text('PRACTITIONER ATTESTATION & SIGNATURE', margin, y);
doc.line(margin, y + 4, doc.internal.pageSize.getWidth() - margin, y + 4);
y += 16;
doc.setFont('helvetica', 'normal');
doc.setFontSize(8);
doc.setTextColor(100, 116, 139);
doc.text(
'I certify that the services listed above were medically necessary and personally rendered by me or under my direct supervision on the date indicated.',
margin,
y
);
y += 25;
doc.setFont('helvetica', 'bold');
doc.setTextColor(15, 23, 42);
doc.text(`Electronically Signed by: ${superbill.providerName}`, margin, y);
doc.setFont('helvetica', 'normal');
doc.text(`Timestamp: ${superbill.generatedAt}`, margin, y + 12);
doc.text(`Verification ID: MED-${superbill.id.toUpperCase()}`, margin, y + 24);
// Footer Branding
doc.setFontSize(8);
doc.setTextColor(148, 163, 184);
doc.text('Generated via Mediusa Clinic OS • Clean Claim Direct Superbill Standard', margin, 760);
doc.save(`Superbill_${superbill.invoiceNumber}_${superbill.patientName.replace(/\s+/g, '_')}.pdf`);
}