import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import '../../kt_model/kt_receive_coin_info.dart'; import '../../kt_model/kt_goods_bean.dart'; import '../../kt_utils/kt_string_extend.dart'; import '../kt_mine/kt_store/logic.dart'; import 'logic.dart'; class KtRefillPage extends StatefulWidget { const KtRefillPage({super.key}); @override State createState() => _KtRefillPageState(); } class _KtRefillPageState extends State { final logic = Get.put(KtRefillLogic()); final state = Get.find().state; @override Widget build(BuildContext context) { return Scaffold( extendBodyBehindAppBar: true, body: Container( padding: EdgeInsets.fromLTRB( 15.w, ScreenUtil().statusBarHeight, 15.w, 0, ), decoration: BoxDecoration( image: DecorationImage( image: AssetImage('bg1.png'.ktIcon), fit: BoxFit.fill, ), ), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ IconButton( icon: Image.asset('ic_back.png'.ktIcon, width: 10.w), onPressed: () => Navigator.of(context).maybePop(), ), Text( 'My Refills', style: TextStyle( fontSize: 18.sp, fontWeight: FontWeight.w600, color: Colors.black, ), ), SizedBox(width: 24.w), ], ), Expanded( child: GetBuilder( builder: (ctrl) { return SmartRefresher( controller: logic.refreshController, physics: const ClampingScrollPhysics(), enablePullUp: false, enablePullDown: true, onRefresh: logic.refreshInfo, child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ cardView(), if (state.hasSubCoin) activeRefillView(), weeklyRefillView(), ruleView(), ], ), ), ); }, ), ), ], ), ), ); } Widget cardView() { return Container( width: 345.w, height: 258.w, padding: EdgeInsets.only(top: 59.w, left: 14.w), decoration: BoxDecoration( image: DecorationImage( image: AssetImage('refills_top_bg.png'.ktIcon), fit: BoxFit.fill, ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Rewards Overview', style: TextStyle( fontFamily: 'Inter', color: Color(0xFF1E1E20), fontSize: 15.sp, fontWeight: FontWeight.w600, ), ), Container( margin: EdgeInsets.symmetric(vertical: 16.w), child: Row( children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Weekly Total', style: TextStyle( fontFamily: 'Inter', color: Color(0xFF5E5E5E), fontSize: 12.sp, fontWeight: FontWeight.w600, ), ), SizedBox(height: 4.w), Row( children: [ Image.asset('ic_coin.png'.ktIcon, width: 17), SizedBox(width: 4.w), Text( '${state.receiveCoinInfo?.weekMaxTotal ?? 0}', style: TextStyle( fontFamily: 'Inter', color: Color(0xFFFF9500), fontSize: 18.sp, fontWeight: FontWeight.w700, ), ), ], ), ], ), Container( margin: EdgeInsets.symmetric(horizontal: 18.w), width: 1.w, height: 32.w, decoration: BoxDecoration( image: DecorationImage( image: AssetImage('refills_top_bg_line.png'.ktIcon), fit: BoxFit.fill, ), ), ), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Claimable Coins', style: TextStyle( fontFamily: 'Inter', color: Color(0xFF5E5E5E), fontSize: 12.sp, fontWeight: FontWeight.w600, ), ), SizedBox(height: 4.w), Row( children: [ Image.asset('ic_coin.png'.ktIcon, width: 17), SizedBox(width: 4.w), Text( '${state.receiveCoinInfo?.weekTotal ?? 0}', style: TextStyle( fontFamily: 'Inter', color: Color(0xFFFF9500), fontSize: 18.sp, fontWeight: FontWeight.w700, ), ), ], ), ], ), ], ), ), Row( children: [ Text( 'Active Refills:', style: TextStyle( fontFamily: 'Inter', color: Color(0xFF777777), fontSize: 12.sp, fontWeight: FontWeight.w400, ), ), Text( '${state.receiveCoinInfo?.receiveCount ?? 0}', style: TextStyle( fontFamily: 'Inter', color: Color(0xFF79C900), fontSize: 12.sp, fontWeight: FontWeight.w700, ), ), ], ), SizedBox(height: 6.w), GestureDetector( onTap: () { if (!state.hasSubCoin) return; logic.receiveDayCoin(); }, child: state.hasSubCoin ? Stack( children: [ Image.asset( 'refills_top_btn_all.png'.ktIcon, width: 337.w, height: 68.w, ), Container( height: 46.w, margin: EdgeInsets.only(top: 5.w), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( 'Claim All', style: TextStyle( fontFamily: 'Inter', color: Color(0xFF1E1E20), fontSize: 15.sp, fontWeight: FontWeight.w600, ), ), SizedBox(width: 6.w), Image.asset('ic_coin.png'.ktIcon, width: 13), SizedBox(width: 2.w), Text( '${state.receiveCoinInfo?.receiveCoins ?? 0}', style: TextStyle( fontFamily: 'Inter', color: Color(0xFF1E1E20), fontSize: 14.sp, fontWeight: FontWeight.w700, ), ), ], ), ), ], ) : Stack( children: [ Image.asset( 'refills_top_btn.png'.ktIcon, width: 337.w, height: 68.w, ), Container( height: 46.w, margin: EdgeInsets.only(top: 5.w), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( 'Get a Refill to Claim', style: TextStyle( fontFamily: 'Inter', color: Color(0xFFF7F7F7), fontSize: 15.sp, fontWeight: FontWeight.w600, ), ), ], ), ), ], ), ), ], ), ); } Widget activeRefillView() { return GetBuilder( builder: (ctrl) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox(height: 20.w), Text( 'Active Refills', style: TextStyle( fontSize: 15.sp, fontFamily: 'Inter', fontWeight: FontWeight.w600, color: Color(0xFF1C1C1C), ), ), ListView.builder( padding: EdgeInsets.only(top: 0.w), physics: NeverScrollableScrollPhysics(), shrinkWrap: true, itemCount: state.receiveCoinInfo?.receiveList?.length ?? 2, itemBuilder: (context, index) { ReceiveList? item = state.receiveCoinInfo?.receiveList?[index]; return Container( width: 345.w, height: 122.w, padding: EdgeInsets.only(top: 14.w, left: 12.w), margin: EdgeInsets.only(top: 10.w), decoration: BoxDecoration( image: DecorationImage( image: AssetImage('refills_center_bg-s.png'.ktIcon), fit: BoxFit.fill, ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Text( item?.title ?? '', style: TextStyle( fontFamily: 'Inter', fontSize: 14.sp, fontWeight: FontWeight.w700, color: Colors.white, ), ), SizedBox(width: 8.w), Text( '(Day ${item?.dayText ?? ''}/7)', style: TextStyle( fontFamily: 'Inter', fontSize: 14.sp, fontWeight: FontWeight.w400, color: Colors.white.withValues(alpha: 0.70), ), ), ], ), Container( margin: EdgeInsets.symmetric(vertical: 12.w), width: 320.w, height: 1.w, decoration: BoxDecoration( image: DecorationImage( image: AssetImage('refills_center_line.png'.ktIcon), fit: BoxFit.fill, ), ), ), Row( children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Total Reward', style: TextStyle( fontFamily: 'Inter', color: Color(0xFFCAB7A9), fontSize: 12.sp, fontWeight: FontWeight.w700, ), ), SizedBox(height: 8.w), Row( children: [ Image.asset('ic_coin.png'.ktIcon, width: 14), SizedBox(width: 4.w), Text( '${item?.weekMaxTotal ?? 0}', style: TextStyle( fontFamily: 'Inter', color: Color(0xFFFFF9E8), fontSize: 14.sp, fontWeight: FontWeight.w700, ), ), ], ), ], ), Container( margin: EdgeInsets.symmetric(horizontal: 12.w), width: 1.w, height: 32.w, decoration: BoxDecoration( image: DecorationImage( image: AssetImage( 'refills_center_line2.png'.ktIcon, ), fit: BoxFit.fill, ), ), ), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Remaining', style: TextStyle( fontFamily: 'Inter', color: Color(0xFFCAB7A9), fontSize: 12.sp, fontWeight: FontWeight.w700, ), ), SizedBox(height: 8.w), Row( children: [ Image.asset('ic_coin.png'.ktIcon, width: 14), SizedBox(width: 4.w), Text( '${item?.weekRemainingTotal ?? 0}', style: TextStyle( fontFamily: 'Inter', color: Color(0xFFFFF9E8), fontSize: 14.sp, fontWeight: FontWeight.w700, ), ), ], ), ], ), const Spacer(), GestureDetector( onTap: () { if (item?.receiveCoins == 0) return; logic.receiveDayCoin(id: item!.id); }, child: item?.receiveCoins == 0 ? Container( width: 100.w, height: 48.w, decoration: BoxDecoration( color: Color(0xE5B1B1B1), borderRadius: BorderRadius.all( Radius.circular(14.w), ), ), child: Center( child: Text( 'Claimed', style: TextStyle( color: Color(0xFFF7F7F7), fontSize: 14.sp, fontWeight: FontWeight.w600, ), ), ), ) : Stack( children: [ Container( width: 100.w, height: 48.w, padding: EdgeInsets.only(top: 5.w), decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ const Color(0xFF986100), const Color(0xFF322000), ], ), border: Border.all( width: 0.5.w, color: Colors.white, ), borderRadius: BorderRadius.all( Radius.circular(14.w), ), ), child: Column( children: [ Text( 'Claim', style: TextStyle( fontFamily: 'Inter', color: Colors.white, fontSize: 14.sp, fontWeight: FontWeight.w700, ), ), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Image.asset( 'ic_coin.png'.ktIcon, width: 14, ), SizedBox(width: 4.w), Text( '${item?.receiveCoins ?? 0}', style: TextStyle( fontFamily: 'Inter', color: Colors.white .withValues( alpha: 0.70, ), fontSize: 12.sp, fontWeight: FontWeight.w600, ), ), ], ), ], ), ), Positioned( left: -6.w, top: -6.w, child: Image.asset( 'refills_center_star.png'.ktIcon, width: 20.w, ), ), Positioned( right: -6.w, bottom: -6.w, child: Image.asset( 'refills_center_star.png'.ktIcon, width: 20.w, ), ), ], ), ), SizedBox(width: 12.w), ], ), ], ), ); }, ), ], ); }, ); } Widget weeklyRefillView() { Get.put(KtStoreLogic()); return GetBuilder( builder: (ctrl) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox(height: 20.w), if (ctrl.state.refillCoinList.isNotEmpty) Text( 'Weekly Refill', style: TextStyle( fontFamily: 'Inter', fontSize: 15.sp, fontWeight: FontWeight.w600, color: Color(0xFF1C1C1C), ), ), ListView.builder( physics: NeverScrollableScrollPhysics(), shrinkWrap: true, itemCount: ctrl.state.refillCoinList.length, itemBuilder: (context, index) { KtGoodsBean? item = ctrl.state.refillCoinList[index]; return GestureDetector( onTap: () => ctrl.buyGoods(item), child: Container( width: 345.w, height: 80.w, padding: EdgeInsets.only(left: 16.w, right: 13.w), margin: EdgeInsets.only(top: 10.w), decoration: BoxDecoration( image: DecorationImage( image: AssetImage('refills_center_bg.png'.ktIcon), fit: BoxFit.fill, ), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Weekly Refill', style: TextStyle( fontFamily: 'Inter', color: Colors.white, fontSize: 14.sp, fontWeight: FontWeight.w700, ), ), SizedBox(height: 5.w), Row( children: [ Image.asset('ic_coin.png'.ktIcon, width: 16), SizedBox(width: 4.w), Text( '${item.extInfo?.maxTotalCoins ?? 0}', style: TextStyle( fontFamily: 'Inter', color: Color(0xFFFFF9E8), fontSize: 18.sp, fontWeight: FontWeight.w600, ), ), SizedBox(width: 4.w), Container( height: 18.w, padding: EdgeInsets.symmetric( horizontal: 8.w, ), decoration: BoxDecoration( color: Colors.white.withValues(alpha: 0.15), borderRadius: BorderRadius.all( Radius.circular(4.w), ), ), child: Text( item.extInfo?.receiveCoinsRate ?? '', style: TextStyle( fontFamily: 'Inter', color: Colors.white, fontSize: 12.sp, fontWeight: FontWeight.w400, ), ), ), ], ), ], ), Stack( children: [ Container( constraints: BoxConstraints(minWidth: 90.w), height: 48.w, padding: EdgeInsets.only( top: 5.w, left: 15.w, right: 15.w, ), decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ const Color(0xFF986100), const Color(0xFF322000), ], ), border: Border.all( width: 0.5.w, color: Colors.white, ), borderRadius: BorderRadius.all( Radius.circular(14.w), ), ), child: Column( children: [ Text( item.productDetails?.price ?? '', style: TextStyle( fontFamily: 'Inter', height: 1, color: Colors.white, fontSize: 18.sp, fontWeight: FontWeight.w700, ), ), Text( '/week', style: TextStyle( fontFamily: 'Inter', color: Colors.white.withValues( alpha: 0.50, ), fontSize: 12.sp, fontWeight: FontWeight.w400, ), ), ], ), ), Positioned( left: -6.w, top: -6.w, child: Image.asset( 'refills_center_star.png'.ktIcon, width: 20.w, ), ), Positioned( right: -6.w, bottom: -6.w, child: Image.asset( 'refills_center_star.png'.ktIcon, width: 20.w, ), ), ], ), ], ), ), ); }, ), ], ); }, ); } Widget ruleView() { return Container( margin: EdgeInsets.only(top: 10.w, bottom: 43.w), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Subscription Rules', style: TextStyle( fontFamily: 'Inter', fontSize: 14.sp, fontWeight: FontWeight.w600, color: Color(0xFF94949B), ), ), SizedBox(height: 6.w), ...[ '1.Up to 2 subscriptions can be active at once.', '2.Coins are delivered instantly upon purchase.', '3.Daily bonus coins available from the next day.', '4.All coins will be revoked when the subscription expires,', 'including both initial and daily coins.', ].map( (text) => Container( margin: EdgeInsets.only(bottom: 4.w), child: Text( text, style: TextStyle( fontFamily: 'Inter', fontSize: 12.sp, fontWeight: FontWeight.w400, color: Color(0xFF94949B), ), ), ), ), ], ), ); } }