Files
web-antrean/components/checkin/QRScanTab.vue
T
2026-01-05 08:32:59 +07:00

219 lines
6.3 KiB
Vue

<script setup lang="ts">
const props = defineProps<{
isScanning: boolean;
hasCamera: boolean;
cameraChecking: boolean;
cameraReady: boolean;
primaryColor: string;
}>();
const emit = defineEmits<{
'start-scanning': [];
'stop-scanning': [];
'test-camera': [];
'open-history': [];
'open-qr-history': [];
}>();
const handleStartScanning = () => {
emit('start-scanning');
};
const handleStopScanning = () => {
emit('stop-scanning');
};
const handleTestCamera = () => {
emit('test-camera');
};
const handleOpenHistory = () => {
emit('open-history');
};
const handleOpenQRHistory = () => {
emit('open-qr-history');
};
</script>
<template>
<div class="tab-content">
<!-- Status Header -->
<div class="status-header mb-3">
<div class="status-icon-wrapper">
<v-icon :color="primaryColor" size="24">mdi-qrcode-scan</v-icon>
</div>
<div class="status-text">
<h3 class="status-title">
{{ isScanning ? 'Arahkan Kamera ke QR Code' : 'Siap untuk Scan QR Code' }}
</h3>
<p class="status-subtitle">
{{ isScanning ? 'Pastikan QR code terlihat jelas dan tidak terpotong' : 'Klik tombol di bawah untuk memulai scan' }}
</p>
</div>
</div>
<!-- Camera Status Check -->
<div v-if="cameraChecking" class="text-center mb-4">
<v-progress-circular
indeterminate
:color="primaryColor"
size="24"
class="mr-2"
></v-progress-circular>
<span class="text-body-2 text-grey">Memeriksa ketersediaan kamera...</span>
</div>
<!-- Camera Not Available Warning -->
<v-alert
v-else-if="!hasCamera && !isScanning"
type="warning"
variant="tonal"
class="mb-4"
>
<template #prepend>
<v-icon>mdi-camera-off</v-icon>
</template>
<div>
<p class="font-weight-bold mb-1">Kamera tidak terdeteksi</p>
<p class="text-body-2 mb-0">
Perangkat Anda tidak memiliki kamera atau kamera tidak dapat diakses.
Silakan gunakan tab <strong>Manual</strong> untuk input data secara manual.
</p>
</div>
</v-alert>
<!-- QR Scanner Area dengan webcam -->
<div class="qr-scanner-container mb-4">
<div v-if="!isScanning" class="qr-placeholder">
<div class="scanner-overlay">
<div class="corner corner-tl"></div>
<div class="corner corner-tr"></div>
<div class="corner corner-bl"></div>
<div class="corner corner-br"></div>
<div class="scan-line"></div>
</div>
<v-icon size="64" :color="primaryColor" class="qr-icon">mdi-qrcode-scan</v-icon>
</div>
<div v-else class="qr-reader-container">
<div class="scanner-status mb-2">
<v-chip color="success" size="small" class="mr-2">
<v-icon start size="16">mdi-camera</v-icon>
Kamera Aktif
</v-chip>
<span class="text-caption text-grey">Preview kamera sedang berjalan</span>
</div>
<div id="qr-reader" class="qr-reader-wrapper">
<div v-if="!cameraReady" class="scanner-loading-overlay">
<v-progress-circular
indeterminate
color="white"
size="48"
></v-progress-circular>
<p class="text-white mt-4">Memuat kamera...</p>
</div>
</div>
<div class="scanner-instruction">
<v-icon :color="primaryColor" size="20" class="mr-2">mdi-information</v-icon>
<span class="text-body-2">Arahkan kamera ke QR code. Pastikan QR code berada dalam kotak pemindaian.</span>
</div>
</div>
</div>
<!-- Action Button Minimalis -->
<div class="action-buttons">
<v-btn
v-if="!isScanning"
class="btn-primary-modern btn-centered"
size="large"
elevation="0"
@click="handleStartScanning"
:disabled="!hasCamera && !cameraChecking"
>
<v-icon start size="20">mdi-camera</v-icon>
{{ hasCamera ? 'Mulai Scan QR' : 'Kamera Tidak Tersedia' }}
</v-btn>
<v-btn
v-else
class="btn-stop-modern btn-centered"
size="large"
elevation="0"
@click="handleStopScanning"
>
<v-icon start size="20">mdi-camera-off</v-icon>
Stop Scan
</v-btn>
</div>
<!-- Info tambahan -->
<div class="info-card mt-3">
<v-alert
type="info"
variant="tonal"
:color="primaryColor"
class="text-body-2 info-alert-centered"
density="compact"
>
<div class="d-flex align-center justify-center">
<v-icon size="16" class="mr-2">mdi-lightbulb-outline</v-icon>
<span style="font-size: 12px;">Tips: Pastikan pencahayaan cukup untuk hasil scan optimal</span>
</div>
</v-alert>
</div>
<!-- Test Camera Button (Debug) -->
<div class="test-camera-section mt-2 mb-2">
<v-btn
variant="outlined"
color="primary"
size="small"
class="text-none btn-centered-small btn-test-camera"
@click="handleTestCamera"
>
<v-icon start size="18" color="#1565C0">mdi-camera</v-icon>
Test Kamera
</v-btn>
<p class="text-caption text-grey text-center mt-1" style="font-size: 11px;">
Klik untuk menguji apakah browser dapat mengakses kamera
</p>
</div>
<!-- Quick Access Buttons -->
<div class="quick-actions mt-4">
<p class="text-caption text-grey text-center mb-3">Akses Cepat</p>
<v-row dense>
<v-col cols="12">
<v-btn
variant="outlined"
:color="primaryColor"
block
size="small"
class="text-none"
@click="handleOpenHistory"
>
<v-icon start size="18">mdi-history</v-icon>
Riwayat Check-in
</v-btn>
</v-col>
<v-col cols="12">
<v-btn
variant="outlined"
color="primary"
block
size="small"
class="text-none"
@click="handleOpenQRHistory"
>
<v-icon start size="18" color="#1565C0">mdi-qrcode-scan</v-icon>
Riwayat QR Scan
</v-btn>
</v-col>
</v-row>
</div>
</div>
</template>
<style scoped lang="scss">
@import '~/assets/scss/checkin/components';
</style>