Kasir/resources/js/components/NiimbotConnector.vue
Baghaztra 8665584567 [Update] print label
Library niimblue tidak digunakan, namun potongan kode tetap disimpan
2025-10-15 14:33:47 +07:00

190 lines
6.3 KiB
Vue

<!-- Komponen ini digunakan jika menggunakan library @mmote/niimbluelib -->
<template>
<div v-if="show" class="fixed inset-0 bg-black/75 flex items-center justify-center p-4 z-50 backdrop-blur-sm">
<div class="bg-white rounded-xl shadow-lg max-w-md w-full p-6 relative transform transition-all duration-300">
<!-- Header -->
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-bold text-D">
<i class="fas fa-print mr-2"></i>
Koneksi Printer Niimbot
</h3>
<button @click="$emit('close')" class="text-gray-400 hover:text-gray-600">
<i class="fas fa-times"></i>
</button>
</div>
<!-- Connection Status -->
<div class="mb-4">
<div v-if="isConnected" class="flex items-center justify-between p-3 bg-green-50 border border-green-200 rounded-lg">
<div class="flex items-center gap-2">
<div class="w-3 h-3 bg-green-500 rounded-full animate-pulse"></div>
<div>
<div class="font-medium text-green-900">Terhubung</div>
<div class="text-sm text-green-700">{{ connectedPrinterName }}</div>
</div>
</div>
<button @click="handleDisconnect" class="px-3 py-1 bg-red-500 text-white rounded hover:bg-red-600 transition text-sm">
<i class="fas fa-power-off mr-1"></i>
Putus
</button>
</div>
<div v-else-if="connectionState === 'connecting'" class="flex items-center gap-2 p-3 bg-blue-50 border border-blue-200 rounded-lg">
<div class="animate-spin rounded-full h-5 w-5 border-b-2 border-blue-600"></div>
<span class="text-blue-900">Menghubungkan...</span>
</div>
<div v-else class="p-3 bg-gray-50 border border-gray-200 rounded-lg">
<div class="text-gray-600 text-sm mb-2">Status: Tidak terhubung</div>
<!-- Connection Type Selector -->
<div class="flex gap-2 mb-3">
<button
v-if="featureSupport.webBluetooth"
@click="connectionType = 'bluetooth'"
:class="[
'flex-1 px-3 py-2 rounded border transition text-sm',
connectionType === 'bluetooth'
? 'bg-D text-white border-D'
: 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'
]">
<i class="fab fa-bluetooth-b mr-1"></i>
Bluetooth
</button>
<button
v-if="featureSupport.webSerial"
@click="connectionType = 'serial'"
:class="[
'flex-1 px-3 py-2 rounded border transition text-sm',
connectionType === 'serial'
? 'bg-D text-white border-D'
: 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'
]">
<i class="fas fa-usb mr-1"></i>
USB
</button>
</div>
<!-- Connect Button -->
<button
@click="handleConnect"
:disabled="!canConnect"
:class="[
'w-full px-4 py-2 rounded transition flex items-center justify-center',
canConnect
? 'bg-D text-white hover:bg-D/80'
: 'bg-gray-300 text-gray-500 cursor-not-allowed'
]">
<i class="fas fa-power mr-2"></i>
Hubungkan Printer
</button>
<div v-if="!canConnect" class="text-xs text-red-500 mt-2 text-center">
Browser Anda tidak mendukung koneksi printer
</div>
</div>
</div>
<!-- Printer Info (when connected) -->
<div v-if="isConnected && printerInfo" class="mb-4">
<button
@click="showDetails = !showDetails"
class="w-full flex items-center justify-between p-2 bg-gray-50 rounded hover:bg-gray-100 transition">
<span class="text-sm font-medium text-D">Detail Printer</span>
<i :class="['fas transition-transform', showDetails ? 'fa-chevron-up' : 'fa-chevron-down']"></i>
</button>
<div v-if="showDetails" class="mt-2 p-3 bg-gray-50 rounded text-sm">
<div v-for="(value, key) in printerInfo" :key="key" class="flex justify-between py-1">
<span class="text-gray-600">{{ key }}:</span>
<span class="font-medium text-D">{{ value || '-' }}</span>
</div>
</div>
</div>
<!-- Error Display -->
<div v-if="error" class="mb-4 p-3 bg-red-50 border border-red-200 rounded text-sm text-red-700">
<i class="fas fa-exclamation-triangle mr-2"></i>
{{ error }}
</div>
<!-- Help Text -->
<div class="text-xs text-gray-500 p-3 bg-gray-50 rounded">
<i class="fas fa-info-circle mr-1"></i>
<strong>Tips:</strong> Pastikan printer Niimbot sudah dihidupkan dan mode pairing aktif (untuk Bluetooth) atau terhubung via USB.
</div>
</div>
</div>
</template>
<script setup>
import { ref, computed, watch } from 'vue';
import { useNiimbotPrinter } from '../composables/useNiimbotPrinter';
const props = defineProps({
show: {
type: Boolean,
default: false
}
});
const emit = defineEmits(['close', 'connected', 'disconnected']);
// Use Niimbot composable
const {
connectionState,
connectedPrinterName,
printerInfo,
printerMeta,
isConnected,
isDisconnected,
featureSupport,
connectionType,
initClient,
connect,
disconnect,
} = useNiimbotPrinter();
// Local state
const error = ref('');
const showDetails = ref(false);
// Computed
const canConnect = computed(() => {
return featureSupport.value.webBluetooth || featureSupport.value.webSerial;
});
// Methods
const handleConnect = async () => {
error.value = '';
try {
await connect();
emit('connected');
} catch (err) {
console.error('Connection error:', err);
error.value = err.message || 'Gagal terhubung ke printer. Pastikan printer sudah dinyalakan dan dalam mode pairing.';
}
};
const handleDisconnect = () => {
disconnect();
emit('disconnected');
error.value = '';
};
// Watch connection state changes
watch(isConnected, (newVal) => {
if (newVal) {
error.value = '';
}
});
</script>
<style scoped>
@keyframes fadeIn {
from { opacity: 0; transform: scale(0.95); }
to { opacity: 1; transform: scale(1); }
}
</style>