import 'package:community_material_icon/community_material_icon.dart'; import 'package:flutter/material.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:mobile_pos/Provider/profile_provider.dart'; import 'package:mobile_pos/generated/l10n.dart' as lang; import '../../GlobalComponents/go_to_subscription-package_page_popup_widget.dart'; import '../../constant.dart'; import '../../http_client/custome_http_client.dart'; import '../../model/business_info_model.dart' as bInfo; import '../Currency/Model/currency_model.dart'; import '../Currency/Provider/currency_provider.dart'; import '../Home/home.dart'; import '../../service/check_user_role_permission_provider.dart'; import '../payment getway/payment_getway_screen.dart'; import 'Model/subscription_plan_model.dart'; import 'Provider/subacription_plan_provider.dart'; import 'Repo/subscriptionPlanRepo.dart'; // class PurchasePremiumPlanScreenPrevious extends StatefulWidget { // const PurchasePremiumPlanScreenPrevious({super.key, required this.isCameBack, this.isExpired, this.enrolledPlan, this.willExpire}); // // final bool isCameBack; // final bool? isExpired; // final bInfo.EnrolledPlan? enrolledPlan; // final String? willExpire; // // @override // State createState() => _PurchasePremiumPlanScreenState(); // } // // class _PurchasePremiumPlanScreenState extends State { // SubscriptionPlanModelNew? selectedPlan; // bool isPlanExpiringIn7Days = false; // // List imageList = [ // 'images/sp1.png', // 'images/sp2.png', // 'images/sp3.png', // 'images/sp4.png', // 'images/sp5.png', // 'images/sp6.png', // ]; // // List planDetailsImages = [ // 'images/plan_details_1.png', // 'images/plan_details_2.png', // 'images/plan_details_3.png', // 'images/plan_details_4.png', // 'images/plan_details_5.png', // 'images/plan_details_6.png', // ]; // // @override // void didChangeDependencies() { // super.didChangeDependencies(); // WidgetsBinding.instance.addPostFrameCallback((_) { // if (widget.isExpired == true) { // getUpgradeDialog(); // } // }); // } // // CurrencyModel? getDefoultCurrency({required List currencies}) { // for (var element in currencies) { // if (element.isDefault ?? false) { // return element; // } // } // return null; // } // // // warning popup // void getUpgradeDialog() { // showDialog( // context: context, // builder: (BuildContext dialogContext) { // return goToPackagePagePopup(context: dialogContext, enrolledPlan: widget.enrolledPlan); // }); // } // // bool _isRefreshing = false; // Prevents multiple refresh calls // // Future refreshData(WidgetRef ref) async { // if (_isRefreshing) return; // Prevent duplicate refresh calls // _isRefreshing = true; // // ref.refresh(businessInfoProvider); // ref.refresh(subscriptionPlanProvider); // ref.refresh(getExpireDateProvider(ref)); // // await Future.delayed(const Duration(seconds: 1)); // Optional delay // _isRefreshing = false; // } // // @override // void initState() { // // selectedPlan = SubscriptionPlanModel(id: widget.enrolledPlan?.planId); // if (widget.willExpire != null && DateTime.tryParse(widget.willExpire ?? '') != null) { // DateTime expiryDate = DateTime.parse(widget.willExpire!); // isPlanExpiringIn7Days = expiryDate.isBefore(DateTime.now().add(const Duration(days: 6))); // } // // super.initState(); // } // // @override // Widget build(BuildContext context) { // List planDetailsText = [ // lang.S.of(context).freeLifetimeUpdate, // lang.S.of(context).android, // lang.S.of(context).premiumCustomerSupport, // lang.S.of(context).customInvoiceBranding, // lang.S.of(context).unlimitedUsage, // lang.S.of(context).freeDataBackup, // ]; // List titleListData = [ // lang.S.of(context).freeLifetimeUpdate, // lang.S.of(context).android, // lang.S.of(context).premiumCustomerSupport, // lang.S.of(context).customInvoiceBranding, // lang.S.of(context).unlimitedUsage, // lang.S.of(context).freeDataBackup, // ]; // // return Consumer(builder: (context, ref, __) { // final subscriptionPlanData = ref.watch(subscriptionPlanProvider); // final businessInfo = ref.watch(businessInfoProvider); // final currencyData = ref.watch(currencyProvider); // return Scaffold( // backgroundColor: kWhite, // body: PopScope( // canPop: widget.isExpired != true, // child: RefreshIndicator( // onRefresh: () => refreshData(ref), // child: SingleChildScrollView( // physics: const AlwaysScrollableScrollPhysics(), // child: SafeArea( // child: Padding( // padding: const EdgeInsets.all(20.0), // child: Column( // crossAxisAlignment: CrossAxisAlignment.start, // children: [ // Row( // mainAxisAlignment: MainAxisAlignment.spaceBetween, // children: [ // Text( // lang.S.of(context).purchasePremium, // style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w500), // ), // GestureDetector( // onTap: widget.isExpired != true // ? () { // if (widget.isCameBack) { // Navigator.pop(context); // } else { // Navigator.pushAndRemoveUntil( // context, // MaterialPageRoute(builder: (context) => const Home()), // (Route route) => false, // ); // } // } // : () => Navigator.pushAndRemoveUntil( // context, // MaterialPageRoute(builder: (context) => const Home()), // (Route route) => false, // ), // // ScaffoldMessenger.of(context).showSnackBar( // // const SnackBar( // // backgroundColor: Colors.red, // // content: Text('Please update your plan'), // // ), // // ), // // child: Icon( // Icons.cancel_outlined, // color: widget.isExpired != true ? Colors.grey : Colors.black, // ), // ) // ], // ), // const SizedBox(height: 20), // ListView.builder( // itemCount: imageList.length, // shrinkWrap: true, // physics: const NeverScrollableScrollPhysics(), // itemBuilder: (_, i) { // return Padding( // padding: const EdgeInsets.only(bottom: 15), // child: GestureDetector( // onTap: () { // showDialog( // context: context, // builder: (BuildContext context) { // return Dialog( // child: Column( // mainAxisSize: MainAxisSize.min, // mainAxisAlignment: MainAxisAlignment.center, // crossAxisAlignment: CrossAxisAlignment.center, // children: [ // const SizedBox(height: 20), // Row( // mainAxisSize: MainAxisSize.max, // mainAxisAlignment: MainAxisAlignment.end, // children: [ // GestureDetector( // child: const Icon(Icons.cancel), // onTap: () { // Navigator.pop(context); // }, // ), // const SizedBox(width: 20), // ], // ), // const SizedBox(height: 20), // Image( // height: 200, // width: 200, // image: AssetImage(planDetailsImages[i]), // ), // const SizedBox(height: 20), // Text( // planDetailsText[i], // textAlign: TextAlign.center, // style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold), // ), // const SizedBox(height: 15), // Padding( // padding: const EdgeInsets.all(8.0), // child: Text(lang.S.of(context).loremIpsumDolor, // //'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Natoque aliquet et, cur eget. Tellus sapien odio aliq.', // textAlign: TextAlign.center, // style: const TextStyle(fontSize: 16)), // ), // const SizedBox(height: 20), // ], // ), // ); // }, // ); // }, // child: Container( // decoration: BoxDecoration(borderRadius: BorderRadius.circular(6), color: kWhite, boxShadow: [ // BoxShadow(color: const Color(0xff0C1A4B).withOpacity(0.24), blurRadius: 1), // BoxShadow(color: const Color(0xff473232).withOpacity(0.05), offset: const Offset(0, 3), blurRadius: 8, spreadRadius: -1) // ]), // child: ListTile( // visualDensity: const VisualDensity(horizontal: -4), // contentPadding: const EdgeInsets.only(left: 8, right: 10), // leading: SizedBox( // height: 40, // width: 40, // child: Image( // image: AssetImage(imageList[i]), // ), // ), // title: Text( // titleListData[i], // style: const TextStyle(fontSize: 16), // ), // trailing: const Icon( // FeatherIcons.alertCircle, // color: kGreyTextColor, // size: 20, // ), // ), // ), // ), // ); // }), // const SizedBox(height: 10), // Text( // lang.S.of(context).buyPremium, // style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold), // ), // // ///_______Plans_List______________________________________________________________ // subscriptionPlanData.when(data: (data) { // return SizedBox( // height: (context.width() / 2.5) + 18, // child: ListView.builder( // physics: const ClampingScrollPhysics(), // shrinkWrap: true, // scrollDirection: Axis.horizontal, // itemCount: data.length, // itemBuilder: (BuildContext context, int index) { // return GestureDetector( // onTap: () { // setState(() { // selectedPlan = data[index]; // }); // }, // child: (data[index].offerPrice != null && (data[index].offerPrice ?? 0) > 0) // ? Padding( // padding: const EdgeInsets.only(right: 10), // child: SizedBox( // height: (context.width() / 3) + 18, // child: Stack( // alignment: Alignment.center, // children: [ // Padding( // padding: const EdgeInsets.only(bottom: 20, top: 20), // child: Container( // // height: (context.width() / 3) - 20, // width: (context.width() / 3) - 20, // decoration: BoxDecoration( // color: data[index].id == selectedPlan?.id ? kPremiumPlanColor2.withOpacity(0.1) : Colors.white, // borderRadius: const BorderRadius.all( // Radius.circular(10), // ), // border: Border.all( // width: 1, // color: data[index].id == selectedPlan?.id ? kPremiumPlanColor2 : kPremiumPlanColor, // ), // ), // child: Column( // mainAxisAlignment: MainAxisAlignment.center, // children: [ // Text( // data[index].subscriptionName ?? '', // style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold), // ), // Text( // '${data[index].duration} days', // textAlign: TextAlign.center, // style: const TextStyle( // fontSize: 13, // ), // ), // Text( // '${getDefoultCurrency(currencies: currencyData.value ?? [])?.symbol ?? ''}${data[index].offerPrice}', // style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold, color: kPremiumPlanColor2), // ), // Text( // '${getDefoultCurrency(currencies: currencyData.value ?? [])?.symbol ?? ''}${data[index].subscriptionPrice}', // style: const TextStyle(decoration: TextDecoration.lineThrough, fontSize: 14, color: Colors.grey), // ), // ], // ), // ), // ), // Positioned( // top: 8, // left: 0, // child: Container( // height: 25, // width: 70, // decoration: const BoxDecoration( // color: kPremiumPlanColor2, // borderRadius: BorderRadius.only( // topLeft: Radius.circular(10), // bottomRight: Radius.circular(10), // ), // ), // child: Center( // child: Text( // // 'Save ${(100 - (((data[index].offerPrice ?? 0) * 100) / (data[index].subscriptionPrice ?? 0))).round().toString()}%', // '${lang.S.of(context).save} ${(100 - (((data[index].offerPrice ?? 0) * 100) / (data[index].subscriptionPrice ?? 0))).round().toString()}%', // style: const TextStyle(color: Colors.white), // ), // ), // ), // ), // ], // ), // ), // ) // : Padding( // padding: const EdgeInsets.only(bottom: 20, top: 20, right: 10), // child: Container( // width: (context.width() / 3) - 20, // decoration: BoxDecoration( // color: data[index].id == selectedPlan?.id ? kPremiumPlanColor2.withOpacity(0.1) : Colors.white, // borderRadius: const BorderRadius.all( // Radius.circular(10), // ), // border: Border.all(width: 1, color: data[index].id == selectedPlan?.id ? kPremiumPlanColor2 : kPremiumPlanColor), // ), // child: Column( // mainAxisAlignment: MainAxisAlignment.center, // children: [ // Text( // data[index].subscriptionName ?? '', // style: const TextStyle(fontSize: 16), // ), // Text( // //'${data[index].duration} days', // '${data[index].duration} ${lang.S.of(context).days}', // textAlign: TextAlign.center, // style: const TextStyle( // fontSize: 13, // ), // ), // const SizedBox(height: 12), // Text( // '${getDefoultCurrency(currencies: currencyData.value ?? [])?.symbol ?? ''}${data[index].subscriptionPrice.toString()}', // style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold, color: kPremiumPlanColor), // ) // ], // ), // ), // ), // ); // }, // ), // ); // }, error: (Object error, StackTrace? stackTrace) { // return Text(error.toString()); // }, loading: () { // return const Center(child: CircularProgressIndicator()); // }), // const SizedBox(height: 20), // Visibility( // visible: (selectedPlan != null && // (widget.enrolledPlan?.planId != selectedPlan?.id || isPlanExpiringIn7Days) && // ((widget.enrolledPlan?.duration ?? 0) < (selectedPlan?.duration ?? 0)) && // (selectedPlan?.offerPrice != null ? selectedPlan!.offerPrice! > 0 : (selectedPlan?.subscriptionPrice ?? 0) > 0)), // child: GestureDetector( // onTap: () async { // if (selectedPlan != null) { // bool success = await Navigator.push( // context, // MaterialPageRoute( // builder: (context) => PaymentScreen( // planId: selectedPlan?.id.toString() ?? '', // businessId: businessInfo.value?.id.toString() ?? '', // ), // )); // // if (success) { // ref.refresh(businessInfoProvider); // ref.refresh(getExpireDateProvider(ref)); // widget.isExpired == false; // EasyLoading.showSuccess( // lang.S.of(context).successfullyPaid, // // 'successfully paid' // ); // Navigator.push(context, MaterialPageRoute(builder: (context) => const Home())); // } else { // EasyLoading.showError( // lang.S.of(context).field, // // 'Field' // ); // } // } // }, // child: Container( // height: 50, // decoration: const BoxDecoration( // color: kMainColor, // borderRadius: BorderRadius.all(Radius.circular(10)), // ), // child: Center( // child: Text( // lang.S.of(context).payForSubscribe, // style: const TextStyle(fontSize: 18, color: Colors.white), // ), // ), // ), // ), // ), // ], // ), // ), // ), // ), // ), // ), // ); // }); // } // } class PurchasePremiumPlanScreen extends ConsumerStatefulWidget { const PurchasePremiumPlanScreen({ super.key, required this.isCameBack, this.isExpired, this.enrolledPlan, this.willExpire, this.initiallyShowDialog = true, }); final bool isCameBack; final bool? isExpired; final bInfo.EnrolledPlan? enrolledPlan; final String? willExpire; final bool initiallyShowDialog; @override ConsumerState createState() => _SubscriptionPlanScreenState(); } class _SubscriptionPlanScreenState extends ConsumerState { SubscriptionPlanModelNew? selectedPlan; bool _isLoading = false; bool isPlanExpiringIn7Days = false; bool _isRefreshing = false; int? ineligibleIndex; SubscriptionPlanRepo subscriptionRepo = SubscriptionPlanRepo(); Widget _buildFeatureItem(String featureKey, dynamic featureValue) { final isActive = featureValue is List && featureValue.length > 1 && featureValue[1] == "1"; final featureText = featureValue is List ? featureValue[0].toString() : featureKey; return Container( padding: EdgeInsets.symmetric(horizontal: 6, vertical: 8), margin: EdgeInsets.only(bottom: 10), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(6), boxShadow: [ BoxShadow( color: Color(0xff473232).withValues(alpha: 0.05), blurRadius: 8, offset: Offset(0, 3), spreadRadius: -1), BoxShadow( color: Color(0xff0C1A4B).withValues(alpha: 0.024), blurRadius: 1, offset: Offset(0, 0), spreadRadius: 0) ], ), child: ListTile( contentPadding: EdgeInsets.symmetric(horizontal: 8, vertical: 0), visualDensity: VisualDensity(horizontal: -4, vertical: -4), leading: Icon( isActive ? Icons.check_circle : CommunityMaterialIcons.close_circle, color: isActive ? Colors.green : Colors.red, ), title: Text( featureText, style: TextStyle( color: kGreyTextColor, ), ), ), ); } CurrencyModel? getDefoultCurrency({required List currencies}) { for (var element in currencies) { if (element.isDefault ?? false) { return element; } } return null; } int calculateDiscountPercent(double originalPrice, double offerPrice) { return ((1 - (offerPrice / originalPrice)) * 100).round(); } @override void initState() { super.initState(); if (widget.willExpire != null && DateTime.tryParse(widget.willExpire ?? '') != null) { DateTime expiryDate = DateTime.parse(widget.willExpire!); isPlanExpiringIn7Days = expiryDate.isBefore(DateTime.now().add(const Duration(days: 6))); } // Fetch plans and select initial plan subscriptionRepo.fetchAllPlans().then((plans) { if (plans.isNotEmpty) { final currentPlanId = widget.enrolledPlan?.planId; final matchedPlan = plans.firstWhere( (plan) => plan.id == currentPlanId, orElse: () => plans.first, ); setState(() { selectedPlan = matchedPlan; }); } }); } @override void didChangeDependencies() { super.didChangeDependencies(); WidgetsBinding.instance.addPostFrameCallback((_) { if (widget.isExpired == true && widget.initiallyShowDialog) { getUpgradeDialog(); } }); } void getUpgradeDialog() { showDialog( context: context, builder: (BuildContext dialogContext) { return goToPackagePagePopup( context: dialogContext, enrolledPlan: widget.enrolledPlan, ); }, ); } Future refreshData(WidgetRef ref) async { if (_isRefreshing) return; _isRefreshing = true; ref.refresh(businessInfoProvider); ref.refresh(subscriptionPlanProvider); ref.refresh(getExpireDateProvider(ref)); await Future.delayed(const Duration(seconds: 1)); _isRefreshing = false; } bool showIneligibleMessage = false; @override @override @override Widget build(BuildContext context) { final businessInfo = ref.watch(businessInfoProvider); final currencyData = ref.watch(currencyProvider); final theme = Theme.of(context); final permissionService = PermissionService(ref); return SafeArea( child: Scaffold( backgroundColor: kWhite, bottomNavigationBar: selectedPlan == null ? const SizedBox.shrink() : Container( padding: const EdgeInsets.all(16), child: SizedBox( height: 50, width: double.infinity, child: ElevatedButton( onPressed: () async { if (!permissionService.hasPermission(Permit.subscriptionsRead.value)) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( backgroundColor: Colors.red, content: Text(lang.S.of(context).youDoNotHavePermissionToCreatePurchase), ), ); return; } final plan = selectedPlan!; final isCurrentPlan = plan.id == widget.enrolledPlan?.planId; final isUpgradeEligible = (widget.enrolledPlan?.planId != plan.id || isPlanExpiringIn7Days) && ((widget.enrolledPlan?.duration ?? 0) < (plan.duration ?? 0)); if ((plan.subscriptionPrice ?? 0) <= 0) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(lang.S.of(context).thisPlanIsNotAvailableToPurchase)), ); return; } if (isUpgradeEligible || isCurrentPlan) { final success = await Navigator.push( context, MaterialPageRoute( builder: (_) => PaymentScreen( planId: plan.id.toString(), businessId: businessInfo.value?.data?.id.toString() ?? '', ), ), ); if (success == true) { ref.refresh(businessInfoProvider); ref.refresh(getExpireDateProvider(ref)); EasyLoading.showSuccess(lang.S.of(context).successfullyPaid); Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => const Home()), ); } else { EasyLoading.showError(lang.S.of(context).field); } } else { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(lang.S.of(context).thisPlanIsEligibleForUpgrade)), ); } }, style: ElevatedButton.styleFrom( backgroundColor: kMainColor, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), child: Text( selectedPlan?.id == widget.enrolledPlan?.planId ? lang.S.of(context).extendPlan : lang.S.of(context).buyNow, style: const TextStyle( color: Colors.white, fontWeight: FontWeight.w600, ), ), ), ), ), body: FutureBuilder>( future: subscriptionRepo.fetchAllPlans(), builder: (context, snapshot) { if (snapshot.hasError) return Center(child: Text('Error: ${snapshot.error}')); if (!snapshot.hasData) return const Center(child: CircularProgressIndicator()); final plans = snapshot.data!; return Padding( padding: const EdgeInsets.all(16.0), child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Features if (selectedPlan != null) Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( lang.S.of(context).purchasePremium, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w500, color: kTitleColor), ), GestureDetector( onTap: widget.isExpired != true ? () { if (widget.isCameBack) { Navigator.pop(context); } else { Navigator.pushAndRemoveUntil( context, MaterialPageRoute(builder: (context) => const Home()), (Route route) => false, ); } } : () => Navigator.pushAndRemoveUntil( context, MaterialPageRoute(builder: (context) => const Home()), (Route route) => false, ), // ScaffoldMessenger.of(context).showSnackBar( // const SnackBar( // backgroundColor: Colors.red, // content: Text('Please update your plan'), // ), // ), child: Icon( Icons.close, color: widget.isExpired != true ? Colors.grey : Colors.black, ), ) ], ), const SizedBox(height: 8), ...selectedPlan!.features.entries.map((entry) => _buildFeatureItem(entry.key, entry.value)), const SizedBox(height: 16), ], ), Text( lang.S.of(context).outPremiumPlan, style: theme.textTheme.titleMedium?.copyWith( fontWeight: FontWeight.w700, fontSize: 18, ), ), SizedBox(height: 10), // Horizontal Plan List SizedBox( height: 165, child: ListView.builder( scrollDirection: Axis.horizontal, itemCount: plans.length, itemBuilder: (context, index) { final plan = plans[index]; final isSelected = selectedPlan?.id == plan.id; final hasOffer = plan.offerPrice != null && plan.offerPrice! > 0; final discountPercent = hasOffer ? calculateDiscountPercent(plan.subscriptionPrice, plan.offerPrice!) : null; return GestureDetector( onTap: () => setState(() => selectedPlan = plan), child: Container( padding: const EdgeInsets.symmetric(vertical: 10), margin: const EdgeInsets.only(right: 16), width: 115, child: Stack( clipBehavior: Clip.none, children: [ // Main card container (single instance now) Container( height: 145, width: 115, decoration: BoxDecoration( color: isSelected ? const Color(0xffFEF0F1).withOpacity(0.2) : theme.colorScheme.primaryContainer, borderRadius: BorderRadius.circular(8), border: Border.all( color: isSelected ? kMainColor : const Color(0xffEAECF0), ), ), padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( plan.subscriptionName, style: theme.textTheme.titleMedium?.copyWith( fontWeight: FontWeight.w400, fontSize: 18, ), maxLines: 1, overflow: TextOverflow.ellipsis, textAlign: TextAlign.center, ), const SizedBox(height: 8), Text( '${plan.duration} ${lang.S.of(context).days}', style: theme.textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w400, fontSize: 14, ), ), const SizedBox(height: 12), if (hasOffer) Column( children: [ Text( '${getDefoultCurrency(currencies: currencyData.value ?? [])?.symbol ?? ''}${plan.offerPrice}', style: TextStyle( fontSize: 20, fontWeight: FontWeight.w700, color: isSelected ? kMainColor : kTitleColor, ), ), Text( '${getDefoultCurrency(currencies: currencyData.value ?? [])?.symbol ?? ''}${plan.subscriptionPrice}', style: const TextStyle( fontSize: 13, fontWeight: FontWeight.w400, decoration: TextDecoration.lineThrough, color: Colors.grey, ), ), const SizedBox(height: 4), ], ) else Text( '${getDefoultCurrency(currencies: currencyData.value ?? [])?.symbol ?? ''}${plan.subscriptionPrice}', style: TextStyle( fontSize: 20, fontWeight: FontWeight.w700, color: isSelected ? kMainColor : kTitleColor, ), ), ], ), ), // Offer banner if (hasOffer) Positioned( top: -8, left: 0, child: Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), decoration: const BoxDecoration( color: kMainColor, borderRadius: BorderRadius.only( topLeft: Radius.circular(8), bottomRight: Radius.circular(8), ), ), child: Text( '${lang.S.of(context).save} $discountPercent%', style: const TextStyle( fontSize: 14, fontWeight: FontWeight.w500, color: Colors.white, ), ), ), ), ], ), ), ); }, ), ), ], ), ), ); }, ), ), ); } }