Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import React, { useState, useCallback } from 'react';
- import { Upload, File, AlertCircle, CheckCircle, Download } from 'lucide-react';
- import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
- // Simple ID generator
- const generateId = () => Math.random().toString(36).substr(2, 9);
- const MedicalFormValidator = () => {
- const [files, setFiles] = useState([]);
- const [validationResults, setValidationResults] = useState([]);
- const [isProcessing, setIsProcessing] = useState(false);
- const [error, setError] = useState(null);
- const [progress, setProgress] = useState(0);
- // File handling functions
- const handleFileDrop = useCallback((e) => {
- e.preventDefault();
- e.stopPropagation();
- const droppedFiles = Array.from(e.dataTransfer?.files || [])
- .filter(file => file.type === 'application/pdf');
- setFiles(prevFiles => [...prevFiles, ...droppedFiles]);
- }, []);
- const handleFileSelect = useCallback((e) => {
- const selectedFiles = Array.from(e.target.files || [])
- .filter(file => file.type === 'application/pdf');
- setFiles(prevFiles => [...prevFiles, ...selectedFiles]);
- }, []);
- // Mock validation function - replace with actual PDF processing
- const validateForms = async () => {
- setIsProcessing(true);
- setError(null);
- setProgress(0);
- try {
- const results = [];
- for (let i = 0; i < files.length; i++) {
- const file = files[i];
- setProgress((i / files.length) * 100);
- // Simulate processing time
- await new Promise(resolve => setTimeout(resolve, 1000));
- // Mock validation results
- const mockIssues = [
- {
- type: 'SIDE_MISMATCH',
- description: 'Left shoulder pain indicated but right shoulder treatment selected',
- page: 1,
- severity: 'high',
- suggestions: [
- 'Review side selection',
- 'Ensure treatment matches affected side'
- ]
- },
- {
- type: 'MISSING_TREATMENT',
- description: 'No treatment specified for indicated knee pain',
- page: 1,
- severity: 'medium',
- suggestions: [
- 'Add treatment plan',
- 'Remove if not relevant'
- ]
- }
- ];
- const report = generateReport(mockIssues);
- results.push({
- fileName: file.name,
- status: 'processed',
- issues: mockIssues,
- report
- });
- }
- setValidationResults(results);
- } catch (err) {
- setError('Error processing files: ' + err.message);
- } finally {
- setIsProcessing(false);
- setProgress(100);
- }
- };
- // Generate markdown report
- const generateReport = (issues) => {
- let report = '# Medical Form Validation Report\n\n';
- if (issues.length === 0) {
- report += '✅ No validation issues found\n';
- return report;
- }
- const groupedByType = {};
- issues.forEach(issue => {
- if (!groupedByType[issue.type]) {
- groupedByType[issue.type] = [];
- }
- groupedByType[issue.type].push(issue);
- });
- Object.entries(groupedByType).forEach(([type, typeIssues]) => {
- report += `## ${type}\n\n`;
- typeIssues.forEach(issue => {
- report += `- ${issue.description}\n`;
- if (issue.suggestions?.length) {
- report += ' Suggestions:\n';
- issue.suggestions.forEach(suggestion => {
- report += ` * ${suggestion}\n`;
- });
- }
- report += '\n';
- });
- });
- return report;
- };
- // Download report function
- const downloadReport = useCallback((result) => {
- const blob = new Blob([result.report], { type: 'text/markdown' });
- const url = URL.createObjectURL(blob);
- const a = document.createElement('a');
- a.href = url;
- a.download = `validation-report-${result.fileName}.md`;
- document.body.appendChild(a);
- a.click();
- document.body.removeChild(a);
- URL.revokeObjectURL(url);
- }, []);
- return (
- <div className="w-full max-w-4xl mx-auto p-6">
- <div className="mb-8">
- <h1 className="text-2xl font-bold mb-2">Medical Form Validator</h1>
- <p className="text-gray-600">
- Upload medical forms to validate consistency between marked body parts and treatments
- </p>
- </div>
- {/* File Upload Area */}
- <div
- className="border-2 border-dashed border-gray-300 rounded-lg p-8 mb-6 text-center"
- onDragOver={(e) => e.preventDefault()}
- onDrop={handleFileDrop}
- >
- <Upload className="mx-auto h-12 w-12 text-gray-400 mb-4" />
- <p className="mb-2">Drag and drop PDF files here, or</p>
- <label className="inline-block">
- <span className="bg-blue-500 text-white px-4 py-2 rounded cursor-pointer hover:bg-blue-600">
- Browse Files
- </span>
- <input
- type="file"
- className="hidden"
- multiple
- accept=".pdf"
- onChange={handleFileSelect}
- />
- </label>
- </div>
- {/* Progress Bar */}
- {isProcessing && (
- <div className="mb-6">
- <div className="w-full bg-gray-200 rounded-full h-2">
- <div
- className="bg-blue-600 h-2 rounded-full transition-all duration-300"
- style={{ width: `${progress}%` }}
- />
- </div>
- <p className="text-sm text-gray-600 mt-2">
- Processing files... {Math.round(progress)}%
- </p>
- </div>
- )}
- {/* File List */}
- {files.length > 0 && (
- <div className="mb-6">
- <h2 className="text-lg font-semibold mb-2">Selected Files</h2>
- <div className="space-y-2">
- {files.map((file, index) => (
- <div
- key={index}
- className="flex items-center p-3 bg-gray-50 rounded"
- >
- <File className="h-5 w-5 text-gray-500 mr-2" />
- <span className="flex-1">{file.name}</span>
- <span className="text-sm text-gray-500">
- {(file.size / 1024).toFixed(1)} KB
- </span>
- </div>
- ))}
- </div>
- <button
- className="mt-4 bg-green-500 text-white px-6 py-2 rounded hover:bg-green-600 disabled:opacity-50"
- onClick={validateForms}
- disabled={isProcessing}
- >
- {isProcessing ? 'Processing...' : 'Validate Forms'}
- </button>
- </div>
- )}
- {/* Error Display */}
- {error && (
- <Alert variant="destructive" className="mb-6">
- <AlertCircle className="h-4 w-4" />
- <AlertTitle>Error</AlertTitle>
- <AlertDescription>{error}</AlertDescription>
- </Alert>
- )}
- {/* Validation Results */}
- {validationResults.length > 0 && (
- <div className="space-y-4">
- <h2 className="text-lg font-semibold">Validation Results</h2>
- {validationResults.map((result, index) => (
- <div key={index} className="border rounded-lg p-4">
- <div className="flex items-center justify-between mb-2">
- <div className="flex items-center">
- <h3 className="text-lg font-medium">{result.fileName}</h3>
- {result.issues.length === 0 ? (
- <CheckCircle className="h-5 w-5 text-green-500 ml-2" />
- ) : (
- <AlertCircle className="h-5 w-5 text-red-500 ml-2" />
- )}
- </div>
- <button
- onClick={() => downloadReport(result)}
- className="flex items-center text-blue-500 hover:text-blue-600"
- >
- <Download className="h-4 w-4 mr-1" />
- Download Report
- </button>
- </div>
- {result.issues.length > 0 ? (
- <div className="space-y-2">
- {result.issues.map((issue, issueIndex) => (
- <div
- key={issueIndex}
- className="bg-red-50 border-l-4 border-red-500 p-3"
- >
- <p className="text-red-700">{issue.description}</p>
- <p className="text-sm text-red-600">
- Page {issue.page} - Severity: {issue.severity}
- </p>
- {issue.suggestions && (
- <ul className="mt-2 text-sm text-red-600">
- {issue.suggestions.map((suggestion, i) => (
- <li key={i}>• {suggestion}</li>
- ))}
- </ul>
- )}
- </div>
- ))}
- </div>
- ) : (
- <p className="text-green-600">No issues found</p>
- )}
- </div>
- ))}
- </div>
- )}
- </div>
- );
- };
- export default MedicalFormValidator;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement