diff --git a/frontend/src/main-page/grants/grant-details/CostBenefitAnalysis.tsx b/frontend/src/main-page/grants/grant-details/CostBenefitAnalysis.tsx new file mode 100644 index 0000000..d6569b3 --- /dev/null +++ b/frontend/src/main-page/grants/grant-details/CostBenefitAnalysis.tsx @@ -0,0 +1,137 @@ +import React, { useState } from 'react'; +import { Grant } from '../../../../../middle-layer/types/Grant'; +import '../styles/CostBenefitAnalysis.css'; + +interface CostBenefitAnalysisProps { + grant: Grant; +} + +export const CostBenefitAnalysis: React.FC = ({ grant }) => { + const [hourlyRate, setHourlyRate] = useState(''); + const [timePerReport, setTimePerReport] = useState(''); + const [netBenefit, setNetBenefit] = useState(null); + + const calculateNetBenefit = () => { + console.log('Called calculate') + console.log('hourlyRate state:', hourlyRate) + console.log('timePerReport state:', timePerReport) + const rate = parseFloat(hourlyRate); + const timeReport = parseFloat(timePerReport); + + console.log('Parsed rate:', rate) + console.log('Parsed timeReport:', timeReport) + + // Validation + if (isNaN(rate) || isNaN(timeReport) || rate <= 0 || timeReport <= 0) { + alert('Please enter valid positive numbers for hourly rate and time per report.'); + return; + } + + const reportCount = grant.report_deadlines?.length ?? 0; + const grantAmount = grant.amount; + const estimatedTime = grant.estimated_completion_time | 5; + + console.log('Grant values - Amount:', grantAmount, 'EstTime:', estimatedTime, 'ReportCount:', reportCount); + + // Formula: NetBenefit = GrantAmount - ((EstimatedCompletionTime + ReportCount * TimePerReport) * StaffHourlyRate) + const result = grantAmount - ((estimatedTime + reportCount * timeReport) * rate); + + console.log('Final result:', result); + + setNetBenefit(result); + }; + + const formatCurrency = (amount: number): string => { + return new Intl.NumberFormat('en-US', { + style: 'currency', + currency: 'USD', + maximumFractionDigits: 2 + }).format(amount); + }; + + return ( +
+ + +
+ {/* Hourly Rate Input */} +
+ + setHourlyRate(e.target.value)} + className="w-full h-[42px] px-3 py-4 border border-gray-400 rounded-md" + style={{ backgroundColor: '#F2EBE4' }} + /> +
+ + {/* Time Per Report Input */} +
+ + { + console.log('Time per report changed to:', e.target.value); + setTimePerReport(e.target.value); + }} + className="w-full h-[42px] px-3 py-4 border border-gray-400 rounded-md" + style={{ backgroundColor: '#F2EBE4' }} + /> +
+ + {/* Calculate Button */} + + + {/* Analysis Button - Shows the net benefit result */} +
+ Net Benefit: +
+ {netBenefit !== null ? formatCurrency(netBenefit) : 'Analysis'} +
+
+
+
+ ); +}; \ No newline at end of file diff --git a/frontend/src/main-page/grants/grant-list/GrantItem.tsx b/frontend/src/main-page/grants/grant-list/GrantItem.tsx index 3dfb5f7..3360955 100644 --- a/frontend/src/main-page/grants/grant-list/GrantItem.tsx +++ b/frontend/src/main-page/grants/grant-list/GrantItem.tsx @@ -9,6 +9,7 @@ import { api } from "../../../api"; import { MdOutlinePerson2 } from "react-icons/md"; import Attachment from "../../../../../middle-layer/types/Attachment"; import NewGrantModal from "../new-grant/NewGrantModal"; +import { CostBenefitAnalysis } from "../grant-details/CostBenefitAnalysis"; import ActionConfirmation from "../../../custom/ActionConfirmation"; import { observer } from "mobx-react-lite"; import { fetchGrants } from "../filter-bar/processGrantData"; @@ -331,7 +332,7 @@ const GrantItem: React.FC = observer( {/*Report deadlines div*/}
-
@@ -607,29 +609,37 @@ const GrantItem: React.FC = observer( {/*End two main left right columns */} - {/*Description*/} -
- -
- {curGrant.description} -
+ {/*Cost Benefit Analysis and Description Row*/} +
+ {/* Cost Benefit Analysis */} +
+ +
+ + {/*Description */} +
+ +
+ {curGrant.description}
+
+
{/*bottom buttons */} -
+
<>