import 'package:aslan/chatvibe_data/models/enum/at_vip_type.dart'; import 'package:aslan/chatvibe_ui/theme/chatvibe_theme.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:aslan/app_localizations.dart'; import 'package:aslan/chatvibe_core/routes/at_fluro_navigator.dart'; import 'package:aslan/chatvibe_core/utilities/at_string_utils.dart'; import 'package:aslan/chatvibe_data/sources/local/user_manager.dart'; import 'package:aslan/chatvibe_data/sources/repositories/user_repository_impl.dart'; import 'package:aslan/chatvibe_domain/models/res/at_user_level_exp_res.dart'; import 'package:aslan/chatvibe_features/store/store_route.dart'; import 'package:aslan/chatvibe_ui/components/at_compontent.dart'; import '../../../../chatvibe_core/constants/at_global_config.dart'; import '../../../../chatvibe_core/utilities/at_date_utils.dart'; import '../../../../chatvibe_core/utilities/at_user_utils.dart'; import '../../../../chatvibe_data/models/enum/at_level_type.dart'; import '../../../../chatvibe_ui/components/text/at_text.dart'; class WealthLevelPage extends StatefulWidget { const WealthLevelPage({super.key}); @override State createState() => _WealthLevelPageState(); } class _WealthLevelPageState extends State { ATUserLevelExpRes? _levelExpRes; @override void initState() { super.initState(); _loadLevelInfo(); } Future _loadLevelInfo() async { final value = await AccountRepository().userLevelConsumptionExp( AccountStorage().getCurrentUser()?.userProfile?.id ?? "", ATLevelType.WEALTH.name, ); if (!mounted) { return; } setState(() { _levelExpRes = value; }); } @override Widget build(BuildContext context) { if (_levelExpRes == null) { return SizedBox( height: 420.h, child: const Center( child: CupertinoActivityIndicator(color: Colors.white24), ), ); } return SingleChildScrollView( padding: EdgeInsets.fromLTRB(12.w, 14.w, 12.w, 12.w), child: Column( children: [ _buildTopSummaryCard(context), _buildTopPrivilegesCard(context), SizedBox(height: 16.w), _buildRewardCard(context), ], ), ); } Widget _buildTopSummaryCard(BuildContext context) { final currentUser = AccountStorage().getCurrentUser()?.userProfile; final int level = (_levelExpRes?.level ?? 0).toInt(); final int nextLevel = level >= 50 ? 50 : level + 1; return Column( children: [ Image.asset( "atu_images/level/at_icon_wealth_level_tag${_wealthLevel2(level)}.png", width: 88.w, ), SizedBox(height: 15.w), ShaderMask( blendMode: BlendMode.srcIn, shaderCallback: (bounds) => const LinearGradient( colors: [Color(0xFFFED90A), Color(0xFFFFB31E)], begin: Alignment.topCenter, end: Alignment.bottomCenter, ).createShader(bounds), child: Text( "Lv$level", style: TextStyle( fontSize: 32.sp, fontWeight: FontWeight.w800, color: Colors.white, height: 1, ), ), ), Container( margin: EdgeInsets.only(top: 12.w), padding: EdgeInsets.fromLTRB(20.w, 12.w, 20.w, 12.w), decoration: _buildCardDecoration( beginColor: const Color(0xFF563120), middleColor: const Color(0xFF2b1910), endColor: const Color(0xFF110a06), begin: Alignment.centerLeft, end: Alignment.centerRight, ), child: Row( children: [ netImage( url: currentUser?.userAvatar ?? "", width: 45.w, shape: BoxShape.circle, ), Expanded( child: Column( children: [ Row( children: [ SizedBox(width: 10.w), Expanded( child: text( AccountStorage() .getCurrentUser() ?.userProfile ?.userNickname ?? "", fontWeight: FontWeight.w700, fontSize: 15.sp, textColor: const Color(0xFFF6E62A), ), ), ], ), SizedBox(height: 4.w), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox(width: 10.w), Expanded( child: Text( _buildUpgradeHint(nextLevel), style: TextStyle( fontSize: 12.sp, fontWeight: FontWeight.w500, color: const Color(0xFFF6E62A), height: 1.2, ), ), ), ], ), SizedBox(height: 12.w), Padding( padding: EdgeInsetsDirectional.only( start: 10.w, end: 20.w, ), child: ClipRRect( borderRadius: BorderRadius.circular(99.r), child: SizedBox( height: 6.w, child: LinearProgressIndicator( value: _buildProgressRatio(), backgroundColor: Colors.white.withValues( alpha: 0.16, ), valueColor: const AlwaysStoppedAnimation( Color(0xFFFFC700), ), ), ), ), ), ], ), ), ], ), ), ], ); } int _wealthLevel2(int level) { int level2 = 1; if (level > 0 && level <= 10) { level2 = 1; } else if (level > 10 && level <= 20) { level2 = 2; } else if (level > 20 && level <= 30) { level2 = 3; } else if (level > 30 && level <= 40) { level2 = 4; } else if (level > 40 && level <= 50) { level2 = 5; } return level2; } Widget _buildRewardCard(BuildContext context) { final localizations = ATAppLocalizations.of(context)!; final int level = (_levelExpRes?.level ?? 0).toInt(); return Container( width: double.infinity, padding: EdgeInsets.fromLTRB(0.w, 20.w, 0.w, 18.w), decoration: _buildCardDecoration( beginColor: const Color(0xFF563120), middleColor: const Color(0xFF2b1910), endColor: const Color(0xFF110a06), begin: Alignment.topCenter, end: Alignment.bottomCenter, ), child: Column( children: [ _buildPanelTitle( title: localizations.medalAndAvatarFrameRewards, subtitle: localizations.higherLevelFancierAvatarFrame, ), SizedBox(height: 16.w), _buildSectionLabel(localizations.levelIcon), SizedBox(height: 10.w), Padding( padding: EdgeInsets.symmetric(horizontal: 12.w), child: _buildLevelTrack(level), ), Image.asset( "atu_images/level/at_icon_user_wealth_center_bg_1.png", width: double.infinity, fit: BoxFit.fitWidth, ), SizedBox(height: 18.w), _buildSectionLabel(localizations.levelMedal), SizedBox(height: 10.w), Container( margin: EdgeInsets.symmetric(horizontal: 3.w), child: Image.asset( "atu_images/level/at_icon_user_wealth_center_bg_2.png", width: double.infinity, fit: BoxFit.fitWidth, ), ), SizedBox(height: 18.w), _buildPanelTitle( title: localizations.howToUpgrade, subtitle: localizations.spendCoinsToGainExperiencePoints, ), SizedBox(height: 16.w), GestureDetector( onTap: () { ATNavigatorUtils.push(context, StoreRoute.list); }, child: Container( width: 160.w, height: 48.w, alignment: Alignment.center, decoration: BoxDecoration( borderRadius: BorderRadius.circular(999.r), border: Border.all(color: Colors.white, width: 1.w), gradient: const LinearGradient( colors: [Color(0xFFFF8B2A), Color(0xFFFF4E00)], begin: Alignment.topCenter, end: Alignment.bottomCenter, ), boxShadow: [ BoxShadow( color: const Color(0xFFFF5A00).withValues(alpha: 0.34), blurRadius: 26, offset: const Offset(0, 10), ), ], ), child: Text( localizations.toConsume, style: TextStyle( fontSize: 18.sp, fontWeight: FontWeight.w700, color: Colors.white, height: 1, ), ), ), ), ], ), ); } Widget _buildLevelTrack(int level) { const labels = ["LV.1-10", "LV.11-20", "LV.21-30", "LV.31-40", "LV.41-50"]; final int activeIndex = _resolveLevelStageIndex(level); return LayoutBuilder( builder: (context, constraints) { final double itemWidth = constraints.maxWidth / labels.length; final double dotSize = 10.w; final double trackTop = 20.w; final double activeCenter = itemWidth * activeIndex + itemWidth / 2; return SizedBox( height: 34.w, child: Stack( children: [ for (int i = 0; i < labels.length; i++) Positioned( left: itemWidth * i, width: itemWidth, top: 0, child: Center( child: text( labels[i], textColor: i == activeIndex ? ChatVibeTheme.primaryLight : Colors.white, fontSize: 11.sp, ), ), ), Positioned( left: 0, right: 0, top: trackTop + dotSize / 2 - 1.w, child: Container( height: 4.w, decoration: BoxDecoration( color: Colors.white24, borderRadius: BorderRadius.circular(50.r), ), ), ), Positioned( left: 0, width: activeCenter, top: trackTop + dotSize / 2 - 1.w, child: Container( height: 4.w, decoration: BoxDecoration( color: ChatVibeTheme.primaryLight, borderRadius: BorderRadius.circular(50.r), ), ), ), for (int i = 0; i < labels.length; i++) Positioned( left: itemWidth * i + (itemWidth - dotSize) / 2, top: trackTop + 1, child: Image.asset( i == activeIndex ? "atu_images/level/at_icon_level_pd_en.png" : "atu_images/level/at_icon_level_pd_no.png", width: dotSize, height: dotSize, ), ), ], ), ); }, ); } Widget _buildPanelTitle({required String title, required String subtitle}) { return Column( children: [ ShaderMask( blendMode: BlendMode.srcIn, shaderCallback: (bounds) => const LinearGradient( colors: [Color(0xFFFDFCF8), Color(0xFFFFB31E)], begin: Alignment.topCenter, end: Alignment.bottomCenter, ).createShader(bounds), child: Text( title, textAlign: TextAlign.center, style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w800, color: Colors.white, height: 1.15, ), ), ), SizedBox(height: 6.w), Text( subtitle, textAlign: TextAlign.center, style: TextStyle( fontSize: 11.sp, fontWeight: FontWeight.w500, color: Colors.white, height: 1.3, ), ), ], ); } Widget _buildSectionLabel(String title) { return Row( children: [ SizedBox(width: 35.w), Expanded(child: _buildGlowLine()), SizedBox(width: 8.w), ShaderMask( blendMode: BlendMode.srcIn, shaderCallback: (bounds) => const LinearGradient( colors: [Color(0xFFFDFCF8), Color(0xFFFFB31E)], begin: Alignment.topCenter, end: Alignment.bottomCenter, ).createShader(bounds), child: Text( title, style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w800, color: Colors.white, height: 1, ), ), ), SizedBox(width: 8.w), Expanded(child: _buildGlowLine(reverse: true)), SizedBox(width: 35.w), ], ); } Widget _buildGlowLine({bool reverse = false}) { return Image.asset( reverse ? "atu_images/level/at_icon_wealth_title_01_right.png" : "atu_images/level/at_icon_wealth_title_01_left.png", height: 14.w, fit: BoxFit.fill, ); } BoxDecoration _buildCardDecoration({ required Color beginColor, required Color middleColor, required Color endColor, required AlignmentGeometry begin, required AlignmentGeometry end, }) { return BoxDecoration( borderRadius: BorderRadius.circular(12.r), border: Border.all(color: const Color(0xFFFFD673), width: 1.w), gradient: LinearGradient( colors: [beginColor, middleColor, endColor], begin: begin, end: end, stops: const [0, 0.6, 1], ), ); } String _buildUpgradeHint(int nextLevel) { final int needExp = ATStringUtils.toIntFunction( _levelExpRes?.nextExperience ?? "0", ); if (needExp <= 0) { return "Max Level"; } return "You Need ${ATStringUtils.formatNumber(needExp)} EXP To Lv$nextLevel"; } double _buildProgressRatio() { final int currentExp = ATStringUtils.toIntFunction( _levelExpRes?.thatExperience ?? "0", ); final int nextExp = ATStringUtils.toIntFunction( _levelExpRes?.nextExperience ?? "0", ); final int totalExp = currentExp + nextExp; if (totalExp <= 0) { return 0; } return (currentExp / totalExp).clamp(0, 1).toDouble(); } int _resolveLevelStageIndex(int level) { if (level >= 1 && level <= 10) { return 0; } if (level <= 20) { return 1; } if (level <= 30) { return 2; } if (level <= 40) { return 3; } return 4; } Widget _buildTopPrivilegesCard(BuildContext context) { final int level = (_levelExpRes?.level ?? 0).toInt(); return Container( margin: EdgeInsets.only(top: 12.w), height: 140.w, padding: EdgeInsets.fromLTRB(20.w, 12.w, 20.w, 0.w), decoration: _buildCardDecoration( beginColor: const Color(0xFF563120), middleColor: const Color(0xFF2b1910), endColor: const Color(0xFF110a06), begin: Alignment.centerLeft, end: Alignment.centerRight, ), child: Column( children: [ text( ATAppLocalizations.of( context, )!.currentLevelPrivilegesAndCostumes("Lv.$level"), fontSize: 12.sp, textColor: const Color(0xFFF6E62A), ), Spacer(), Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ SizedBox(width: _levelExpRes?.idIconType != null ? 25.w : 50.w), Expanded( child: Column( children: [ getWealthLevel(level, width: 60.w, height: 30.w), SizedBox(height: 15.w), Stack( alignment: Alignment.center, children: [ Image.asset( "atu_images/level/at_icon_wealth_level_otsb_tg.png", height: 30.w, width: 72.w, fit: BoxFit.fill, ), PositionedDirectional( bottom: 3.w, child: Container( alignment: Alignment.center, width: 72.w, child: text( ATAppLocalizations.of(context)!.levelIcon, fontSize: 10.sp, ), ), ), ], ), ], ), ), if( _levelExpRes?.vipLevel!=null) Expanded( child: Column( children: [ Image.asset( width: 65.w, height: 65.w, ATGlobalConfig.businessLogicStrategy.getVipPageLargeIcon( int.parse( ATAccountHelper.getVipLevel2( _levelExpRes?.vipLevel ?? "", ), ), ), ), SizedBox(height: 5.w), Stack( children: [ Image.asset( "atu_images/level/at_icon_wealth_level_otsb_tg.png", height: 30.w, width: 72.w, fit: BoxFit.fill, ), PositionedDirectional( bottom: 3.w, child: Container( alignment: Alignment.center, width: 72.w, child: text( "${ATAccountHelper.getVipLevel(_levelExpRes?.vipLevel ?? "")}*${"${_levelExpRes?.vipDays ?? 0}${ATAppLocalizations.of(context)!.days}"}", fontSize: 10.sp, ), ), ), ], ), ], ), ), if (_levelExpRes?.idIconType != null) Expanded( child: Column( children: [ getIdIconForLevel( _levelExpRes?.idIconType ?? 0, width: 50.w, height: 50.w, ), SizedBox(height: 10.w), Stack( alignment: Alignment.center, children: [ Image.asset( "atu_images/level/at_icon_wealth_level_otsb_tg.png", height: 30.w, width: 72.w, fit: BoxFit.fill, ), PositionedDirectional( bottom: 3.w, child: Container( alignment: Alignment.center, width: 72.w, child: text( ATAppLocalizations.of(context)!.idIcon, fontSize: 10.sp, ), ), ), ], ), ], ), ), SizedBox(width: _levelExpRes?.idIconType != null ? 25.w : 50.w), ], ), ], ), ); } getIdIconForLevel( num idIconType, { required double width, required double height, }) { String icon = ""; if (idIconType == 1) { icon = "atu_images/level/at_icon_wealth_id_icon_1.png"; } else if (idIconType == 2) { icon = "atu_images/level/at_icon_wealth_id_icon_2.png"; } else if (idIconType == 3) { icon = "atu_images/level/at_icon_wealth_id_icon_3.png"; } else if (idIconType == 4) { icon = "atu_images/level/at_icon_wealth_id_icon_4.png"; } return icon.isNotEmpty ? Image.asset(icon, width: width, height: height) : Container(); } }