diff --git a/client/src/components/c4dic.tsx b/client/src/components/c4dic.tsx index ab9b7c2..f60fc3e 100644 --- a/client/src/components/c4dic.tsx +++ b/client/src/components/c4dic.tsx @@ -19,7 +19,6 @@ export type CoverageInfo = { startDate: string, endDate: string, payer: string, - payerId: string, status: string, medicaidEligibility: string, referenceYear: string, @@ -60,7 +59,6 @@ export default function InsuranceCard() { return { coverageClass: c.coverageClass, payer: c.payer, - payerId: c.payerId, contractId: c.contractId, startDate: c.startDate, endDate: c.endDate, @@ -122,16 +120,28 @@ export default function InsuranceCard() { var backgroundColor = insInfo?.coverages[0]?.colorPalette.background var highlightColor = insInfo?.coverages[0]?.colorPalette.highlight var textColor = insInfo?.coverages[0]?.colorPalette.foreground - const primaryStyle = { - backgroundColor: backgroundColor, - color: textColor + const root = document.documentElement; + if (backgroundColor != null) { + root.style.setProperty('--c4dic-backgroundColor', backgroundColor); } - const highlightStyle = { - backgroundColor: highlightColor, - color: textColor + if (highlightColor != null) { + root.style.setProperty('--c4dic-highlightColor', highlightColor); } + if (textColor != null) { + root.style.setProperty('--c4dic-textColor', textColor); + } + const medicaidEligibility = (insInfo?.coverages[0]?.medicaidEligibility != null) ? + ( +
+ Medicaid Eligibility +
+
+
{insInfo?.coverages[0]?.medicaidEligibility}
+
+
+ ) : null return ( -
+
C4DIC Logo

{insInfo?.coverages[0]?.payer}

@@ -139,27 +149,18 @@ export default function InsuranceCard() {
- NAME + Name
{insInfo?.name||""}
- MEDICARE NUMBER + Medicare Number
{insInfo?.identifier||""}
-
- PAYER ID -
- {insInfo?.coverages[0]?.payerId||""} -
-
- MEDICAID ELIGIBILITY -
- {insInfo?.coverages[0]?.medicaidEligibility||"TBD"} -
+ {medicaidEligibility}
@@ -167,22 +168,26 @@ export default function InsuranceCard() {
Benefits
{insInfo?.coverages.map(c => { + const startDateDiv = (c.startDate != null && c.startDate != "") ? + ( +
+ Start Date +
+ {c.startDate} +
+ ) : null switch (c.coverageClass) { case "Part A": return ( -
-
- COVERAGE -
- {c.coverageClass} -
+
- START DATE + Coverage
- {c.startDate}??? ?, ???? + Hospital
{c.coverageClass}
+ {startDateDiv}
- ENTITLEMENT REASON + Entitlement Reason
{c.contractId}
@@ -190,37 +195,38 @@ export default function InsuranceCard() { ) case "Part B": return ( -
+
- COVERAGE + Coverage
- {c.coverageClass} -
-
- START DATE -
- {c.startDate}??? ?, ???? + Medical
{c.coverageClass}
+ {startDateDiv}
) case "Part C": + const partCTypeDiv = (c.coverageClass != null) ? + ( +
+ Type +
+ {c.coverageClass} +
+ ) : null return ( -
+
- COVERAGE + Coverage
- {c.coverageClass} -
- TYPE -
- {c.coverageClass} + Advantage
{c.coverageClass}
+ {partCTypeDiv}
- PLAN # + Plan #
{c.contractId}
- ORGANIZATION + Organization
{c.payer}
@@ -228,23 +234,15 @@ export default function InsuranceCard() { ) case "Part D": return ( -
-
- COVERAGE -
- {c.coverageClass} -
+
- START DATE -
- {c.startDate}??? ?, ???? + Coverage
- PLAN # -
- {c.contractId} + Rx
{c.coverageClass}
-
- COST SHARE + {startDateDiv} +
+ Plan #
{c.contractId}
@@ -257,7 +255,7 @@ export default function InsuranceCard() {
Contact
- CUSTOMER SERVICE + Customer Service
{insInfo?.coverages[0]?.contacts.map(contact => { diff --git a/client/src/styles/index.scss b/client/src/styles/index.scss index be944ad..2e16d7a 100644 --- a/client/src/styles/index.scss +++ b/client/src/styles/index.scss @@ -29,6 +29,11 @@ $image-path: "~@cmsgov/design-system/dist/images"; position: relative; transition: all .3s; padding: 1rem; + background-color: var(--c4dic-backgroundColor); + color: var(--c4dic-textColor); + ::selection { + background: var(--c4dic-highlightColor); + } } label { @@ -156,6 +161,7 @@ input[type=number]::-webkit-input-placeholder { .field-label { font-size: 10px; font-weight: lighter; + text-transform: uppercase; } .field-value { @@ -163,7 +169,17 @@ input[type=number]::-webkit-input-placeholder { } h6 { - margin: 0px; + font-size: 10px; + font-style: normal; + font-weight: 700; + line-height: normal; + margin: 0px + } + + hr { + border: none; + background-color: var(--c4dic-textColor); + height: 4px; } } @@ -175,6 +191,29 @@ input[type=number]::-webkit-input-placeholder { text-wrap: pretty; } +.bb-c-c4dic-badge-container { + display: flex; + flex-direction: column; + align-items: center; + gap: 5px; +} + +.bb-c-c4dic-badge { + display: flex; + width: fit-content; + padding: 4px 8px; + justify-content: center; + align-items: center; + gap: 10px; + border-radius: 9999px; + border: 0.5px solid; + + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 150%; /* 21px */ +} + .bb-c-c4dic-card-pii-area { background-color: transparent; position: relative; @@ -183,8 +222,8 @@ input[type=number]::-webkit-input-placeholder { } .patient-info { - display: grid; - grid-template-columns: 1fr 1fr 1fr; + display: flex; + gap: 15px; } } @@ -193,10 +232,31 @@ input[type=number]::-webkit-input-placeholder { position: relative; } -.bb-c-c4dic-coverage { +.bb-c-c4dic-coverage-a { + display: grid; + grid-template-columns: 1fr 1fr 2fr; + padding: 10px; +} + +.bb-c-c4dic-coverage-b { + display: grid; + grid-template-columns: 1fr 1fr 2fr; + padding: 10px; + border-top: 0.5px solid +} + +.bb-c-c4dic-coverage-c { + display: grid; + grid-template-columns: 1fr 3fr; + padding: 10px; + border-top: 0.5px solid +} + +.bb-c-c4dic-coverage-d { display: grid; - grid-template-columns: 1fr 1fr 1fr; + grid-template-columns: 1fr 1fr 2fr; padding: 10px; + border-top: 0.5px solid } .bb-c-c4dic-card-org-contact { diff --git a/server/app.py b/server/app.py index e1dda36..8b7893b 100644 --- a/server/app.py +++ b/server/app.py @@ -5,6 +5,7 @@ from jsonpath_ng import jsonpath from jsonpath_ng.ext import parse as ext_parse from cms_bluebutton.cms_bluebutton import BlueButton +from datetime import datetime C4DIC_COLOR_PALETTE_EXT = "http://hl7.org/fhir/us/insurance-card/StructureDefinition/C4DIC-ColorPalette-extension" C4DIC_COLOR_BG = "http://hl7.org/fhir/us/insurance-card/StructureDefinition/C4DIC-BackgroundColor-extension" @@ -208,9 +209,10 @@ def get_patient_insurance(): ## 7. other info such as: DIB, ESRD etc. can be added as needed pt = dic_patient['entry'] patient = pt[0] - # TODO: format the mbi with dashes - pt_id = lookup_1_and_get("$.resource.identifier[?(@.system=='http://hl7.org/fhir/sid/us-mbi')]", "value", patient) - insurance['identifier'] = pt_id + mbi = lookup_1_and_get("$.resource.identifier[?(@.system=='http://hl7.org/fhir/sid/us-mbi')]", "value", patient) + if len(mbi) == 11: + mbi = mbi[0:4] + '-' + mbi[4:7] + '-' + mbi[7:] + insurance['identifier'] = mbi # TODO: handle wider variety of given/family names pt_name = patient['resource']['name'][0]['given'][0] + " " + patient['resource']['name'][0]['family'] insurance['name'] = pt_name @@ -223,15 +225,21 @@ def get_patient_insurance(): coverage['coverageClass'] = c_coverageClass if c_coverageClass else "Null" c_status = c['resource']['status'] coverage['status'] = c_status - c_period = c['resource'].get('period') ## Part C seems not have period + c_medicaidEligibility = "FULL" + coverage['medicaidEligibility'] = c_medicaidEligibility + c_period = c['resource'].get('period') c_start = c_period.get('start') if c_period else "" + try: + c_start_date = datetime.strptime(c_start, '%Y-%m-%d').date() + c_start = c_start_date.strftime("%b %d, %Y") + except ValueError: + pass # Some room for improvement here, but for now, we'll just use the original value from FHIR coverage['startDate'] = c_start if c_start else "" c_end = c_period.get('end') if c_period else "" coverage['endDate'] = c_end if c_end else "" c_payer = c['resource']['payor'][0] c_payer_org = "TO BE RESOLVED" c_contacts = [] - c_payer_id = "TO BE RESOLVED" if c_payer: ## BFD C4DIC Coverage response: payer is a reference to the contained Organization ref_payer_org = c_payer['reference'] @@ -247,7 +255,6 @@ def get_patient_insurance(): c_contacts.append(t['value']) coverage['payer'] = c_payer_org - coverage['payerId'] = c_payer_id coverage['contacts'] = c_contacts c_contract_id = "" ## Part A and Part B does not have contract number if c_coverageClass == "Part C":