Dr-Swopt hace 2 días
padre
commit
91ccf07089

+ 0 - 8
ai-data-entry-ui/src/app/app.routes.ts

@@ -5,17 +5,9 @@ export const routes: Routes = [
     path: '', 
     loadComponent: () => import('./components/claims-dashboard/claims-dashboard.component').then(m => m.DashboardComponent) 
   },
-  { 
-    path: 'user-selection', 
-    loadComponent: () => import('./components/user-selection/user-selection.component').then(m => m.UserSelectionComponent) 
-  },
   { 
     path: 'new-claim', 
     loadComponent: () => import('./components/claim-form/claim-form.component').then(m => m.ClaimFormComponent) 
   },
-  { 
-    path: 'user-management', 
-    loadComponent: () => import('./components/user-management/user-management.component').then(m => m.UserManagementComponent) 
-  },
   { path: '**', redirectTo: '' }
 ];

+ 0 - 1
ai-data-entry-ui/src/app/components/claim-form/claim-form.component.html

@@ -15,7 +15,6 @@
             <span class="name">{{ currentUser.name }}</span>
             <span class="allowance">Allowance Remaining: RM {{ currentUser.medical_allowance | number:'1.2-2' }}</span>
          </div>
-         <button class="change-user" routerLink="/">Change</button>
       </div>
     </header>
 

+ 1 - 17
ai-data-entry-ui/src/app/components/claims-dashboard/claims-dashboard.component.html

@@ -8,21 +8,8 @@
     
     <nav>
       <a routerLink="/" class="nav-item active">Dashboard</a>
-      <a routerLink="/user-management" class="nav-item">
-        <lucide-icon [name]="UserCog" class="icon-small"></lucide-icon> Users
-      </a>
     </nav>
 
-    <div class="user-profile" *ngIf="currentUser">
-      <div class="avatar">{{ currentUser.name[0] }}</div>
-      <div class="info">
-        <span class="name">{{ currentUser.name }}</span>
-        <span class="dept">{{ currentUser.department }}</span>
-      </div>
-      <button class="logout-btn" (click)="logout()" title="Logout">
-        <lucide-icon [name]="LogOut" class="icon-small"></lucide-icon>
-      </button>
-    </div>
   </aside>
 
   <!-- Main Content -->
@@ -33,10 +20,7 @@
         <p>Monitor and audit medical expenditure across the organization</p>
       </div>
       <div class="quick-actions">
-        <button class="secondary-btn" routerLink="/user-management">
-          <lucide-icon [name]="UserCog" class="icon-small"></lucide-icon> Manage Employees
-        </button>
-        <button class="action-btn" routerLink="/user-selection">
+        <button class="action-btn" routerLink="/new-claim">
           <lucide-icon [name]="Plus" class="icon-small"></lucide-icon> File New Claim
         </button>
       </div>

+ 2 - 7
ai-data-entry-ui/src/app/components/claims-dashboard/claims-dashboard.component.ts

@@ -4,7 +4,7 @@ import { Router, RouterModule } from '@angular/router';
 import { ExtractionService } from '../../services/extraction.service';
 import { SessionService, User } from '../../services/session.service';
 import { ClaimRecord } from '../../services/extraction';
-import { LucideAngularModule, LogOut, Plus, UserCog, ExternalLink, X, FileText, Trash2 } from 'lucide-angular';
+import { LucideAngularModule, Plus, ExternalLink, X, FileText, Trash2 } from 'lucide-angular';
 
 @Component({
   selector: 'app-dashboard',
@@ -20,9 +20,7 @@ export class DashboardComponent implements OnInit {
   selectedClaim: ClaimRecord | null = null;
   totalClaimed = 0;
 
-  readonly LogOut = LogOut;
   readonly Plus = Plus;
-  readonly UserCog = UserCog;
   readonly ExternalLink = ExternalLink;
   readonly X = X;
   readonly FileText = FileText;
@@ -88,8 +86,5 @@ export class DashboardComponent implements OnInit {
     this.selectedClaim = null;
   }
 
-  logout(): void {
-    this.sessionService.logout();
-    this.router.navigate(['/']);
-  }
+  // logout method removed
 }

+ 0 - 174
ai-data-entry-ui/src/app/components/user-management/user-management.component.css

@@ -1,174 +0,0 @@
-.management-container {
-  padding: 2rem;
-  max-width: 1200px;
-  margin: 0 auto;
-  font-family: 'Inter', sans-serif;
-  color: var(--text-primary);
-  background-color: var(--bg-primary);
-  min-height: 100vh;
-}
-
-header {
-  margin-bottom: 2rem;
-}
-
-h1 {
-  font-size: 2.5rem;
-  margin-top: 1rem;
-  color: var(--text-primary);
-  font-weight: 800;
-}
-
-header p {
-  color: var(--text-secondary);
-}
-
-.management-grid {
-  display: grid;
-  grid-template-columns: 1fr 2fr;
-  gap: 2rem;
-}
-
-.card {
-  background: var(--bg-card);
-  border-radius: 16px;
-  padding: 2rem;
-  border: 1px solid var(--border-color);
-  box-shadow: var(--shadow-sm);
-}
-
-h2 {
-  font-size: 1.25rem;
-  margin-bottom: 1.5rem;
-  color: var(--text-primary);
-  font-weight: 700;
-}
-
-.form-field {
-  margin-bottom: 1.5rem;
-}
-
-.form-field label {
-  display: block;
-  margin-bottom: 0.5rem;
-  color: var(--text-secondary);
-  font-size: 0.9rem;
-  font-weight: 500;
-}
-
-input {
-  width: 100%;
-  padding: 0.75rem;
-  background: var(--bg-primary);
-  border: 1px solid var(--border-color);
-  border-radius: 8px;
-  color: var(--text-primary);
-}
-
-.submit-btn {
-  width: 100%;
-  background: linear-gradient(90deg, var(--accent-primary) 0%, var(--accent-secondary) 100%);
-  border: none;
-  padding: 1rem;
-  border-radius: 8px;
-  color: #fff;
-  font-weight: 600;
-  cursor: pointer;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  gap: 0.5rem;
-  box-shadow: var(--shadow-sm);
-}
-
-.user-list {
-  display: flex;
-  flex-direction: column;
-  gap: 1rem;
-}
-
-.user-item {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  background: var(--bg-primary);
-  padding: 1rem;
-  border-radius: 12px;
-  transition: all 0.2s;
-  border: 1px solid transparent;
-}
-
-.user-item:hover {
-  background: #fff;
-  border-color: var(--border-color);
-  box-shadow: var(--shadow-sm);
-}
-
-.user-info {
-  display: flex;
-  align-items: center;
-  gap: 1rem;
-}
-
-.user-avatar-small {
-  width: 40px;
-  height: 40px;
-  background: var(--accent-primary);
-  color: #fff;
-  border-radius: 50%;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  font-weight: bold;
-}
-
-.user-info h3 {
-  margin: 0;
-  font-size: 1rem;
-  color: var(--text-primary);
-}
-
-.user-info p {
-  margin: 0;
-  font-size: 0.8rem;
-  color: var(--text-secondary);
-}
-
-.user-balance {
-  text-align: right;
-  display: flex;
-  flex-direction: column;
-}
-
-.user-balance .label {
-  font-size: 0.75rem;
-  color: var(--text-secondary);
-}
-
-.user-balance .value {
-  font-weight: bold;
-  color: #166534;
-}
-
-.back-btn {
-  background: transparent;
-  border: none;
-  color: var(--accent-primary);
-  cursor: pointer;
-  display: flex;
-  align-items: center;
-  gap: 0.5rem;
-  padding: 0;
-  font-weight: 600;
-}
-
-.icon-small {
-  width: 18px;
-  height: 18px;
-}
-
-@media (max-width: 900px) {
-  .management-grid {
-    grid-template-columns: 1fr;
-  }
-}

+ 0 - 56
ai-data-entry-ui/src/app/components/user-management/user-management.component.html

@@ -1,56 +0,0 @@
-<div class="management-container">
-  <header>
-    <button class="back-btn" routerLink="/">
-      <lucide-icon [name]="ArrowLeft" class="icon-small"></lucide-icon> Back to Dashboard
-    </button>
-    <h1>User Management</h1>
-    <p>Manage employee medical allowances and profiles</p>
-  </header>
-
-  <div class="management-grid">
-    <!-- Creation Form -->
-    <div class="card form-card">
-      <h2>Add New Employee</h2>
-      <form [formGroup]="userForm" (ngSubmit)="onSubmit()">
-        <div class="form-field">
-          <label for="name">Full Name</label>
-          <input id="name" type="text" formControlName="name" placeholder="E.g. John Doe">
-        </div>
-        <div class="form-field">
-          <label for="department">Department</label>
-          <input id="department" type="text" formControlName="department" placeholder="E.g. Engineering">
-        </div>
-        <div class="form-field">
-          <label for="medical_allowance">Annual Allowance (MYR)</label>
-          <input id="medical_allowance" type="number" formControlName="medical_allowance">
-        </div>
-        <button type="submit" [disabled]="!userForm.valid || isLoading" class="submit-btn text-white">
-          <lucide-icon [name]="UserPlus" class="icon-small"></lucide-icon>
-          {{ isLoading ? 'Creating...' : 'Create Profile' }}
-        </button>
-      </form>
-    </div>
-
-    <!-- User List -->
-    <div class="card list-card">
-      <h2>Employee Directory</h2>
-      <div class="user-list">
-        <div *ngIf="isLoading && users.length === 0" class="loading">Loading directory...</div>
-        <div *ngFor="let user of users" class="user-item">
-          <div class="user-info">
-            <div class="user-avatar-small">{{ user.name[0] }}</div>
-            <div>
-              <h3>{{ user.name }}</h3>
-              <p>{{ user.department }}</p>
-            </div>
-          </div>
-          <div class="user-balance">
-            <span class="label">Balance</span>
-            <span class="value">RM {{ user.medical_allowance | number:'1.2-2' }}</span>
-          </div>
-        </div>
-        <div *ngIf="!isLoading && users.length === 0" class="empty-state">No employees registered yet.</div>
-      </div>
-    </div>
-  </div>
-</div>

+ 0 - 75
ai-data-entry-ui/src/app/components/user-management/user-management.component.ts

@@ -1,75 +0,0 @@
-import { Component, OnInit } from '@angular/core';
-import { CommonModule } from '@angular/common';
-import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
-import { Router, RouterModule } from '@angular/router';
-import { ExtractionService } from '../../services/extraction.service';
-import { UserAccount } from '../../services/extraction';
-import { LucideAngularModule, UserPlus, ArrowLeft, Trash2 } from 'lucide-angular';
-
-@Component({
-  selector: 'app-user-management',
-  standalone: true,
-  imports: [CommonModule, ReactiveFormsModule, RouterModule, LucideAngularModule],
-  templateUrl: './user-management.component.html',
-  styleUrls: ['./user-management.component.css']
-})
-export class UserManagementComponent implements OnInit {
-  userForm: FormGroup;
-  users: UserAccount[] = [];
-  isLoading = false;
-  readonly UserPlus = UserPlus;
-  readonly ArrowLeft = ArrowLeft;
-  readonly Trash2 = Trash2;
-
-  constructor(
-    private fb: FormBuilder,
-    private extractionService: ExtractionService,
-    private router: Router
-  ) {
-    this.userForm = this.fb.group({
-      name: ['', Validators.required],
-      department: ['', Validators.required],
-      medical_allowance: [1000, [Validators.required, Validators.min(0)]]
-    });
-  }
-
-  ngOnInit(): void {
-    this.loadUsers();
-  }
-
-  loadUsers(): void {
-    this.isLoading = true;
-    this.extractionService.getUsers().subscribe({
-      next: (data) => {
-        this.users = data;
-        this.isLoading = false;
-      },
-      error: (err) => {
-        console.error('Error loading users:', err);
-        this.isLoading = false;
-      }
-    });
-  }
-
-  onSubmit(): void {
-    if (this.userForm.invalid) return;
-
-    this.isLoading = true;
-    const newUser: UserAccount = {
-      id: Math.random().toString(36).substr(2, 9),
-      ...this.userForm.value
-    };
-
-    this.extractionService.createUser(newUser).subscribe({
-      next: () => {
-        this.loadUsers();
-        this.userForm.reset({ medical_allowance: 1000 });
-        this.isLoading = false;
-      },
-      error: (err) => {
-        console.error('Error creating user:', err);
-        this.isLoading = false;
-      }
-    });
-  }
-}

+ 0 - 83
ai-data-entry-ui/src/app/components/user-selection/user-selection.component.css

@@ -1,83 +0,0 @@
-.selection-container {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  justify-content: center;
-  min-height: 100vh;
-  background-color: var(--bg-primary);
-  color: var(--text-primary);
-  font-family: 'Inter', sans-serif;
-  text-align: center;
-  padding: 2rem;
-}
-
-h1 {
-  font-size: 2.5rem;
-  margin-bottom: 0.5rem;
-  color: var(--text-primary);
-  font-weight: 800;
-}
-
-p {
-  color: var(--text-secondary);
-  margin-bottom: 3rem;
-  font-size: 1.1rem;
-}
-
-.user-grid {
-  display: grid;
-  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
-  gap: 2rem;
-  max-width: 1000px;
-  width: 100%;
-}
-
-.user-card {
-  background: var(--bg-card);
-  border: 1px solid var(--border-color);
-  border-radius: 20px;
-  padding: 2.5rem;
-  cursor: pointer;
-  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
-  box-shadow: var(--shadow-sm);
-}
-
-.user-card:hover {
-  transform: translateY(-8px);
-  border-color: var(--accent-primary);
-  box-shadow: var(--shadow-md);
-}
-
-.user-avatar {
-  width: 80px;
-  height: 80px;
-  background: linear-gradient(135deg, var(--accent-primary) 0%, var(--accent-secondary) 100%);
-  border-radius: 50%;
-  margin: 0 auto 1.5rem;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  font-size: 2rem;
-  font-weight: bold;
-  color: #fff;
-  box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
-}
-
-.user-info h3 {
-  margin: 0;
-  font-size: 1.25rem;
-  color: var(--text-primary);
-  font-weight: 700;
-}
-
-.user-info p {
-  margin: 0.5rem 0 0;
-  font-size: 0.9rem;
-  color: var(--text-secondary);
-}
-
-@media (max-width: 768px) {
-  .user-grid {
-    grid-template-columns: 1fr;
-  }
-}

+ 0 - 27
ai-data-entry-ui/src/app/components/user-selection/user-selection.component.html

@@ -1,27 +0,0 @@
-<div class="selection-container">
-  <div class="glass-card">
-    <header>
-      <h1>Internal Claims Portal</h1>
-      <p>Select your profile to continue to the intelligence dashboard</p>
-    </header>
-
-    <div *ngIf="isLoading" class="loading-state">
-       <div class="spinner"></div>
-       <p>Fetching secure profiles...</p>
-    </div>
-
-    <div *ngIf="!isLoading" class="user-grid">
-      <div *ngFor="let user of users" class="user-card" (click)="selectUser(user)">
-        <div class="avatar">{{ user.name[0] }}</div>
-        <div class="info">
-          <span class="name">{{ user.name }}</span>
-          <span class="dept">{{ user.department }}</span>
-        </div>
-      </div>
-    </div>
-    
-    <div *ngIf="!isLoading && users.length === 0" class="empty-state">
-      <p>No profiles found. Database initialization required.</p>
-    </div>
-  </div>
-</div>

+ 0 - 53
ai-data-entry-ui/src/app/components/user-selection/user-selection.component.ts

@@ -1,53 +0,0 @@
-import { Component, OnInit } from '@angular/core';
-import { CommonModule } from '@angular/common';
-import { Router } from '@angular/router';
-import { SessionService, User } from '../../services/session.service';
-import { ExtractionService } from '../../services/extraction.service';
-import { UserAccount } from '../../services/extraction';
-
-@Component({
-  selector: 'app-user-selection',
-  standalone: true,
-  imports: [CommonModule],
-  templateUrl: './user-selection.component.html',
-  styleUrls: ['./user-selection.component.css']
-})
-export class UserSelectionComponent implements OnInit {
-  users: UserAccount[] = [];
-  isLoading = true;
-
-  constructor(
-    private sessionService: SessionService, 
-    private extractionService: ExtractionService,
-    private router: Router
-  ) {}
-
-  ngOnInit(): void {
-    this.loadUsers();
-  }
-
-  loadUsers(): void {
-    this.isLoading = true;
-    this.extractionService.getUsers().subscribe({
-      next: (data) => {
-        this.users = data;
-        this.isLoading = false;
-      },
-      error: (err) => {
-        console.error('Error loading users:', err);
-        this.isLoading = false;
-      }
-    });
-  }
-
-  selectUser(user: UserAccount): void {
-    const sessionUser: User = {
-      id: user.id,
-      name: user.name,
-      department: user.department,
-      medical_allowance: user.medical_allowance
-    };
-    this.sessionService.setCurrentUser(sessionUser);
-    this.router.navigate(['/new-claim']);
-  }
-}

+ 7 - 6
ai-data-entry-ui/src/app/services/session.service.ts

@@ -16,10 +16,12 @@ export class SessionService {
   currentUser$: Observable<User | null> = this.currentUserSubject.asObservable();
 
   constructor() {
-    const savedUser = localStorage.getItem('currentUser');
-    if (savedUser) {
-      this.currentUserSubject.next(JSON.parse(savedUser));
-    }
+    this.currentUserSubject.next({
+      id: 'demo-user-123',
+      name: 'Demo User',
+      department: 'Operations',
+      medical_allowance: 5000.0
+    });
   }
 
   setCurrentUser(user: User): void {
@@ -32,7 +34,6 @@ export class SessionService {
   }
 
   logout(): void {
-    localStorage.removeItem('currentUser');
-    this.currentUserSubject.next(null);
+    // No-op for demo
   }
 }

+ 10 - 3
backend/main.py

@@ -23,7 +23,14 @@ app.add_middleware(
 
 # In-memory database
 CLAIMS_DB: List[ClaimRecord] = []
-USERS_DB: List[UserAccount] = []
+USERS_DB: List[UserAccount] = [
+    UserAccount(
+        id="demo-user-123",
+        name="Demo User",
+        department="Operations",
+        medical_allowance=5000.0
+    )
+]
 
 @app.get("/health")
 async def health_check():
@@ -41,8 +48,8 @@ async def create_user(user: UserAccount):
 @app.post("/api/v1/extract", response_model=ExtractionResponse)
 async def extract_receipt(
     file: UploadFile = File(...),
-    user_name: str = Form("Unknown Employee"),
-    department: str = Form("Unknown Department")
+    user_name: str = Form("Demo User"),
+    department: str = Form("Operations")
 ):
     if not file.content_type.startswith("image/"):
         raise HTTPException(