Pathora / frontend /src /components /ReportModal.tsx
malavikapradeep2001's picture
Update
095c768
raw
history blame
8.18 kB
import { useState, useEffect } from 'react';
import { XIcon } from 'lucide-react';
// Static defaults for fields requested to be static. Change these constants to update the values shown.
const DEFAULT_PATIENT_ID = '41334';
const DEFAULT_PHYSICIAN = 'Rajesh Venugopal';
const DEFAULT_FACILITY = 'Multi-Lab Speciality';
interface ReportModalProps {
isOpen: boolean;
onClose: () => void;
onSubmit: (formData: FormData) => void;
analysisId: string;
analysisSummaryJson: string;
}
export interface ReportFormData {
patient_id: string;
exam_date: string;
metadata: {
physician: string;
facility: string;
clinical_history?: string;
};
notes?: string;
analysis_id: string;
}
export function ReportModal({ isOpen, onClose, onSubmit, analysisId, analysisSummaryJson }: ReportModalProps) {
const [formData, setFormData] = useState<ReportFormData>({
patient_id: DEFAULT_PATIENT_ID,
exam_date: new Date().toISOString().split('T')[0],
metadata: {
physician: DEFAULT_PHYSICIAN,
facility: DEFAULT_FACILITY,
clinical_history: '',
},
notes: '',
analysis_id: analysisId,
});
// Keep internal form state in sync when the parent passes a new analysisId
useEffect(() => {
setFormData(prev => ({ ...prev, analysis_id: analysisId }));
}, [analysisId]);
if (!isOpen) return null;
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
// Build FormData for FastAPI endpoint
const payload = new FormData();
payload.append("patient_id", formData.patient_id);
payload.append("exam_date", formData.exam_date);
payload.append("metadata", JSON.stringify(formData.metadata));
payload.append("notes", formData.notes || "");
payload.append("analysis_id", formData.analysis_id);
payload.append("analysis_summary", analysisSummaryJson);
// Pass the FormData object to the parent onSubmit
onSubmit(payload);
};
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
const { name, value } = e.target;
if (name.startsWith('metadata.')) {
const field = name.split('.')[1];
setFormData(prev => ({
...prev,
metadata: {
...prev.metadata,
[field]: value,
},
}));
} else {
setFormData(prev => ({
...prev,
[name]: value,
}));
}
};
return (
<div className="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-4">
<div className="bg-white rounded-lg shadow-xl max-w-2xl w-full max-h-[90vh] overflow-y-auto">
<div className="p-6 space-y-6">
<div className="flex items-center justify-between border-b pb-3">
<h2 className="text-2xl font-semibold text-gray-900">Generate Medical Report</h2>
<button
onClick={onClose}
className="text-gray-400 hover:text-gray-500"
>
<XIcon className="w-6 h-6" />
</button>
</div>
<form onSubmit={handleSubmit} className="space-y-6">
{/* Patient Information */}
<div className="space-y-4">
<h3 className="text-lg font-medium text-gray-900">Patient Information</h3>
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
<div>
<label htmlFor="patient_id" className="block text-sm font-medium text-gray-700">
Patient ID *
</label>
<input
required
type="text"
name="patient_id"
id="patient_id"
value={formData.patient_id}
onChange={handleChange}
readOnly
className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500"
/>
</div>
<div>
<label htmlFor="exam_date" className="block text-sm font-medium text-gray-700">
Exam Date *
</label>
<input
required
type="date"
name="exam_date"
id="exam_date"
value={formData.exam_date}
onChange={handleChange}
className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500"
/>
</div>
</div>
</div>
{/* Slide Metadata */}
<div className="space-y-4">
<h3 className="text-lg font-medium text-gray-900">Slide Metadata</h3>
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
<div>
<label htmlFor="metadata.physician" className="block text-sm font-medium text-gray-700">
Physician Name *
</label>
<input
required
type="text"
name="metadata.physician"
id="metadata.physician"
value={formData.metadata.physician}
onChange={handleChange}
readOnly
className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500"
/>
</div>
<div>
<label htmlFor="metadata.facility" className="block text-sm font-medium text-gray-700">
Facility *
</label>
<input
required
type="text"
name="metadata.facility"
id="metadata.facility"
value={formData.metadata.facility}
onChange={handleChange}
readOnly
className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500"
/>
</div>
<div>
<label htmlFor="metadata.clinical_history" className="block text-sm font-medium text-gray-700">
Clinical History
</label>
<input
type="text"
name="metadata.clinical_history"
id="metadata.clinical_history"
value={formData.metadata.clinical_history}
onChange={handleChange}
className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500"
/>
</div>
</div>
</div>
{/* Notes */}
<div className="space-y-4">
<h3 className="text-lg font-medium text-gray-900">Doctor's Notes</h3>
<textarea
name="notes"
id="notes"
rows={4}
value={formData.notes}
onChange={handleChange}
placeholder="Add any additional notes or observations..."
className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500"
/>
</div>
{/* Actions */}
<div className="flex items-center justify-end space-x-3 pt-4 border-t">
<button
type="button"
onClick={onClose}
className="px-4 py-2 text-sm font-medium text-gray-700 hover:text-gray-500"
>
Cancel
</button>
<button
type="submit"
className="px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
>
Generate Report
</button>
</div>
</form>
</div>
</div>
</div>
);
}