Skip to content

Commit d6290eb

Browse files
authored
Feature/c4dic jimmy bb2 3391 (#81)
* First pass of edits * Render logo and bcg * Fix layout, add contact, addl info, etc * Remove some unneeded data fields * Adjustments from self-review * Updates to C4DIC
1 parent a09c510 commit d6290eb

File tree

3 files changed

+138
-73
lines changed

3 files changed

+138
-73
lines changed

client/src/components/c4dic.tsx

Lines changed: 60 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ export type CoverageInfo = {
1919
startDate: string,
2020
endDate: string,
2121
payer: string,
22-
payerId: string,
2322
status: string,
2423
medicaidEligibility: string,
2524
referenceYear: string,
@@ -60,7 +59,6 @@ export default function InsuranceCard() {
6059
return {
6160
coverageClass: c.coverageClass,
6261
payer: c.payer,
63-
payerId: c.payerId,
6462
contractId: c.contractId,
6563
startDate: c.startDate,
6664
endDate: c.endDate,
@@ -122,129 +120,129 @@ export default function InsuranceCard() {
122120
var backgroundColor = insInfo?.coverages[0]?.colorPalette.background
123121
var highlightColor = insInfo?.coverages[0]?.colorPalette.highlight
124122
var textColor = insInfo?.coverages[0]?.colorPalette.foreground
125-
const primaryStyle = {
126-
backgroundColor: backgroundColor,
127-
color: textColor
123+
const root = document.documentElement;
124+
if (backgroundColor != null) {
125+
root.style.setProperty('--c4dic-backgroundColor', backgroundColor);
128126
}
129-
const highlightStyle = {
130-
backgroundColor: highlightColor,
131-
color: textColor
127+
if (highlightColor != null) {
128+
root.style.setProperty('--c4dic-highlightColor', highlightColor);
132129
}
130+
if (textColor != null) {
131+
root.style.setProperty('--c4dic-textColor', textColor);
132+
}
133+
const medicaidEligibility = (insInfo?.coverages[0]?.medicaidEligibility != null) ?
134+
(
135+
<div>
136+
<text className="field-label">Medicaid Eligibility</text>
137+
<br/>
138+
<div className="bb-c-c4dic-badge-container">
139+
<div className="bb-c-c4dic-badge">{insInfo?.coverages[0]?.medicaidEligibility}</div>
140+
</div>
141+
</div>
142+
) : null
133143
return (
134-
<div className="ins-c4dic-card" style={primaryStyle}>
144+
<div className="ins-c4dic-card">
135145
<div className="bb-c-c4dic-card-header">
136146
<img src={insInfo?.coverages[0]?.logo} alt="C4DIC Logo" height="48px"/>
137147
<h3>{insInfo?.coverages[0]?.payer}</h3>
138148
</div>
139149
<div className="pii-sec bb-c-c4dic-card-pii-area">
140150
<div className="ins-fld-text patient-name">
141151
<div>
142-
<text className="field-label">NAME</text>
152+
<text className="field-label">Name</text>
143153
<br/>
144154
<text className="field-value">{insInfo?.name||""}</text>
145155
</div>
146156
</div>
147157
<div className="ins-fld-text patient-info">
148158
<div>
149-
<text className="field-label">MEDICARE NUMBER</text>
159+
<text className="field-label">Medicare Number</text>
150160
<br/>
151161
<text className="field-value">{insInfo?.identifier||""}</text>
152162
</div>
153-
<div>
154-
<text className="field-label">PAYER ID</text>
155-
<br/>
156-
<text className="field-value">{insInfo?.coverages[0]?.payerId||""}</text>
157-
</div>
158-
<div>
159-
<text className="field-label">MEDICAID ELIGIBILITY</text>
160-
<br/>
161-
<text className="field-value">{insInfo?.coverages[0]?.medicaidEligibility||"TBD"}</text>
162-
</div>
163+
{medicaidEligibility}
163164
</div>
164165
</div>
165166

166167
<div className="coverage-sec bb-c-c4dic-card-coverages-area">
167168
<hr/>
168169
<h6>Benefits</h6>
169170
{insInfo?.coverages.map(c => {
171+
const startDateDiv = (c.startDate != null && c.startDate != "") ?
172+
(
173+
<div>
174+
<text className="field-label">Start Date</text>
175+
<br/>
176+
<text className="field-value">{c.startDate}</text>
177+
</div>
178+
) : null
170179
switch (c.coverageClass) {
171180
case "Part A":
172181
return (
173-
<div className="bb-c-c4dic-coverage">
174-
<div>
175-
<text className="field-label">COVERAGE</text>
176-
<br/>
177-
<text className="field-value">{c.coverageClass}</text>
178-
</div>
182+
<div className="bb-c-c4dic-coverage-a">
179183
<div>
180-
<text className="field-label">START DATE</text>
184+
<text className="field-label">Coverage</text>
181185
<br/>
182-
<text className="field-value">{c.startDate}??? ?, ????</text>
186+
<text className="field-value">Hospital<br/>{c.coverageClass}</text>
183187
</div>
188+
{startDateDiv}
184189
<div>
185-
<text className="field-label">ENTITLEMENT REASON</text>
190+
<text className="field-label">Entitlement Reason</text>
186191
<br/>
187192
<text className="field-value">{c.contractId}</text>
188193
</div>
189194
</div>
190195
)
191196
case "Part B":
192197
return (
193-
<div className="bb-c-c4dic-coverage" style={highlightStyle}>
198+
<div className="bb-c-c4dic-coverage-b">
194199
<div>
195-
<text className="field-label">COVERAGE</text>
200+
<text className="field-label">Coverage</text>
196201
<br/>
197-
<text className="field-value">{c.coverageClass}</text>
198-
</div>
199-
<div>
200-
<text className="field-label">START DATE</text>
201-
<br/>
202-
<text className="field-value">{c.startDate}??? ?, ????</text>
202+
<text className="field-value">Medical<br/>{c.coverageClass}</text>
203203
</div>
204+
{startDateDiv}
204205
</div>
205206
)
206207
case "Part C":
208+
const partCTypeDiv = (c.coverageClass != null) ?
209+
(
210+
<div>
211+
<text className="field-label">Type</text>
212+
<br/>
213+
<text className="field-value">{c.coverageClass}</text>
214+
</div>
215+
) : null
207216
return (
208-
<div className="bb-c-c4dic-coverage">
217+
<div className="bb-c-c4dic-coverage-c">
209218
<div>
210-
<text className="field-label">COVERAGE</text>
219+
<text className="field-label">Coverage</text>
211220
<br/>
212-
<text className="field-value">{c.coverageClass}</text>
213-
<br/>
214-
<text className="field-label">TYPE</text>
215-
<br/>
216-
<text className="field-value">{c.coverageClass}</text>
221+
<text className="field-value">Advantage<br/>{c.coverageClass}</text>
222+
{partCTypeDiv}
217223
</div>
218224
<div>
219-
<text className="field-label">PLAN #</text>
225+
<text className="field-label">Plan #</text>
220226
<br/>
221227
<text className="field-value">{c.contractId}</text>
222228
<br/>
223-
<text className="field-label">ORGANIZATION</text>
229+
<text className="field-label">Organization</text>
224230
<br/>
225231
<text className="field-value">{c.payer}</text>
226232
</div>
227233
</div>
228234
)
229235
case "Part D":
230236
return (
231-
<div className="bb-c-c4dic-coverage" style={highlightStyle}>
232-
<div>
233-
<text className="field-label">COVERAGE</text>
234-
<br/>
235-
<text className="field-value">{c.coverageClass}</text>
236-
</div>
237+
<div className="bb-c-c4dic-coverage-d">
237238
<div>
238-
<text className="field-label">START DATE</text>
239-
<br/>
240-
<text className="field-value">{c.startDate}??? ?, ????</text>
239+
<text className="field-label">Coverage</text>
241240
<br/>
242-
<text className="field-label">PLAN #</text>
243-
<br/>
244-
<text className="field-value">{c.contractId}</text>
241+
<text className="field-value">Rx<br/>{c.coverageClass}</text>
245242
</div>
246-
<div>
247-
<text className="field-label">COST SHARE</text>
243+
{startDateDiv}
244+
<div>
245+
<text className="field-label">Plan #</text>
248246
<br/>
249247
<text className="field-value">{c.contractId}</text>
250248
</div>
@@ -257,7 +255,7 @@ export default function InsuranceCard() {
257255
<hr/>
258256
<h6>Contact</h6>
259257

260-
<text className="field-label">CUSTOMER SERVICE</text>
258+
<text className="field-label">Customer Service</text>
261259
<br/>
262260
<div className="contact-list">
263261
{insInfo?.coverages[0]?.contacts.map(contact => {

client/src/styles/index.scss

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ $image-path: "~@cmsgov/design-system/dist/images";
2929
position: relative;
3030
transition: all .3s;
3131
padding: 1rem;
32+
background-color: var(--c4dic-backgroundColor);
33+
color: var(--c4dic-textColor);
34+
::selection {
35+
background: var(--c4dic-highlightColor);
36+
}
3237
}
3338

3439
label {
@@ -156,14 +161,25 @@ input[type=number]::-webkit-input-placeholder {
156161
.field-label {
157162
font-size: 10px;
158163
font-weight: lighter;
164+
text-transform: uppercase;
159165
}
160166

161167
.field-value {
162168
font-size: 18px;
163169
}
164170

165171
h6 {
166-
margin: 0px;
172+
font-size: 10px;
173+
font-style: normal;
174+
font-weight: 700;
175+
line-height: normal;
176+
margin: 0px
177+
}
178+
179+
hr {
180+
border: none;
181+
background-color: var(--c4dic-textColor);
182+
height: 4px;
167183
}
168184
}
169185

@@ -175,6 +191,29 @@ input[type=number]::-webkit-input-placeholder {
175191
text-wrap: pretty;
176192
}
177193

194+
.bb-c-c4dic-badge-container {
195+
display: flex;
196+
flex-direction: column;
197+
align-items: center;
198+
gap: 5px;
199+
}
200+
201+
.bb-c-c4dic-badge {
202+
display: flex;
203+
width: fit-content;
204+
padding: 4px 8px;
205+
justify-content: center;
206+
align-items: center;
207+
gap: 10px;
208+
border-radius: 9999px;
209+
border: 0.5px solid;
210+
211+
font-size: 14px;
212+
font-style: normal;
213+
font-weight: 400;
214+
line-height: 150%; /* 21px */
215+
}
216+
178217
.bb-c-c4dic-card-pii-area {
179218
background-color: transparent;
180219
position: relative;
@@ -183,8 +222,8 @@ input[type=number]::-webkit-input-placeholder {
183222
}
184223

185224
.patient-info {
186-
display: grid;
187-
grid-template-columns: 1fr 1fr 1fr;
225+
display: flex;
226+
gap: 15px;
188227
}
189228
}
190229

@@ -193,10 +232,31 @@ input[type=number]::-webkit-input-placeholder {
193232
position: relative;
194233
}
195234

196-
.bb-c-c4dic-coverage {
235+
.bb-c-c4dic-coverage-a {
236+
display: grid;
237+
grid-template-columns: 1fr 1fr 2fr;
238+
padding: 10px;
239+
}
240+
241+
.bb-c-c4dic-coverage-b {
242+
display: grid;
243+
grid-template-columns: 1fr 1fr 2fr;
244+
padding: 10px;
245+
border-top: 0.5px solid
246+
}
247+
248+
.bb-c-c4dic-coverage-c {
249+
display: grid;
250+
grid-template-columns: 1fr 3fr;
251+
padding: 10px;
252+
border-top: 0.5px solid
253+
}
254+
255+
.bb-c-c4dic-coverage-d {
197256
display: grid;
198-
grid-template-columns: 1fr 1fr 1fr;
257+
grid-template-columns: 1fr 1fr 2fr;
199258
padding: 10px;
259+
border-top: 0.5px solid
200260
}
201261

202262
.bb-c-c4dic-card-org-contact {

server/app.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from jsonpath_ng import jsonpath
66
from jsonpath_ng.ext import parse as ext_parse
77
from cms_bluebutton.cms_bluebutton import BlueButton
8+
from datetime import datetime
89

910
C4DIC_COLOR_PALETTE_EXT = "http://hl7.org/fhir/us/insurance-card/StructureDefinition/C4DIC-ColorPalette-extension"
1011
C4DIC_COLOR_BG = "http://hl7.org/fhir/us/insurance-card/StructureDefinition/C4DIC-BackgroundColor-extension"
@@ -208,9 +209,10 @@ def get_patient_insurance():
208209
## 7. other info such as: DIB, ESRD etc. can be added as needed
209210
pt = dic_patient['entry']
210211
patient = pt[0]
211-
# TODO: format the mbi with dashes
212-
pt_id = lookup_1_and_get("$.resource.identifier[?(@.system=='http://hl7.org/fhir/sid/us-mbi')]", "value", patient)
213-
insurance['identifier'] = pt_id
212+
mbi = lookup_1_and_get("$.resource.identifier[?(@.system=='http://hl7.org/fhir/sid/us-mbi')]", "value", patient)
213+
if len(mbi) == 11:
214+
mbi = mbi[0:4] + '-' + mbi[4:7] + '-' + mbi[7:]
215+
insurance['identifier'] = mbi
214216
# TODO: handle wider variety of given/family names
215217
pt_name = patient['resource']['name'][0]['given'][0] + " " + patient['resource']['name'][0]['family']
216218
insurance['name'] = pt_name
@@ -223,15 +225,21 @@ def get_patient_insurance():
223225
coverage['coverageClass'] = c_coverageClass if c_coverageClass else "Null"
224226
c_status = c['resource']['status']
225227
coverage['status'] = c_status
226-
c_period = c['resource'].get('period') ## Part C seems not have period
228+
c_medicaidEligibility = "FULL"
229+
coverage['medicaidEligibility'] = c_medicaidEligibility
230+
c_period = c['resource'].get('period')
227231
c_start = c_period.get('start') if c_period else ""
232+
try:
233+
c_start_date = datetime.strptime(c_start, '%Y-%m-%d').date()
234+
c_start = c_start_date.strftime("%b %d, %Y")
235+
except ValueError:
236+
pass # Some room for improvement here, but for now, we'll just use the original value from FHIR
228237
coverage['startDate'] = c_start if c_start else ""
229238
c_end = c_period.get('end') if c_period else ""
230239
coverage['endDate'] = c_end if c_end else ""
231240
c_payer = c['resource']['payor'][0]
232241
c_payer_org = "TO BE RESOLVED"
233242
c_contacts = []
234-
c_payer_id = "TO BE RESOLVED"
235243
if c_payer:
236244
## BFD C4DIC Coverage response: payer is a reference to the contained Organization
237245
ref_payer_org = c_payer['reference']
@@ -247,7 +255,6 @@ def get_patient_insurance():
247255
c_contacts.append(t['value'])
248256

249257
coverage['payer'] = c_payer_org
250-
coverage['payerId'] = c_payer_id
251258
coverage['contacts'] = c_contacts
252259
c_contract_id = "" ## Part A and Part B does not have contract number
253260
if c_coverageClass == "Part C":

0 commit comments

Comments
 (0)