diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index f4ec8bc8..dd87955b 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -230,6 +230,17 @@ "companyName": "اسم الشركة:", "receiptOn": "الإيصال على:", "expiryDate": "تاريخ الانتهاء:", + "myCards": "بطاقاتي", + "savedCards": "البطاقات المحفوظة", + "addNewCard": "إضافة بطاقة جديدة", + "noSavedCards": "لا توجد بطاقات محفوظة", + "cardEndingWith": "البطاقة المنتهية بـ", + "expiry": "الصلاحية", + "defaultCard": "افتراضي", + "deleteCard": "حذف البطاقة؟", + "deleteCardConfirmation": "هل أنت متأكد من حذف هذه البطاقة المنتهية بـ", + "cardDeletedSuccessfully": "تم حذف البطاقة بنجاح", + "addCardComingSoon": "وظيفة إضافة البطاقة قريباً", "expiryPoints": "منتهي الصلاحية", "expiryOn": "ينتهي في:", "procedureName": "اسم الإجراء:", @@ -1895,5 +1906,7 @@ "referenceNo": "رقم المرجع", "advanceNumber": "رقم الدفعة المقدمة", "amountOnly": "المبلغ", - "invoiceHistory": "سجل الفواتير" + "invoiceHistory": "سجل الفواتير", + "thisInvoiceIsNotEligibleForRefund": "هذه الفاتورة غير مؤهلة للاسترداد", + "refund": "استرداد" } diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 047da473..ce4f869a 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -227,6 +227,17 @@ "companyName": "Company Name:", "receiptOn": "Receipt on:", "expiryDate": "Expiry Date:", + "myCards": "My Cards", + "savedCards": "Saved Cards", + "addNewCard": "Add New Card", + "noSavedCards": "No saved cards", + "cardEndingWith": "Card ending with", + "expiry": "Expiry", + "defaultCard": "Default", + "deleteCard": "Delete Card?", + "deleteCardConfirmation": "Are you sure you want to delete this card ending in", + "cardDeletedSuccessfully": "Card deleted successfully", + "addCardComingSoon": "Add card functionality coming soon", "expiryPoints": "Expired", "expiryOn": "Expiry on:", "procedureName": "Procedure Name:", diff --git a/lib/core/utils/utils.dart b/lib/core/utils/utils.dart index 6ab5865a..35532d69 100644 --- a/lib/core/utils/utils.dart +++ b/lib/core/utils/utils.dart @@ -1154,4 +1154,30 @@ class Utils { } return result; } + + /// Normalize Arabic text for search by handling Hamza variations and removing diacritics + /// This makes searching more flexible for Arabic text + static String normalizeArabicText(String text) { + if (text.isEmpty) return text; + + String normalized = text; + + // Normalize Hamza variations to a single character 'ا' + normalized = normalized.replaceAll('أ', 'ا'); // Hamza on Alif + normalized = normalized.replaceAll('إ', 'ا'); // Hamza below Alif + normalized = normalized.replaceAll('آ', 'ا'); // Madda on Alif + normalized = normalized.replaceAll('ء', 'ا'); // Hamza alone + normalized = normalized.replaceAll('ؤ', 'و'); // Hamza on Waw + normalized = normalized.replaceAll('ئ', 'ي'); // Hamza on Ya + + // Normalize Alif Maqsura to Ya + normalized = normalized.replaceAll('ى', 'ي'); + + // Remove Arabic diacritics (Tashkeel) + normalized = normalized.replaceAll(RegExp(r'[\u064B-\u065F]'), ''); // Fatha, Damma, Kasra, etc. + normalized = normalized.replaceAll(RegExp(r'[\u0670]'), ''); // Superscript Alif + normalized = normalized.replaceAll(RegExp(r'[\u0640]'), ''); // Tatweel + + return normalized; + } } diff --git a/lib/features/book_appointments/book_appointments_view_model.dart b/lib/features/book_appointments/book_appointments_view_model.dart index 890ef76d..200b51de 100644 --- a/lib/features/book_appointments/book_appointments_view_model.dart +++ b/lib/features/book_appointments/book_appointments_view_model.dart @@ -372,7 +372,15 @@ class BookAppointmentsViewModel extends ChangeNotifier { _filteredClinicsList = List.from(clinicsList); showSortFilterButtons = false; } else { - _filteredClinicsList = clinicsList.where((clinic) => clinic.clinicDescription?.toLowerCase().contains(query!.toLowerCase()) ?? false).toList(); + // Normalize the search query for better Arabic text matching + String normalizedQuery = Utils.normalizeArabicText(query.toLowerCase()); + + _filteredClinicsList = clinicsList.where((clinic) { + String clinicName = clinic.clinicDescription?.toLowerCase() ?? ''; + String normalizedClinicName = Utils.normalizeArabicText(clinicName); + return normalizedClinicName.contains(normalizedQuery); + }).toList(); + showSortFilterButtons = query.length >= 3; } notifyListeners(); diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 821c419f..a588a98d 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -231,6 +231,17 @@ abstract class LocaleKeys { static const companyName = 'companyName'; static const receiptOn = 'receiptOn'; static const expiryDate = 'expiryDate'; + static const myCards = 'myCards'; + static const savedCards = 'savedCards'; + static const addNewCard = 'addNewCard'; + static const noSavedCards = 'noSavedCards'; + static const cardEndingWith = 'cardEndingWith'; + static const expiry = 'expiry'; + static const defaultCard = 'defaultCard'; + static const deleteCard = 'deleteCard'; + static const deleteCardConfirmation = 'deleteCardConfirmation'; + static const cardDeletedSuccessfully = 'cardDeletedSuccessfully'; + static const addCardComingSoon = 'addCardComingSoon'; static const expiryPoints = 'expiryPoints'; static const expiryOn = 'expiryOn'; static const procedureName = 'procedureName';