|
|
@@ -1,133 +0,0 @@
|
|
|
-import { Component, inject, OnInit } from '@angular/core';
|
|
|
-import { Capacitor } from '@capacitor/core';
|
|
|
-import { CapacitorBarcodeScanner } from '@capacitor/barcode-scanner';
|
|
|
-import { CommonModule } from '@angular/common';
|
|
|
-import { QRCodeComponent } from 'angularx-qrcode';
|
|
|
-import { AuthService } from '../services/auth.service';
|
|
|
-import { AuthResponse, IncomingMessage } from '../interfaces/interface';
|
|
|
-import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';
|
|
|
-import { SocketService } from '../services/socket.service';
|
|
|
-import { NativeBiometric } from '@capgo/capacitor-native-biometric'; // ✅ import
|
|
|
-
|
|
|
-@Component({
|
|
|
- standalone: true,
|
|
|
- selector: 'app-payment',
|
|
|
- imports: [CommonModule, QRCodeComponent, MatSnackBarModule],
|
|
|
- templateUrl: './payment.component.html',
|
|
|
- styleUrls: ['./payment.component.css']
|
|
|
-})
|
|
|
-export class PaymentComponent implements OnInit {
|
|
|
- private snackbar = inject(MatSnackBar);
|
|
|
- paymentList: { name: string, time: Date }[] = [];
|
|
|
- isMobile = false;
|
|
|
- qrData = '';
|
|
|
- loading = false;
|
|
|
- scannedResult = '';
|
|
|
- postResponse = '';
|
|
|
-
|
|
|
- constructor(private auth: AuthService, private socket: SocketService) {
|
|
|
- if (!this.isMobile) {
|
|
|
- this.socket.onMessage().subscribe((message: IncomingMessage) => {
|
|
|
- if (message.action === 'Payment') {
|
|
|
- this.paymentList.push({ name: message.name, time: message.time });
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- ngOnInit(): void {
|
|
|
- this.isMobile = Capacitor.getPlatform() !== 'web';
|
|
|
-
|
|
|
- if (!this.isMobile) {
|
|
|
- this.loading = true;
|
|
|
- this.auth.getServerUrl().subscribe({
|
|
|
- next: (url) => {
|
|
|
- this.qrData = JSON.stringify({ action: 'Payment', serverUrl: url });
|
|
|
- this.loading = false;
|
|
|
- },
|
|
|
- error: () => {
|
|
|
- this.loading = false;
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- async startScan() {
|
|
|
- this.loading = true;
|
|
|
-
|
|
|
- try {
|
|
|
- const result = await CapacitorBarcodeScanner.scanBarcode({ hint: 0 });
|
|
|
- this.loading = false;
|
|
|
-
|
|
|
- if (!result?.ScanResult) {
|
|
|
- this.scannedResult = 'No QR code found.';
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- this.scannedResult = result.ScanResult;
|
|
|
- console.log('[QR Scan Result]', this.scannedResult);
|
|
|
-
|
|
|
- let parsed: any;
|
|
|
- try {
|
|
|
- parsed = JSON.parse(this.scannedResult);
|
|
|
- } catch (err) {
|
|
|
- console.error('Invalid QR format:', err);
|
|
|
- this.postResponse = 'Invalid QR code format.';
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (!parsed?.action || !parsed?.serverUrl || parsed.action !== 'Payment') {
|
|
|
- this.postResponse = 'Missing or incorrect data in QR code.';
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- // ✅ Biometric check
|
|
|
- const available = await NativeBiometric.isAvailable();
|
|
|
- if (!available.isAvailable) {
|
|
|
- this.snackbar.open('Biometrics not available.', 'Close', { duration: 3000 });
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- const verified = await NativeBiometric.verifyIdentity({
|
|
|
- reason: 'Scan biometrics to confirm payment',
|
|
|
- title: 'Biometric Authentication',
|
|
|
- subtitle: 'Required for security',
|
|
|
- description: 'Use fingerprint or face to proceed'
|
|
|
- }).then(() => true).catch((err) => {
|
|
|
- console.warn('Biometric auth failed or cancelled', err);
|
|
|
- this.snackbar.open('Authentication cancelled.', 'Close', { duration: 3000 });
|
|
|
- return false;
|
|
|
- });
|
|
|
-
|
|
|
- if (!verified) return;
|
|
|
-
|
|
|
- // ✅ Proceed to POST
|
|
|
- const snackRef = this.snackbar.open('Submitting payment...', 'Dismiss', {
|
|
|
- duration: undefined,
|
|
|
- });
|
|
|
-
|
|
|
- this.loading = true;
|
|
|
- this.auth.reportPayment(parsed.serverUrl, verified).subscribe({
|
|
|
- next: (res: AuthResponse) => {
|
|
|
- console.log('[Payment Success]', res);
|
|
|
- this.postResponse = 'Payment submitted successfully!';
|
|
|
- this.snackbar.open('✅ Payment submitted!', 'Close', { duration: 3000 });
|
|
|
- snackRef.dismiss();
|
|
|
- this.loading = false;
|
|
|
- },
|
|
|
- error: (err) => {
|
|
|
- console.error('[Payment Error]', err);
|
|
|
- this.postResponse = 'Failed to submit payment.';
|
|
|
- this.snackbar.open('❌ Failed to submit payment.', 'Close', { duration: 3000 });
|
|
|
- snackRef.dismiss();
|
|
|
- this.loading = false;
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- } catch (error) {
|
|
|
- console.error('Scan failed', error);
|
|
|
- this.loading = false;
|
|
|
- this.scannedResult = 'Scan failed.';
|
|
|
- }
|
|
|
- }
|
|
|
-}
|