From 64cbae3602a151a94a10abec2c3f8b91cf68b3d2 Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Thu, 3 Dec 2020 22:47:30 +0200 Subject: [PATCH] Search --- lib/config/config.dart | 8 + lib/config/localized_values.dart | 39 +- lib/core/model/pharmacy/brands_model.dart | 24 + lib/core/model/pharmacy/scan_qr_model.dart | 584 ++++++++++++ lib/core/model/search_products_model.dart | 185 ++++ .../service/pharmacy_categorise_service.dart | 74 ++ .../pharmacy_categorise_view_model.dart | 51 ++ lib/pages/final_products_page.dart | 154 ++-- lib/pages/landing/landing_page_pharmcy.dart | 29 +- lib/pages/offers_categorise_page.dart | 1 + lib/pages/parent_categorise_page.dart | 859 ++++++++++++------ lib/pages/pharmacy_categorise.dart | 88 +- lib/pages/search_products_page.dart | 287 ++++++ lib/pages/sub_categorise_page.dart | 842 +++++++++++------ lib/uitl/translations_delegate_base.dart | 29 +- lib/widgets/input/text_field.dart | 12 +- .../pharmacy/bottom_nav_pharmacy_bar.dart | 8 +- pubspec.yaml | 3 +- 18 files changed, 2529 insertions(+), 748 deletions(-) create mode 100644 lib/core/model/pharmacy/brands_model.dart create mode 100644 lib/core/model/pharmacy/scan_qr_model.dart create mode 100644 lib/core/model/search_products_model.dart create mode 100644 lib/pages/search_products_page.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index 1a6a97af..9bc05e27 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -372,6 +372,14 @@ const TIMER_MIN = 10; const GOOGLE_API_KEY = "AIzaSyCmevVlr2Bh-c8W1VUzo8gt8JRY7n5PANw"; +const GET_BRANDS_LIST = + 'epharmacy/api/categoryManufacturer?categoryids=1&fields=id,name,image,namen'; + +const GET_SEARCH_PRODUCTS = + 'epharmacy/api/searchproducts?fields=id,discount_ids,reviews,name,namen,localized_names,display_order,short_description,full_description,full_descriptionn,sku,order_minimum_quantity,order_maximum_quantity,price,old_price,images,is_rx,rx_message,rx_messagen,discount_name,discount_namen,approved_rating_sum,approved_total_reviews,allow_back_in_stock_subscriptions,stock_quantity,stock_availability,stock_availabilityn,discount_percentage&search_key='; + +const SCAN_QR_CODE = 'epharmacy/api/productbysku/6440010010'; + class AppGlobal { static var context; diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 77cb1c44..3f2934fe 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -660,38 +660,20 @@ const Map> localizedValues = { "remeberthat": {"en": "Remember that", "ar": "تذكر ذلك:"}, // pharmacy module - "medicationRefill": { - "en": "MEDICATION REFILL", - "ar": "إعادة تعبئة الدواء" - }, + "medicationRefill": {"en": "MEDICATION REFILL", "ar": "إعادة تعبئة الدواء"}, "offersAndPromotions": { "en": "OFFERS & SPECIAL PROMOTIONS", "ar": "العروض والترقيات الخاصة" }, - "myPrescriptions": { - "en": "MY PRESCRIPTIONS", - "ar": "وصفاتي" - }, + "myPrescriptions": {"en": "MY PRESCRIPTIONS", "ar": "وصفاتي"}, "searchAndScanMedication": { "en": "SEARCH & SCAN FOR MEDICATION", "ar": "البحث والمسح للأدوية" }, - "shopByBrands": { - "en": "Shop By Brands", - "ar": "تسوق حسب الماركات" - }, - "recentlyViewed": { - "en": "Recently Viewed", - "ar": "شوهدت مؤخرا" - }, - "bestSellers": { - "en": "Best Sellers", - "ar": "أفضل البائعين" - }, - "deleteAllItems": { - "en": "Delete All Items", - "ar": "حذف كافة العناصر" - }, + "shopByBrands": {"en": "Shop By Brands", "ar": "تسوق حسب الماركات"}, + "recentlyViewed": {"en": "Recently Viewed", "ar": "شوهدت مؤخرا"}, + "bestSellers": {"en": "Best Sellers", "ar": "أفضل البائعين"}, + "deleteAllItems": {"en": "Delete All Items", "ar": "حذف كافة العناصر"}, "select-gender": {"en": "Select Gender", "ar": "اختر الجنس"}, "i-am-a": {"en": "I am a ...", "ar": "أنا ..."}, "select-age": {"en": "Select Your Age", "ar": "حدد العمر"}, @@ -701,4 +683,13 @@ const Map> localizedValues = { "en": "Drag point to change your age", "ar": "اسحب لتغيير عمرك" }, + + "categorise": {"en": "Categories", "ar": "التطبيقات"}, + "wishList": {"en": "WishList", "ar": "الرغبات"}, + "myAccount": {"en": "My Account", "ar": "حسابي"}, + "cart": {"en": "Cart", "ar": "التسوق"}, + "searchProductHere": { + "en": "Search Product here", + "ar": "ابحث في الطلب الخاص بك" + }, }; diff --git a/lib/core/model/pharmacy/brands_model.dart b/lib/core/model/pharmacy/brands_model.dart new file mode 100644 index 00000000..03cd689e --- /dev/null +++ b/lib/core/model/pharmacy/brands_model.dart @@ -0,0 +1,24 @@ +class BrandsModel { + String id; + String name; + String namen; + Null image; + + BrandsModel({this.id, this.name, this.namen, this.image}); + + BrandsModel.fromJson(Map json) { + id = json['id']; + name = json['name']; + namen = json['namen']; + image = json['image']; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['name'] = this.name; + data['namen'] = this.namen; + data['image'] = this.image; + return data; + } +} diff --git a/lib/core/model/pharmacy/scan_qr_model.dart b/lib/core/model/pharmacy/scan_qr_model.dart new file mode 100644 index 00000000..71e25e8d --- /dev/null +++ b/lib/core/model/pharmacy/scan_qr_model.dart @@ -0,0 +1,584 @@ +class ScanQrModel { + String id; + bool visibleIndividually; + String name; + String namen; + List localizedNames; + String shortDescription; + String shortDescriptionn; + String fullDescription; + String fullDescriptionn; + bool markasNew; + bool showOnHomePage; + dynamic metaKeywords; + dynamic metaDescription; + dynamic metaTitle; + bool allowCustomerReviews; + dynamic approvedRatingSum; + dynamic notApprovedRatingSum; + dynamic approvedTotalReviews; + dynamic notApprovedTotalReviews; + String sku; + bool isRx; + bool prescriptionRequired; + dynamic rxMessage; + dynamic rxMessagen; + dynamic manufacturerPartNumber; + dynamic gtin; + bool isGiftCard; + bool requireOtherProducts; + bool automaticallyAddRequiredProducts; + bool isDownload; + bool unlimitedDownloads; + dynamic maxNumberOfDownloads; + dynamic downloadExpirationDays; + bool hasSampleDownload; + bool hasUserAgreement; + bool isRecurring; + dynamic recurringCycleLength; + dynamic recurringTotalCycles; + bool isRental; + dynamic rentalPriceLength; + bool isShipEnabled; + bool isFreeShipping; + bool shipSeparately; + dynamic additionalShippingCharge; + bool isTaxExempt; + bool isTelecommunicationsOrBroadcastingOrElectronicServices; + bool useMultipleWarehouses; + dynamic manageInventoryMethodId; + dynamic stockQuantity; + String stockAvailability; + String stockAvailabilityn; + bool displayStockAvailability; + bool displayStockQuantity; + dynamic minStockQuantity; + dynamic notifyAdminForQuantityBelow; + bool allowBackInStockSubscriptions; + dynamic orderMinimumQuantity; + dynamic orderMaximumQuantity; + dynamic allowedQuantities; + bool allowAddingOnlyExistingAttributeCombinations; + bool disableBuyButton; + bool disableWishlistButton; + bool availableForPreOrder; + dynamic preOrderAvailabilityStartDateTimeUtc; + bool callForPrice; + dynamic price; + dynamic oldPrice; + dynamic productCost; + dynamic specialPrice; + dynamic specialPriceStartDateTimeUtc; + dynamic specialPriceEndDateTimeUtc; + bool customerEntersPrice; + dynamic minimumCustomerEnteredPrice; + dynamic maximumCustomerEnteredPrice; + bool basepriceEnabled; + dynamic basepriceAmount; + dynamic basepriceBaseAmount; + bool hasTierPrices; + bool hasDiscountsApplied; + dynamic discountName; + dynamic discountNamen; + dynamic discountDescription; + dynamic discountDescriptionn; + dynamic discountPercentage; + String currency; + String currencyn; + double weight; + dynamic length; + dynamic width; + dynamic height; + dynamic availableStartDateTimeUtc; + dynamic availableEndDateTimeUtc; + dynamic displayOrder; + bool published; + bool deleted; + String createdOnUtc; + String updatedOnUtc; + String productType; + dynamic parentGroupedProductId; + List roleIds; + List discountIds; + List storeIds; + List manufacturerIds; + List reviews; + List images; + List attributes; + List specifications; + List associatedProductIds; + List tags; + dynamic vendorId; + String seName; + + ScanQrModel( + {this.id, + this.visibleIndividually, + this.name, + this.namen, + this.localizedNames, + this.shortDescription, + this.shortDescriptionn, + this.fullDescription, + this.fullDescriptionn, + this.markasNew, + this.showOnHomePage, + this.metaKeywords, + this.metaDescription, + this.metaTitle, + this.allowCustomerReviews, + this.approvedRatingSum, + this.notApprovedRatingSum, + this.approvedTotalReviews, + this.notApprovedTotalReviews, + this.sku, + this.isRx, + this.prescriptionRequired, + this.rxMessage, + this.rxMessagen, + this.manufacturerPartNumber, + this.gtin, + this.isGiftCard, + this.requireOtherProducts, + this.automaticallyAddRequiredProducts, + this.isDownload, + this.unlimitedDownloads, + this.maxNumberOfDownloads, + this.downloadExpirationDays, + this.hasSampleDownload, + this.hasUserAgreement, + this.isRecurring, + this.recurringCycleLength, + this.recurringTotalCycles, + this.isRental, + this.rentalPriceLength, + this.isShipEnabled, + this.isFreeShipping, + this.shipSeparately, + this.additionalShippingCharge, + this.isTaxExempt, + this.isTelecommunicationsOrBroadcastingOrElectronicServices, + this.useMultipleWarehouses, + this.manageInventoryMethodId, + this.stockQuantity, + this.stockAvailability, + this.stockAvailabilityn, + this.displayStockAvailability, + this.displayStockQuantity, + this.minStockQuantity, + this.notifyAdminForQuantityBelow, + this.allowBackInStockSubscriptions, + this.orderMinimumQuantity, + this.orderMaximumQuantity, + this.allowedQuantities, + this.allowAddingOnlyExistingAttributeCombinations, + this.disableBuyButton, + this.disableWishlistButton, + this.availableForPreOrder, + this.preOrderAvailabilityStartDateTimeUtc, + this.callForPrice, + this.price, + this.oldPrice, + this.productCost, + this.specialPrice, + this.specialPriceStartDateTimeUtc, + this.specialPriceEndDateTimeUtc, + this.customerEntersPrice, + this.minimumCustomerEnteredPrice, + this.maximumCustomerEnteredPrice, + this.basepriceEnabled, + this.basepriceAmount, + this.basepriceBaseAmount, + this.hasTierPrices, + this.hasDiscountsApplied, + this.discountName, + this.discountNamen, + this.discountDescription, + this.discountDescriptionn, + this.discountPercentage, + this.currency, + this.currencyn, + this.weight, + this.length, + this.width, + this.height, + this.availableStartDateTimeUtc, + this.availableEndDateTimeUtc, + this.displayOrder, + this.published, + this.deleted, + this.createdOnUtc, + this.updatedOnUtc, + this.productType, + this.parentGroupedProductId, + this.roleIds, + this.discountIds, + this.storeIds, + this.manufacturerIds, + this.reviews, + this.images, + this.attributes, + this.specifications, + this.associatedProductIds, + this.tags, + this.vendorId, + this.seName}); + + ScanQrModel.fromJson(Map json) { + id = json['id']; + visibleIndividually = json['visible_individually']; + name = json['name']; + namen = json['namen']; + if (json['localized_names'] != null) { + localizedNames = new List(); + json['localized_names'].forEach((v) { + localizedNames.add(new LocalizedNames.fromJson(v)); + }); + } + shortDescription = json['short_description']; + shortDescriptionn = json['short_descriptionn']; + fullDescription = json['full_description']; + fullDescriptionn = json['full_descriptionn']; + markasNew = json['markas_new']; + showOnHomePage = json['show_on_home_page']; + metaKeywords = json['meta_keywords']; + metaDescription = json['meta_description']; + metaTitle = json['meta_title']; + allowCustomerReviews = json['allow_customer_reviews']; + approvedRatingSum = json['approved_rating_sum']; + notApprovedRatingSum = json['not_approved_rating_sum']; + approvedTotalReviews = json['approved_total_reviews']; + notApprovedTotalReviews = json['not_approved_total_reviews']; + sku = json['sku']; + isRx = json['is_rx']; + prescriptionRequired = json['prescription_required']; + rxMessage = json['rx_message']; + rxMessagen = json['rx_messagen']; + manufacturerPartNumber = json['manufacturer_part_number']; + gtin = json['gtin']; + isGiftCard = json['is_gift_card']; + requireOtherProducts = json['require_other_products']; + automaticallyAddRequiredProducts = + json['automatically_add_required_products']; + isDownload = json['is_download']; + unlimitedDownloads = json['unlimited_downloads']; + maxNumberOfDownloads = json['max_number_of_downloads']; + downloadExpirationDays = json['download_expiration_days']; + hasSampleDownload = json['has_sample_download']; + hasUserAgreement = json['has_user_agreement']; + isRecurring = json['is_recurring']; + recurringCycleLength = json['recurring_cycle_length']; + recurringTotalCycles = json['recurring_total_cycles']; + isRental = json['is_rental']; + rentalPriceLength = json['rental_price_length']; + isShipEnabled = json['is_ship_enabled']; + isFreeShipping = json['is_free_shipping']; + shipSeparately = json['ship_separately']; + additionalShippingCharge = json['additional_shipping_charge']; + isTaxExempt = json['is_tax_exempt']; + isTelecommunicationsOrBroadcastingOrElectronicServices = + json['is_telecommunications_or_broadcasting_or_electronic_services']; + useMultipleWarehouses = json['use_multiple_warehouses']; + manageInventoryMethodId = json['manage_inventory_method_id']; + stockQuantity = json['stock_quantity']; + stockAvailability = json['stock_availability']; + stockAvailabilityn = json['stock_availabilityn']; + displayStockAvailability = json['display_stock_availability']; + displayStockQuantity = json['display_stock_quantity']; + minStockQuantity = json['min_stock_quantity']; + notifyAdminForQuantityBelow = json['notify_admin_for_quantity_below']; + allowBackInStockSubscriptions = json['allow_back_in_stock_subscriptions']; + orderMinimumQuantity = json['order_minimum_quantity']; + orderMaximumQuantity = json['order_maximum_quantity']; + allowedQuantities = json['allowed_quantities']; + allowAddingOnlyExistingAttributeCombinations = + json['allow_adding_only_existing_attribute_combinations']; + disableBuyButton = json['disable_buy_button']; + disableWishlistButton = json['disable_wishlist_button']; + availableForPreOrder = json['available_for_pre_order']; + preOrderAvailabilityStartDateTimeUtc = + json['pre_order_availability_start_date_time_utc']; + callForPrice = json['call_for_price']; + price = json['price']; + oldPrice = json['old_price']; + productCost = json['product_cost']; + specialPrice = json['special_price']; + specialPriceStartDateTimeUtc = json['special_price_start_date_time_utc']; + specialPriceEndDateTimeUtc = json['special_price_end_date_time_utc']; + customerEntersPrice = json['customer_enters_price']; + minimumCustomerEnteredPrice = json['minimum_customer_entered_price']; + maximumCustomerEnteredPrice = json['maximum_customer_entered_price']; + basepriceEnabled = json['baseprice_enabled']; + basepriceAmount = json['baseprice_amount']; + basepriceBaseAmount = json['baseprice_base_amount']; + hasTierPrices = json['has_tier_prices']; + hasDiscountsApplied = json['has_discounts_applied']; + discountName = json['discount_name']; + discountNamen = json['discount_namen']; + discountDescription = json['discount_description']; + discountDescriptionn = json['discount_Descriptionn']; + discountPercentage = json['discount_percentage']; + currency = json['currency']; + currencyn = json['currencyn']; + weight = json['weight']; + length = json['length']; + width = json['width']; + height = json['height']; + availableStartDateTimeUtc = json['available_start_date_time_utc']; + availableEndDateTimeUtc = json['available_end_date_time_utc']; + displayOrder = json['display_order']; + published = json['published']; + deleted = json['deleted']; + createdOnUtc = json['created_on_utc']; + updatedOnUtc = json['updated_on_utc']; + productType = json['product_type']; + parentGroupedProductId = json['parent_grouped_product_id']; + if (json['role_ids'] != null) { + roleIds = new List(); + } + if (json['discount_ids'] != null) { + discountIds = new List(); + } + if (json['store_ids'] != null) { + storeIds = new List(); + } + manufacturerIds = json['manufacturer_ids'].cast(); + if (json['reviews'] != null) { + reviews = new List(); + } + if (json['images'] != null) { + images = new List(); + json['images'].forEach((v) { + images.add(new Images.fromJson(v)); + }); + } + if (json['attributes'] != null) { + attributes = new List(); + } + if (json['specifications'] != null) { + specifications = new List(); + json['specifications'].forEach((v) { + specifications.add(new Specifications.fromJson(v)); + }); + } + if (json['associated_product_ids'] != null) { + associatedProductIds = new List(); + } + if (json['tags'] != null) { + tags = new List(); + } + vendorId = json['vendor_id']; + seName = json['se_name']; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['visible_individually'] = this.visibleIndividually; + data['name'] = this.name; + data['namen'] = this.namen; + if (this.localizedNames != null) { + data['localized_names'] = + this.localizedNames.map((v) => v.toJson()).toList(); + } + data['short_description'] = this.shortDescription; + data['short_descriptionn'] = this.shortDescriptionn; + data['full_description'] = this.fullDescription; + data['full_descriptionn'] = this.fullDescriptionn; + data['markas_new'] = this.markasNew; + data['show_on_home_page'] = this.showOnHomePage; + data['meta_keywords'] = this.metaKeywords; + data['meta_description'] = this.metaDescription; + data['meta_title'] = this.metaTitle; + data['allow_customer_reviews'] = this.allowCustomerReviews; + data['approved_rating_sum'] = this.approvedRatingSum; + data['not_approved_rating_sum'] = this.notApprovedRatingSum; + data['approved_total_reviews'] = this.approvedTotalReviews; + data['not_approved_total_reviews'] = this.notApprovedTotalReviews; + data['sku'] = this.sku; + data['is_rx'] = this.isRx; + data['prescription_required'] = this.prescriptionRequired; + data['rx_message'] = this.rxMessage; + data['rx_messagen'] = this.rxMessagen; + data['manufacturer_part_number'] = this.manufacturerPartNumber; + data['gtin'] = this.gtin; + data['is_gift_card'] = this.isGiftCard; + data['require_other_products'] = this.requireOtherProducts; + data['automatically_add_required_products'] = + this.automaticallyAddRequiredProducts; + data['is_download'] = this.isDownload; + data['unlimited_downloads'] = this.unlimitedDownloads; + data['max_number_of_downloads'] = this.maxNumberOfDownloads; + data['download_expiration_days'] = this.downloadExpirationDays; + data['has_sample_download'] = this.hasSampleDownload; + data['has_user_agreement'] = this.hasUserAgreement; + data['is_recurring'] = this.isRecurring; + data['recurring_cycle_length'] = this.recurringCycleLength; + data['recurring_total_cycles'] = this.recurringTotalCycles; + data['is_rental'] = this.isRental; + data['rental_price_length'] = this.rentalPriceLength; + data['is_ship_enabled'] = this.isShipEnabled; + data['is_free_shipping'] = this.isFreeShipping; + data['ship_separately'] = this.shipSeparately; + data['additional_shipping_charge'] = this.additionalShippingCharge; + data['is_tax_exempt'] = this.isTaxExempt; + data['is_telecommunications_or_broadcasting_or_electronic_services'] = + this.isTelecommunicationsOrBroadcastingOrElectronicServices; + data['use_multiple_warehouses'] = this.useMultipleWarehouses; + data['manage_inventory_method_id'] = this.manageInventoryMethodId; + data['stock_quantity'] = this.stockQuantity; + data['stock_availability'] = this.stockAvailability; + data['stock_availabilityn'] = this.stockAvailabilityn; + data['display_stock_availability'] = this.displayStockAvailability; + data['display_stock_quantity'] = this.displayStockQuantity; + data['min_stock_quantity'] = this.minStockQuantity; + data['notify_admin_for_quantity_below'] = this.notifyAdminForQuantityBelow; + data['allow_back_in_stock_subscriptions'] = + this.allowBackInStockSubscriptions; + data['order_minimum_quantity'] = this.orderMinimumQuantity; + data['order_maximum_quantity'] = this.orderMaximumQuantity; + data['allowed_quantities'] = this.allowedQuantities; + data['allow_adding_only_existing_attribute_combinations'] = + this.allowAddingOnlyExistingAttributeCombinations; + data['disable_buy_button'] = this.disableBuyButton; + data['disable_wishlist_button'] = this.disableWishlistButton; + data['available_for_pre_order'] = this.availableForPreOrder; + data['pre_order_availability_start_date_time_utc'] = + this.preOrderAvailabilityStartDateTimeUtc; + data['call_for_price'] = this.callForPrice; + data['price'] = this.price; + data['old_price'] = this.oldPrice; + data['product_cost'] = this.productCost; + data['special_price'] = this.specialPrice; + data['special_price_start_date_time_utc'] = + this.specialPriceStartDateTimeUtc; + data['special_price_end_date_time_utc'] = this.specialPriceEndDateTimeUtc; + data['customer_enters_price'] = this.customerEntersPrice; + data['minimum_customer_entered_price'] = this.minimumCustomerEnteredPrice; + data['maximum_customer_entered_price'] = this.maximumCustomerEnteredPrice; + data['baseprice_enabled'] = this.basepriceEnabled; + data['baseprice_amount'] = this.basepriceAmount; + data['baseprice_base_amount'] = this.basepriceBaseAmount; + data['has_tier_prices'] = this.hasTierPrices; + data['has_discounts_applied'] = this.hasDiscountsApplied; + data['discount_name'] = this.discountName; + data['discount_namen'] = this.discountNamen; + data['discount_description'] = this.discountDescription; + data['discount_Descriptionn'] = this.discountDescriptionn; + data['discount_percentage'] = this.discountPercentage; + data['currency'] = this.currency; + data['currencyn'] = this.currencyn; + data['weight'] = this.weight; + data['length'] = this.length; + data['width'] = this.width; + data['height'] = this.height; + data['available_start_date_time_utc'] = this.availableStartDateTimeUtc; + data['available_end_date_time_utc'] = this.availableEndDateTimeUtc; + data['display_order'] = this.displayOrder; + data['published'] = this.published; + data['deleted'] = this.deleted; + data['created_on_utc'] = this.createdOnUtc; + data['updated_on_utc'] = this.updatedOnUtc; + data['product_type'] = this.productType; + data['parent_grouped_product_id'] = this.parentGroupedProductId; + + data['manufacturer_ids'] = this.manufacturerIds; + + if (this.images != null) { + data['images'] = this.images.map((v) => v.toJson()).toList(); + } + + if (this.specifications != null) { + data['specifications'] = + this.specifications.map((v) => v.toJson()).toList(); + } + + data['vendor_id'] = this.vendorId; + data['se_name'] = this.seName; + return data; + } +} + +class LocalizedNames { + int languageId; + String localizedName; + + LocalizedNames({this.languageId, this.localizedName}); + + LocalizedNames.fromJson(Map json) { + languageId = json['language_id']; + localizedName = json['localized_name']; + } + + Map toJson() { + final Map data = new Map(); + data['language_id'] = this.languageId; + data['localized_name'] = this.localizedName; + return data; + } +} + +class Images { + int id; + int position; + String src; + String thumb; + String attachment; + + Images({this.id, this.position, this.src, this.thumb, this.attachment}); + + Images.fromJson(Map json) { + id = json['id']; + position = json['position']; + src = json['src']; + thumb = json['thumb']; + attachment = json['attachment']; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['position'] = this.position; + data['src'] = this.src; + data['thumb'] = this.thumb; + data['attachment'] = this.attachment; + return data; + } +} + +class Specifications { + int id; + int displayOrder; + String defaultValue; + String defaultValuen; + String name; + String nameN; + + Specifications( + {this.id, + this.displayOrder, + this.defaultValue, + this.defaultValuen, + this.name, + this.nameN}); + + Specifications.fromJson(Map json) { + id = json['id']; + displayOrder = json['display_order']; + defaultValue = json['default_value']; + defaultValuen = json['default_valuen']; + name = json['name']; + nameN = json['nameN']; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['display_order'] = this.displayOrder; + data['default_value'] = this.defaultValue; + data['default_valuen'] = this.defaultValuen; + data['name'] = this.name; + data['nameN'] = this.nameN; + return data; + } +} diff --git a/lib/core/model/search_products_model.dart b/lib/core/model/search_products_model.dart new file mode 100644 index 00000000..d63fd4b0 --- /dev/null +++ b/lib/core/model/search_products_model.dart @@ -0,0 +1,185 @@ +class SearchProductsModel { + String id; + String name; + String namen; + List localizedNames; + String shortDescription; + String fullDescription; + String fullDescriptionn; + dynamic approvedRatingSum; + dynamic approvedTotalReviews; + String sku; + bool isRx; + dynamic rxMessage; + dynamic rxMessagen; + dynamic stockQuantity; + String stockAvailability; + String stockAvailabilityn; + bool allowBackInStockSubscriptions; + dynamic orderMinimumQuantity; + dynamic orderMaximumQuantity; + double price; + dynamic oldPrice; + dynamic discountName; + dynamic discountNamen; + dynamic discountPercentage; + dynamic displayOrder; + List discountIds; + List reviews; + List images; + + SearchProductsModel( + {this.id, + this.name, + this.namen, + this.localizedNames, + this.shortDescription, + this.fullDescription, + this.fullDescriptionn, + this.approvedRatingSum, + this.approvedTotalReviews, + this.sku, + this.isRx, + this.rxMessage, + this.rxMessagen, + this.stockQuantity, + this.stockAvailability, + this.stockAvailabilityn, + this.allowBackInStockSubscriptions, + this.orderMinimumQuantity, + this.orderMaximumQuantity, + this.price, + this.oldPrice, + this.discountName, + this.discountNamen, + this.discountPercentage, + this.displayOrder, + this.discountIds, + this.reviews, + this.images}); + + SearchProductsModel.fromJson(Map json) { + id = json['id']; + name = json['name']; + namen = json['namen']; + if (json['localized_names'] != null) { + localizedNames = new List(); + json['localized_names'].forEach((v) { + localizedNames.add(new LocalizedNames.fromJson(v)); + }); + } + shortDescription = json['short_description']; + fullDescription = json['full_description']; + fullDescriptionn = json['full_descriptionn']; + approvedRatingSum = json['approved_rating_sum']; + approvedTotalReviews = json['approved_total_reviews']; + sku = json['sku']; + isRx = json['is_rx']; + rxMessage = json['rx_message']; + rxMessagen = json['rx_messagen']; + stockQuantity = json['stock_quantity']; + stockAvailability = json['stock_availability']; + stockAvailabilityn = json['stock_availabilityn']; + allowBackInStockSubscriptions = json['allow_back_in_stock_subscriptions']; + orderMinimumQuantity = json['order_minimum_quantity']; + orderMaximumQuantity = json['order_maximum_quantity']; + price = json['price']; + oldPrice = json['old_price']; + discountName = json['discount_name']; + discountNamen = json['discount_namen']; + discountPercentage = json['discount_percentage']; + displayOrder = json['display_order']; + + if (json['images'] != null) { + images = new List(); + json['images'].forEach((v) { + images.add(new Images.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['name'] = this.name; + data['namen'] = this.namen; + if (this.localizedNames != null) { + data['localized_names'] = + this.localizedNames.map((v) => v.toJson()).toList(); + } + data['short_description'] = this.shortDescription; + data['full_description'] = this.fullDescription; + data['full_descriptionn'] = this.fullDescriptionn; + data['approved_rating_sum'] = this.approvedRatingSum; + data['approved_total_reviews'] = this.approvedTotalReviews; + data['sku'] = this.sku; + data['is_rx'] = this.isRx; + data['rx_message'] = this.rxMessage; + data['rx_messagen'] = this.rxMessagen; + data['stock_quantity'] = this.stockQuantity; + data['stock_availability'] = this.stockAvailability; + data['stock_availabilityn'] = this.stockAvailabilityn; + data['allow_back_in_stock_subscriptions'] = + this.allowBackInStockSubscriptions; + data['order_minimum_quantity'] = this.orderMinimumQuantity; + data['order_maximum_quantity'] = this.orderMaximumQuantity; + data['price'] = this.price; + data['old_price'] = this.oldPrice; + data['discount_name'] = this.discountName; + data['discount_namen'] = this.discountNamen; + data['discount_percentage'] = this.discountPercentage; + data['display_order'] = this.displayOrder; + + if (this.images != null) { + data['images'] = this.images.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class LocalizedNames { + int languageId; + String localizedName; + + LocalizedNames({this.languageId, this.localizedName}); + + LocalizedNames.fromJson(Map json) { + languageId = json['language_id']; + localizedName = json['localized_name']; + } + + Map toJson() { + final Map data = new Map(); + data['language_id'] = this.languageId; + data['localized_name'] = this.localizedName; + return data; + } +} + +class Images { + int id; + int position; + String src; + String thumb; + String attachment; + + Images({this.id, this.position, this.src, this.thumb, this.attachment}); + + Images.fromJson(Map json) { + id = json['id']; + position = json['position']; + src = json['src']; + thumb = json['thumb']; + attachment = json['attachment']; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['position'] = this.position; + data['src'] = this.src; + data['thumb'] = this.thumb; + data['attachment'] = this.attachment; + return data; + } +} diff --git a/lib/core/service/pharmacy_categorise_service.dart b/lib/core/service/pharmacy_categorise_service.dart index 562a4496..dfb93045 100644 --- a/lib/core/service/pharmacy_categorise_service.dart +++ b/lib/core/service/pharmacy_categorise_service.dart @@ -1,10 +1,13 @@ import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacy/brands_model.dart'; import 'package:diplomaticquarterapp/core/model/pharmacy/categorise_parent_model.dart'; import 'package:diplomaticquarterapp/core/model/pharmacy/final_products_model.dart'; import 'package:diplomaticquarterapp/core/model/pharmacy/parent_products_model.dart'; import 'package:diplomaticquarterapp/core/model/pharmacy/pharmacy_categorise.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacy/scan_qr_model.dart'; import 'package:diplomaticquarterapp/core/model/pharmacy/sub_categories_model.dart'; import 'package:diplomaticquarterapp/core/model/pharmacy/sub_products_model.dart'; +import 'package:diplomaticquarterapp/core/model/search_products_model.dart'; import 'base_service.dart'; @@ -33,6 +36,23 @@ class PharmacyCategoriseService extends BaseService { List _finalProducts = List(); List get finalProducts => _finalProducts; + //service 7 + + List _brandsList = List(); + List get brandsList => _brandsList; + + // service 8 + + List _searchList = List(); + List get searchList => _searchList; + + List _scanList = List(); + List get scanList => _scanList; + + clearSearchList() { + _searchList.clear(); + } + Future getCategorise() async { hasError = false; _categoriseList.clear(); @@ -50,6 +70,60 @@ class PharmacyCategoriseService extends BaseService { ); } + Future scanQr() async { + hasError = false; + _scanList.clear(); + await baseAppClient.get( + SCAN_QR_CODE, + onSuccess: (dynamic response, int statusCode) { + response['products'].forEach((item) { + _scanList.add(ScanQrModel.fromJson(item)); + }); + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + ); + } + + Future searchProducts({String productName}) async { + hasError = false; + _searchList.clear(); + String endPoint = productName != null + ? GET_SEARCH_PRODUCTS + "$productName" + '&language_id=1' + : GET_SEARCH_PRODUCTS + ""; + await baseAppClient.get( + endPoint, + onSuccess: (dynamic response, int statusCode) { + response['products'].forEach((item) { + _searchList.add(SearchProductsModel.fromJson(item)); + }); + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + ); + } + + Future getBrands() async { + hasError = false; + _brandsList.clear(); + await baseAppClient.get( + GET_BRANDS_LIST, + onSuccess: (dynamic response, int statusCode) { + response['manufacturer'].forEach((item) { + _brandsList.add(BrandsModel.fromJson(item)); + }); + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + ); + } + Future getCategoriseParent({String id}) async { hasError = false; _parentCategoriseList.clear(); diff --git a/lib/core/viewModels/pharmacy_categorise_view_model.dart b/lib/core/viewModels/pharmacy_categorise_view_model.dart index 16249206..a2f5b654 100644 --- a/lib/core/viewModels/pharmacy_categorise_view_model.dart +++ b/lib/core/viewModels/pharmacy_categorise_view_model.dart @@ -1,10 +1,14 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacy/brands_model.dart'; import 'package:diplomaticquarterapp/core/model/pharmacy/categorise_parent_model.dart'; import 'package:diplomaticquarterapp/core/model/pharmacy/final_products_model.dart'; import 'package:diplomaticquarterapp/core/model/pharmacy/parent_products_model.dart'; import 'package:diplomaticquarterapp/core/model/pharmacy/pharmacy_categorise.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacy/scan_qr_model.dart'; import 'package:diplomaticquarterapp/core/model/pharmacy/sub_categories_model.dart'; import 'package:diplomaticquarterapp/core/model/pharmacy/sub_products_model.dart'; +import 'package:diplomaticquarterapp/core/model/search_products_model.dart'; + import 'package:diplomaticquarterapp/core/service/pharmacy_categorise_service.dart'; import 'package:diplomaticquarterapp/locator.dart'; @@ -32,6 +36,12 @@ class PharmacyCategoriseViewModel extends BaseViewModel { List get finalProducts => _pharmacyCategoriseService.finalProducts; + List get brandsList => _pharmacyCategoriseService.brandsList; + + List get searchList => + _pharmacyCategoriseService.searchList; + + List get scanList => _pharmacyCategoriseService.scanList; Future getCategorise() async { hasError = false; @@ -45,6 +55,46 @@ class PharmacyCategoriseViewModel extends BaseViewModel { setState(ViewState.Idle); } + Future getBrands() async { + hasError = false; + // _insuranceCardService.clearInsuranceCard(); + setState(ViewState.Busy); + await _pharmacyCategoriseService.getBrands(); + if (_pharmacyCategoriseService.hasError) { + error = _pharmacyCategoriseService.error; + setState(ViewState.ErrorLocal); + } else + setState(ViewState.Idle); + } + + Future scanQr() async { + hasError = false; + // _insuranceCardService.clearInsuranceCard(); + setState(ViewState.Busy); + await _pharmacyCategoriseService.scanQr(); + if (_pharmacyCategoriseService.hasError) { + error = _pharmacyCategoriseService.error; + setState(ViewState.ErrorLocal); + } else + setState(ViewState.Idle); + } + + clearSearchList() { + _pharmacyCategoriseService.clearSearchList(); + } + + Future searchProducts({String productName}) async { + hasError = false; + _pharmacyCategoriseService.clearSearchList(); + setState(ViewState.Busy); + await _pharmacyCategoriseService.searchProducts(productName: productName); + if (_pharmacyCategoriseService.hasError) { + error = _pharmacyCategoriseService.error; + setState(ViewState.ErrorLocal); + } else + setState(ViewState.Idle); + } + Future getCategoriseParent({String i}) async { hasError = false; // _insuranceCardService.clearInsuranceCard(); @@ -55,6 +105,7 @@ class PharmacyCategoriseViewModel extends BaseViewModel { setState(ViewState.ErrorLocal); } else await getParentProducts(i: i); + await getBrands(); } Future getParentProducts({String i}) async { diff --git a/lib/pages/final_products_page.dart b/lib/pages/final_products_page.dart index 66b5ee0d..03adee97 100644 --- a/lib/pages/final_products_page.dart +++ b/lib/pages/final_products_page.dart @@ -7,9 +7,16 @@ import 'package:flutter/material.dart'; import 'base/base_view.dart'; -class FinalProductsPage extends StatelessWidget { +class FinalProductsPage extends StatefulWidget { String id; FinalProductsPage({this.id}); + @override + _FinalProductsPageState createState() => _FinalProductsPageState(id: id); +} + +class _FinalProductsPageState extends State { + String id; + _FinalProductsPageState({this.id}); String categoriseName = "Personal Care"; bool styleOne = true; bool styleTwo = false; @@ -32,7 +39,7 @@ class FinalProductsPage extends StatelessWidget { isShowDecPage: false, baseViewModel: model, body: Container( - height: MediaQuery.of(context).size.height * 1.87, + height: MediaQuery.of(context).size.height * 5.87, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -64,23 +71,25 @@ class FinalProductsPage extends StatelessWidget { child: InkWell( child: styleIcon, onTap: () { - if (styleOne == true) { - styleOne = false; - styleTwo = true; - styleIcon = Icon( - Icons.auto_awesome_mosaic, - color: Colors.blue, - size: 29.0, - ); - } else { - styleOne = true; - styleTwo = false; - styleIcon = Icon( - Icons.widgets_sharp, - color: Colors.blue, - size: 29.0, - ); - } + setState(() { + if (styleOne == true) { + styleOne = false; + styleTwo = true; + styleIcon = Icon( + Icons.auto_awesome_mosaic, + color: Colors.blue, + size: 29.0, + ); + } else { + styleOne = true; + styleTwo = false; + styleIcon = Icon( + Icons.widgets_sharp, + color: Colors.blue, + size: 29.0, + ); + } + }); }, ), ), @@ -95,7 +104,7 @@ class FinalProductsPage extends StatelessWidget { styleOne == true ? Expanded( child: Container( - height: MediaQuery.of(context).size.height * 1.90, + height: MediaQuery.of(context).size.height * 3.90, child: GridView.builder( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( @@ -302,64 +311,42 @@ class FinalProductsPage extends StatelessWidget { ) : Expanded( child: Container( + height: MediaQuery.of(context).size.height * 5.0, child: ListView.builder( itemCount: model.finalProducts.length, itemBuilder: (BuildContext context, int index) { return Card( - // color: - // model.products[index].discountName != - // null - // ? Color(0xffFFFF00) - // : Colors.white, child: Row( children: [ Stack( children: [ Column( children: [ - if (model.finalProducts[index] - .discountName != - null) - Container( - decoration: - BoxDecoration(), - child: Padding( - padding: - EdgeInsets.only( - left: 9.0, - top: 8.0, - right: 10.0, - ), - child: Container( - color: Colors.yellow, - height: 25.0, - width: 70.0, - child: Center( - child: Texts( - 'offer' - .toUpperCase(), - color: Colors.red, - fontSize: 13.0, - fontWeight: - FontWeight - .w900, - ), - ), - ), + Container( + decoration: BoxDecoration(), + child: Padding( + padding: EdgeInsets.only( + left: 9.0, + top: 8.0, + right: 10.0, ), - transform: - new Matrix4.rotationZ( - 6.15099), ), + ), Container( margin: EdgeInsets.fromLTRB( 0, 0, 0, 0), alignment: Alignment.center, child: Image.network( model.finalProducts[index] - .images[index].thumb, - fit: BoxFit.cover, + .images.isNotEmpty + ? model + .finalProducts[ + index] + .images[0] + .thumb + : 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/No_image_3x4.svg/1200px-No_image_3x4.svg.png', + fit: BoxFit.contain, height: 80, ), ), @@ -376,7 +363,7 @@ class FinalProductsPage extends StatelessWidget { ? MediaQuery.of(context) .size .width / - 5 + 3.5 : 0, padding: EdgeInsets.all(4), decoration: BoxDecoration( @@ -399,7 +386,7 @@ class FinalProductsPage extends StatelessWidget { regular: true, fontSize: 10, fontWeight: - FontWeight.w400, + FontWeight.w600, ), ), ], @@ -407,48 +394,31 @@ class FinalProductsPage extends StatelessWidget { ], ), Container( + height: 100.0, margin: EdgeInsets.symmetric( horizontal: 6, vertical: 0, ), child: Column( + mainAxisAlignment: + MainAxisAlignment.spaceAround, crossAxisAlignment: CrossAxisAlignment.start, children: [ - if (model.finalProducts[index] - .discountName != - null) - Container( - width: 250.0, - height: 18.5, - decoration: BoxDecoration( - color: Color(0xff5AB145), - ), - child: Padding( - padding: - EdgeInsets.symmetric( - horizontal: 5.5, - ), - child: Texts( - model - .finalProducts[ - index] - .discountName, - regular: true, - color: Colors.white, - fontSize: 11.4, - ), - ), - ), SizedBox( height: 4.0, ), - Texts( - model.finalProducts[index] - .name, - regular: true, - fontSize: 12, - fontWeight: FontWeight.w400, + Container( + height: 35.0, + width: 250.0, + child: Texts( + model.finalProducts[index] + .name, + regular: true, + fontSize: 13.2, + fontWeight: FontWeight.w500, + maxLines: 2, + ), ), SizedBox( height: 8.0, diff --git a/lib/pages/landing/landing_page_pharmcy.dart b/lib/pages/landing/landing_page_pharmcy.dart index 058a42fe..6a687e1a 100644 --- a/lib/pages/landing/landing_page_pharmcy.dart +++ b/lib/pages/landing/landing_page_pharmcy.dart @@ -1,7 +1,9 @@ import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/parent_categorise_page.dart'; import 'package:diplomaticquarterapp/pages/pharmacy_categorise.dart'; +import 'package:diplomaticquarterapp/pages/search_products_page.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/drawer/app_drawer_widget.dart'; import 'package:diplomaticquarterapp/widgets/pharmacy/bottom_nav_pharmacy_bar.dart'; import 'package:flutter/material.dart'; @@ -38,29 +40,36 @@ class _LandingPagePharmacyState extends State { backgroundColor: Color(0xff5AB145), elevation: 0, title: Container( - height: 30, + height: MediaQuery.of(context).size.height * 0.056, decoration: BoxDecoration( - borderRadius: BorderRadius.circular(4.0), + borderRadius: BorderRadius.circular(5.0), color: Colors.white, ), child: InkWell( child: Padding( padding: EdgeInsets.all(8.0), child: Row( + //crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.start, children: [ - Icon(Icons.search, size: 16.0), + Icon(Icons.search, size: 25.0), SizedBox( - width: 5.0, + width: 15.0, ), - Text( - 'Search your Medicine', - style: TextStyle( - fontSize: 13.0, fontWeight: FontWeight.w300), + Texts( + TranslationBase.of(context).searchProductHere, + fontSize: 13, ) ], ), ), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => SearchProductsPage()), + ); + }, ), ), leading: Builder( @@ -125,7 +134,9 @@ class _LandingPagePharmacyState extends State { ), PharmacyCategorisePage(), OffersCategorisePage(), - ParentCategorisePage(), + Container( + child: Text('text'), + ), Container( child: Center(child: Text('This Is Cart Page')), ), diff --git a/lib/pages/offers_categorise_page.dart b/lib/pages/offers_categorise_page.dart index f81f0588..45ae2696 100644 --- a/lib/pages/offers_categorise_page.dart +++ b/lib/pages/offers_categorise_page.dart @@ -94,6 +94,7 @@ class _OffersCategorisePageState extends State { child: Texts( model.categorise[index].name, fontWeight: FontWeight.w600, + fontSize: 13.8, ), ), ), diff --git a/lib/pages/parent_categorise_page.dart b/lib/pages/parent_categorise_page.dart index ccb33bb2..4acb3b68 100644 --- a/lib/pages/parent_categorise_page.dart +++ b/lib/pages/parent_categorise_page.dart @@ -1,6 +1,7 @@ import 'package:diplomaticquarterapp/core/viewModels/pharmacy_categorise_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/sub_categorise_page.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/StarRating.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_pharmacy_widget.dart'; @@ -13,14 +14,22 @@ import 'package:giffy_dialog/giffy_dialog.dart'; import 'base/base_view.dart'; import 'final_products_page.dart'; -class ParentCategorisePage extends StatelessWidget { - final String id; - final String titleName; - +class ParentCategorisePage extends StatefulWidget { + String id; + String titleName; ParentCategorisePage({this.id, this.titleName}); + @override + _ParentCategorisePageState createState() => + _ParentCategorisePageState(id: id, titleName: titleName); +} - String categoriesID; - +class _ParentCategorisePageState extends State { + String id; + String titleName; + _ParentCategorisePageState({this.id, this.titleName}); + Map values = {'huusam': false, 'ali': false, 'noor': false}; + bool checkedBrands = false; + bool checkedCategorise = false; String categoriseName = "Personal Care"; bool styleOne = true; bool styleTwo = false; @@ -31,7 +40,7 @@ class ParentCategorisePage extends StatelessWidget { ); @override Widget build(BuildContext context) { - ProjectViewModel projectProvider = Provider.of(context); + ProjectViewModel projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) => model.getCategoriseParent(i: id), builder: (BuildContext context, PharmacyCategoriseViewModel model, @@ -76,49 +85,91 @@ class ParentCategorisePage extends StatelessWidget { height: 160.0, width: double.infinity), ), - if (model.categoriseParent.length >= 8) + if (model.categoriseParent.length > 8) Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Padding( - padding: EdgeInsets.all(10.0), - child: InkWell( - child: Container( - child: Texts( - 'View All Categories', - fontWeight: FontWeight.w300, - ), - ), - onTap: () { - showModalBottomSheet( - context: context, - builder: (BuildContext context) { - return Container( - height: - MediaQuery.of(context).size.height * - 0.9, - color: Colors.white, - child: Center( - child: Column( - mainAxisAlignment: - MainAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - const Text('Modal BottomSheet'), - ElevatedButton( - child: const Text( - 'Close BottomSheet'), - onPressed: () => - Navigator.pop(context), - ) - ], - ), - ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: EdgeInsets.all(10.0), + child: InkWell( + child: Container( + child: Texts( + 'View All Categories', + fontWeight: FontWeight.w300, + ), + ), + onTap: () { + showModalBottomSheet( + isScrollControlled: true, + context: context, + builder: (BuildContext context) { + return Container( + height: MediaQuery.of(context) + .size + .height * + 0.89, + color: Colors.white, + child: Center( + child: ListView.builder( + scrollDirection: + Axis.vertical, + itemCount: model + .categoriseParent.length, + itemBuilder: + (BuildContext context, + int index) { + return Container( + child: Padding( + padding: + EdgeInsets.all(8.0), + child: InkWell( + child: Column( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Texts(model + .categoriseParent[ + index] + .name), + Divider( + thickness: 0.6, + color: Colors + .black12, + ) + ], + ), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: + (context) => + SubCategorisePage( + title: + model.categoriseParent[index].name, + id: model.categoriseParent[index].id, + parentId: + id, + )), + ); + }, + ), + ), + ); + }), + ), + ); + }, ); }, - ); - }, - ), + ), + ), + Icon(Icons.arrow_forward) + ], ), Divider( thickness: 1.0, @@ -170,18 +221,23 @@ class ParentCategorisePage extends StatelessWidget { width: MediaQuery.of(context) .size .width * - 0.17, + 0.197, height: MediaQuery.of(context) .size .height * - 0.10, + 0.08, child: Center( child: Texts( - model.categoriseParent[index] - .name, - fontSize: 14, + projectViewModel.isArabic + ? model + .categoriseParent[index] + .namen + : model + .categoriseParent[index] + .name, + fontSize: 13.4, fontWeight: FontWeight.w600, - maxLines: 2, + maxLines: 3, ), ), ), @@ -220,19 +276,299 @@ class ParentCategorisePage extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Row( - children: [ - Icon( - Icons.wrap_text, - ), - SizedBox( - width: 10.0, - ), - Texts( - 'Refine', - fontWeight: FontWeight.w600, - ), - ], + InkWell( + child: Row( + children: [ + Icon( + Icons.wrap_text, + ), + SizedBox( + width: 10.0, + ), + Texts( + 'Refine', + fontWeight: FontWeight.w600, + ), + ], + ), + onTap: () { + showModalBottomSheet( + isScrollControlled: true, + context: context, + builder: (BuildContext context) { + return DraggableScrollableSheet( + initialChildSize: 0.95, + maxChildSize: 0.95, + minChildSize: 0.9, + builder: (BuildContext context, + ScrollController scrollController) { + return SingleChildScrollView( + controller: scrollController, + child: Container( + height: MediaQuery.of(context) + .size + .height * + 1.95, + child: Column( + children: [ + Padding( + padding: + EdgeInsets.all(8.0), + child: Row( + children: [ + Icon( + Icons.wrap_text, + ), + SizedBox( + width: 10.0, + ), + Texts( + 'Refine', + fontWeight: + FontWeight.w600, + ), + SizedBox( + width: 250.0, + ), + InkWell( + child: Texts( + 'Close', + color: Colors.red, + fontWeight: + FontWeight.w600, + fontSize: 15.0, + ), + onTap: () { + Navigator.pop( + context); + }, + ), + ], + ), + ), + Divider( + thickness: 1.0, + color: Colors.black12, + ), + Column( + children: [ + ExpansionTile( + title: + Texts('Categorise'), + children: [ + Container( + height: 350, + child: ListView + .builder( + controller: + scrollController, + scrollDirection: + Axis + .vertical, + shrinkWrap: + true, + itemCount: model + .categoriseParent + .length, + itemBuilder: + (BuildContext + context, + int index) { + return CheckboxListTile( + tristate: + true, + title: Texts(model + .categoriseParent[index] + .name), + controlAffinity: + ListTileControlAffinity.leading, + value: + checkedCategorise, + onChanged: + (bool + value) { + setState( + () { + checkedCategorise = + value; + }); + }, + ); + }), + ) + ], + ), + Divider( + thickness: 1.0, + color: Colors.black12, + ), + ExpansionTile( + title: Texts('Brands'), + children: [ + Container( + height: 350, + child: ListView + .builder( + scrollDirection: + Axis + .vertical, + shrinkWrap: + true, + itemCount: model + .brandsList + .length, + itemBuilder: + (BuildContext + context, + int index) { + return CheckboxListTile( + tristate: + true, + title: Texts(model + .brandsList[index] + .name), + controlAffinity: + ListTileControlAffinity.leading, + value: + checkedBrands, + onChanged: + (bool + value) { + setState( + () { + checkedBrands = + value; + }); + }, + autofocus: + true, + ); + }), + ) + ], + ), + Divider( + thickness: 1.0, + color: Colors.black12, + ), + ExpansionTile( + title: Texts('Price'), + children: [ + Container( + color: Color( + 0xffEEEEEE), + child: Row( + mainAxisAlignment: + MainAxisAlignment + .spaceAround, + children: [ + Column( + mainAxisAlignment: + MainAxisAlignment + .start, + children: [ + Texts( + 'Min'), + Container( + color: Colors + .white, + width: + 200, + height: + 40, + child: + TextFormField( + decoration: + InputDecoration( + border: + OutlineInputBorder(), + ), + ), + ), + ], + ), + Column( + mainAxisAlignment: + MainAxisAlignment + .start, + children: [ + Texts( + 'Max'), + Container( + color: Colors + .white, + width: + 200, + height: + 40, + child: + TextFormField( + decoration: + InputDecoration( + border: + OutlineInputBorder(), + ), + ), + ), + ], + ), + ], + ), + ) + ], + ), + Divider( + thickness: 1.0, + color: Colors.black12, + ), + SizedBox( + height: MediaQuery.of( + context) + .size + .height * + 0.4, + ), + Padding( + padding: + EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: + MainAxisAlignment + .spaceEvenly, + children: [ + Container( + width: 100, + child: Button( + label: 'Reset', + backgroundColor: + Colors.red, + ), + ), + SizedBox( + width: 30, + ), + Container( + width: 200, + child: Button( + label: 'Apply', + backgroundColor: + Colors + .green, + ), + ), + ], + ), + ), + ], + ), + ], + ), + ), + ); + }); + }, + ); + }, ), Row( children: [ @@ -241,8 +577,8 @@ class ParentCategorisePage extends StatelessWidget { child: VerticalDivider( color: Colors.black45, thickness: 1.0, - //width: 0.3, - // indent: 0.0, +//width: 0.3, +// indent: 0.0, ), ), Padding( @@ -250,23 +586,25 @@ class ParentCategorisePage extends StatelessWidget { child: InkWell( child: styleIcon, onTap: () { - if (styleOne == true) { - styleOne = false; - styleTwo = true; - styleIcon = Icon( - Icons.auto_awesome_mosaic, - color: Colors.blue, - size: 29.0, - ); - } else { - styleOne = true; - styleTwo = false; - styleIcon = Icon( - Icons.widgets_sharp, - color: Colors.blue, - size: 29.0, - ); - } + setState(() { + if (styleOne == true) { + styleOne = false; + styleTwo = true; + styleIcon = Icon( + Icons.auto_awesome_mosaic, + color: Colors.blue, + size: 29.0, + ); + } else { + styleOne = true; + styleTwo = false; + styleIcon = Icon( + Icons.widgets_sharp, + color: Colors.blue, + size: 29.0, + ); + } + }); }, ), ), @@ -522,229 +860,168 @@ class ParentCategorisePage extends StatelessWidget { }, ), ) - : Expanded( - child: Container( - child: ListView.builder( - itemCount: model.parentProducts.length, - itemBuilder: - (BuildContext context, int index) { - return Card( - // color: - // model.products[index].discountName != - // null - // ? Color(0xffFFFF00) - // : Colors.white, - child: Row( - children: [ - Stack( - children: [ - Column( - children: [ - if (model - .parentProducts[ - index] - .discountName != - null) - Container( - decoration: - BoxDecoration(), - child: Padding( - padding: - EdgeInsets.only( - left: 9.0, - top: 8.0, - right: 10.0, - ), - child: Container( - color: - Colors.yellow, - height: 25.0, - width: 70.0, - child: Center( - child: Texts( - 'offer' - .toUpperCase(), - color: - Colors.red, - fontSize: 13.0, - fontWeight: - FontWeight - .w900, - ), - ), - ), - ), - transform: new Matrix4 - .rotationZ(6.15099), + : Container( + height: MediaQuery.of(context).size.height * 5.0, + child: ListView.builder( + physics: NeverScrollableScrollPhysics(), + itemCount: model.parentProducts.length, + itemBuilder: + (BuildContext context, int index) { + return Card( + child: Row( + children: [ + Stack( + children: [ + Column( + children: [ + Container( + decoration: BoxDecoration(), + child: Padding( + padding: EdgeInsets.only( + left: 9.0, + top: 8.0, + right: 10.0, ), - Container( - margin: - EdgeInsets.fromLTRB( - 0, 0, 0, 0), - alignment: - Alignment.center, - child: Image.network( - model - .parentProducts[ - index] - .images - .isNotEmpty - ? model + ), + ), + Container( + margin: EdgeInsets.fromLTRB( + 0, 0, 0, 0), + alignment: Alignment.center, + child: Image.network( + model + .parentProducts[ + index] + .images + .isNotEmpty + ? model + .parentProducts[ + index] + .images[0] + .thumb + : 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/No_image_3x4.svg/1200px-No_image_3x4.svg.png', + fit: BoxFit.contain, + height: 80, + ), + ), + ], + ), + Column( + children: [ + Container( + width: model .parentProducts[ index] - .images[0] - .thumb - : 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/No_image_3x4.svg/1200px-No_image_3x4.svg.png', - fit: BoxFit.cover, - height: 80, - ), + .rxMessage != + null + ? MediaQuery.of(context) + .size + .width / + 5 + : 0, + padding: EdgeInsets.all(4), + decoration: BoxDecoration( + color: Color(0xffb23838), + borderRadius: + BorderRadius.only( + topLeft: Radius + .circular(6)), ), - ], - ), - Column( - children: [ - Container( - width: model + child: Texts( + model .parentProducts[ index] .rxMessage != null - ? MediaQuery.of( - context) - .size - .width / - 5 - : 0, - padding: - EdgeInsets.all(4), - decoration: BoxDecoration( - color: - Color(0xffb23838), - borderRadius: - BorderRadius.only( - topLeft: Radius - .circular( - 6)), - ), - child: Texts( - model - .parentProducts[ - index] - .rxMessage != - null - ? model - .parentProducts[ - index] - .rxMessage - : "", - color: Colors.white, - regular: true, - fontSize: 10, - fontWeight: - FontWeight.w400, - ), - ), - ], - ), - ], - ), - Container( - margin: EdgeInsets.symmetric( - horizontal: 6, - vertical: 0, - ), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - if (model - .parentProducts[index] - .discountName != - null) - Container( - width: 250.0, - height: 18.5, - decoration: BoxDecoration( - color: - Color(0xff5AB145), - ), - child: Padding( - padding: EdgeInsets - .symmetric( - horizontal: 5.5, - ), - child: Texts( - model + ? model .parentProducts[ index] - .discountName, - regular: true, - color: Colors.white, - fontSize: 11.4, - ), - ), - ), - SizedBox( - height: 4.0, - ), - Texts( - model.parentProducts[index] - .name, - regular: true, - fontSize: 12, - fontWeight: FontWeight.w400, - ), - SizedBox( - height: 8.0, - ), - Padding( - padding: - const EdgeInsets.only( - top: 4, bottom: 4), - child: Texts( - "SAR ${model.parentProducts[index].price}", - bold: true, - fontSize: 14, + .rxMessage + : "", + color: Colors.white, + regular: true, + fontSize: 10, + fontWeight: + FontWeight.w400, ), ), - Row( - children: [ - StarRating( - totalAverage: model - .parentProducts[ - index] - .approvedRatingSum > - 0 - ? (model - .parentProducts[ - index] - .approvedRatingSum - .toDouble() / - model - .parentProducts[ - index] - .approvedRatingSum - .toDouble()) - .toDouble() - : 0, - forceStars: true), - Texts( - "(${model.parentProducts[index].approvedTotalReviews})", - regular: true, - fontSize: 10, - fontWeight: - FontWeight.w400, - ) - ], - ), ], ), + ], + ), + Container( + height: 100.0, + margin: EdgeInsets.symmetric( + horizontal: 6, + vertical: 0, ), - ], - ), - ); - }), - ), + child: Column( + mainAxisAlignment: + MainAxisAlignment.spaceAround, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + SizedBox( + height: 4.0, + ), + Texts( + model.parentProducts[index] + .name, + regular: true, + fontSize: 13.2, + fontWeight: FontWeight.w500, + maxLines: 5, + ), + SizedBox( + height: 8.0, + ), + Padding( + padding: + const EdgeInsets.only( + top: 4, bottom: 4), + child: Texts( + "SAR ${model.parentProducts[index].price}", + bold: true, + fontSize: 14, + ), + ), + Row( + children: [ + StarRating( + totalAverage: model + .parentProducts[ + index] + .approvedRatingSum > + 0 + ? (model + .parentProducts[ + index] + .approvedRatingSum + .toDouble() / + model + .parentProducts[ + index] + .approvedRatingSum + .toDouble()) + .toDouble() + : 0, + forceStars: true), + Texts( + "(${model.parentProducts[index].approvedTotalReviews})", + regular: true, + fontSize: 10, + fontWeight: + FontWeight.w400, + ) + ], + ), + ], + ), + ), + ], + ), + ); + }), ) ], ), diff --git a/lib/pages/pharmacy_categorise.dart b/lib/pages/pharmacy_categorise.dart index 640251ec..b9954d20 100644 --- a/lib/pages/pharmacy_categorise.dart +++ b/lib/pages/pharmacy_categorise.dart @@ -1,10 +1,16 @@ import 'package:charts_flutter/flutter.dart'; +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacy_categorise_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/landing/landing_page_pharmcy.dart'; import 'package:diplomaticquarterapp/pages/parent_categorise_page.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; - +import 'package:barcode_scan/platform_wrapper.dart'; +import 'package:provider/provider.dart'; import 'base/base_view.dart'; import 'final_products_page.dart'; @@ -18,6 +24,7 @@ class _PharmacyCategorisePageState extends State { @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) => model.getCategorise(), builder: (BuildContext context, PharmacyCategoriseViewModel model, @@ -50,7 +57,9 @@ class _PharmacyCategorisePageState extends State { child: Padding( padding: EdgeInsets.symmetric(horizontal: 10.0), child: Texts( - model.categorise[index].name, + projectViewModel.isArabic + ? model.categorise[index].namen + : model.categorise[index].name, fontWeight: FontWeight.w600, ), ), @@ -77,7 +86,7 @@ class _PharmacyCategorisePageState extends State { ), ), Container( - height: 200, + height: 150, child: Column( children: [ Divider( @@ -102,7 +111,9 @@ class _PharmacyCategorisePageState extends State { child: Padding( padding: EdgeInsets.symmetric(horizontal: 10.0), child: Texts( - 'best sellers', + projectViewModel.isArabic + ? 'الاكثر مبيعا' + : 'Best Sellers', fontWeight: FontWeight.w600, ), ), @@ -123,7 +134,9 @@ class _PharmacyCategorisePageState extends State { child: Padding( padding: EdgeInsets.symmetric(horizontal: 10.0), child: Texts( - 'Most Viewed', + projectViewModel.isArabic + ? 'الاكثر مشاهدة' + : 'Most Viewed', fontWeight: FontWeight.w600, ), ), @@ -147,7 +160,9 @@ class _PharmacyCategorisePageState extends State { child: Padding( padding: EdgeInsets.symmetric(horizontal: 10.0), child: Texts( - 'New Proudcts', + projectViewModel.isArabic + ? 'منتجات جديدة' + : 'New Products', fontWeight: FontWeight.w600, ), ), @@ -157,18 +172,27 @@ class _PharmacyCategorisePageState extends State { Expanded( child: Padding( padding: EdgeInsets.all(4.0), - child: Container( - height: 50.0, - width: 55.0, - decoration: BoxDecoration( - color: Colors.purple.shade200.withOpacity(0.34), - borderRadius: BorderRadius.circular(5.0), - ), - child: Padding( - padding: EdgeInsets.symmetric(horizontal: 10.0), - child: Texts( - 'Recently Viewed', - fontWeight: FontWeight.w600, + child: InkWell( + onTap: () { + _scanQrAndGetPatient(context, model); + }, + child: Container( + height: 50.0, + width: 55.0, + decoration: BoxDecoration( + color: + Colors.purple.shade200.withOpacity(0.34), + borderRadius: BorderRadius.circular(5.0), + ), + child: Padding( + padding: + EdgeInsets.symmetric(horizontal: 10.0), + child: Texts( + projectViewModel.isArabic + ? 'شوهد مؤخرا' + : 'Recently Viewed', + fontWeight: FontWeight.w600, + ), ), ), ), @@ -183,4 +207,32 @@ class _PharmacyCategorisePageState extends State { ), ); } + + _scanQrAndGetPatient( + BuildContext context, + PharmacyCategoriseViewModel model, + ) async { + /// When give qr we will change this method to get data + /// var result = await BarcodeScanner.scan(); + /// int patientID = get from qr result + var result = await BarcodeScanner.scan(); + if (result.rawContent == "") { + List listOfParams = result.rawContent.split(','); + // ScanQrRequestModel _scanQrRequestModel = ScanQrRequestModel( + // deliveryOrderID: int.parse(listOfParams[0]), groupID: 0); + String patientType = "1"; + await model.scanQr(); + if (model.state == ViewState.ErrorLocal) { + Utils.showErrorToast(model.error); + } else { + AppToast.showSuccessToast(message: model.scanList[0].id); + { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => LandingPagePharmacy()), + ); + } + } + } + } } diff --git a/lib/pages/search_products_page.dart b/lib/pages/search_products_page.dart new file mode 100644 index 00000000..45cafd35 --- /dev/null +++ b/lib/pages/search_products_page.dart @@ -0,0 +1,287 @@ +import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacy_categorise_view_model.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/input/text_field.dart'; +import 'package:diplomaticquarterapp/widgets/others/StarRating.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_pharmacy_widget.dart'; +import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart'; +import 'package:flutter/material.dart'; + +import 'base/base_view.dart'; + +class SearchProductsPage extends StatefulWidget { + @override + _SearchProductsPageState createState() => _SearchProductsPageState(); +} + +class _SearchProductsPageState extends State { + final textController = TextEditingController(); + final _formKey = GlobalKey(); + String msg = ''; + + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) => model.clearSearchList(), + builder: (BuildContext context, PharmacyCategoriseViewModel model, + Widget child) => + PharmacyAppScaffold( + appBarTitle: 'Search', + isBottomBar: false, + isShowAppBar: true, + backgroundColor: Colors.white, + isShowDecPage: false, + //baseViewModel: model, + body: SingleChildScrollView( + child: Container( + height: SizeConfig.screenHeight, + child: Column( + children: [ + Padding( + padding: EdgeInsets.all(8.0), + child: Row( + children: [ + Container( + width: MediaQuery.of(context).size.width * 0.79, + child: Form( + key: _formKey, + child: TextFields( + autoFocus: true, + hintText: 'Search', + fontSize: 19.0, + prefixIcon: Icon(Icons.search), + inputAction: TextInputAction.search, + onSaved: (value) { + //searchMedicine(model, context); + }, + onSubmit: (value) { + searchMedicine(model, context); + msg = 'No Result Found'; + }, + controller: textController, + validator: (value) { + if (value.isEmpty) { + return 'please Enter Product Name'; + } + return null; + }, + ), + ), + ), + SizedBox( + width: 10.0, + ), + InkWell( + child: Texts( + 'Cancel', + fontSize: 17.0, + fontWeight: FontWeight.w500, + ), + onTap: () { + Navigator.pop(context); + }, + ), + + // child: Container( + // child: Button( + // backgroundColor: Colors.green, + // loading: model.state == ViewState.BusyLocal, + // label: 'Search', + // onTap: () { + // searchMedicine(model, context); + // }), + // width: MediaQuery.of(context).size.width * 0.09, + // ), + ], + ), + ), + Center( + child: NetworkBaseView( + baseViewModel: model, + child: model.searchList.isNotEmpty + ? Container( + height: MediaQuery.of(context).size.height * 0.80, + child: GridView.builder( + //physics: NeverScrollableScrollPhysics(), + gridDelegate: + SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + crossAxisSpacing: 0.5, + mainAxisSpacing: 2.0, + childAspectRatio: 1.0, + ), + itemCount: model.searchList.length, + itemBuilder: (BuildContext context, int index) { + return Card( + color: model.searchList[index].discountName != + null + ? Color(0xffFFFF00) + : Colors.white, + elevation: 0, + shape: Border( + right: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + left: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + bottom: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + top: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + ), + margin: EdgeInsets.symmetric( + horizontal: 8, + vertical: 4, + ), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(110.0), + ), + color: Colors.white, + ), + padding: + EdgeInsets.symmetric(horizontal: 0), + width: + MediaQuery.of(context).size.width / 3, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Stack( + children: [ + Container( + margin: EdgeInsets.fromLTRB( + 0, 16, 0, 0), + alignment: Alignment.center, + child: Image.network( + model.searchList[index].images + .isNotEmpty + ? model.searchList[index] + .images[0].thumb + : 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/No_image_3x4.svg/1200px-No_image_3x4.svg.png', + fit: BoxFit.cover, + height: 80, + ), + ), + Container( + width: model.searchList[index] + .rxMessage != + null + ? MediaQuery.of(context) + .size + .width / + 5 + : 0, + padding: EdgeInsets.all(4), + decoration: BoxDecoration( + color: Color(0xffb23838), + borderRadius: BorderRadius.only( + topLeft: + Radius.circular(6)), + ), + child: Texts( + model.searchList[index] + .rxMessage != + null + ? model.searchList[index] + .rxMessage + : "", + color: Colors.white, + regular: true, + fontSize: 10, + fontWeight: FontWeight.w400, + ), + ), + ], + ), + Container( + margin: EdgeInsets.symmetric( + horizontal: 6, + vertical: 0, + ), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Texts( + model.searchList[index].name, + regular: true, + fontSize: 12, + fontWeight: FontWeight.w400, + ), + Padding( + padding: const EdgeInsets.only( + top: 4, bottom: 4), + child: Texts( + "SAR ${model.searchList[index].price}", + bold: true, + fontSize: 14, + ), + ), + Row( + children: [ + StarRating( + totalAverage: model + .searchList[ + index] + .approvedRatingSum > + 0 + ? (model + .searchList[ + index] + .approvedRatingSum + .toDouble() / + model + .searchList[ + index] + .approvedRatingSum + .toDouble()) + .toDouble() + : 0, + forceStars: true), + Texts( + "(${model.searchList[index].approvedTotalReviews})", + regular: true, + fontSize: 10, + fontWeight: FontWeight.w400, + ) + ], + ), + ], + ), + ), + ], + ), + ), + ); + }, + ), + ) + : Texts(msg), + ), + ) + ], + ), + ), + ), + ), + ); + } + + searchMedicine(PharmacyCategoriseViewModel model, BuildContext context) { + Utils.hideKeyboard(context); + if (_formKey.currentState.validate()) + model.searchProducts(productName: textController.text); + } +} diff --git a/lib/pages/sub_categorise_page.dart b/lib/pages/sub_categorise_page.dart index 039d40e2..45c9fd6c 100644 --- a/lib/pages/sub_categorise_page.dart +++ b/lib/pages/sub_categorise_page.dart @@ -1,5 +1,6 @@ import 'package:diplomaticquarterapp/core/viewModels/pharmacy_categorise_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/StarRating.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_pharmacy_widget.dart'; @@ -10,12 +11,24 @@ import 'package:provider/provider.dart'; import 'base/base_view.dart'; import 'final_products_page.dart'; -class SubCategorisePage extends StatelessWidget { - String parentId; +class SubCategorisePage extends StatefulWidget { String id; String title; - SubCategorisePage({this.id, this.title, this.parentId}); + String parentId; + SubCategorisePage({this.id, this.parentId, this.title}); + @override + _SubCategorisePageState createState() => + _SubCategorisePageState(id: id, title: title, parentId: parentId); +} + +class _SubCategorisePageState extends State { + bool checkedBrands = false; + bool checkedCategorise = false; + String id; + String title; + String parentId; + _SubCategorisePageState({this.title, this.parentId, this.id}); String categoriseName = "Personal Care"; bool styleOne = true; bool styleTwo = false; @@ -26,7 +39,6 @@ class SubCategorisePage extends StatelessWidget { ); @override Widget build(BuildContext context) { - ProjectViewModel projectProvider = Provider.of(context); return BaseView( onModelReady: (model) => model.getSubCategorise(i: id), builder: (BuildContext context, PharmacyCategoriseViewModel model, @@ -40,7 +52,7 @@ class SubCategorisePage extends StatelessWidget { baseViewModel: model, body: SingleChildScrollView( child: Container( - height: MediaQuery.of(context).size.height * 2.97, + height: MediaQuery.of(context).size.height * 5.97, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -72,16 +84,82 @@ class SubCategorisePage extends StatelessWidget { height: 160.0, width: double.infinity), ), - if (model.subCategorise.length >= 8) + if (model.subCategorise.length > 8) Column( children: [ - Padding( - padding: EdgeInsets.all(10.0), - child: Container( - child: Texts(model.categoriseParent.length >= 8 - ? 'View All Categories' - : ''), + InkWell( + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: EdgeInsets.all(10.0), + child: Container( + child: Texts('View All Categories'), + ), + ), + Icon(Icons.arrow_forward) + ], ), + onTap: () { + showModalBottomSheet( + isScrollControlled: true, + context: context, + builder: (BuildContext context) { + return Container( + height: + MediaQuery.of(context).size.height * + 0.89, + color: Colors.white, + child: Center( + child: ListView.builder( + scrollDirection: Axis.vertical, + itemCount: + model.subCategorise.length, + itemBuilder: (BuildContext context, + int index) { + return Container( + child: Padding( + padding: EdgeInsets.all(8.0), + child: InkWell( + child: Column( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Texts(model + .subCategorise[ + index] + .name), + Divider( + thickness: 0.6, + color: Colors.black12, + ) + ], + ), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + FinalProductsPage( + id: model + .subCategorise[ + index] + .id, + ), + ), + ); + }, + ), + ), + ); + }), + ), + ); + }, + ); + }, ), Divider( thickness: 1.0, @@ -174,14 +252,297 @@ class SubCategorisePage extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Row( - children: [ - Icon(Icons.wrap_text), - SizedBox( - width: 10.0, - ), - Texts('Refine'), - ], + InkWell( + child: Row( + children: [ + Icon(Icons.wrap_text), + SizedBox( + width: 10.0, + ), + Texts( + 'Refine', + fontWeight: FontWeight.w600, + ), + ], + ), + onTap: () { + showModalBottomSheet( + isScrollControlled: true, + context: context, + builder: (BuildContext context) { + return DraggableScrollableSheet( + initialChildSize: 0.95, + maxChildSize: 0.95, + minChildSize: 0.9, + builder: (BuildContext context, + ScrollController scrollController) { + return SingleChildScrollView( + controller: scrollController, + child: Container( + height: MediaQuery.of(context) + .size + .height * + 1.95, + child: Column( + children: [ + Padding( + padding: + EdgeInsets.all(8.0), + child: Row( + children: [ + Icon( + Icons.wrap_text, + ), + SizedBox( + width: 10.0, + ), + Texts( + 'Refine', + fontWeight: + FontWeight.w600, + ), + SizedBox( + width: 250.0, + ), + InkWell( + child: Texts( + 'Close', + color: Colors.red, + fontWeight: + FontWeight.w600, + fontSize: 15.0, + ), + onTap: () { + Navigator.pop( + context); + }, + ), + ], + ), + ), + Divider( + thickness: 1.0, + color: Colors.black12, + ), + Column( + children: [ + ExpansionTile( + title: + Texts('Categorise'), + children: [ + Container( + height: 350, + child: ListView + .builder( + controller: + scrollController, + scrollDirection: + Axis + .vertical, + shrinkWrap: + true, + itemCount: model + .categoriseParent + .length, + itemBuilder: + (BuildContext + context, + int index) { + return CheckboxListTile( + tristate: + true, + title: Texts(model + .categoriseParent[index] + .name), + controlAffinity: + ListTileControlAffinity.leading, + value: + checkedCategorise, + onChanged: + (bool + value) { + setState( + () { + checkedCategorise = + value; + }); + }, + ); + }), + ) + ], + ), + Divider( + thickness: 1.0, + color: Colors.black12, + ), + ExpansionTile( + title: Texts('Brands'), + children: [ + Container( + height: 350, + child: ListView + .builder( + scrollDirection: + Axis + .vertical, + shrinkWrap: + true, + itemCount: model + .brandsList + .length, + itemBuilder: + (BuildContext + context, + int index) { + return CheckboxListTile( + tristate: + true, + title: Texts(model + .brandsList[index] + .name), + controlAffinity: + ListTileControlAffinity.leading, + value: + checkedBrands, + onChanged: + (bool + value) { + setState( + () { + checkedBrands = + value; + }); + }, + autofocus: + true, + ); + }), + ) + ], + ), + Divider( + thickness: 1.0, + color: Colors.black12, + ), + ExpansionTile( + title: Texts('Price'), + children: [ + Container( + color: Color( + 0xffEEEEEE), + child: Row( + mainAxisAlignment: + MainAxisAlignment + .spaceAround, + children: [ + Column( + mainAxisAlignment: + MainAxisAlignment + .start, + children: [ + Texts( + 'Min'), + Container( + color: Colors + .white, + width: + 200, + height: + 40, + child: + TextFormField( + decoration: + InputDecoration( + border: + OutlineInputBorder(), + ), + ), + ), + ], + ), + Column( + mainAxisAlignment: + MainAxisAlignment + .start, + children: [ + Texts( + 'Max'), + Container( + color: Colors + .white, + width: + 200, + height: + 40, + child: + TextFormField( + decoration: + InputDecoration( + border: + OutlineInputBorder(), + ), + ), + ), + ], + ), + ], + ), + ) + ], + ), + Divider( + thickness: 1.0, + color: Colors.black12, + ), + SizedBox( + height: MediaQuery.of( + context) + .size + .height * + 0.4, + ), + Padding( + padding: + EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: + MainAxisAlignment + .spaceEvenly, + children: [ + Container( + width: 100, + child: Button( + label: 'Reset', + backgroundColor: + Colors.red, + ), + ), + SizedBox( + width: 30, + ), + Container( + width: 200, + child: Button( + label: 'Apply', + backgroundColor: + Colors + .green, + ), + ), + ], + ), + ), + ], + ), + ], + ), + ), + ); + }); + }, + ); + }, ), Row( children: [ @@ -199,23 +560,25 @@ class SubCategorisePage extends StatelessWidget { child: InkWell( child: styleIcon, onTap: () { - if (styleOne == true) { - styleOne = false; - styleTwo = true; - styleIcon = Icon( - Icons.auto_awesome_mosaic, - color: Colors.blue, - size: 29.0, - ); - } else { - styleOne = true; - styleTwo = false; - styleIcon = Icon( - Icons.widgets_sharp, - color: Colors.blue, - size: 29.0, - ); - } + setState(() { + if (styleOne == true) { + styleOne = false; + styleTwo = true; + styleIcon = Icon( + Icons.auto_awesome_mosaic, + color: Colors.blue, + size: 29.0, + ); + } else { + styleOne = true; + styleTwo = false; + styleIcon = Icon( + Icons.widgets_sharp, + color: Colors.blue, + size: 29.0, + ); + } + }); }, ), ), @@ -230,7 +593,7 @@ class SubCategorisePage extends StatelessWidget { ), styleOne == true ? Container( - height: MediaQuery.of(context).size.height * 1.85, + height: MediaQuery.of(context).size.height * 3.85, child: GridView.builder( physics: NeverScrollableScrollPhysics(), gridDelegate: @@ -292,35 +655,6 @@ class SubCategorisePage extends StatelessWidget { children: [ Stack( children: [ - if (model.subProducts[index] - .discountName != - null) - RotatedBox( - quarterTurns: 4, - child: Container( - decoration: - BoxDecoration(), - child: Padding( - padding: - EdgeInsets.only( - right: 5.0, - top: 20.0, - bottom: 5.0, - ), - child: Texts( - 'offer' - .toUpperCase(), - color: Colors.red, - fontSize: 13.0, - fontWeight: - FontWeight.w900, - ), - ), - transform: new Matrix4 - .rotationZ( - 5.837200), - ), - ), Container( margin: EdgeInsets.fromLTRB( 0, 16, 0, 0), @@ -384,29 +718,6 @@ class SubCategorisePage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ - if (model.subProducts[index] - .discountName != - null) - Container( - width: double.infinity, - height: 13.0, - decoration: - BoxDecoration( - color: - Color(0xff5AB145), - ), - child: Center( - child: Texts( - model - .subProducts[ - index] - .discountName, - regular: true, - color: Colors.white, - fontSize: 10.4, - ), - ), - ), Texts( model.subProducts[index] .name, @@ -462,222 +773,167 @@ class SubCategorisePage extends StatelessWidget { }, ), ) - : Expanded( - child: Container( - child: ListView.builder( - itemCount: model.subProducts.length, - itemBuilder: - (BuildContext context, int index) { - return Card( - // color: - // model.products[index].discountName != - // null - // ? Color(0xffFFFF00) - // : Colors.white, - child: Row( - children: [ - Stack( - children: [ - Column( - children: [ - if (model.subProducts[index] - .discountName != - null) - Container( - decoration: - BoxDecoration(), - child: Padding( - padding: - EdgeInsets.only( - left: 9.0, - top: 8.0, - right: 10.0, - ), - child: Container( - color: - Colors.yellow, - height: 25.0, - width: 70.0, - child: Center( - child: Texts( - 'offer' - .toUpperCase(), - color: - Colors.red, - fontSize: 13.0, - fontWeight: - FontWeight - .w900, - ), - ), - ), - ), - transform: new Matrix4 - .rotationZ(6.15099), - ), - Container( - margin: - EdgeInsets.fromLTRB( - 0, 0, 0, 0), - alignment: - Alignment.center, - child: Image.network( - model - .subProducts[index] - .images[index] - .thumb, - fit: BoxFit.cover, - height: 80, + : Container( + height: MediaQuery.of(context).size.height * 5.0, + child: ListView.builder( + physics: NeverScrollableScrollPhysics(), + itemCount: model.subProducts.length, + itemBuilder: + (BuildContext context, int index) { + return Card( + child: Row( + children: [ + Stack( + children: [ + Column( + children: [ + Container( + decoration: BoxDecoration(), + child: Padding( + padding: EdgeInsets.only( + left: 9.0, + top: 8.0, + right: 10.0, ), ), - ], - ), - Column( - children: [ - Container( - width: model - .subProducts[ - index] - .rxMessage != - null - ? MediaQuery.of( - context) - .size - .width / - 5 - : 0, - padding: - EdgeInsets.all(4), - decoration: BoxDecoration( - color: - Color(0xffb23838), - borderRadius: - BorderRadius.only( - topLeft: Radius - .circular( - 6)), - ), - child: Texts( - model.subProducts[index] - .rxMessage != - null - ? model - .subProducts[ - index] - .rxMessage - : "", - color: Colors.white, - regular: true, - fontSize: 10, - fontWeight: - FontWeight.w400, - ), + ), + Container( + margin: EdgeInsets.fromLTRB( + 0, 0, 0, 0), + alignment: Alignment.center, + child: Image.network( + model.subProducts[index] + .images.isNotEmpty + ? model + .subProducts[ + index] + .images[0] + .thumb + : 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/No_image_3x4.svg/1200px-No_image_3x4.svg.png', + fit: BoxFit.contain, + height: 80, ), - ], - ), - ], - ), - Container( - margin: EdgeInsets.symmetric( - horizontal: 6, - vertical: 0, + ), + ], ), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, + Column( children: [ - if (model.subProducts[index] - .discountName != - null) - Container( - width: 250.0, - height: 18.5, - decoration: BoxDecoration( - color: - Color(0xff5AB145), - ), - child: Padding( - padding: EdgeInsets - .symmetric( - horizontal: 5.5, - ), - child: Texts( - model + Container( + width: model + .subProducts[ + index] + .rxMessage != + null + ? MediaQuery.of(context) + .size + .width / + 5 + : 0, + padding: EdgeInsets.all(4), + decoration: BoxDecoration( + color: Color(0xffb23838), + borderRadius: + BorderRadius.only( + topLeft: Radius + .circular(6)), + ), + child: Texts( + model.subProducts[index] + .rxMessage != + null + ? model .subProducts[ index] - .discountName, - regular: true, - color: Colors.white, - fontSize: 11.4, - ), - ), + .rxMessage + : "", + color: Colors.white, + regular: true, + fontSize: 10, + fontWeight: + FontWeight.w400, ), - SizedBox( - height: 4.0, ), - Texts( - projectProvider.isArabic - ? model - .subProducts[index] - .name - : model - .subProducts[index] - .namen, + ], + ), + ], + ), + Container( + height: 100.0, + margin: EdgeInsets.symmetric( + horizontal: 6, + vertical: 0, + ), + child: Column( + mainAxisAlignment: + MainAxisAlignment.spaceAround, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + SizedBox( + height: 4.0, + ), + Container( + height: 35.0, + width: 250.0, + child: Texts( + model.subProducts[index] + .name, regular: true, - fontSize: 12, - fontWeight: FontWeight.w400, - ), - SizedBox( - height: 8.0, + fontSize: 13.2, + fontWeight: FontWeight.w500, + maxLines: 2, ), - Padding( - padding: - const EdgeInsets.only( - top: 4, bottom: 4), - child: Texts( - "SAR ${model.subProducts[index].price}", - bold: true, - fontSize: 14, - ), - ), - Row( - children: [ - StarRating( - totalAverage: model - .subProducts[ - index] - .approvedRatingSum > - 0 - ? (model - .subProducts[ - index] - .approvedRatingSum - .toDouble() / - model - .subProducts[ - index] - .approvedRatingSum - .toDouble()) - .toDouble() - : 0, - forceStars: true), - Texts( - "(${model.subProducts[index].approvedTotalReviews})", - regular: true, - fontSize: 10, - fontWeight: - FontWeight.w400, - ) - ], + ), + SizedBox( + height: 8.0, + ), + Padding( + padding: + const EdgeInsets.only( + top: 4, bottom: 4), + child: Texts( + "SAR ${model.subProducts[index].price}", + bold: true, + fontSize: 14, ), - ], - ), + ), + Row( + children: [ + StarRating( + totalAverage: model + .subProducts[ + index] + .approvedRatingSum > + 0 + ? (model + .subProducts[ + index] + .approvedRatingSum + .toDouble() / + model + .parentProducts[ + index] + .approvedRatingSum + .toDouble()) + .toDouble() + : 0, + forceStars: true), + Texts( + "(${model.subProducts[index].approvedTotalReviews})", + regular: true, + fontSize: 10, + fontWeight: + FontWeight.w400, + ) + ], + ), + ], ), - ], - ), - ); - }), - ), + ), + ], + ), + ); + }), ) ], ), diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index c5246e35..e71ff473 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -695,17 +695,25 @@ class TranslationBase { localizedValues['LoginRegister'][locale.languageCode]; String get orderLog => localizedValues['OrderLog'][locale.languageCode]; String get infoLab => localizedValues['info-lab'][locale.languageCode]; - String get infoRadiology => localizedValues['info-radiology'][locale.languageCode]; + String get infoRadiology => + localizedValues['info-radiology'][locale.languageCode]; // pharmacy module - String get medicationRefill => localizedValues['medicationRefill'][locale.languageCode]; - String get offersAndPromotions => localizedValues['offersAndPromotions'][locale.languageCode]; - String get myPrescriptions => localizedValues['myPrescriptions'][locale.languageCode]; - String get searchAndScanMedication => localizedValues['searchAndScanMedication'][locale.languageCode]; - String get shopByBrands => localizedValues['shopByBrands'][locale.languageCode]; - String get recentlyViewed => localizedValues['recentlyViewed'][locale.languageCode]; + String get medicationRefill => + localizedValues['medicationRefill'][locale.languageCode]; + String get offersAndPromotions => + localizedValues['offersAndPromotions'][locale.languageCode]; + String get myPrescriptions => + localizedValues['myPrescriptions'][locale.languageCode]; + String get searchAndScanMedication => + localizedValues['searchAndScanMedication'][locale.languageCode]; + String get shopByBrands => + localizedValues['shopByBrands'][locale.languageCode]; + String get recentlyViewed => + localizedValues['recentlyViewed'][locale.languageCode]; String get bestSellers => localizedValues['bestSellers'][locale.languageCode]; - String get deleteAllItems => localizedValues['deleteAllItems'][locale.languageCode]; + String get deleteAllItems => + localizedValues['deleteAllItems'][locale.languageCode]; String get termsService => localizedValues['TermsService'][locale.languageCode]; @@ -731,6 +739,11 @@ class TranslationBase { String get selectAge => localizedValues['select-age'][locale.languageCode]; String get iAm => localizedValues['i-am'][locale.languageCode]; String get yearOld => localizedValues['years-old'][locale.languageCode]; + String get categorise => localizedValues['categorise'][locale.languageCode]; + String get cart => localizedValues['cart'][locale.languageCode]; + String get wishList => localizedValues['wishList'][locale.languageCode]; + String get searchProductHere => + localizedValues['searchProductHere'][locale.languageCode]; } class TranslationBaseDelegate extends LocalizationsDelegate { diff --git a/lib/widgets/input/text_field.dart b/lib/widgets/input/text_field.dart index 7cfba5e6..7b732fec 100644 --- a/lib/widgets/input/text_field.dart +++ b/lib/widgets/input/text_field.dart @@ -73,7 +73,7 @@ class TextFields extends StatefulWidget { this.fontSize = 16.0, this.fontWeight = FontWeight.w700, this.autoValidate = false, - this.fillColor, + this.fillColor, this.hintColor}) : super(key: key); @@ -214,7 +214,6 @@ class _TextFieldsState extends State { blurRadius: focus ? 34.0 : 12.0) ]), child: TextFormField( - keyboardAppearance: Theme.of(context).brightness, scrollPhysics: BouncingScrollPhysics(), autovalidate: widget.autoValidate, @@ -253,15 +252,12 @@ class _TextFieldsState extends State { ] : widget.inputFormatters, decoration: InputDecoration( - counterText: "", hintText: widget.hintText, hintStyle: TextStyle( - fontSize: widget.fontSize, - fontWeight: widget.fontWeight, - color: widget.hintColor ?? Theme.of(context).hintColor, - - + fontSize: widget.fontSize, + fontWeight: widget.fontWeight, + color: widget.hintColor ?? Theme.of(context).hintColor, ), contentPadding: widget.padding != null ? widget.padding diff --git a/lib/widgets/pharmacy/bottom_nav_pharmacy_bar.dart b/lib/widgets/pharmacy/bottom_nav_pharmacy_bar.dart index 7012b392..d9717c38 100644 --- a/lib/widgets/pharmacy/bottom_nav_pharmacy_bar.dart +++ b/lib/widgets/pharmacy/bottom_nav_pharmacy_bar.dart @@ -61,7 +61,7 @@ class _BottomNavPharmacyBarState extends State { changeIndex: _changeIndex, index: widget.index, currentIndex: 1, - title: 'Categorise', + title: TranslationBase.of(context).categorise, ), // Expanded( // child: SizedBox( @@ -83,7 +83,7 @@ class _BottomNavPharmacyBarState extends State { changeIndex: _changeIndex, index: widget.index, currentIndex: 2, - title: 'Wishlist'), + title: TranslationBase.of(context).wishList), BottomNavPharmacyItem( icon: EvaIcons.person, @@ -91,7 +91,7 @@ class _BottomNavPharmacyBarState extends State { changeIndex: _changeIndex, index: widget.index, currentIndex: 3, - title: 'My Account', + title: TranslationBase.of(context).myAccount, ), BottomNavPharmacyItem( icon: EvaIcons.shoppingCart, @@ -99,7 +99,7 @@ class _BottomNavPharmacyBarState extends State { changeIndex: _changeIndex, index: widget.index, currentIndex: 4, - title: 'Cart') + title: TranslationBase.of(context).cart) ], ), ), diff --git a/pubspec.yaml b/pubspec.yaml index f43d4d93..9747e6a3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -82,7 +82,8 @@ dependencies: google_maps_flutter: ^1.0.3 # Qr code Scanner TODO fix it - #barcode_scan: ^3.0.1 + barcode_scanner: ^1.0.1 + barcode_scan: any # Rating Stars rating_bar: ^0.2.0