1132 lines
68 KiB
Dart
1132 lines
68 KiB
Dart
import 'package:badges/badges.dart' as badges;
|
|
import 'package:customer/constant/constant.dart';
|
|
import 'package:customer/controllers/home_e_commerce_controller.dart';
|
|
import 'package:customer/controllers/theme_controller.dart';
|
|
import 'package:customer/models/advertisement_model.dart';
|
|
import 'package:customer/models/banner_model.dart';
|
|
import 'package:customer/models/brands_model.dart';
|
|
import 'package:customer/models/favourite_model.dart';
|
|
import 'package:customer/models/product_model.dart';
|
|
import 'package:customer/models/user_model.dart';
|
|
import 'package:customer/models/vendor_category_model.dart';
|
|
import 'package:customer/models/vendor_model.dart';
|
|
import 'package:customer/screen_ui/auth_screens/login_screen.dart';
|
|
import 'package:customer/screen_ui/ecommarce/all_brand_product_screen.dart';
|
|
import 'package:customer/screen_ui/ecommarce/all_category_product_screen.dart';
|
|
import 'package:customer/screen_ui/location_enable_screens/address_list_screen.dart';
|
|
import 'package:customer/screen_ui/multi_vendor_service/advertisement_screens/all_advertisement_screen.dart';
|
|
import 'package:customer/screen_ui/multi_vendor_service/cart_screen/cart_screen.dart';
|
|
import 'package:customer/screen_ui/multi_vendor_service/home_screen/category_restaurant_screen.dart';
|
|
import 'package:customer/screen_ui/multi_vendor_service/home_screen/restaurant_list_screen.dart' show RestaurantListScreen;
|
|
import 'package:customer/screen_ui/multi_vendor_service/home_screen/view_all_category_screen.dart';
|
|
import 'package:customer/screen_ui/multi_vendor_service/restaurant_details_screen/restaurant_details_screen.dart';
|
|
import 'package:customer/screen_ui/multi_vendor_service/search_screen/search_screen.dart';
|
|
import 'package:customer/service/fire_store_utils.dart';
|
|
import 'package:customer/themes/app_them_data.dart';
|
|
import 'package:customer/themes/responsive.dart';
|
|
import 'package:customer/themes/round_button_border.dart';
|
|
import 'package:customer/themes/show_toast_dialog.dart';
|
|
import 'package:customer/themes/text_field_widget.dart';
|
|
import 'package:customer/utils/network_image_widget.dart';
|
|
import 'package:customer/widget/osm_map/map_picker_page.dart';
|
|
import 'package:customer/widget/place_picker/location_picker_screen.dart';
|
|
import 'package:customer/widget/place_picker/selected_location_model.dart';
|
|
import 'package:customer/widget/video_widget.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_svg/flutter_svg.dart';
|
|
import 'package:geocoding/geocoding.dart';
|
|
import 'package:geolocator/geolocator.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:url_launcher/url_launcher.dart';
|
|
|
|
class HomeECommerceScreen extends StatelessWidget {
|
|
const HomeECommerceScreen({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final themeController = Get.find<ThemeController>();
|
|
final isDark = themeController.isDark.value;
|
|
return GetX(
|
|
init: HomeECommerceController(),
|
|
builder: (controller) {
|
|
return Scaffold(
|
|
backgroundColor: isDark ? AppThemeData.grey900 : AppThemeData.grey50,
|
|
appBar: AppBar(
|
|
backgroundColor: isDark ? AppThemeData.ecommerce300 : AppThemeData.ecommerce300,
|
|
titleSpacing: 0,
|
|
leading: InkWell(
|
|
onTap: () {
|
|
Get.back();
|
|
},
|
|
child: Icon(Icons.arrow_back, color: isDark ? AppThemeData.grey50 : AppThemeData.grey50, size: 20),
|
|
),
|
|
title: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Constant.userModel == null
|
|
? InkWell(
|
|
onTap: () {
|
|
Get.offAll(const LoginScreen());
|
|
},
|
|
child: Text("Login".tr, textAlign: TextAlign.center, style: AppThemeData.semiBoldTextStyle(color: isDark ? AppThemeData.grey50 : AppThemeData.grey50, fontSize: 12)),
|
|
)
|
|
: Text(Constant.userModel!.fullName(), textAlign: TextAlign.center, style: AppThemeData.semiBoldTextStyle(color: isDark ? AppThemeData.grey50 : AppThemeData.grey50, fontSize: 12)),
|
|
InkWell(
|
|
onTap: () async {
|
|
if (Constant.userModel != null) {
|
|
Get.to(AddressListScreen())!.then((value) {
|
|
if (value != null) {
|
|
ShippingAddress shippingAddress = value;
|
|
Constant.selectedLocation = shippingAddress;
|
|
controller.getData();
|
|
}
|
|
});
|
|
} else {
|
|
Constant.checkPermission(
|
|
onTap: () async {
|
|
ShowToastDialog.showLoader("Please wait...".tr);
|
|
|
|
// ✅ declare it once here!
|
|
ShippingAddress shippingAddress = ShippingAddress();
|
|
|
|
try {
|
|
await Geolocator.requestPermission();
|
|
await Geolocator.getCurrentPosition();
|
|
ShowToastDialog.closeLoader();
|
|
|
|
if (Constant.selectedMapType == 'osm') {
|
|
final result = await Get.to(() => MapPickerPage());
|
|
if (result != null) {
|
|
final firstPlace = result;
|
|
final lat = firstPlace.coordinates.latitude;
|
|
final lng = firstPlace.coordinates.longitude;
|
|
final address = firstPlace.address;
|
|
|
|
shippingAddress.addressAs = "Home";
|
|
shippingAddress.locality = address.toString();
|
|
shippingAddress.location = UserLocation(latitude: lat, longitude: lng);
|
|
Constant.selectedLocation = shippingAddress;
|
|
controller.getData();
|
|
Get.back();
|
|
}
|
|
} else {
|
|
Get.to(LocationPickerScreen())!.then((value) async {
|
|
if (value != null) {
|
|
SelectedLocationModel selectedLocationModel = value;
|
|
|
|
shippingAddress.addressAs = "Home";
|
|
shippingAddress.location = UserLocation(latitude: selectedLocationModel.latLng!.latitude, longitude: selectedLocationModel.latLng!.longitude);
|
|
shippingAddress.locality = "Picked from Map"; // You can reverse-geocode
|
|
|
|
Constant.selectedLocation = shippingAddress;
|
|
controller.getData();
|
|
}
|
|
});
|
|
}
|
|
} catch (e) {
|
|
await placemarkFromCoordinates(19.228825, 72.854118).then((valuePlaceMaker) {
|
|
Placemark placeMark = valuePlaceMaker[0];
|
|
shippingAddress.location = UserLocation(latitude: 19.228825, longitude: 72.854118);
|
|
String currentLocation =
|
|
"${placeMark.name}, ${placeMark.subLocality}, ${placeMark.locality}, ${placeMark.administrativeArea}, ${placeMark.postalCode}, ${placeMark.country}";
|
|
shippingAddress.locality = currentLocation;
|
|
});
|
|
|
|
Constant.selectedLocation = shippingAddress;
|
|
ShowToastDialog.closeLoader();
|
|
controller.getData();
|
|
}
|
|
},
|
|
context: context,
|
|
);
|
|
}
|
|
},
|
|
child: Text.rich(
|
|
maxLines: 1,
|
|
overflow: TextOverflow.ellipsis,
|
|
TextSpan(
|
|
children: [
|
|
TextSpan(text: Constant.selectedLocation.getFullAddress(), style: AppThemeData.boldTextStyle(color: isDark ? AppThemeData.grey50 : AppThemeData.grey50, fontSize: 14)),
|
|
WidgetSpan(child: SvgPicture.asset("assets/icons/ic_down.svg", colorFilter: ColorFilter.mode(AppThemeData.grey50, BlendMode.srcIn))),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
actions: [
|
|
Obx(
|
|
() => Padding(
|
|
padding: const EdgeInsets.only(right: 15.0, left: 10),
|
|
child: badges.Badge(
|
|
showBadge: true,
|
|
badgeContent: Text(
|
|
"${cartItem.length}",
|
|
style: TextStyle(
|
|
fontSize: 14,
|
|
overflow: TextOverflow.ellipsis,
|
|
fontFamily: AppThemeData.semiBold,
|
|
fontWeight: FontWeight.w600,
|
|
color: isDark ? AppThemeData.grey50 : AppThemeData.grey50,
|
|
),
|
|
),
|
|
badgeStyle: badges.BadgeStyle(shape: badges.BadgeShape.circle, badgeColor: AppThemeData.info300),
|
|
child: InkWell(
|
|
onTap: () async {
|
|
(await Get.to(const CartScreen()));
|
|
controller.getCartData();
|
|
},
|
|
child: ClipOval(
|
|
child: Container(
|
|
width: 30,
|
|
height: 30,
|
|
decoration: ShapeDecoration(
|
|
shape: RoundedRectangleBorder(side: BorderSide(width: 1, color: isDark ? AppThemeData.grey700 : AppThemeData.grey200), borderRadius: BorderRadius.circular(120)),
|
|
),
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(8.0),
|
|
child: SvgPicture.asset("assets/icons/ic_shoping_cart.svg", colorFilter: ColorFilter.mode(isDark ? AppThemeData.grey50 : AppThemeData.grey50, BlendMode.srcIn)),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
bottom: PreferredSize(
|
|
preferredSize: Size.fromHeight(50.0), // height of the bottom widget
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
|
child: InkWell(
|
|
onTap: () {
|
|
Get.to(const SearchScreen(), arguments: {"vendorList": controller.allNearestRestaurant});
|
|
},
|
|
child: TextFieldWidget(
|
|
hintText: 'Search the store, item and more...'.tr,
|
|
controller: null,
|
|
enable: false,
|
|
backgroundColor: AppThemeData.grey50,
|
|
hintColor: isDark ? AppThemeData.grey400 : AppThemeData.grey400,
|
|
prefix: Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
|
child: SvgPicture.asset("assets/icons/ic_search.svg", colorFilter: ColorFilter.mode(isDark ? AppThemeData.grey400 : AppThemeData.grey400, BlendMode.srcIn)),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
body:
|
|
controller.isLoading.value
|
|
? Constant.loader()
|
|
: SingleChildScrollView(
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(vertical: 10),
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
|
child: Row(
|
|
children: [
|
|
Expanded(
|
|
child: Text(
|
|
"Category".tr,
|
|
textAlign: TextAlign.start,
|
|
style: AppThemeData.semiBoldTextStyle(color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900, fontSize: 16),
|
|
),
|
|
),
|
|
InkWell(
|
|
onTap: () {
|
|
Get.to(const ViewAllCategoryScreen());
|
|
},
|
|
child: Text(
|
|
"View all".tr,
|
|
textAlign: TextAlign.start,
|
|
style: AppThemeData.semiBoldTextStyle(
|
|
decoration: TextDecoration.underline,
|
|
color: isDark ? AppThemeData.multiVendorDark300 : AppThemeData.multiVendor300,
|
|
fontSize: 14,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
SizedBox(height: 10),
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
|
child: SizedBox(
|
|
height: 100,
|
|
child: ListView.builder(
|
|
shrinkWrap: true,
|
|
physics: const NeverScrollableScrollPhysics(),
|
|
itemCount: controller.vendorCategoryModel.length,
|
|
scrollDirection: Axis.horizontal,
|
|
itemBuilder: (context, index) {
|
|
VendorCategoryModel vendorCategoryModel = controller.vendorCategoryModel[index];
|
|
return InkWell(
|
|
onTap: () {
|
|
Get.to(const CategoryRestaurantScreen(), arguments: {"vendorCategoryModel": vendorCategoryModel, "dineIn": false});
|
|
},
|
|
child: Padding(
|
|
padding: const EdgeInsets.only(right: 18),
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: [
|
|
NetworkImageWidget(imageUrl: vendorCategoryModel.photo.toString(), height: 60, width: 60, fit: BoxFit.cover),
|
|
const SizedBox(height: 5),
|
|
Text(
|
|
vendorCategoryModel.title.toString(),
|
|
textAlign: TextAlign.center,
|
|
style: AppThemeData.mediumTextStyle(color: isDark ? AppThemeData.greyDark800 : AppThemeData.grey800, fontSize: 14),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
),
|
|
SizedBox(height: 10),
|
|
Padding(padding: const EdgeInsets.symmetric(horizontal: 16), child: controller.bannerModel.isEmpty ? const SizedBox() : BannerView(controller: controller)),
|
|
Visibility(visible: (Constant.isEnableAdsFeature == true && controller.advertisementList.isNotEmpty), child: const SizedBox(height: 20)),
|
|
Visibility(
|
|
visible: Constant.isEnableAdsFeature == true,
|
|
child:
|
|
controller.advertisementList.isEmpty
|
|
? const SizedBox()
|
|
: Container(
|
|
color: AppThemeData.primary300.withAlpha(40),
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: Text(
|
|
"Highlights for you".tr,
|
|
textAlign: TextAlign.start,
|
|
style: TextStyle(fontFamily: AppThemeData.semiBold, fontSize: 16, color: isDark ? AppThemeData.grey50 : AppThemeData.grey900),
|
|
),
|
|
),
|
|
InkWell(
|
|
onTap: () {
|
|
Get.to(AllAdvertisementScreen())?.then((value) {
|
|
controller.getFavouriteRestaurant();
|
|
});
|
|
},
|
|
child: Text(
|
|
"View all".tr,
|
|
textAlign: TextAlign.center,
|
|
style: TextStyle(fontFamily: AppThemeData.regular, color: isDark ? AppThemeData.primary300 : AppThemeData.primary300),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 16),
|
|
SizedBox(
|
|
height: 220,
|
|
child: ListView.builder(
|
|
physics: const BouncingScrollPhysics(),
|
|
scrollDirection: Axis.horizontal,
|
|
itemCount: controller.advertisementList.length >= 10 ? 10 : controller.advertisementList.length,
|
|
padding: EdgeInsets.all(0),
|
|
itemBuilder: (BuildContext context, int index) {
|
|
return AdvertisementHomeCard(controller: controller, model: controller.advertisementList[index]);
|
|
},
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(height: 20),
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
|
child: Text(
|
|
"New Arrivals".tr,
|
|
textAlign: TextAlign.start,
|
|
style: AppThemeData.semiBoldTextStyle(color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900, fontSize: 16),
|
|
),
|
|
),
|
|
SizedBox(height: 20),
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
|
child: SizedBox(
|
|
height: 380,
|
|
child: GridView.count(
|
|
crossAxisCount: 2,
|
|
// 2 columns
|
|
mainAxisSpacing: 0,
|
|
crossAxisSpacing: 20,
|
|
childAspectRatio: 1 / 1.1,
|
|
padding: EdgeInsets.zero,
|
|
physics: NeverScrollableScrollPhysics(),
|
|
children: controller.newArrivalRestaurantList.take(4).map((item) => NewArrivalCard(item: item)).toList(),
|
|
),
|
|
),
|
|
),
|
|
SizedBox(height: 5),
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
|
child: RoundedButtonBorder(
|
|
radius: 10,
|
|
color: isDark ? AppThemeData.greyDark100 : AppThemeData.grey100,
|
|
borderColor: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200,
|
|
title: 'View All Arrivals'.tr,
|
|
onPress: () {
|
|
Get.to(RestaurantListScreen(), arguments: {"vendorList": controller.newArrivalRestaurantList, "title": "New Arrivals".tr});
|
|
},
|
|
),
|
|
),
|
|
SizedBox(height: 20),
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text("Top Brands".tr, textAlign: TextAlign.start, style: AppThemeData.semiBoldTextStyle(color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900, fontSize: 16)),
|
|
SizedBox(height: 10),
|
|
GridView.builder(
|
|
padding: EdgeInsets.zero,
|
|
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 4, childAspectRatio: 4.5 / 6, crossAxisSpacing: 2),
|
|
itemCount: controller.brandList.length,
|
|
physics: const NeverScrollableScrollPhysics(),
|
|
shrinkWrap: true,
|
|
itemBuilder: (context, index) {
|
|
BrandsModel brandModel = controller.brandList[index];
|
|
return InkWell(
|
|
onTap: () {
|
|
Get.to(AllBrandProductScreen(), arguments: {"brandModel": brandModel});
|
|
},
|
|
child: Column(
|
|
children: [
|
|
Container(
|
|
width: 80,
|
|
height: 80,
|
|
decoration: ShapeDecoration(
|
|
color: isDark ? AppThemeData.grey900 : AppThemeData.grey50,
|
|
shape: RoundedRectangleBorder(
|
|
side: BorderSide(width: 1, strokeAlign: BorderSide.strokeAlignOutside, color: isDark ? AppThemeData.grey800 : AppThemeData.grey100),
|
|
borderRadius: BorderRadius.circular(10),
|
|
),
|
|
),
|
|
child: Padding(padding: const EdgeInsets.all(10), child: ClipOval(child: NetworkImageWidget(imageUrl: brandModel.photo.toString(), fit: BoxFit.cover))),
|
|
),
|
|
SizedBox(height: 5),
|
|
Text(
|
|
'${brandModel.title}',
|
|
textAlign: TextAlign.center,
|
|
maxLines: 2,
|
|
style: AppThemeData.mediumTextStyle(color: isDark ? AppThemeData.grey50 : AppThemeData.grey900),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
SizedBox(height: 10),
|
|
ListView.builder(
|
|
shrinkWrap: true,
|
|
physics: const BouncingScrollPhysics(),
|
|
padding: EdgeInsets.zero,
|
|
itemCount: controller.categoryWiseProductList.length,
|
|
itemBuilder: (context, index) {
|
|
VendorCategoryModel item = controller.categoryWiseProductList[index];
|
|
String imagePath = ["assets/images/ic_product_bg_1.png", "assets/images/ic_product_bg_2.png", "assets/images/ic_product_bg_3.png"][index % ["", "", ""].length];
|
|
return Container(
|
|
width: Responsive.width(100, context),
|
|
decoration: BoxDecoration(image: DecorationImage(image: AssetImage(imagePath), fit: BoxFit.fill)),
|
|
child: Padding(
|
|
padding: const EdgeInsets.only(left: 16, right: 16, top: 10, bottom: 20),
|
|
child: FutureBuilder<List<ProductModel>>(
|
|
future: FireStoreUtils.getProductListByCategoryId(item.id.toString()),
|
|
builder: (context, snapshot) {
|
|
if (snapshot.connectionState == ConnectionState.waiting) {
|
|
return Center(child: CircularProgressIndicator.adaptive(valueColor: AlwaysStoppedAnimation(AppThemeData.primary300)));
|
|
} else if ((snapshot.hasData || (snapshot.data?.isNotEmpty ?? false))) {
|
|
List<ProductModel> productList = snapshot.data!;
|
|
return snapshot.data!.isEmpty
|
|
? Container()
|
|
: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
children: [
|
|
Text(item.title.toString(), textAlign: TextAlign.start, style: AppThemeData.boldTextStyle(color: AppThemeData.grey900, fontSize: 18)),
|
|
Text(
|
|
"Style up with the latest fits, now at unbeatable prices.".tr,
|
|
textAlign: TextAlign.start,
|
|
style: AppThemeData.regularTextStyle(color: AppThemeData.grey900, fontSize: 12),
|
|
),
|
|
SizedBox(height: 20),
|
|
GridView.builder(
|
|
shrinkWrap: true,
|
|
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 3.5 / 6, crossAxisSpacing: 10),
|
|
padding: EdgeInsets.zero,
|
|
physics: NeverScrollableScrollPhysics(),
|
|
itemCount: productList.length > 6 ? 6 : productList.length,
|
|
itemBuilder: (context, index) {
|
|
ProductModel productModel = productList[index];
|
|
return FutureBuilder(
|
|
future: FireStoreUtils.getVendorById(productModel.vendorID.toString()),
|
|
builder: (context, vendorSnapshot) {
|
|
if (!vendorSnapshot.hasData || vendorSnapshot.connectionState == ConnectionState.waiting) {
|
|
return const SizedBox(); // Show placeholder or loader
|
|
}
|
|
VendorModel? vendorModel = vendorSnapshot.data;
|
|
String price = "0.0";
|
|
String disPrice = "0.0";
|
|
List<String> selectedVariants = [];
|
|
List<String> selectedIndexVariants = [];
|
|
List<String> selectedIndexArray = [];
|
|
if (productModel.itemAttribute != null) {
|
|
if (productModel.itemAttribute!.attributes!.isNotEmpty) {
|
|
for (var element in productModel.itemAttribute!.attributes!) {
|
|
if (element.attributeOptions!.isNotEmpty) {
|
|
selectedVariants.add(
|
|
productModel.itemAttribute!.attributes![productModel.itemAttribute!.attributes!.indexOf(element)].attributeOptions![0].toString(),
|
|
);
|
|
selectedIndexVariants.add(
|
|
'${productModel.itemAttribute!.attributes!.indexOf(element)} _${productModel.itemAttribute!.attributes![0].attributeOptions![0].toString()}',
|
|
);
|
|
selectedIndexArray.add('${productModel.itemAttribute!.attributes!.indexOf(element)}_0');
|
|
}
|
|
}
|
|
}
|
|
|
|
if (productModel.itemAttribute!.variants!.where((element) => element.variantSku == selectedVariants.join('-')).isNotEmpty) {
|
|
price = Constant.productCommissionPrice(
|
|
vendorModel!,
|
|
productModel.itemAttribute!.variants!.where((element) => element.variantSku == selectedVariants.join('-')).first.variantPrice ?? '0',
|
|
);
|
|
disPrice = "0";
|
|
}
|
|
} else {
|
|
price = Constant.productCommissionPrice(vendorModel!, productModel.price.toString());
|
|
disPrice =
|
|
double.parse(productModel.disPrice.toString()) <= 0
|
|
? "0"
|
|
: Constant.productCommissionPrice(vendorModel, productModel.disPrice.toString());
|
|
}
|
|
return GestureDetector(
|
|
onTap: () async {
|
|
Get.to(const RestaurantDetailsScreen(), arguments: {"vendorModel": vendorModel});
|
|
},
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
ClipRRect(
|
|
borderRadius: BorderRadius.circular(10),
|
|
child: SizedBox(
|
|
height: 90,
|
|
width: Responsive.width(100, context),
|
|
child: NetworkImageWidget(imageUrl: productModel.photo.toString(), fit: BoxFit.cover),
|
|
),
|
|
),
|
|
Column(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
productModel.name!.capitalizeString(),
|
|
textAlign: TextAlign.start,
|
|
maxLines: 1,
|
|
style: AppThemeData.semiBoldTextStyle(fontSize: 18, color: isDark ? AppThemeData.greyDark600 : AppThemeData.grey600),
|
|
),
|
|
disPrice == "" || disPrice == "0"
|
|
? Text(Constant.amountShow(amount: price), style: AppThemeData.semiBoldTextStyle(fontSize: 16, color: AppThemeData.primary300))
|
|
: Column(
|
|
children: [
|
|
Text(
|
|
Constant.amountShow(amount: price),
|
|
style: AppThemeData.semiBoldTextStyle(fontSize: 14, color: Colors.grey, decoration: TextDecoration.lineThrough),
|
|
),
|
|
const SizedBox(width: 5),
|
|
Text(
|
|
Constant.amountShow(amount: disPrice),
|
|
style: AppThemeData.semiBoldTextStyle(fontSize: 14, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900),
|
|
),
|
|
],
|
|
),
|
|
Container(
|
|
decoration: BoxDecoration(color: isDark ? AppThemeData.warning50 : AppThemeData.warning50, borderRadius: BorderRadius.circular(30)),
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Icon(Icons.star, size: 18, color: AppThemeData.warning400),
|
|
Text(
|
|
"${Constant.calculateReview(reviewCount: productModel.reviewsCount.toString(), reviewSum: productModel.reviewsSum.toString())} (${productModel.reviewsSum})",
|
|
style: AppThemeData.semiBoldTextStyle(fontSize: 12, color: AppThemeData.warning400),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
);
|
|
},
|
|
);
|
|
},
|
|
),
|
|
RoundedButtonBorder(
|
|
radius: 10,
|
|
color: isDark ? AppThemeData.greyDark100 : AppThemeData.grey100,
|
|
borderColor: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200,
|
|
title: 'View All Products',
|
|
onPress: () {
|
|
Get.to(AllCategoryProductScreen(), arguments: {"categoryModel": item});
|
|
},
|
|
),
|
|
],
|
|
);
|
|
} else {
|
|
return SizedBox();
|
|
}
|
|
},
|
|
),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
SizedBox(height: 10),
|
|
Padding(padding: const EdgeInsets.symmetric(horizontal: 16), child: controller.bannerModel.isEmpty ? const SizedBox() : BannerBottomView(controller: controller)),
|
|
// Visibility(
|
|
// visible: (Constant.isEnableAdsFeature == true && controller.advertisementList.isNotEmpty),
|
|
// child: const SizedBox(height: 20),
|
|
// ),
|
|
// Visibility(
|
|
// visible: Constant.isEnableAdsFeature == true,
|
|
// child:
|
|
// controller.advertisementList.isEmpty
|
|
// ? const SizedBox()
|
|
// : Container(
|
|
// color: AppThemeData.primary300.withAlpha(40),
|
|
// child: Padding(
|
|
// padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
|
|
// child: Column(
|
|
// mainAxisAlignment: MainAxisAlignment.start,
|
|
// crossAxisAlignment: CrossAxisAlignment.start,
|
|
// children: [
|
|
// Row(
|
|
// children: [
|
|
// Expanded(
|
|
// child: Text(
|
|
// "Highlights for you".tr,
|
|
// textAlign: TextAlign.start,
|
|
// style: TextStyle(
|
|
// fontFamily: AppThemeData.semiBold,
|
|
// fontSize: 16,
|
|
// color: isDark ? AppThemeData.grey50 : AppThemeData.grey900,
|
|
// ),
|
|
// ),
|
|
// ),
|
|
// InkWell(
|
|
// onTap: () {
|
|
// Get.to(AllAdvertisementScreen())?.then((value) {
|
|
// controller.getFavouriteRestaurant();
|
|
// });
|
|
// },
|
|
// child: Text(
|
|
// "View all".tr,
|
|
// textAlign: TextAlign.center,
|
|
// style: TextStyle(
|
|
// fontFamily: AppThemeData.regular,
|
|
// color: isDark ? AppThemeData.primary300 : AppThemeData.primary300,
|
|
// ),
|
|
// ),
|
|
// ),
|
|
// ],
|
|
// ),
|
|
// const SizedBox(height: 16),
|
|
// SizedBox(
|
|
// height: 220,
|
|
// child: ListView.builder(
|
|
// physics: const BouncingScrollPhysics(),
|
|
// scrollDirection: Axis.horizontal,
|
|
// itemCount:
|
|
// controller.advertisementList.length >= 10
|
|
// ? 10
|
|
// : controller.advertisementList.length,
|
|
// padding: EdgeInsets.all(0),
|
|
// itemBuilder: (BuildContext context, int index) {
|
|
// return AdvertisementHomeCard(
|
|
// controller: controller,
|
|
// model: controller.advertisementList[index],
|
|
// );
|
|
// },
|
|
// ),
|
|
// ),
|
|
// ],
|
|
// ),
|
|
// ),
|
|
// ),
|
|
// ),
|
|
const SizedBox(height: 20),
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text("All Store".tr, textAlign: TextAlign.start, style: AppThemeData.semiBoldTextStyle(color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900, fontSize: 16)),
|
|
SizedBox(height: 10),
|
|
ListView.builder(
|
|
padding: EdgeInsets.zero,
|
|
shrinkWrap: true,
|
|
physics: const NeverScrollableScrollPhysics(),
|
|
itemCount: controller.allNearestRestaurant.length > 8 ? 8 : controller.allNearestRestaurant.length,
|
|
itemBuilder: (context, index) {
|
|
VendorModel item = controller.allNearestRestaurant[index];
|
|
return InkWell(
|
|
onTap: () {
|
|
Get.to(const RestaurantDetailsScreen(), arguments: {"vendorModel": item});
|
|
},
|
|
child: Padding(
|
|
padding: const EdgeInsets.only(bottom: 20),
|
|
child: Row(
|
|
children: [
|
|
ClipRRect(borderRadius: BorderRadius.circular(10), child: NetworkImageWidget(imageUrl: item.photo.toString(), height: 80, width: 130, fit: BoxFit.cover)),
|
|
SizedBox(width: 10),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(item.title.toString(), style: AppThemeData.semiBoldTextStyle(color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900, fontSize: 16)),
|
|
Row(
|
|
children: [
|
|
Icon(Icons.location_on, size: 14, color: Colors.grey),
|
|
SizedBox(width: 4),
|
|
Expanded(
|
|
child: Text(
|
|
item.location.toString(),
|
|
style: AppThemeData.semiBoldTextStyle(fontSize: 12, color: isDark ? AppThemeData.greyDark500 : AppThemeData.grey500),
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
Container(
|
|
decoration: BoxDecoration(color: isDark ? AppThemeData.warning50 : AppThemeData.warning50, borderRadius: BorderRadius.circular(30)),
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Icon(Icons.star, size: 18, color: AppThemeData.warning400),
|
|
Text(
|
|
"${Constant.calculateReview(reviewCount: item.reviewsCount.toString(), reviewSum: item.reviewsSum.toString())} (${item.reviewsSum})",
|
|
style: AppThemeData.semiBoldTextStyle(fontSize: 12, color: AppThemeData.warning400),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
RoundedButtonBorder(
|
|
radius: 10,
|
|
color: isDark ? AppThemeData.greyDark100 : AppThemeData.grey100,
|
|
borderColor: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200,
|
|
title: 'View All Stores'.tr,
|
|
onPress: () {
|
|
Get.to(const RestaurantListScreen(), arguments: {"vendorList": controller.allNearestRestaurant});
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|
|
class NewArrivalCard extends StatelessWidget {
|
|
final VendorModel item;
|
|
|
|
const NewArrivalCard({super.key, required this.item});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final themeController = Get.find<ThemeController>();
|
|
final isDark = themeController.isDark.value;
|
|
return InkWell(
|
|
onTap: () {
|
|
Get.to(const RestaurantDetailsScreen(), arguments: {"vendorModel": item});
|
|
},
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
ClipRRect(
|
|
borderRadius: BorderRadius.circular(10),
|
|
child: NetworkImageWidget(
|
|
height: 100,
|
|
width: double.infinity,
|
|
fit: BoxFit.cover,
|
|
imageUrl: item.photo != null && item.photo!.isNotEmpty ? item.photo.toString() : Constant.placeHolderImage.toString(),
|
|
),
|
|
),
|
|
SizedBox(height: 5),
|
|
Text(item.title.toString(), style: AppThemeData.semiBoldTextStyle(color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900, fontSize: 14)),
|
|
Row(
|
|
children: [
|
|
Icon(Icons.location_on, size: 14, color: Colors.grey),
|
|
SizedBox(width: 4),
|
|
Expanded(
|
|
child: Text(
|
|
item.location.toString(),
|
|
style: AppThemeData.semiBoldTextStyle(fontSize: 12, color: isDark ? AppThemeData.greyDark500 : AppThemeData.grey500),
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
Container(
|
|
decoration: BoxDecoration(color: isDark ? AppThemeData.warning50 : AppThemeData.warning50, borderRadius: BorderRadius.circular(30)),
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Icon(Icons.star, size: 18, color: AppThemeData.warning400),
|
|
Text(
|
|
"${Constant.calculateReview(reviewCount: item.reviewsCount.toString(), reviewSum: item.reviewsSum.toString())} (${item.reviewsSum})",
|
|
style: AppThemeData.semiBoldTextStyle(fontSize: 12, color: AppThemeData.warning400),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class BannerView extends StatelessWidget {
|
|
final HomeECommerceController controller;
|
|
|
|
const BannerView({super.key, required this.controller});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Column(
|
|
children: [
|
|
SizedBox(
|
|
height: 160,
|
|
child: PageView.builder(
|
|
physics: const BouncingScrollPhysics(),
|
|
controller: controller.pageController.value,
|
|
scrollDirection: Axis.horizontal,
|
|
itemCount: controller.bannerModel.length,
|
|
padEnds: false,
|
|
pageSnapping: true,
|
|
allowImplicitScrolling: true,
|
|
onPageChanged: (value) {
|
|
controller.currentPage.value = value;
|
|
},
|
|
itemBuilder: (BuildContext context, int index) {
|
|
BannerModel bannerModel = controller.bannerModel[index];
|
|
return InkWell(
|
|
onTap: () async {
|
|
if (bannerModel.redirect_type == "store") {
|
|
ShowToastDialog.showLoader("Please wait...".tr);
|
|
VendorModel? vendorModel = await FireStoreUtils.getVendorById(bannerModel.redirect_id.toString());
|
|
|
|
ShowToastDialog.closeLoader();
|
|
Get.to(const RestaurantDetailsScreen(), arguments: {"vendorModel": vendorModel});
|
|
} else if (bannerModel.redirect_type == "product") {
|
|
ShowToastDialog.showLoader("Please wait...".tr);
|
|
ProductModel? productModel = await FireStoreUtils.getProductById(bannerModel.redirect_id.toString());
|
|
VendorModel? vendorModel = await FireStoreUtils.getVendorById(productModel!.vendorID.toString());
|
|
|
|
ShowToastDialog.closeLoader();
|
|
Get.to(const RestaurantDetailsScreen(), arguments: {"vendorModel": vendorModel});
|
|
} else if (bannerModel.redirect_type == "external_link") {
|
|
final uri = Uri.parse(bannerModel.redirect_id.toString());
|
|
if (await canLaunchUrl(uri)) {
|
|
await launchUrl(uri);
|
|
} else {
|
|
ShowToastDialog.showToast("Could not launch".tr);
|
|
}
|
|
}
|
|
},
|
|
child: Padding(
|
|
padding: const EdgeInsets.only(right: 14),
|
|
child: ClipRRect(borderRadius: const BorderRadius.all(Radius.circular(12)), child: NetworkImageWidget(imageUrl: bannerModel.photo.toString(), fit: BoxFit.cover)),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(vertical: 10),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: List.generate(controller.bannerModel.length, (index) {
|
|
return Obx(
|
|
() => Container(
|
|
margin: const EdgeInsets.only(right: 5),
|
|
alignment: Alignment.centerLeft,
|
|
height: 9,
|
|
width: 9,
|
|
decoration: BoxDecoration(shape: BoxShape.circle, color: controller.currentPage.value == index ? AppThemeData.primary300 : Colors.black12),
|
|
),
|
|
);
|
|
}),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|
|
|
|
class BannerBottomView extends StatelessWidget {
|
|
final HomeECommerceController controller;
|
|
|
|
const BannerBottomView({super.key, required this.controller});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Column(
|
|
children: [
|
|
SizedBox(
|
|
height: 150,
|
|
child: PageView.builder(
|
|
physics: const BouncingScrollPhysics(),
|
|
controller: controller.pageBottomController.value,
|
|
scrollDirection: Axis.horizontal,
|
|
itemCount: controller.bannerBottomModel.length,
|
|
padEnds: false,
|
|
pageSnapping: true,
|
|
allowImplicitScrolling: true,
|
|
onPageChanged: (value) {
|
|
controller.currentBottomPage.value = value;
|
|
},
|
|
itemBuilder: (BuildContext context, int index) {
|
|
BannerModel bannerModel = controller.bannerBottomModel[index];
|
|
return InkWell(
|
|
onTap: () async {
|
|
if (bannerModel.redirect_type == "store") {
|
|
ShowToastDialog.showLoader("Please wait...".tr);
|
|
VendorModel? vendorModel = await FireStoreUtils.getVendorById(bannerModel.redirect_id.toString());
|
|
|
|
ShowToastDialog.closeLoader();
|
|
Get.to(const RestaurantDetailsScreen(), arguments: {"vendorModel": vendorModel});
|
|
} else if (bannerModel.redirect_type == "product") {
|
|
ShowToastDialog.showLoader("Please wait...".tr);
|
|
ProductModel? productModel = await FireStoreUtils.getProductById(bannerModel.redirect_id.toString());
|
|
VendorModel? vendorModel = await FireStoreUtils.getVendorById(productModel!.vendorID.toString());
|
|
|
|
ShowToastDialog.closeLoader();
|
|
Get.to(const RestaurantDetailsScreen(), arguments: {"vendorModel": vendorModel});
|
|
} else if (bannerModel.redirect_type == "external_link") {
|
|
final uri = Uri.parse(bannerModel.redirect_id.toString());
|
|
if (await canLaunchUrl(uri)) {
|
|
await launchUrl(uri);
|
|
} else {
|
|
ShowToastDialog.showToast("Could not launch".tr);
|
|
}
|
|
}
|
|
},
|
|
child: Padding(
|
|
padding: const EdgeInsets.only(right: 14),
|
|
child: ClipRRect(borderRadius: const BorderRadius.all(Radius.circular(12)), child: NetworkImageWidget(imageUrl: bannerModel.photo.toString(), fit: BoxFit.cover)),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(vertical: 10),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: List.generate(controller.bannerBottomModel.length, (index) {
|
|
return Obx(
|
|
() => Container(
|
|
margin: const EdgeInsets.only(right: 5),
|
|
alignment: Alignment.centerLeft,
|
|
height: 9,
|
|
width: 9,
|
|
decoration: BoxDecoration(shape: BoxShape.circle, color: controller.currentBottomPage.value == index ? AppThemeData.primary300 : Colors.black12),
|
|
),
|
|
);
|
|
}),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|
|
|
|
class AdvertisementHomeCard extends StatelessWidget {
|
|
final AdvertisementModel model;
|
|
final HomeECommerceController controller;
|
|
|
|
const AdvertisementHomeCard({super.key, required this.controller, required this.model});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final themeController = Get.find<ThemeController>();
|
|
final isDark = themeController.isDark.value;
|
|
return InkWell(
|
|
onTap: () async {
|
|
ShowToastDialog.showLoader("Please wait...".tr);
|
|
VendorModel? vendorModel = await FireStoreUtils.getVendorById(model.vendorId!);
|
|
ShowToastDialog.closeLoader();
|
|
Get.to(const RestaurantDetailsScreen(), arguments: {"vendorModel": vendorModel});
|
|
},
|
|
child: Container(
|
|
margin: EdgeInsets.only(right: 16),
|
|
width: Responsive.width(70, context),
|
|
decoration: BoxDecoration(
|
|
color: isDark ? AppThemeData.info600 : AppThemeData.surface,
|
|
borderRadius: BorderRadius.circular(16),
|
|
boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.1), blurRadius: isDark ? 6 : 2, spreadRadius: 0, offset: Offset(0, isDark ? 3 : 1))],
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Stack(
|
|
children: [
|
|
model.type == 'restaurant_promotion'
|
|
? ClipRRect(
|
|
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
|
|
child: NetworkImageWidget(imageUrl: model.coverImage ?? '', height: 135, width: double.infinity, fit: BoxFit.cover),
|
|
)
|
|
: VideoAdvWidget(url: model.video ?? '', height: 135, width: double.infinity),
|
|
if (model.type != 'video_promotion' && model.vendorId != null && (model.showRating == true || model.showReview == true))
|
|
Positioned(
|
|
bottom: 8,
|
|
right: 8,
|
|
child: FutureBuilder(
|
|
future: FireStoreUtils.getVendorById(model.vendorId!),
|
|
builder: (context, snapshot) {
|
|
if (snapshot.connectionState == ConnectionState.waiting) {
|
|
return const SizedBox();
|
|
} else {
|
|
if (snapshot.hasError) {
|
|
return const SizedBox();
|
|
} else if (snapshot.data == null) {
|
|
return const SizedBox();
|
|
} else {
|
|
VendorModel vendorModel = snapshot.data!;
|
|
return Container(
|
|
decoration: ShapeDecoration(color: isDark ? AppThemeData.primary600 : AppThemeData.primary50, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(120))),
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
|
child: Row(
|
|
children: [
|
|
if (model.showRating == true) SvgPicture.asset("assets/icons/ic_star.svg", colorFilter: ColorFilter.mode(AppThemeData.primary300, BlendMode.srcIn)),
|
|
if (model.showRating == true) const SizedBox(width: 5),
|
|
Text(
|
|
"${model.showRating == true ? Constant.calculateReview(reviewCount: vendorModel.reviewsCount!.toStringAsFixed(0), reviewSum: vendorModel.reviewsSum.toString()) : ''} ${model.showReview == true ? '(${vendorModel.reviewsCount!.toStringAsFixed(0)})' : ''}",
|
|
style: TextStyle(fontSize: 14, color: isDark ? AppThemeData.primary300 : AppThemeData.primary300, fontFamily: AppThemeData.semiBold, fontWeight: FontWeight.w600),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
},
|
|
),
|
|
),
|
|
],
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.all(12),
|
|
child: Row(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
if (model.type == 'restaurant_promotion')
|
|
ClipRRect(borderRadius: BorderRadius.circular(30), child: NetworkImageWidget(imageUrl: model.profileImage ?? '', height: 50, width: 50, fit: BoxFit.cover)),
|
|
SizedBox(width: 8),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
model.title ?? '',
|
|
style: TextStyle(color: isDark ? AppThemeData.grey50 : AppThemeData.grey900, fontSize: 14, fontWeight: FontWeight.bold),
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
Text(
|
|
model.description ?? '',
|
|
style: TextStyle(fontSize: 12, fontFamily: AppThemeData.medium, color: isDark ? AppThemeData.grey400 : AppThemeData.grey600),
|
|
overflow: TextOverflow.ellipsis,
|
|
maxLines: 2,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
model.type == 'restaurant_promotion'
|
|
? IconButton(
|
|
icon: Obx(
|
|
() =>
|
|
controller.favouriteList.where((p0) => p0.restaurantId == model.vendorId).isNotEmpty
|
|
? SvgPicture.asset("assets/icons/ic_like_fill.svg")
|
|
: SvgPicture.asset("assets/icons/ic_like.svg", colorFilter: ColorFilter.mode(isDark ? AppThemeData.grey400 : AppThemeData.grey600, BlendMode.srcIn)),
|
|
),
|
|
onPressed: () async {
|
|
if (controller.favouriteList.where((p0) => p0.restaurantId == model.vendorId).isNotEmpty) {
|
|
FavouriteModel favouriteModel = FavouriteModel(restaurantId: model.vendorId, userId: FireStoreUtils.getCurrentUid());
|
|
controller.favouriteList.removeWhere((item) => item.restaurantId == model.vendorId);
|
|
await FireStoreUtils.removeFavouriteRestaurant(favouriteModel);
|
|
} else {
|
|
FavouriteModel favouriteModel = FavouriteModel(restaurantId: model.vendorId, userId: FireStoreUtils.getCurrentUid());
|
|
controller.favouriteList.add(favouriteModel);
|
|
await FireStoreUtils.setFavouriteRestaurant(favouriteModel);
|
|
}
|
|
controller.update();
|
|
},
|
|
)
|
|
: Container(
|
|
decoration: ShapeDecoration(color: isDark ? AppThemeData.primary600 : AppThemeData.primary50, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5))),
|
|
child: Padding(padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), child: Icon(Icons.arrow_forward, size: 20, color: AppThemeData.primary300)),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|