import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:voitrans/data/models/goods.dart'; import '../controllers/goodsvip_controller.dart'; import '../utils/goods_i18n.dart'; class GoodsvipView extends GetView { const GoodsvipView({super.key}); @override Widget build(BuildContext context) { final isDarkMode = Theme.of(context).brightness == Brightness.dark; return Scaffold( backgroundColor: isDarkMode ? Colors.black : Colors.grey[50], appBar: AppBar( backgroundColor: isDarkMode ? Colors.black : Colors.white, elevation: 0.5, title: Text( 'premiumMember'.tr, // 高级会员 style: TextStyle( fontSize: 18.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black, ), ), centerTitle: true, ), body: Obx(() { Widget content; if (controller.loading.value) { content = const Center(child: CircularProgressIndicator()); } else if (controller.error.isNotEmpty) { content = Center(child: Text(controller.error.value)); } else { content = ListView.separated( padding: EdgeInsets.all(16.w), itemCount: controller.items.length + 2, separatorBuilder: (_, __) => SizedBox(height: 12.h), itemBuilder: (_, index) { if (index < controller.items.length) { final item = controller.items[index]; return _buildGoodsCard(item, isDarkMode); } if (index == controller.items.length) { return _buildFeaturesSection(isDarkMode); } return _buildFooterSection(isDarkMode); }, ); } return Stack( children: [ content, if (controller.isPaying.value) Positioned.fill( child: AbsorbPointer( absorbing: true, child: Container( color: Colors.black.withOpacity(0.35), child: const Center( child: CircularProgressIndicator(), ), ), ), ), ], ); }), ); } Widget _buildGoodsCard(DBGoods item, bool isDarkMode) { return Container( padding: EdgeInsets.all(16.w), decoration: BoxDecoration( color: isDarkMode ? Colors.grey[900] : Colors.white, borderRadius: BorderRadius.circular(12.r), boxShadow: [ BoxShadow( color: isDarkMode ? Colors.black.withOpacity(0.2) : Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: Row( children: [ Container( width: 42.w, height: 42.w, decoration: BoxDecoration( color: isDarkMode ? Colors.amber[900]!.withOpacity(0.3) : Colors.amber[100]!, borderRadius: BorderRadius.circular(21.r), ), child: Icon(Icons.workspace_premium, color: isDarkMode ? Colors.amber[300]! : Colors.amber[600]!), ), SizedBox(width: 12.w), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(item.name, style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black, )), SizedBox(height: 4.h), Text(localizedGoodsDesc(item), style: TextStyle( fontSize: 12.sp, color: isDarkMode ? Colors.white70 : Colors.grey[600], )), ], ), ), SizedBox(width: 12.w), Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ Text('¥${item.price.toStringAsFixed(2)}', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black, )), SizedBox(height: 8.h), GestureDetector( onTap: () => controller.purchase(item), child: Container( padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 6.h), decoration: BoxDecoration( color: Colors.blue[600], borderRadius: BorderRadius.circular(20.r), ), child: Text( 'purchase'.tr, style: TextStyle( fontSize: 12.sp, color: Colors.white, ), ), ), ), ], ), ], ), ); } Widget _buildFeaturesSection(bool isDarkMode) { final textColor = isDarkMode ? Colors.white : Colors.black; final subColor = isDarkMode ? Colors.white70 : Colors.grey[700]; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'featureDescription'.tr, style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: textColor, ), ), SizedBox(height: 10.h), Wrap( spacing: 12.w, runSpacing: 12.h, alignment: WrapAlignment.start, crossAxisAlignment: WrapCrossAlignment.start, children: [ _buildFeatureCard( isDarkMode, icon: Icons.workspace_premium, title: 'benefitsOverview'.tr, lines: ['higherQuota'.tr, 'lowerUnitPrice'.tr], colorSeed: Colors.amber, ), _buildFeatureCard( isDarkMode, icon: Icons.support_agent, title: 'priorityService'.tr, lines: ['exclusiveSupportChannel'.tr, 'fastResponse'.tr], colorSeed: Colors.purple, ), _buildFeatureCard( isDarkMode, icon: Icons.local_offer, title: 'eventsAndDiscounts'.tr, lines: ['memberExclusiveEvents'.tr, 'longTermDiscountPlan'.tr], colorSeed: Colors.indigo, ), _buildFeatureCard( isDarkMode, icon: Icons.auto_awesome, title: 'generalPrivileges'.tr, lines: ['earlyAccessNewFeatures'.tr, 'crossDeviceSync'.tr], colorSeed: Colors.teal, ), ], ), SizedBox(height: 12.h), Text( 'vipDisclaimer'.tr, style: TextStyle(fontSize: 12.sp, color: subColor), ), ], ); } Widget _buildFeatureCard( bool isDarkMode, { required IconData icon, required String title, required List lines, required MaterialColor colorSeed, }) { final bgColor = isDarkMode ? Colors.grey[900] : Colors.white; final mainColor = isDarkMode ? colorSeed[300]! : colorSeed[600]!; final subColor = isDarkMode ? Colors.white70 : Colors.grey[700]; final width = (Get.width - 16.w * 2 - 12.w) / 2; return Container( width: width, padding: EdgeInsets.all(12.w), decoration: BoxDecoration( color: bgColor, borderRadius: BorderRadius.circular(12.r), boxShadow: [ BoxShadow( color: isDarkMode ? Colors.black.withOpacity(0.2) : Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Container( width: 36.w, height: 36.w, decoration: BoxDecoration( color: isDarkMode ? mainColor.withOpacity(0.25) : mainColor.withOpacity(0.15), borderRadius: BorderRadius.circular(18.r), ), child: Icon(icon, color: mainColor), ), SizedBox(width: 8.w), Expanded( child: Text( title, style: TextStyle( fontSize: 14.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black, ), ), ), ], ), SizedBox(height: 8.h), ...lines.map((l) => Padding( padding: EdgeInsets.only(bottom: 4.h), child: Text(l, style: TextStyle(fontSize: 12.sp, color: subColor)), )), ], ), ); } Widget _buildFooterSection(bool isDarkMode) { final subColor = isDarkMode ? Colors.white60 : Colors.grey[600]; return Padding( padding: EdgeInsets.symmetric(vertical: 12.h), child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ SizedBox( width: double.infinity, child: Divider(color: isDarkMode ? Colors.white24 : Colors.black12), ), SizedBox(height: 8.h), Text( 'appNameProvider'.tr, textAlign: TextAlign.center, style: TextStyle(fontSize: 11.sp, color: subColor), ), SizedBox(height: 4.h), Text( 'moreInfoViewInSettingsAbout'.tr, textAlign: TextAlign.center, style: TextStyle(fontSize: 11.sp, color: subColor), ), SizedBox(height: 4.h), Text( 'copyrightVoiTrans'.tr, textAlign: TextAlign.center, style: TextStyle(fontSize: 11.sp, color: subColor), ), ], ), ); } }