Skip to content

Commit 2a6e05f

Browse files
committed
Refining DIVOC's card for India, SriLanka and Philippines
1 parent 9860104 commit 2a6e05f

File tree

1 file changed

+190
-78
lines changed

1 file changed

+190
-78
lines changed

app/components/CowinCard.js

Lines changed: 190 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -8,93 +8,205 @@ import Moment from 'moment';
88
import { CardStyles as styles } from '../themes/CardStyles'
99

1010
const TRUST_REGISTRY = {
11-
"did:india": "Republic of India",
12-
"did:srilanka:moh": "Republic of Sri Lanka",
13-
"did:philippines": "Republic of the Philippines"
11+
"did:india": "Gov of India",
12+
"did:srilanka:moh": "Gov of Sri Lanka",
13+
"did:philippines": "Gov of Philippines"
1414
}
1515

1616
export default class CowinCard extends Component {
17-
issuerName = (card) => {
18-
if (TRUST_REGISTRY[card.pub_key.toLowerCase()]) {
19-
return TRUST_REGISTRY[card.pub_key.toLowerCase()]
20-
}
21-
return card.pub_key.toLowerCase();
22-
}
17+
issuerName = card => {
18+
if (TRUST_REGISTRY[card.pub_key.toLowerCase()]) {
19+
return TRUST_REGISTRY[card.pub_key.toLowerCase()];
20+
}
21+
return card.pub_key.toLowerCase();
22+
};
2323

24-
issuedAt = (card) => {
25-
return Moment(card.cert.issuanceDate).format('MMM DD, YYYY');
26-
}
24+
issuedAt = card => {
25+
return Moment(card.cert.issuanceDate).format('MMM DD, YYYY');
26+
};
2727

28-
showQR = (card) => {
29-
this.props.navigation.navigate({name: 'QRShow', params: {
30-
qr: card.rawQR,
31-
title: card.cert.credentialSubject.name,
28+
showQR = card => {
29+
this.props.navigation.navigate({
30+
name: 'QRShow',
31+
params: {
32+
qr: card.rawQR,
33+
title: card.cert.credentialSubject.name,
3234
detail: card.cert.credentialSubject.id.substring(4),
33-
signedBy: this.issuerName(card) + " on " + this.issuedAt(card)
34-
}
35+
signedBy: this.issuerName(card) + ' on ' + this.issuedAt(card),
36+
},
3537
});
36-
}
38+
};
39+
40+
formatPerson = () => {
41+
if (this.cert().credentialSubject.name) {
42+
let names = this.cert().credentialSubject.name.trim().split(' ');
43+
for (i = 1; i < names.length - 1; i++) {
44+
names[i] = names[i][0];
45+
}
46+
return names.join(' ');
47+
} else return undefined;
48+
};
49+
50+
cert = () => {
51+
return this.props.detail.cert ? this.props.detail.cert : this.props.detail;
52+
};
53+
54+
formatDoB = () => {
55+
let str = [];
56+
57+
if (this.cert().credentialSubject.id && this.cert().credentialSubject.id !== 'NA')
58+
str.push(this.cert().credentialSubject.id.replace('did:', '').replace(' Card',""));
59+
else
60+
if (this.cert().credentialSubject.refId)
61+
str.push("ID: " + this.cert().credentialSubject.refId);
62+
63+
if (this.cert().credentialSubject.age)
64+
str.push(this.cert().credentialSubject.age + 'yrs');
65+
66+
if (this.cert().credentialSubject.gender)
67+
str.push(this.cert().credentialSubject.gender);
68+
69+
if (this.cert().credentialSubject.sex)
70+
str.push(this.cert().credentialSubject.sex);
71+
72+
return str.join(', ');
73+
};
74+
75+
formatManufacturer = (item) => {
76+
if (item.vaccine === item.manufacturer)
77+
return undefined;
78+
79+
if (this.cert().proof.verificationMethod !== "did:india")
80+
return item.vaccine;
81+
else
82+
return item.manufacturer;
83+
}
3784

38-
renderCard = () => {
39-
return (
40-
<View style={[styles.card, {backgroundColor:this.props.colors.primary}]}>
41-
<View style={{flexDirection:'row', justifyContent:'space-between', alignItems:'center'}}>
42-
<Text style={styles.notes}>{Moment(this.props.detail.scanDate).format('MMM DD, hh:mma')} - COVID Vaccine</Text>
43-
<FontAwesome5 style={styles.button} name={'trash'} onPress={() => this.props.removeItem(this.props.detail.signature)} solid/>
44-
</View>
45-
46-
<View style={{flexDirection:'row', justifyContent:'space-between', alignItems:'center'}}>
47-
<Text style={styles.title}>{this.props.detail.cert.credentialSubject.name}</Text>
48-
</View>
49-
50-
<View style={{flexDirection:'row', justifyContent:'space-between', alignItems:'center'}}>
51-
<Text style={styles.notes}>{this.props.detail.cert.credentialSubject.age} yrs-old {this.props.detail.cert.credentialSubject.gender}</Text>
52-
</View>
53-
54-
<View style={{flexDirection:'row', justifyContent:'space-between', alignItems:'center'}}>
55-
<Text style={styles.notes}>{this.props.detail.cert.credentialSubject.id.substring(4)}</Text>
56-
</View>
57-
58-
<Divider style={[styles.divisor, {borderBottomColor:this.props.colors.cardText}]} />
59-
60-
<FlatList
61-
data={this.props.detail.cert.evidence}
62-
keyExtractor={item => item.certificateId}
63-
renderItem={({item}) => {
64-
return ( <View>
65-
<View style={styles.row}>
66-
<Text style={styles.notes}>Shots taken: {item.dose} of {item.totalDoses}</Text>
67-
</View>
68-
69-
<View style={styles.row}>
70-
<Text style={styles.notes}>
71-
Vaccine: {item.vaccine} #{item.batch}
72-
</Text>
73-
</View>
74-
75-
<View style={styles.row}>
76-
<Text style={styles.notes}>
77-
{item.manufacturer}
78-
</Text>
79-
</View>
80-
</View>)
81-
}} />
82-
83-
<Divider style={[styles.divisor, {borderBottomColor:this.props.colors.cardText}]} />
84-
85-
<View style={{flexDirection:'row', alignItems: 'center'}}>
86-
<FontAwesome5 style={styles.icon} name={'check-circle'} solid/>
87-
<Text style={styles.notes}>{this.issuerName(this.props.detail)} on {this.issuedAt(this.props.detail)}</Text>
88-
</View>
89-
</View>
90-
)
85+
formatBrand = (item) => {
86+
if (this.cert().proof.verificationMethod === "did:india")
87+
return item.vaccine;
88+
else
89+
return item.manufacturer.replace(/\([^()]*\)/g, "")
9190
}
9291

93-
render() {
94-
return this.props.pressable ?
95-
( <TouchableOpacity onPress={() => this.showQR(this.props.detail)}>
96-
{this.renderCard()}
97-
</TouchableOpacity>
98-
) : this.renderCard();
92+
formatBatch = (item) => {
93+
if (item.batch)
94+
return item.batch.replace(item.vaccine, "").replace(" -","").replace("#","").replace(" ", "");
95+
return undefined;
9996
}
97+
98+
renderCard = () => {
99+
console.log(this.cert().evidence[0]);
100+
return (
101+
<View style={[styles.card, {backgroundColor: this.props.colors.primary}]}>
102+
<View
103+
style={{
104+
flexDirection: 'row',
105+
justifyContent: 'space-between',
106+
alignItems: 'center',
107+
}}>
108+
<Text style={styles.notes}>
109+
{Moment(this.props.detail.scanDate).format('MMM DD, hh:mma')} -
110+
COVID Vaccine
111+
</Text>
112+
<FontAwesome5
113+
style={styles.button}
114+
name={'trash'}
115+
onPress={() => this.props.removeItem(this.props.detail.signature)}
116+
solid
117+
/>
118+
</View>
119+
120+
{this.formatPerson() && (
121+
<View style={styles.row}>
122+
<Text style={styles.title}>{this.formatPerson()}</Text>
123+
</View>
124+
)}
125+
126+
{this.formatDoB() && (
127+
<View style={styles.row}>
128+
<Text style={styles.notes}>{this.formatDoB()}</Text>
129+
</View>
130+
)}
131+
132+
<Divider
133+
style={[
134+
styles.divisor,
135+
{borderBottomColor: this.props.colors.cardText},
136+
]}
137+
/>
138+
139+
<FlatList
140+
data={this.cert().evidence}
141+
keyExtractor={item => item.certificateId}
142+
renderItem={({item}) => {
143+
return (
144+
<View>
145+
<View style={{alignItems: 'center'}}>
146+
<Text style={styles.subtitle}>COVID Vaccine {item.dose} of {item.totalDoses}</Text>
147+
</View>
148+
149+
<View style={{alignItems: 'center'}}>
150+
<Text style={styles.notes}>{this.formatBrand(item)} #{this.formatBatch(item)}</Text>
151+
</View>
152+
153+
<View style={{alignItems: 'center'}}>
154+
<Text style={styles.notes}>{Moment(item.date).format('MMM DD, YYYY')}</Text>
155+
</View>
156+
157+
{ item.certificateId &&
158+
<View style={{alignItems: 'center'}}>
159+
<Text style={styles.notes}>Cert ID: {item.certificateId}</Text>
160+
</View>
161+
}
162+
163+
{ item.effectiveStart &&
164+
<View style={{alignItems: 'center'}}>
165+
<Text style={styles.notes}>Effective from {Moment(item.effectiveStart).format('MMM DD')} to {Moment(item.effectiveUntil).format('MMM DD, YYYY')}</Text>
166+
</View>
167+
}
168+
169+
{ this.formatManufacturer(item) &&
170+
<View style={{alignItems: 'center'}}>
171+
<Text style={styles.notesSmall}>{this.formatManufacturer(item)}</Text>
172+
</View>
173+
}
174+
175+
{ item.prophylaxis &&
176+
<View style={{alignItems: 'center'}}>
177+
<Text style={styles.notesSmall}>{item.prophylaxis}</Text>
178+
</View>
179+
}
180+
</View>
181+
);
182+
}}
183+
/>
184+
185+
<Divider
186+
style={[
187+
styles.divisor,
188+
{borderBottomColor: this.props.colors.cardText},
189+
]}
190+
/>
191+
192+
<View style={{flexDirection: 'row', alignItems: 'center'}}>
193+
<FontAwesome5 style={styles.icon} name={'check-circle'} solid />
194+
<Text style={styles.notes}>
195+
{this.issuerName(this.props.detail)} on{' '}
196+
{this.issuedAt(this.props.detail)}
197+
</Text>
198+
</View>
199+
</View>
200+
);
201+
};
202+
203+
render() {
204+
return this.props.pressable ? (
205+
<TouchableOpacity onPress={() => this.showQR(this.props.detail)}>
206+
{this.renderCard()}
207+
</TouchableOpacity>
208+
) : (
209+
this.renderCard()
210+
);
211+
}
100212
}

0 commit comments

Comments
 (0)