|
|
@@ -1,14 +1,16 @@
|
|
|
import { Component, OnInit } from '@angular/core';
|
|
|
import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
|
|
|
import { CommonModule } from '@angular/common';
|
|
|
-import { ExtractionService, ExtractionResponse } from '../../services/extraction.service';
|
|
|
-import { HttpClientModule } from '@angular/common/http';
|
|
|
-import { LucideAngularModule, ShieldCheck, AlertCircle } from 'lucide-angular';
|
|
|
+import { Router, RouterModule } from '@angular/router';
|
|
|
+import { ExtractionService } from '../../services/extraction.service';
|
|
|
+import { ExtractionResponse } from '../../services/extraction';
|
|
|
+import { LucideAngularModule, ShieldCheck, AlertCircle, CheckCircle, ArrowLeft } from 'lucide-angular';
|
|
|
+import { SessionService } from '../../services/session.service';
|
|
|
|
|
|
@Component({
|
|
|
selector: 'app-claim-form',
|
|
|
standalone: true,
|
|
|
- imports: [CommonModule, ReactiveFormsModule, LucideAngularModule],
|
|
|
+ imports: [CommonModule, ReactiveFormsModule, LucideAngularModule, RouterModule],
|
|
|
templateUrl: './claim-form.component.html',
|
|
|
styleUrls: ['./claim-form.component.css']
|
|
|
})
|
|
|
@@ -17,12 +19,19 @@ export class ClaimFormComponent implements OnInit {
|
|
|
previewUrl: string | null = null;
|
|
|
extractionResponse: ExtractionResponse | null = null;
|
|
|
isLoading = false;
|
|
|
+ isSubmitting = false;
|
|
|
+ isDragging = false;
|
|
|
readonly ShieldCheck = ShieldCheck;
|
|
|
readonly AlertCircle = AlertCircle;
|
|
|
+ readonly CheckCircle = CheckCircle;
|
|
|
+ readonly ArrowLeft = ArrowLeft;
|
|
|
+ errorMessage: string | null = null;
|
|
|
|
|
|
constructor(
|
|
|
private fb: FormBuilder,
|
|
|
- private extractionService: ExtractionService
|
|
|
+ private extractionService: ExtractionService,
|
|
|
+ private sessionService: SessionService,
|
|
|
+ private router: Router
|
|
|
) {
|
|
|
this.claimForm = this.fb.group({
|
|
|
provider_name: ['', Validators.required],
|
|
|
@@ -32,34 +41,97 @@ export class ClaimFormComponent implements OnInit {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- ngOnInit(): void {}
|
|
|
+ ngOnInit(): void {
|
|
|
+ const user = this.sessionService.getCurrentUser();
|
|
|
+ if (!user) {
|
|
|
+ this.router.navigate(['/']);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ onDragOver(event: DragEvent): void {
|
|
|
+ event.preventDefault();
|
|
|
+ event.stopPropagation();
|
|
|
+ this.isDragging = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ onDragLeave(event: DragEvent): void {
|
|
|
+ event.preventDefault();
|
|
|
+ event.stopPropagation();
|
|
|
+ this.isDragging = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ onDrop(event: DragEvent): void {
|
|
|
+ event.preventDefault();
|
|
|
+ event.stopPropagation();
|
|
|
+ this.isDragging = false;
|
|
|
+
|
|
|
+ const files = event.dataTransfer?.files;
|
|
|
+ if (files && files.length > 0) {
|
|
|
+ this.processFile(files[0]);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
onFileSelected(event: any): void {
|
|
|
const file: File = event.target.files[0];
|
|
|
if (file) {
|
|
|
- this.previewUrl = URL.createObjectURL(file);
|
|
|
- this.isLoading = true;
|
|
|
-
|
|
|
- this.extractionService.extractData(file).subscribe({
|
|
|
- next: (response) => {
|
|
|
- this.extractionResponse = response;
|
|
|
- this.claimForm.patchValue({
|
|
|
- provider_name: response.provider_name,
|
|
|
- visit_date: response.visit_date,
|
|
|
- total_amount: response.total_amount,
|
|
|
- currency: response.currency
|
|
|
- });
|
|
|
- this.isLoading = false;
|
|
|
- },
|
|
|
- error: (err) => {
|
|
|
- console.error('Extraction failed', err);
|
|
|
- this.isLoading = false;
|
|
|
- alert('Failed to extract data. Please try again.');
|
|
|
- }
|
|
|
- });
|
|
|
+ this.processFile(file);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private processFile(file: File): void {
|
|
|
+ this.previewUrl = URL.createObjectURL(file);
|
|
|
+ this.isLoading = true;
|
|
|
+ this.errorMessage = null;
|
|
|
+
|
|
|
+ const user = this.sessionService.getCurrentUser();
|
|
|
+
|
|
|
+ this.extractionService.extractData(file, user?.name, user?.department).subscribe({
|
|
|
+ next: (response) => {
|
|
|
+ this.extractionResponse = response;
|
|
|
+ this.claimForm.patchValue({
|
|
|
+ provider_name: response.provider_name,
|
|
|
+ visit_date: response.visit_date,
|
|
|
+ total_amount: response.total_amount,
|
|
|
+ currency: response.currency || 'MYR'
|
|
|
+ });
|
|
|
+ this.isLoading = false;
|
|
|
+ },
|
|
|
+ error: (err: Error) => {
|
|
|
+ console.error('Extraction failed', err);
|
|
|
+ this.errorMessage = err.message;
|
|
|
+ this.isLoading = false;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ onSubmit(): void {
|
|
|
+ if (this.claimForm.invalid) return;
|
|
|
+
|
|
|
+ const user = this.sessionService.getCurrentUser();
|
|
|
+ if (!user) return;
|
|
|
+
|
|
|
+ this.isSubmitting = true;
|
|
|
+ const formData = this.claimForm.value;
|
|
|
+
|
|
|
+ // Merge user-verified data with AI response metadata if needed
|
|
|
+ const submissionData: ExtractionResponse = {
|
|
|
+ ...this.extractionResponse!,
|
|
|
+ ...formData
|
|
|
+ };
|
|
|
+
|
|
|
+ this.extractionService.submitClaim(submissionData, user.name, user.department).subscribe({
|
|
|
+ next: () => {
|
|
|
+ this.isSubmitting = false;
|
|
|
+ this.router.navigate(['/dashboard']);
|
|
|
+ },
|
|
|
+ error: (err) => {
|
|
|
+ console.error('Submission failed', err);
|
|
|
+ this.errorMessage = 'Failed to submit claim. Please try again.';
|
|
|
+ this.isSubmitting = false;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
get confidenceScore(): number {
|
|
|
return this.extractionResponse?.confidence_score ?? 0;
|
|
|
}
|