import 'package:flutter/material.dart'; import '../../../../app/i18n/app_localizations.dart'; import '../../../../app/theme/app_colors.dart'; import '../../../../app/theme/app_typography.dart'; import '../../../../app/theme/app_spacing.dart'; import '../../../../shared/widgets/coupon_card.dart'; /// A3. 搜索页 - 搜索券、品牌、分类 /// /// 热门搜索标签 + 搜索历史 + 实时搜索结果 class SearchPage extends StatefulWidget { const SearchPage({super.key}); @override State createState() => _SearchPageState(); } class _SearchPageState extends State { final _searchController = TextEditingController(); bool _hasInput = false; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( titleSpacing: 0, title: _buildSearchInput(), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: Text(context.t('search.cancel')), ), ], ), body: _hasInput ? _buildSearchResults() : _buildSearchSuggestions(), ); } Widget _buildSearchInput() { return Container( height: 40, decoration: BoxDecoration( color: AppColors.gray50, borderRadius: AppSpacing.borderRadiusFull, border: Border.all(color: AppColors.borderLight), ), child: TextField( controller: _searchController, autofocus: true, decoration: InputDecoration( hintText: context.t('search.hint'), prefixIcon: const Icon(Icons.search_rounded, size: 20), border: InputBorder.none, contentPadding: const EdgeInsets.symmetric(vertical: 10), ), onChanged: (v) => setState(() => _hasInput = v.isNotEmpty), ), ); } Widget _buildSearchSuggestions() { return SingleChildScrollView( padding: AppSpacing.pagePadding, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 20), // Hot Tags Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(context.t('search.hotSearch'), style: AppTypography.h3), GestureDetector(onTap: () {}, child: const Icon(Icons.refresh_rounded, size: 18, color: AppColors.textTertiary)), ], ), const SizedBox(height: 12), Wrap( spacing: 8, runSpacing: 8, children: ['Starbucks', 'Amazon', context.t('search.diningCoupon'), context.t('search.discountCoupon'), context.t('search.travel'), 'Nike'].map((tag) { return GestureDetector( onTap: () { _searchController.text = tag; setState(() => _hasInput = true); }, child: Container( padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8), decoration: BoxDecoration( color: AppColors.gray50, borderRadius: AppSpacing.borderRadiusFull, border: Border.all(color: AppColors.borderLight), ), child: Text(tag, style: AppTypography.labelSmall), ), ); }).toList(), ), const SizedBox(height: 32), // History Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(context.t('search.history'), style: AppTypography.h3), GestureDetector( onTap: () {}, child: Text(context.t('search.clear'), style: AppTypography.labelSmall.copyWith(color: AppColors.textTertiary)), ), ], ), const SizedBox(height: 12), ...['星巴克 礼品卡', 'Nike 运动券', '餐饮 折扣'].map((h) { return ListTile( contentPadding: EdgeInsets.zero, leading: const Icon(Icons.history_rounded, size: 18, color: AppColors.textTertiary), title: Text(h, style: AppTypography.bodyMedium), trailing: const Icon(Icons.north_west_rounded, size: 16, color: AppColors.textTertiary), onTap: () { _searchController.text = h; setState(() => _hasInput = true); }, ); }), ], ), ); } Widget _buildSearchResults() { return ListView.builder( padding: AppSpacing.pagePadding, itemCount: 5, itemBuilder: (context, index) { return Padding( padding: const EdgeInsets.only(bottom: 12), child: CouponCard( brandName: ['Starbucks', 'Amazon', 'Walmart', 'Target', 'Nike'][index], couponName: ['星巴克 \$25 礼品卡', 'Amazon \$100 购物券', 'Walmart \$50 生活券', 'Target \$30 折扣券', 'Nike \$80 运动券'][index], faceValue: [25.0, 100.0, 50.0, 30.0, 80.0][index], currentPrice: [21.25, 85.0, 42.5, 24.0, 68.0][index], creditRating: 'AAA', expiryDate: DateTime.now().add(Duration(days: (index + 1) * 10)), onTap: () { Navigator.pushNamed(context, '/coupon/detail'); }, ), ); }, ); } }