Add QR code scanning functionality with new QRScanner component

- Introduced a new QRScanner component to facilitate QR code scanning within the application.
- Integrated QR code scanning capabilities into the SendDialog.vue, allowing users to scan QR codes for payment destinations.
- Updated package.json and package-lock.json to include the qr-scanner library for QR code processing.
- Enhanced user experience by providing visual feedback and error handling during the scanning process.

These changes improve the payment workflow by enabling users to easily scan QR codes for transactions.
This commit is contained in:
padreug 2025-09-18 22:14:22 +02:00
parent c849258b5f
commit bebdc3c24c
5 changed files with 317 additions and 4 deletions

View file

@ -1,5 +1,5 @@
<script setup lang="ts">
import { computed } from 'vue'
import { computed, ref } from 'vue'
import { useForm } from 'vee-validate'
import { toTypedSchema } from '@vee-validate/zod'
import * as z from 'zod'
@ -8,8 +8,9 @@ import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } f
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Textarea } from '@/components/ui/textarea'
import { Send, AlertCircle, Loader2 } from 'lucide-vue-next'
import { Send, AlertCircle, Loader2, ScanLine } from 'lucide-vue-next'
import { FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form'
import QRScanner from '@/components/ui/qr-scanner.vue'
interface Props {
open: boolean
@ -43,11 +44,12 @@ const form = useForm({
}
})
const { resetForm, values, meta } = form
const { resetForm, values, meta, setFieldValue } = form
const isFormValid = computed(() => meta.value.valid)
// State
const isSending = computed(() => walletService?.isSendingPayment?.value || false)
const showScanner = ref(false)
const error = computed(() => walletService?.error?.value)
// Methods
@ -71,6 +73,23 @@ const onSubmit = form.handleSubmit(async (formValues) => {
function closeDialog() {
emit('update:open', false)
resetForm()
showScanner.value = false
}
// QR Scanner functions
function openScanner() {
showScanner.value = true
}
function closeScanner() {
showScanner.value = false
}
function handleScanResult(result: string) {
// Set the scanned result in the destination field
setFieldValue('destination', result)
closeScanner()
toastService?.success('QR code scanned successfully!')
}
// Determine destination type helper text
@ -103,7 +122,19 @@ const destinationType = computed(() => {
<form @submit="onSubmit" class="space-y-4">
<FormField v-slot="{ componentField }" name="destination">
<FormItem>
<FormLabel>Destination *</FormLabel>
<div class="flex items-center justify-between">
<FormLabel>Destination *</FormLabel>
<Button
type="button"
variant="outline"
size="sm"
@click="openScanner"
class="h-7 px-2 text-xs"
>
<ScanLine class="w-3 h-3 mr-1" />
Scan QR
</Button>
</div>
<FormControl>
<Textarea
placeholder="Lightning invoice, LNURL, or Lightning address (user@domain.com)"
@ -170,4 +201,24 @@ const destinationType = computed(() => {
</form>
</DialogContent>
</Dialog>
<!-- QR Scanner Dialog -->
<Dialog :open="showScanner" @update:open="showScanner = $event">
<DialogContent class="sm:max-w-lg">
<DialogHeader>
<DialogTitle class="flex items-center gap-2">
<ScanLine class="h-5 w-5" />
Scan QR Code
</DialogTitle>
<DialogDescription>
Point your camera at a Lightning invoice QR code
</DialogDescription>
</DialogHeader>
<QRScanner
@result="handleScanResult"
@close="closeScanner"
/>
</DialogContent>
</Dialog>
</template>