import 'package:communityapp/bill.dart'; import 'package:communityapp/emergency.dart'; import 'package:communityapp/package.dart'; import 'package:communityapp/visitor.dart'; import 'package:flutter/material.dart'; import 'reapair.dart'; import 'activity.dart'; import 'announcement.dart'; class HomeContentPage extends StatelessWidget { const HomeContentPage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('社區通'), actions: [ Row( children: [ const Text( '林小安 您好', style: TextStyle(fontWeight: FontWeight.bold), ), const SizedBox(width: 8), Stack( children: [ IconButton( icon: const Icon(Icons.notifications), onPressed: () { // TODO: 跳轉到通知頁 }, ), Positioned( right: 8, top: 8, child: Container( padding: const EdgeInsets.all(2), decoration: BoxDecoration( color: Colors.red, borderRadius: BorderRadius.circular(10), ), constraints: const BoxConstraints( minWidth: 16, minHeight: 16, ), child: const Text( '3', style: TextStyle(color: Colors.white, fontSize: 10), textAlign: TextAlign.center, ), ), ), ], ), ], ), ], ), body: SingleChildScrollView( child: Column( children: [ _announcementSection(context), _quickMenuSection(context), _adCarousel(), _marqueeNotice(), _activitySection(), ], ), ), ); } // 📢 重要公告區塊 static Widget _announcementSection(BuildContext context) { return Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ const Text( '📢 重要公告', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), const Spacer(), TextButton( onPressed: () { showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (_) => const AnnouncementWrapper(), ); }, style: OutlinedButton.styleFrom( foregroundColor: Colors.blue, side: const BorderSide(color: Colors.blue), // 藍色外框 shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20), // 更小的圓角 ), padding: const EdgeInsets.symmetric( horizontal: 12, vertical: 6, ), // 更小的內距 minimumSize: const Size(0, 0), // 取消預設最小尺寸限制 tapTargetSize: MaterialTapTargetSize.shrinkWrap, // 點擊範圍不外擴 ), child: const Text( '更多', style: TextStyle(fontSize: 14), // 更小字體 ), ), ], ), const SizedBox(height: 8), Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Card( child: ListTile( title: const Text('4/20 水塔清洗通知'), subtitle: const Text('本週六早上9:00至下午3:00進行清洗,請提前儲水。'), ), ), ), ], ), ); } // 🔧 功能選單區塊 static Widget _quickMenuSection(BuildContext context) { return Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( '🔧 功能選單', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), const SizedBox(height: 8), GridView.count( crossAxisCount: 3, shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), childAspectRatio: 1, children: [ _buildQuickButton(context, '報修', 'assets/icons/repair.png'), _buildQuickButton(context, '包裹', 'assets/icons/mail.png'), _buildQuickButton(context, '訪客', 'assets/icons/visitor.png'), _buildQuickButton(context, '繳費', 'assets/icons/payment.png'), _buildQuickButton(context, '社區互動', 'assets/icons/community.png'), _buildQuickButton(context, '緊急通報', 'assets/icons/emergency.png'), ], ), ], ), ); } static Widget _buildQuickButton( BuildContext context, String title, String imgAssetPath, ) { return GestureDetector( onTap: () { switch (title) { case "報修": showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (_) => const RepairPageWrapper(), ); case "包裹": /*Navigator.push( context, MaterialPageRoute(builder: (context) => PackagePage()), );*/ showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (context) => PackagePageWrapper(), ); case "訪客": showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (context) => VisitorPageWrapper(), ); case "繳費": showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (_) => BillPageWrapper(), ); case "社區互動": showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (_) => ActivityListPage(), ); case "緊急通報": showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (_) => EmergencyPage(), ); default: } }, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Image.asset(imgAssetPath, width: 40, height: 40, color: Colors.grey), const SizedBox(height: 8), Text(title, style: const TextStyle(fontSize: 14)), ], ), ); } // 🖼️ 廣告輪播區 static Widget _adCarousel() { return Padding( padding: const EdgeInsets.symmetric(vertical: 16), child: SizedBox( height: 180, child: PageView( children: [ Image.asset('assets/banners/banner1.png', fit: BoxFit.cover), Image.asset('assets/banners/banner2.png', fit: BoxFit.cover), Image.asset('assets/banners/banner3.png', fit: BoxFit.cover), ], ), ), ); } // 🏃‍♂️ 跑馬燈公告 static Widget _marqueeNotice() { return const MarqueeNotice(); } // 🎉 活動卡片列表 static Widget _activitySection() { return Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( '🎉 最新活動', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), const SizedBox(height: 8), SizedBox( height: 240, child: ListView( scrollDirection: Axis.horizontal, children: [ _buildActivityCard( '中秋烤肉趴', '9/9 晚上6點開烤', 'assets/activities/bbq.png', ), _buildActivityCard( '親子日遊園', '玩具福袋等你拿!', 'assets/activities/family_day.png', ), _buildActivityCard( '健康講堂', '醫師到場解說', 'assets/activities/health.png', ), _buildActivityCard( '防災演習', '模擬火災逃生', 'assets/activities/fire_drill.png', ), _buildActivityCard( '社區園遊會', '免費攤位吃到飽', 'assets/activities/festival.png', ), ], ), ), ], ), ); } static Widget _buildActivityCard( String title, String subtitle, String imgAssetPath, ) { return Container( width: 180, margin: const EdgeInsets.only(right: 12), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(10), boxShadow: [BoxShadow(color: Colors.black12, blurRadius: 5)], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ ClipRRect( borderRadius: const BorderRadius.vertical(top: Radius.circular(10)), child: Image.asset( imgAssetPath, height: 120, width: double.infinity, fit: BoxFit.cover, ), ), Padding( padding: const EdgeInsets.all(8), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: const TextStyle(fontWeight: FontWeight.bold), ), const SizedBox(height: 4), Text( subtitle, style: const TextStyle(fontSize: 12, color: Colors.black54), ), const SizedBox(height: 8), Row( mainAxisAlignment: MainAxisAlignment.start, // 左對齊或你要調整的位置 children: [ ElevatedButton( onPressed: () { // TODO: 報名事件 }, style: ElevatedButton.styleFrom( backgroundColor: Colors.green, // 綠色 fixedSize: const Size(75, 30), // 寬高都 60,正方形 shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), // 0 圓角 ), ), child: const Text( '報名', softWrap: false, style: TextStyle(color: Colors.white, fontSize: 12), ), ), const SizedBox(width: 10), // 按鈕間隔 ElevatedButton( onPressed: () { // TODO: 查看活動 }, style: ElevatedButton.styleFrom( backgroundColor: Colors.blue, // 藍色 fixedSize: const Size(75, 30), // 寬高都 60,正方形 shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), // 0 圓角 ), ), child: const Text( '查看', softWrap: false, style: TextStyle(color: Colors.white, fontSize: 12), ), ), ], ), ], ), ), ], ), ); } } class MarqueeNotice extends StatefulWidget { const MarqueeNotice({super.key}); @override State createState() => _MarqueeNoticeState(); } class _MarqueeNoticeState extends State with SingleTickerProviderStateMixin { late final AnimationController _controller; late final Animation _animation; final String _marqueeText = '公告: 歡迎使用我們的社區通,請多加利用。謝謝您~ 如有問題可洽談管理室'; @override void initState() { super.initState(); _controller = AnimationController( duration: const Duration(seconds: 10), vsync: this, )..repeat(); _animation = Tween(begin: 1.0, end: -1.0).animate(_controller); } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Container( color: Colors.grey.shade300, height: 40, alignment: Alignment.centerLeft, child: ClipRect( child: AnimatedBuilder( animation: _animation, builder: (context, child) { return FractionalTranslation( translation: Offset(_animation.value, 0), child: child, ); }, child: Text( _marqueeText, style: const TextStyle(fontSize: 16), overflow: TextOverflow.visible, softWrap: false, ), ), ), ); } }