import 'package:flutter/material.dart'; import '../models/app_notification.dart'; import '../services/api_service.dart'; import '../services/auth_service.dart'; class NotificationsScreen extends StatefulWidget { const NotificationsScreen({super.key}); @override State createState() => _NotificationsScreenState(); } class _NotificationsScreenState extends State { late final ApiService _api; List _notifications = []; bool _loading = true; final Set _processing = {}; @override void initState() { super.initState(); _api = ApiService(AuthService()); _load(); } Future _load() async { setState(() => _loading = true); final list = await _api.getNotifications(); if (!mounted) return; setState(() { _notifications = list; _loading = false; }); } Future _respond(AppNotification n, bool accepted) async { setState(() => _processing.add(n.id)); final err = await _api.respondToNotification(n.id, accepted); if (!mounted) return; setState(() => _processing.remove(n.id)); if (err != null) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(err, style: const TextStyle(fontSize: 11), textAlign: TextAlign.center), backgroundColor: const Color(0xFF333333), behavior: SnackBarBehavior.floating, duration: const Duration(seconds: 2), margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 40), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), ), ); } else { // refresh _load(); } } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.black, body: SafeArea( child: Column( children: [ // Header Padding( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6), child: Row( children: [ IconButton( onPressed: () => Navigator.pop(context), padding: EdgeInsets.zero, constraints: const BoxConstraints(minWidth: 28, minHeight: 28), icon: const Icon(Icons.arrow_back_ios_new, color: Colors.white70, size: 14), ), const SizedBox(width: 4), const Icon(Icons.notifications_outlined, color: Color(0xFF00C853), size: 14), const SizedBox(width: 4), const Expanded( child: Text( 'اعلان‌ها', style: TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.bold), ), ), IconButton( onPressed: _loading ? null : _load, padding: EdgeInsets.zero, constraints: const BoxConstraints(minWidth: 28, minHeight: 28), icon: const Icon(Icons.refresh, color: Colors.white54, size: 16), ), ], ), ), // Content Expanded( child: _loading ? const Center( child: CircularProgressIndicator(color: Color(0xFF00C853), strokeWidth: 2), ) : _notifications.isEmpty ? const Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.notifications_off_outlined, color: Colors.white24, size: 28), SizedBox(height: 6), Text('اعلانی وجود ندارد', style: TextStyle(color: Colors.white38, fontSize: 11)), ], ), ) : ListView.builder( padding: const EdgeInsets.only(bottom: 4), itemCount: _notifications.length, itemBuilder: (ctx, i) => _NotifTile( notif: _notifications[i], isProcessing: _processing.contains(_notifications[i].id), onAccept: () => _respond(_notifications[i], true), onReject: () => _respond(_notifications[i], false), ), ), ), ], ), ), ); } } class _NotifTile extends StatelessWidget { final AppNotification notif; final bool isProcessing; final VoidCallback onAccept; final VoidCallback onReject; const _NotifTile({ required this.notif, required this.isProcessing, required this.onAccept, required this.onReject, }); @override Widget build(BuildContext context) { final isPending = notif.isPending; final isJoin = notif.isJoinRequest; Color statusColor; if (notif.isAccepted == true) { statusColor = const Color(0xFF00C853); } else if (notif.isAccepted == false) { statusColor = Colors.red; } else { statusColor = const Color(0xFFFFAB00); } return Container( margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 3), decoration: BoxDecoration( color: const Color(0xFF1C1C1E), borderRadius: BorderRadius.circular(12), border: Border.all( color: isPending ? statusColor.withValues(alpha: 0.4) : Colors.transparent, width: 1, ), ), padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon( isJoin ? Icons.group_add_outlined : Icons.campaign_outlined, color: statusColor, size: 13, ), const SizedBox(width: 5), Expanded( child: Text( notif.title, style: const TextStyle( color: Colors.white, fontSize: 11, fontWeight: FontWeight.w600, ), overflow: TextOverflow.ellipsis, ), ), ], ), if (notif.description != null && notif.description!.isNotEmpty) ...[ const SizedBox(height: 4), Text( notif.description!, style: const TextStyle(color: Colors.white60, fontSize: 10), maxLines: 2, overflow: TextOverflow.ellipsis, ), ], if (isJoin && isPending) ...[ const SizedBox(height: 6), if (isProcessing) const Center( child: SizedBox( width: 14, height: 14, child: CircularProgressIndicator(color: Color(0xFF00C853), strokeWidth: 1.5), ), ) else Row( mainAxisAlignment: MainAxisAlignment.end, children: [ // Reject GestureDetector( onTap: onReject, child: Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), decoration: BoxDecoration( color: Colors.red.withValues(alpha: 0.15), borderRadius: BorderRadius.circular(20), ), child: const Text( 'رد', style: TextStyle(color: Colors.red, fontSize: 10, fontWeight: FontWeight.bold), ), ), ), const SizedBox(width: 8), // Accept GestureDetector( onTap: onAccept, child: Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), decoration: BoxDecoration( color: const Color(0xFF00C853).withValues(alpha: 0.15), borderRadius: BorderRadius.circular(20), ), child: const Text( 'قبول', style: TextStyle(color: Color(0xFF00C853), fontSize: 10, fontWeight: FontWeight.bold), ), ), ), ], ), ], if (!isPending) ...[ const SizedBox(height: 4), Align( alignment: Alignment.centerLeft, child: Text( notif.isAccepted == true ? 'پذیرفته شد' : 'رد شد', style: TextStyle(color: statusColor, fontSize: 9), ), ), ], ], ), ); } }