React DropZone π€
The CardScanDropZone
component provides an alternative to camera-based scanning by offering a drag-and-drop file upload interface for insurance card processing. This component is perfect for desktop workflows where users have digital images of their insurance cards ready to upload.
Installation
$ npm i @cardscan.ai/insurance-cardscan-react
$ yarn add @cardscan.ai/insurance-cardscan-react
Usage
Import the component into your project:
import { CardScanDropZone } from "@cardscan.ai/insurance-cardscan-react";
Basic Example
import React from "react";
import { render } from "react-dom";
import { CardScanDropZone } from "@cardscan.ai/insurance-cardscan-react";
function onSuccess(card) {
console.log("Card processed successfully:", card);
}
function onError(error) {
console.error('Error occurred:', error);
}
// See Authentication on where to get this sessionToken
const sessionToken = 'JWT_TOKEN'
function App() {
return (
<div className="App">
<div className="DropZoneContainer">
<CardScanDropZone
live={false}
sessionToken={sessionToken}
onSuccess={onSuccess}
onError={onError}
enableBackside={true}
layout="side-by-side"
/>
</div>
</div>
);
}
const rootElement = document.getElementById('root');
render(<App />, rootElement);
Compatibility
Node Versions: 14, 16, 18
React Versions: >=17.0.2, 18.2.0+
Webpack Versions: 4.x, 5.x
Babel Versions: 6.x, 7.x
Peer Dependencies
React: >=17.0.2
React-DOM: >=17.0.2
react-dropzone: ^14.0.0
Configuration
Available Props
<CardScanDropZone
// Required
live={false}
sessionToken={token}
onSuccess={onSuccess}
// Recommended
onCancel={onCancel}
onError={onError}
onProgress={onProgress}
// Dropzone Options
enableBackside={true}
layout="side-by-side"
// UI Customization
messages={messages}
frontDropIndicator={frontDropIndicator}
backDropIndicator={backDropIndicator}
successIndicator={successIndicator}
errorIndicator={errorIndicator}
// Styling
widgetBackgroundColor="#ffffff"
primaryColor="#007bff"
progressBarColor="#28a745"
/>
Main Props
live
true
Boolean
Toggle production or sandbox version. Default: false
onSuccess
true
Function
Called on successful card processing. First argument is the processed card data.
onCancel
false
Function
Triggered when user cancels the upload process.
onError
false
Function
Called when an error occurs during upload or processing.
onProgress
false
Function
Progress updates during card processing.
enableBackside
false
Boolean
Enable uploading of both front and back card sides. Default: false
layout
false
String
Layout mode: "side-by-side"
or "sequential"
. Default: "side-by-side"
Layout Options
The layout
prop controls how the front and back upload zones are displayed:
Side-by-Side Layout
<CardScanDropZone
layout="side-by-side"
enableBackside={true}
// ... other props
/>
Both drop zones are visible simultaneously, allowing users to see both upload areas at once.
Sequential Layout
<CardScanDropZone
layout="sequential"
enableBackside={true}
// ... other props
/>
The back drop zone is hidden until the front card is successfully uploaded and processed.
File Requirements
The CardScanDropZone component enforces the following file requirements:
File Types: JPEG, PNG
File Size: Maximum 5MB per file
Image Quality: Clear, well-lit images for best OCR results
Upload Workflow
Front Card Upload: User drags and drops or clicks to select the front card image
File Validation: Component validates file type and size
Upload & Processing: File is uploaded via secure S3 direct upload and processed
Real-time Updates: WebSocket connection provides live processing status
Back Card (Optional): If
enableBackside
is true, back card upload becomes availableCompletion:
onSuccess
callback is triggered with complete card data
UI Customization
Custom Messages
const customMessages = {
frontDropTitle: "Upload Front of Insurance Card",
frontDropSubtitle: "Drag and drop or click to select",
backDropTitle: "Upload Back of Insurance Card",
backDropSubtitle: "Drag and drop or click to select",
frontProcessingTitle: "Processing Front Card...",
backProcessingTitle: "Processing Back Card...",
uploadingTitle: "Uploading...",
successTitle: "Upload Complete!",
errorTitle: "Upload Failed",
fileTooLargeError: "File size must be under 5MB",
invalidFileTypeError: "Please upload a JPEG or PNG file"
};
<CardScanDropZone
messages={customMessages}
// ... other props
/>
Custom Components
Replace default UI elements with your own React components:
const CustomFrontIndicator = () => (
<div className="custom-drop-indicator">
<h3>π Drop Front Card Here</h3>
</div>
);
const CustomSuccessIndicator = () => (
<div className="custom-success">
<h3>β
Card Processed Successfully!</h3>
</div>
);
<CardScanDropZone
frontDropIndicator={<CustomFrontIndicator />}
successIndicator={<CustomSuccessIndicator />}
// ... other props
/>
CSS Styling
The component supports CSS custom properties for easy theming:
.cardscan-dropzone {
--dropzone-bg-color: #f8f9fa;
--dropzone-border-color: #dee2e6;
--dropzone-text-color: #212529;
--dropzone-primary-color: #007bff;
--dropzone-success-color: #28a745;
--dropzone-error-color: #dc3545;
--dropzone-border-radius: 8px;
}
Or use the styling props:
<CardScanDropZone
widgetBackgroundColor="#ffffff"
primaryColor="#007bff"
progressBarColor="#28a745"
// ... other props
/>
State Management
The CardScanDropZone uses XState for robust state management with the following states:
Initial: Ready for front card upload
FrontUploading: Front card being uploaded
FrontProcessing: Front card being processed by ML pipeline
BackAvailable: Ready for back card upload (if enabled)
BackUploading: Back card being uploaded
BackProcessing: Back card being processed
Success: Both cards processed successfully
Error: Upload or processing failed
Callbacks
onSuccess Callback
const handleSuccess = (cardData) => {
console.log('Processed card data:', cardData);
// cardData contains extracted information from both front and back
};
<CardScanDropZone
onSuccess={handleSuccess}
// ... other props
/>
onError Callback
const handleError = (error) => {
console.error('Upload error:', error);
// Error object contains type, message, and code
};
<CardScanDropZone
onError={handleError}
// ... other props
/>
onProgress Callback
const handleProgress = (progress) => {
console.log(`Processing: ${progress.cardSide} - State: ${progress.state}`);
};
<CardScanDropZone
onProgress={handleProgress}
// ... other props
/>
Error Handling
The component handles various error scenarios:
FileTooLarge
File exceeds 5MB limit
Select a smaller file
InvalidFileType
File is not JPEG/PNG
Select a valid image file
UploadFailed
Network or server error
Try uploading again
ProcessingFailed
ML processing failed
Try with a clearer image
AuthenticationError
Invalid session token
Refresh authentication
Integration with CardScanView
The DropZone component can be used alongside the camera-based CardScanView:
const [uploadMethod, setUploadMethod] = useState('camera');
return (
<div>
<div className="method-selector">
<button onClick={() => setUploadMethod('camera')}>
πΈ Use Camera
</button>
<button onClick={() => setUploadMethod('upload')}>
π€ Upload Files
</button>
</div>
{uploadMethod === 'camera' ? (
<CardScanView
sessionToken={sessionToken}
onSuccess={onSuccess}
onError={onError}
/>
) : (
<CardScanDropZone
sessionToken={sessionToken}
onSuccess={onSuccess}
onError={onError}
enableBackside={true}
/>
)}
</div>
);
Best Practices
File Validation: Always handle file validation errors gracefully
User Feedback: Provide clear visual feedback during upload and processing
Error Recovery: Allow users to retry failed uploads easily
Accessibility: Ensure keyboard navigation and screen reader support
Mobile Considerations: Consider using CardScanView for mobile devices where camera access is preferred
Troubleshooting
Common Issues
Files not uploading:
Check session token validity
Verify file size is under 5MB
Ensure file format is JPEG or PNG
Processing takes too long:
Images with poor quality may require more processing time
Consider implementing a timeout mechanism
Styling not applying:
Ensure CSS custom properties have sufficient specificity
Check for conflicting styles from other components
Last updated
Was this helpful?