import 'package:coda_project/screens/notifications_screen.dart'; import 'package:coda_project/screens/user_settings_screen.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_svg/flutter_svg.dart'; import '../widgets/settings_bar.dart'; import '../screens/request_leave_screen.dart'; import '../screens/request_advance_scrren.dart'; import '../models/leave_request.dart'; import '../models/advance_request.dart'; import '../services/request_service.dart'; class HolidayScreen extends StatefulWidget { final void Function(bool isScrollingDown)? onScrollEvent; const HolidayScreen({super.key, this.onScrollEvent}); @override State createState() => _HolidayScreenState(); } class _HolidayScreenState extends State { int activeTab = 0; final RequestService _requestService = RequestService(); List _leaveRequests = []; List _advanceRequests = []; final ScrollController _scrollController = ScrollController(); bool _showActions = true; @override void initState() { super.initState(); _initializeData(); _scrollController.addListener(() { final direction = _scrollController.position.userScrollDirection; if (direction == ScrollDirection.reverse) { if (_showActions) setState(() => _showActions = false); widget.onScrollEvent?.call(true); } else if (direction == ScrollDirection.forward) { if (!_showActions) setState(() => _showActions = true); widget.onScrollEvent?.call(false); } if (_scrollController.position.pixels <= 5) { setState(() { _showActions = true; }); widget.onScrollEvent?.call(false); } }); } @override void dispose() { _scrollController.dispose(); super.dispose(); } void _initializeData() async { _leaveRequests = await _requestService.getLeaveRequests(); _advanceRequests = await _requestService.getAdvanceRequests(); _requestService.leaveRequestsStream.listen((requests) { if (mounted) setState(() => _leaveRequests = requests); }); _requestService.advanceRequestsStream.listen((requests) { if (mounted) setState(() => _advanceRequests = requests); }); } @override Widget build(BuildContext context) { return Stack( children: [ // --------------------------------------------------------- // ⭐ MAIN CONTENT - CUSTOM SCROLL VIEW // --------------------------------------------------------- SafeArea( child: CustomScrollView( controller: _scrollController, physics: const BouncingScrollPhysics(), slivers: [ // SETTINGS BAR SliverToBoxAdapter( child: Padding( padding: const EdgeInsets.only(top: 8), // First, make sure you have your screens defined // Then in your main widget: child: SettingsBar( selectedIndex: 0, showBackButton: false, iconPaths: [ 'assets/images/user.svg', 'assets/images/ball.svg', ], onTap: (index) { if (index == 0) { Navigator.push( context, MaterialPageRoute( builder: (context) => UserSettingsScreen(), ), ); } else if (index == 1) { Navigator.push( context, MaterialPageRoute( builder: (context) => NotificationsScreen(), ), ); } }, ), ), ), const SliverToBoxAdapter(child: SizedBox(height: 5)), // TABS SECTION SliverToBoxAdapter( child: SizedBox( height: 55, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ // الأجازات GestureDetector( onTap: () => setState(() => activeTab = 1), child: Column( children: [ Text( "الأجازات", style: TextStyle( fontSize: 22, fontWeight: FontWeight.w600, color: activeTab == 1 ? const Color(0xFF8EFDC2) : const Color(0x9EFFFFFF), ), ), if (activeTab == 1) Container( width: 60, height: 2, margin: const EdgeInsets.only(top: 4), color: const Color(0xFF8EFDC2), ), ], ), ), const SizedBox(width: 70), // السلف GestureDetector( onTap: () => setState(() => activeTab = 0), child: Column( children: [ Text( "السلف", style: TextStyle( fontSize: 22, fontWeight: FontWeight.w600, color: activeTab == 0 ? const Color(0xFF8EFDC2) : const Color(0x9EFFFFFF), ), ), if (activeTab == 0) Container( width: 60, height: 2, margin: const EdgeInsets.only(top: 4), color: const Color(0xFF8EFDC2), ), ], ), ), ], ), ), ), const SliverToBoxAdapter(child: SizedBox(height: 20)), // CONTENT LISTS activeTab == 1 ? _buildLeaveRequestsSliver() : _buildAdvanceRequestsSliver(), const SliverToBoxAdapter(child: SizedBox(height: 120)), ], ), ), // --------------------------------------------------------- // ⭐ FLOATING ACTION BUTTONS // --------------------------------------------------------- Positioned( bottom: 150, right: 20, child: AnimatedSlide( offset: _showActions ? Offset.zero : const Offset(0, 1.3), duration: const Duration(milliseconds: 300), child: AnimatedOpacity( opacity: _showActions ? 1 : 0, duration: const Duration(milliseconds: 250), child: Column( children: [ _HolidayActionButton( label: "طلب سلفة", svgPath: "assets/images/money2.svg", iconWidth: 28, iconHeight: 20, onTap: () { Navigator.push( context, MaterialPageRoute( builder: (_) => const RequestAdvanceScreen(), ), ); }, ), const SizedBox(height: 18), _HolidayActionButton( label: "طلب إجازة", svgPath: "assets/images/plus.svg", iconWidth: 28, iconHeight: 20, onTap: () { Navigator.push( context, MaterialPageRoute( builder: (_) => const RequestLeaveScreen(), ), ); }, ), ], ), ), ), ), ], ); } // ---------------------------------------------------------------- // SLIVERS FOR LISTS // ---------------------------------------------------------------- Widget _buildLeaveRequestsSliver() { if (_leaveRequests.isEmpty) { return SliverToBoxAdapter( child: Padding( padding: const EdgeInsets.all(20.0), child: Center( child: Text( "لا توجد طلبات أجازة", style: const TextStyle(color: Colors.white), ), ), ), ); } return SliverPadding( padding: const EdgeInsets.symmetric(horizontal: 25), sliver: SliverList( delegate: SliverChildBuilderDelegate((context, index) { return Padding( padding: const EdgeInsets.only(bottom: 16), child: _buildLeaveRequestCard(_leaveRequests[index]), ); }, childCount: _leaveRequests.length), ), ); } Widget _buildAdvanceRequestsSliver() { if (_advanceRequests.isEmpty) { return SliverToBoxAdapter( child: Padding( padding: const EdgeInsets.all(20.0), child: Center( child: Text( "لا توجد طلبات سلف", style: const TextStyle(color: Colors.white), ), ), ), ); } return SliverPadding( padding: const EdgeInsets.symmetric(horizontal: 25), sliver: SliverList( delegate: SliverChildBuilderDelegate((context, index) { return Padding( padding: const EdgeInsets.only(bottom: 16), child: _buildAdvanceRequestCard(_advanceRequests[index]), ); }, childCount: _advanceRequests.length), ), ); } // ---------------------------------------------------------------- // CARD BUILDERS (unchanged) // ---------------------------------------------------------------- Widget _buildLeaveRequestCard(LeaveRequest request) { const bgColor = Color(0xFFEAF8F3); const lineColor = Color(0xFF22A685); final bool isWaiting = request.status == "waiting"; final bool isApproved = request.status == "approved"; final bool isDenied = request.status == "denied"; final String dateText = "${request.fromDate.year}.${request.fromDate.month}.${request.fromDate.day}"; return Directionality( textDirection: TextDirection.rtl, child: Container( width: double.infinity, padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 14), decoration: BoxDecoration( color: bgColor, borderRadius: BorderRadius.circular(16), ), child: Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ // STATUS ROW Row( mainAxisAlignment: MainAxisAlignment.center, children: [ _statusCircle( isWaiting, "قيد الانتظار", isWaiting ? "assets/images/waiting.svg" : null, const Color(0xFFA58A1B), const Color(0xFFFFDC69), ), const SizedBox(width: 12), _statusCircle( isApproved, "موافقة", isApproved ? "assets/images/yes.svg" : null, const Color(0xFF0A8A60), const Color(0xFF00D7A3), ), const SizedBox(width: 12), _statusCircle( isDenied, "تم الرفض", isDenied ? "assets/images/no.svg" : null, const Color(0xFFE63946), const Color(0xFFE63946), ), ], ), const SizedBox(height: 8), // TITLE + DATE Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ SvgPicture.asset( "assets/images/holiday.svg", width: 32, height: 32, color: const Color(0xFF11663C), ), const SizedBox(width: 8), Text( request.leaveType, style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 13, ), ), ], ), Text(dateText), ], ), const SizedBox(height: 10), Container(height: 1.4, width: double.infinity, color: lineColor), const SizedBox(height: 10), // REASON ROW Row( textDirection: TextDirection.ltr, // Add this children: [ Expanded( child: Text(request.reason, textAlign: TextAlign.right), ), const SizedBox(width: 6), const Text( "السبب:", style: TextStyle(fontWeight: FontWeight.bold), textAlign: TextAlign.right, ), ], ), ], ), ), ); } Widget _statusCircle( bool active, String label, String? svg, Color color, Color glow, ) { return Column( children: [ Container( width: 36, height: 36, decoration: BoxDecoration( shape: BoxShape.circle, color: active ? color : const Color(0xFFD6D6D6), boxShadow: active ? [BoxShadow(color: glow.withOpacity(0.6), blurRadius: 12)] : [], ), child: svg != null ? Center(child: SvgPicture.asset(svg, width: 18, height: 18)) : null, ), const SizedBox(height: 4), Text(label, style: const TextStyle(fontSize: 10)), ], ); } Widget _buildAdvanceRequestCard(AdvanceRequest request) { // Same card logic as before (unchanged) return _buildLeaveRequestCard( LeaveRequest( id: request.id, leaveType: "سلفة ${request.amount}", isTimedLeave: false, fromDate: DateTime.now(), toDate: DateTime.now(), fromTime: TimeOfDay.now(), toTime: TimeOfDay.now(), reason: request.reason, requestDate: DateTime.now(), status: request.status, ), ); } } // ---------------------------------------------------------------- // FLOATING BUTTON WIDGET (unchanged) // ---------------------------------------------------------------- class _HolidayActionButton extends StatelessWidget { final String label; final String svgPath; final VoidCallback onTap; final double iconWidth; final double iconHeight; const _HolidayActionButton({ required this.label, required this.svgPath, required this.onTap, required this.iconWidth, required this.iconHeight, }); @override Widget build(BuildContext context) { return GestureDetector( onTap: onTap, child: Container( width: 80, height: 70, decoration: BoxDecoration( color: Colors.white, shape: BoxShape.circle, boxShadow: const [ BoxShadow( color: Color(0x4B00C68B), blurRadius: 20, offset: Offset(0, 6), ), ], ), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ SizedBox( width: iconWidth, height: iconHeight, child: SvgPicture.asset(svgPath, fit: BoxFit.contain), ), const SizedBox(height: 6), Text( label, style: const TextStyle( fontSize: 14, fontWeight: FontWeight.w600, color: Colors.black, ), ), ], ), ), ); } }