From b285158fecad8f529c9853e87d0189b56cddf079 Mon Sep 17 00:00:00 2001 From: Khalid Abdi Date: Sat, 18 Jul 2026 23:34:56 +0300 Subject: [PATCH] frontend: scan a patient's wallet code in Import from a patient app Adds a Scan button beside the wallet-number field in the import dialog, reusing the BarcodeScanner. A scanned QR or 2D barcode from the patient's wallet app drops the wallet number straight into the field. i18n added to all locales. Co-Authored-By: Claude Opus 4.8 --- .../patients/import-from-wallet-dialog.tsx | 46 +++++++++++++++---- frontend/lib/i18n/locales/ar/translation.json | 2 + frontend/lib/i18n/locales/de/translation.json | 2 + frontend/lib/i18n/locales/en/translation.json | 2 + frontend/lib/i18n/locales/fr/translation.json | 2 + frontend/lib/i18n/locales/so/translation.json | 2 + 6 files changed, 48 insertions(+), 8 deletions(-) diff --git a/frontend/components/patients/import-from-wallet-dialog.tsx b/frontend/components/patients/import-from-wallet-dialog.tsx index 56f287d..dec6b6b 100644 --- a/frontend/components/patients/import-from-wallet-dialog.tsx +++ b/frontend/components/patients/import-from-wallet-dialog.tsx @@ -1,11 +1,12 @@ "use client"; -import { Check, Loader2, QrCode, Smartphone, X } from "lucide-react"; +import { Check, Loader2, QrCode, ScanLine, Smartphone, X } from "lucide-react"; import { useEffect, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import QRCodeSvg from "react-qr-code"; import { PatientFormDialog } from "@/components/chat/patient-form-dialog"; +import { BarcodeScanner } from "@/components/scan/barcode-scanner"; import { Button } from "@/components/ui/button"; import { Dialog, @@ -63,6 +64,15 @@ export function ImportFromWalletDialog({ const { t } = useTranslation(); const [mode, setMode] = useState("number"); const [walletNumber, setWalletNumber] = useState(""); + const [scanOpen, setScanOpen] = useState(false); + + // Scanning the wallet code shown on the patient's phone (QR or 2D barcode) + // drops its wallet number straight into the field. + const handleScan = (value: string) => { + setScanOpen(false); + setMode("number"); + setWalletNumber(value.trim()); + }; const [temporary, setTemporary] = useState(false); const [durationHours, setDurationHours] = useState(24); const [phase, setPhase] = useState("form"); @@ -302,13 +312,25 @@ export function ImportFromWalletDialog({ {t("patients.importApp.walletLabel")} - setWalletNumber(e.target.value)} - placeholder={t("patients.importApp.walletPlaceholder")} - value={walletNumber} - /> +
+ setWalletNumber(e.target.value)} + placeholder={t("patients.importApp.walletPlaceholder")} + value={walletNumber} + /> + +
) : (

@@ -411,6 +433,14 @@ export function ImportFromWalletDialog({ patient={request.draft} /> ) : null} + + ); } diff --git a/frontend/lib/i18n/locales/ar/translation.json b/frontend/lib/i18n/locales/ar/translation.json index 44e668d..c25efcb 100644 --- a/frontend/lib/i18n/locales/ar/translation.json +++ b/frontend/lib/i18n/locales/ar/translation.json @@ -302,6 +302,8 @@ "qrCaption": "امسح هذا في تطبيق المريض", "generateQr": "عرض رمز QR", "walletLabel": "رقم محفظة المريض", + "scan": "امسح رمز المريض", + "scanHint": "امسح رمز QR أو الباركود الظاهر في تطبيق محفظة المريض.", "walletPlaceholder": "tmw_…", "tempLabel": "مشاركة مؤقتة", "tempHint": "يُحذف السجل تلقائيًا من هذه العيادة عند انتهاء فترة المشاركة.", diff --git a/frontend/lib/i18n/locales/de/translation.json b/frontend/lib/i18n/locales/de/translation.json index 18d662f..6b1ca81 100644 --- a/frontend/lib/i18n/locales/de/translation.json +++ b/frontend/lib/i18n/locales/de/translation.json @@ -298,6 +298,8 @@ "qrCaption": "Dies in der Patienten-App scannen", "generateQr": "QR-Code anzeigen", "walletLabel": "Patienten-Wallet-Nummer", + "scan": "Code des Patienten scannen", + "scanHint": "Scanne den QR- oder Barcode aus der Wallet-App des Patienten.", "walletPlaceholder": "tmw_…", "tempLabel": "Temporär teilen", "tempHint": "Die Akte wird automatisch aus dieser Klinik gelöscht, wenn das Freigabefenster endet.", diff --git a/frontend/lib/i18n/locales/en/translation.json b/frontend/lib/i18n/locales/en/translation.json index 16206c4..b249c82 100644 --- a/frontend/lib/i18n/locales/en/translation.json +++ b/frontend/lib/i18n/locales/en/translation.json @@ -298,6 +298,8 @@ "qrCaption": "Scan this in the patient app", "generateQr": "Show QR code", "walletLabel": "Patient wallet number", + "scan": "Scan patient's code", + "scanHint": "Scan the QR or barcode shown in the patient's wallet app.", "walletPlaceholder": "tmw_…", "tempLabel": "Share temporarily", "tempHint": "The record is automatically deleted from this clinic when the share window ends.", diff --git a/frontend/lib/i18n/locales/fr/translation.json b/frontend/lib/i18n/locales/fr/translation.json index 53c6830..7316aaf 100644 --- a/frontend/lib/i18n/locales/fr/translation.json +++ b/frontend/lib/i18n/locales/fr/translation.json @@ -298,6 +298,8 @@ "qrCaption": "Scannez ceci dans l'application patient", "generateQr": "Afficher le code QR", "walletLabel": "Numéro de portefeuille du patient", + "scan": "Scanner le code du patient", + "scanHint": "Scannez le QR code ou le code-barres affiché dans l'app portefeuille du patient.", "walletPlaceholder": "tmw_…", "tempLabel": "Partager temporairement", "tempHint": "Le dossier est automatiquement supprimé de cette clinique à la fin de la période de partage.", diff --git a/frontend/lib/i18n/locales/so/translation.json b/frontend/lib/i18n/locales/so/translation.json index bb1ef2d..a2cf8bb 100644 --- a/frontend/lib/i18n/locales/so/translation.json +++ b/frontend/lib/i18n/locales/so/translation.json @@ -298,6 +298,8 @@ "qrCaption": "Ku sawir tan app-ka bukaanka", "generateQr": "Tus koodhka QR", "walletLabel": "Lambarka wallet-ka bukaanka", + "scan": "Iskaan garee koodhka bukaanka", + "scanHint": "Iskaan garee koodhka QR ama barcode ee ka muuqda abka wallet-ka bukaanka.", "walletPlaceholder": "tmw_…", "tempLabel": "Wadaag si ku meel gaar ah", "tempHint": "Diiwaanka si toos ah ayaa looga tirtirayaa rugtan marka daaqadda wadaagista dhammaato.",