diff --git a/app/dfda/cba/page.tsx b/app/dfda/cba/page.tsx index 3bd464d9..45fe0e13 100644 --- a/app/dfda/cba/page.tsx +++ b/app/dfda/cba/page.tsx @@ -1,9 +1,6 @@ import React from 'react'; -import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'; -import { Badge } from '@/components/ui/badge'; -import { AlertCircle, CheckCircle, HelpCircle, Skull, Cigarette, Beer, Pill, Droplet, Wind, Users } from 'lucide-react'; -import { ExtendedMetaAnalysisReport, Article} from "@/lib/agents/fdai/fdaiMetaAnalyzer"; -import ArticleCard from "@/lib/agents/fdai/ArticleCard"; +import { ExtendedMetaAnalysisReport} from "@/lib/agents/fdai/fdaiMetaAnalyzer"; +import MetaAnalysisReport from "@/app/dfda/components/MetaAnalysisReport"; // Example report data const exampleReport: ExtendedMetaAnalysisReport = { @@ -73,7 +70,7 @@ const exampleReport: ExtendedMetaAnalysisReport = { severity: "Severe" } ], - relativeSafetyScore: 7.5, + relativeSafetyScore: 2, effectivenessComparison: [ { intervention: "Amlodipine (calcium channel blocker)", @@ -110,224 +107,6 @@ const exampleReport: ExtendedMetaAnalysisReport = { ] }; -const SafetyRatingBadge = ({ rating }: { rating: 'Safe' | 'Moderate' | 'Low' | 'High' }) => { - const color = rating === 'Safe' ? 'bg-green-500' : - rating === 'Moderate' ? 'bg-yellow-500' : 'bg-red-500'; - const icon = rating === 'Safe' ? : - rating === 'Moderate' ? : - ; - - return ( - - {icon} {rating} - - ); -}; - -const ListSection = ({ title, items }: { title: string; items: string[] }) => ( -
-

{title}

-
    - {items.map((item: string, index: number) => ( -
  • {item}
  • - ))} -
-
-); - -const SafetyScoreBar = ({ score }: { score: number }) => { - const getColor = (score: number) => { - if (score < 2) return 'bg-red-600'; - if (score < 4) return 'bg-orange-500'; - if (score < 6) return 'bg-yellow-400'; - if (score < 8) return 'bg-lime-500'; - return 'bg-green-600'; - }; - - const referencePoints = [ - { score: 0, label: 'Extremely unsafe (Cyanide)', icon: }, - { score: 2, label: 'Very unsafe (Cigarette)', icon: }, - { score: 4, label: 'Moderately unsafe (Beer)', icon: }, - { score: 6, label: 'Moderately safe (Aspirin)', icon: }, - { score: 8, label: 'Very safe (Water)', icon: }, - { score: 10, label: 'Extremely safe (Air)', icon: }, - ]; - - return ( -
-
-
-
- - Safety Score: {score.toFixed(1)}/10 - -
-
-
- {referencePoints.map((point, index) => ( -
- {point.icon} - {point.label} -
- ))} -
-
-
-
- ); -}; - -const MetaAnalysisReport = ({ report }: { report: ExtendedMetaAnalysisReport }) => { - return ( -
- - - {report.drugName} for {report.conditionName} -
- -
-
- -

Safety Summary: {report.shortSafetySummary}

- - -
-
- - - - Safety Considerations - - - - - -
-

Long-term Safety

-

{report.longTermSafetyConsiderations}

-
-
-

Special Populations

-

Pregnancy: {report.pregnancySafety}

-

Children: {report.childrenSafety}

-
-
-
- - - - Drug Interactions - - - {report.drugInteractions.map((interaction, index: number) => ( -
- {interaction.drug}: {interaction.interaction} - -
- ))} -
-
- - - - Side Effects - - - {report.sideEffects.map((effect, index: number) => ( -
- {effect.effect}: {effect.frequency} - {effect.severity && ` (Severity: ${effect.severity})`} -
- ))} -
-
- - - - Effectiveness Comparison - - - {report.effectivenessComparison.map((comparison, index: number) => ( -
-

{comparison.intervention}

-

Relative Effectiveness: {comparison.relativeEffectiveness}

- {comparison.dalysAvoided &&

DALYs Avoided: {comparison.dalysAvoided.toFixed(2)}

} - {comparison.qalysIncreased &&

QALYs Increased: {comparison.qalysIncreased.toFixed(2)}

} - {comparison.numberNeededToHarm &&

Number Needed to Harm: {comparison.numberNeededToHarm}

} - {comparison.numberNeededToTreat &&

Number Needed to Treat: {comparison.numberNeededToTreat}

} -
- ))} -
-
- - - - By Making This Treatment Available - - - {report.dalysAvoided && ( -
- - DALYs Avoided: - {report.dalysAvoided.toFixed(2)} -
- Disability-Adjusted Life Years saved per patient if treated -
-
- )} - {report.qalysIncreased && ( -
- - QALYs Increased: - {report.qalysIncreased.toFixed(2)} - - Quality-Adjusted Life Years gained per patient if treated - -
- )} - {report.numberNeededToHarm && ( -
- - Number Needed to Harm: - {report.numberNeededToHarm} - - patients treated before one is harmed - -
- )} - {report.numberNeededToTreat && ( -
- - Number Needed to Treat: - {report.numberNeededToTreat} - (Patients treated for one to benefit) -
- )} - {report.numberOfPatients && ( -
- - Patients Benefiting: - {report.numberOfPatients.toLocaleString()} - (Estimated global impact) -
- )} -
-
-
-

References

- {report.referenceSources.map((source: Article, index: number) => ( - - ))} -
-
- ); -}; const App = () => { return ( diff --git a/app/dfda/components/MetaAnalysisReport.tsx b/app/dfda/components/MetaAnalysisReport.tsx new file mode 100644 index 00000000..8a2ddebd --- /dev/null +++ b/app/dfda/components/MetaAnalysisReport.tsx @@ -0,0 +1,256 @@ +"use client" +import {AlertCircle, Beer, CheckCircle, Cigarette, Droplet, HelpCircle, Pill, Users, Wind} from "lucide-react"; +import {Badge} from "@/components/ui/badge"; +import React, {useState} from "react"; +import {FaSkullCrossbones} from "react-icons/fa"; +import {Tooltip, TooltipContent, TooltipProvider, TooltipTrigger} from "@/components/ui/tooltip"; +import {Article, ExtendedMetaAnalysisReport} from "@/lib/agents/fdai/fdaiMetaAnalyzer"; +import {Card, CardContent, CardHeader, CardTitle} from "@/components/ui/card"; +import ArticleCard from "@/lib/agents/fdai/ArticleCard"; + +const SafetyRatingBadge = ({ rating }: { rating: 'Safe' | 'Moderate' | 'Low' | 'High' }) => { + const color = rating === 'Safe' ? 'bg-green-500' : + rating === 'Moderate' ? 'bg-yellow-500' : 'bg-red-500'; + const icon = rating === 'Safe' ? : + rating === 'Moderate' ? : + ; + + return ( + + {icon} {rating} + + ); +}; + +const ListSection = ({ title, items }: { title: string; items: string[] }) => ( +
+

{title}

+
    + {items.map((item: string, index: number) => ( +
  • {item}
  • + ))} +
+
+); + +const SafetyScoreBar = ({ score }: { score: number }) => { + const [openTooltip, setOpenTooltip] = useState(null); + + const getColor = (score: number) => { + if (score < 2) return 'bg-red-600'; + if (score < 4) return 'bg-orange-500'; + if (score < 6) return 'bg-yellow-400'; + if (score < 8) return 'bg-lime-500'; + return 'bg-green-600'; + }; + + const referencePoints = [ + { score: 0, label: 'Extremely unsafe (Draino)', icon: }, + { score: 2, label: 'Very unsafe (Cigarette)', icon: }, + { score: 4, label: 'Moderately unsafe (Beer)', icon: }, + { score: 6, label: 'Moderately safe (Aspirin)', icon: }, + { score: 8, label: 'Very safe (Water)', icon: }, + { score: 10, label: 'Extremely safe (Air)', icon: }, + ]; + + const handleTooltipClick = (index: number) => { + setOpenTooltip(openTooltip === index ? null : index); + }; + + return ( +
+
+
+
+ + Safety Score: {score.toFixed(1)}/10 + +
+
+
+ {referencePoints.map((point, index) => ( + + setOpenTooltip(open ? index : null)}> + +
handleTooltipClick(index)} + > + {point.icon} + + {point.label.split(' ').map((word, i) => ( + + {word} +
+
+ ))} +
+
+
+ +

{point.label}

+
+
+
+ ))} +
+
+
+
+ ); +}; + +const MetaAnalysisReport = ({ report }: { report: ExtendedMetaAnalysisReport }) => { + return ( +
+ + + {report.drugName} for {report.conditionName} +
+ +
+
+ +

Safety Summary: {report.shortSafetySummary}

+
+
+ + + + + + Safety Considerations + + + + + +
+

Long-term Safety

+

{report.longTermSafetyConsiderations}

+
+
+

Special Populations

+

Pregnancy: {report.pregnancySafety}

+

Children: {report.childrenSafety}

+
+
+
+ + + + Drug Interactions + + + {report.drugInteractions.map((interaction, index: number) => ( +
+ {interaction.drug}: {interaction.interaction} + +
+ ))} +
+
+ + + + Side Effects + + + {report.sideEffects.map((effect, index: number) => ( +
+ {effect.effect}: {effect.frequency} + {effect.severity && ` (Severity: ${effect.severity})`} +
+ ))} +
+
+ + + + Effectiveness Comparison + + + {report.effectivenessComparison.map((comparison, index: number) => ( +
+

{comparison.intervention}

+

Relative Effectiveness: {comparison.relativeEffectiveness}

+ {comparison.dalysAvoided &&

DALYs Avoided: {comparison.dalysAvoided.toFixed(2)}

} + {comparison.qalysIncreased &&

QALYs Increased: {comparison.qalysIncreased.toFixed(2)}

} + {comparison.numberNeededToHarm &&

Number Needed to Harm: {comparison.numberNeededToHarm}

} + {comparison.numberNeededToTreat &&

Number Needed to Treat: {comparison.numberNeededToTreat}

} +
+ ))} +
+
+ + + + By Making This Treatment Available + + + {report.dalysAvoided && ( +
+ + DALYs Avoided: + {report.dalysAvoided.toFixed(2)} +
+ Disability-Adjusted Life Years saved per patient if treated +
+
+ )} + {report.qalysIncreased && ( +
+ + QALYs Increased: + {report.qalysIncreased.toFixed(2)} + + Quality-Adjusted Life Years gained per patient if treated + +
+ )} + {report.numberNeededToHarm && ( +
+ + Number Needed to Harm: + {report.numberNeededToHarm} + + patients treated before one is harmed + +
+ )} + {report.numberNeededToTreat && ( +
+ + Number Needed to Treat: + {report.numberNeededToTreat} + (Patients treated for one to benefit) +
+ )} + {report.numberOfPatients && ( +
+ + Patients Benefiting: + {report.numberOfPatients.toLocaleString()} + (Estimated global impact) +
+ )} +
+
+
+

References

+ {report.referenceSources.map((source: Article, index: number) => ( + + ))} +
+
+ ); +}; + +export default MetaAnalysisReport; \ No newline at end of file