Skip to content

Commit

Permalink
feat(#669): add custom Warfarin content
Browse files Browse the repository at this point in the history
  • Loading branch information
tamslo committed Dec 29, 2023
1 parent 14feee8 commit b1c50c2
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 56 deletions.
52 changes: 45 additions & 7 deletions app/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,49 @@ shown below.

```dart
// TODO(after-testing): remove test data adaption
UserData.instance.diplotypes!['CYP2D6'] = Diplotype(
gene: 'CYP2D6',
resultType: 'Diplotype',
genotype: '*18/*143',
phenotype: 'Poor Metabolizer',
allelesTested: '*xN.*3.*4.*5.*6.*8.*9.*10.*14A.*14B.*17.*18.*41.*143',
);
UserData.instance.diplotypes!['CYP2D6'] = Diplotype(
gene: 'CYP2D6',
resultType: 'Diplotype',
genotype: '*18/*143',
phenotype: 'Poor Metabolizer',
allelesTested: '',
);
```

You can use the CPIC API to get reasonable genotype-phenotype pairings, e.g.,
with
`https://api.cpicpgx.org/v1/diplotype?genesymbol=eq.CYP2C9&select=genesymbol,diplotype,generesult`.

Some more examples are collected below (this is for testing what is shown for
Warfarin):

```dart
UserData.instance.diplotypes!['CYP2C9'] = Diplotype(
gene: 'CYP2C9',
resultType: 'Diplotype',
genotype: '*11/*13',
phenotype: 'Poor Metabolizer',
allelesTested: '',
);
UserData.instance.diplotypes!['VKORC1'] = Diplotype(
gene: 'VKORC1',
resultType: 'Diplotype',
genotype: '-1639G>A variant carriers',
phenotype: '-1639G>A variant carriers',
allelesTested: '',
);
UserData.instance.diplotypes!['CYP4F2'] = Diplotype(
gene: 'CYP4F2',
resultType: 'Diplotype',
genotype: 'rs2108622 T carriers',
phenotype: 'rs2108622 T carriers',
allelesTested: '',
);
UserData.instance.diplotypes!['CYP2C'] = Diplotype(
gene: 'CYP2C',
resultType: 'Diplotype',
genotype: 'rs12777823 A carriers',
phenotype: 'rs12777823 A carriers',
allelesTested: '',
);
```
22 changes: 1 addition & 21 deletions app/lib/drug/pages/drug.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,39 +52,19 @@ class DrugPage extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
DrugAnnotationCard(
DrugAnnotationCards(
drug,
isActive: drug.isActive,
setActivity: ({ value }) =>
context.read<DrugCubit>().setActivity(drug, value),
disabled: loading,
),
SizedBox(height: PharMeTheme.mediumSpace),
SubHeader(
context.l10n.drugs_page_header_guideline,
tooltip: _buildGuidelineTooltipText(context),
),
SizedBox(height: PharMeTheme.smallSpace),
GuidelineAnnotationCard(drug),
],
),
),
],
);
}

String _buildGuidelineTooltipText(BuildContext context) {
return drug.userGuideline != null
? context.l10n.drugs_page_tooltip_guideline(
drug.userGuideline!.externalData.first.source
)
: drug.userOrFirstGuideline != null
// Guideline for drug is present but not for genotype
? context.l10n.drugs_page_tooltip_missing_guideline_for_drug_or_genotype(
context.l10n.drugs_page_tooltip_missing_genotype
)
: context.l10n.drugs_page_tooltip_missing_guideline_for_drug_or_genotype(
context.l10n.drugs_page_tooltip_missing_drug
);
}
}
4 changes: 2 additions & 2 deletions app/lib/drug/widgets/annotation_cards/drug.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import '../../../common/module.dart';
import '../sub_header.dart';

class DrugAnnotationCard extends StatelessWidget {
const DrugAnnotationCard(
class DrugAnnotationCards extends StatelessWidget {
const DrugAnnotationCards(
this.drug, {
required this.isActive,
required this.setActivity,
Expand Down
132 changes: 106 additions & 26 deletions app/lib/drug/widgets/annotation_cards/guideline.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,53 +3,112 @@ import 'package:url_launcher/url_launcher.dart';
import '../../../common/module.dart';
import '../module.dart';

enum WarfarinContent {
tooltip,
implication,
recommendation,
color,
icon,
}

final warfarinProperties = <WarfarinContent, dynamic Function(BuildContext)>{
WarfarinContent.tooltip: (context) =>
context.l10n.drugs_page_tooltip_warfarin,
WarfarinContent.implication: (context) =>
context.l10n.drugs_page_implication_warfarin,
WarfarinContent.recommendation: (context) =>
context.l10n.drugs_page_recommendation_warfarin,
WarfarinContent.color: (_) => WarningLevel.none.color,
WarfarinContent.icon: (_) => WarningLevel.none.icon,
};

class GuidelineAnnotationCard extends StatelessWidget {
const GuidelineAnnotationCard(this.drug);

final Drug drug;

@override
Widget build(BuildContext context) {
return RoundedCard(
innerPadding: const EdgeInsets.all(PharMeTheme.mediumSpace),
child: SingleChildScrollView(
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
if (drug.guidelines.isNotEmpty) ...[
_buildHeader(context),
SizedBox(height: PharMeTheme.mediumSpace),
_buildCard(context),
SizedBox(height: PharMeTheme.mediumSpace),
_buildSourcesSection(context),
]
else ...[
_buildHeader(context),
SizedBox(height: PharMeTheme.smallSpace),
_buildCard(context),
],
]),
),
return Column(
children: [
SubHeader(
context.l10n.drugs_page_header_guideline,
tooltip: _buildGuidelineTooltipText(context),
),
SizedBox(height: PharMeTheme.smallSpace),
RoundedCard(
innerPadding: const EdgeInsets.all(PharMeTheme.mediumSpace),
child: SingleChildScrollView(
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
if (drug.guidelines.isNotEmpty) ...[
_buildHeader(context),
SizedBox(height: PharMeTheme.mediumSpace),
_buildCard(context),
SizedBox(height: PharMeTheme.mediumSpace),
_buildSourcesSection(context),
]
else ...[
_buildHeader(context),
SizedBox(height: PharMeTheme.smallSpace),
_buildCard(context),
],
]),
),
),
],
);
}

dynamic actualOrWarfarinContent(String drugName, BuildContext context, {
required dynamic actual,
required WarfarinContent content,
}) {
if (drugName.toLowerCase() == 'warfarin') {
final getWarfarinContent = warfarinProperties[content]!;
return getWarfarinContent(context);
}
return actual;
}

Widget _buildCard(BuildContext context) {
final upperCardText = drug.userGuideline?.annotations.implication ??
context.l10n.drugs_page_no_guidelines_for_phenotype_implication(
drug.name
);
final lowerCardText = drug.userGuideline?.annotations.recommendation ??
context.l10n.drugs_page_no_guidelines_for_phenotype_recommendation;
final upperCardText = actualOrWarfarinContent(
drug.name,
context,
actual: drug.userGuideline?.annotations.implication ??
context.l10n.drugs_page_no_guidelines_for_phenotype_implication(
drug.name
),
content: WarfarinContent.implication,
);
final lowerCardText = actualOrWarfarinContent(
drug.name,
context,
actual: drug.userGuideline?.annotations.recommendation ??
context.l10n.drugs_page_no_guidelines_for_phenotype_recommendation,
content: WarfarinContent.recommendation,
);
return RoundedCard(
key: Key('annotationCard'),
radius: PharMeTheme.innerCardRadius,
outerHorizontalPadding: 0,
outerVerticalPadding: 0,
color: drug.warningLevel.color,
color: actualOrWarfarinContent(
drug.name,
context,
actual: drug.warningLevel.color,
content: WarfarinContent.color
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(children: [
Icon(
drug.warningLevel.icon,
actualOrWarfarinContent(
drug.name,
context,
actual: drug.warningLevel.icon,
content: WarfarinContent.icon
),
color: PharMeTheme.onSurfaceText,
size: PharMeTheme.largeSpace,
),
Expand All @@ -75,6 +134,27 @@ class GuidelineAnnotationCard extends StatelessWidget {
);
}

String _buildGuidelineTooltipText(BuildContext context) {
final actualTooltip = drug.userGuideline != null
? context.l10n.drugs_page_tooltip_guideline(
drug.userGuideline!.externalData.first.source
)
: drug.userOrFirstGuideline != null
// Guideline for drug is present but not for genotype
? context.l10n.drugs_page_tooltip_missing_guideline_for_drug_or_genotype(
context.l10n.drugs_page_tooltip_missing_genotype
)
: context.l10n.drugs_page_tooltip_missing_guideline_for_drug_or_genotype(
context.l10n.drugs_page_tooltip_missing_drug
);
return actualOrWarfarinContent(
drug.name,
context,
actual: actualTooltip,
content: WarfarinContent.tooltip,
);
}

Widget _buildHeader(BuildContext context) {
if (drug.userGuideline == null && drug.guidelines.isEmpty) {
return Text(
Expand Down
4 changes: 4 additions & 0 deletions app/lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,10 @@
}
},

"drugs_page_tooltip_warfarin": "CPIC guidelines provide recommendations on which drugs to use based on your DNA. However, to calculate your warfarin dose, more information is needed.",
"drugs_page_implication_warfarin": "More information is needed to calculate your warfarin dose.",
"drugs_page_recommendation_warfarin": "Consult your pharmacist or doctor for more information.",

"report_content_explanation": "Here is your PGx report. Tap on a gene name for more details on your results and a list of implicated drugs.",
"report_page_indicator_explanation": "Phenotypes followed by an {indicatorName} ({indicator}) might be influenced by drugs you are currently taking",
"@report_page_indicator_explanation": {
Expand Down

0 comments on commit b1c50c2

Please sign in to comment.