import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.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 { const HolidayScreen({super.key}); @override State createState() => _HolidayScreenState(); } class _HolidayScreenState extends State { int activeTab = 0; // 0 = السلف | 1 = الأجازات // Use the singleton instance final RequestService _requestService = RequestService(); late List _leaveRequests; late List _advanceRequests; @override void initState() { super.initState(); _initializeData(); } void _initializeData() async { // Get initial data _leaveRequests = await _requestService.getLeaveRequests(); _advanceRequests = await _requestService.getAdvanceRequests(); // Listen for updates _requestService.leaveRequestsStream.listen((requests) { setState(() { _leaveRequests = requests; }); }); _requestService.advanceRequestsStream.listen((requests) { setState(() { _advanceRequests = requests; }); }); } Widget buildStatusCircle({ required bool active, required String label, required String? svgPath, required Color activeColor, required Color glowColor, }) { return Column( children: [ Container( width: 36, // Smaller circle height: 36, decoration: BoxDecoration( shape: BoxShape.circle, color: active ? activeColor : const Color(0xFFD6D6D6), boxShadow: active ? [ BoxShadow( color: glowColor.withOpacity(0.6), blurRadius: 15, spreadRadius: 2, ), ] : [], ), child: active && svgPath != null ? Center( child: SvgPicture.asset( svgPath, width: 18, // Smaller icon height: 18, color: Colors.white, ), ) : null, ), const SizedBox(height: 4), // Space between circles Text(label, style: const TextStyle(fontSize: 10)), // Smaller text ], ); } @override Widget build(BuildContext context) { return Directionality( textDirection: TextDirection.rtl, child: Stack( children: [ // Tabs Positioned( top: 5, left: 0, right: 0, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ // الأجازات TAB 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), // السلف TAB 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), ), ], ), ), ], ), ), // Content area for requests Positioned( top: 30, // Position below the tabs left: 0, right: 0, bottom: 0, // Leave space for action buttons child: activeTab == 1 ? _buildLeaveRequestsTab() : _buildAdvanceRequestsTab(), ), // Action buttons Positioned( bottom: 30, right: 20, child: Column( children: [ // Money icon (custom size) _HolidayActionButton( label: "طلب سلفة", svgPath: "assets/images/money2.svg", iconWidth: 28, iconHeight: 20, onTap: () async { // Navigate to RequestAdvanceScreen await Navigator.push( context, MaterialPageRoute( builder: (context) => const RequestAdvanceScreen(), ), ); // Data will be updated automatically through the stream }, ), const SizedBox(height: 18), // Plus icon (custom size) _HolidayActionButton( label: "طلب إجازة", svgPath: "assets/images/plus.svg", iconWidth: 28, iconHeight: 20, onTap: () async { await Navigator.push( context, MaterialPageRoute( builder: (context) => const RequestLeaveScreen(), ), ); // Data will be updated automatically through the stream }, ), ], ), ), ], ), ); } Widget _buildLeaveRequestsTab() { if (_leaveRequests.isEmpty) { return const Center( child: Text( 'لا توجد طلبات أجازة', style: TextStyle( color: Colors.white, fontSize: 18, ), ), ); } return ListView.builder( padding: const EdgeInsets.symmetric(horizontal: 25, vertical: 20), itemCount: _leaveRequests.length, itemBuilder: (context, index) { final request = _leaveRequests[index]; return _buildLeaveRequestCard(request); }, ); } Widget _buildAdvanceRequestsTab() { if (_advanceRequests.isEmpty) { return const Center( child: Text( 'لا توجد طلبات سلف', style: TextStyle( color: Colors.white, fontSize: 18, ), ), ); } return ListView.builder( padding: const EdgeInsets.symmetric(horizontal: 25, vertical: 20), itemCount: _advanceRequests.length, itemBuilder: (context, index) { final request = _advanceRequests[index]; return _buildAdvanceRequestCard(request); }, ); } Widget _buildLeaveRequestCard(LeaveRequest request) { // Base colors from the design const bgColor = Color(0xFFEAF8F3); // const activeColor = Color(0xFFFFC940); // yellow active state // const inactiveColor = Color(0xFFD6D6D6); // grey inactive circles const lineColor = Color(0xFF22A685); // green divider // Status flags 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: MediaQuery.of(context).size.width * 0.8, // 80% of screen width margin: const EdgeInsets.only(bottom: 16), padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 14), // Reduced padding decoration: BoxDecoration( color: bgColor, borderRadius: BorderRadius.circular(16), ), child: Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ // ───────────────── STATUS ROW (centered) ───────────────── Row( mainAxisAlignment: MainAxisAlignment.center, // Center the status circles children: [ buildStatusCircle( active: isWaiting, label: "قيد الانتظار", svgPath: isWaiting ? "assets/images/waiting.svg" : null, activeColor: const Color(0xFFF9C8A01B), glowColor: const Color(0xB4FFDC69), ), const SizedBox(width: 12), // Space between circles buildStatusCircle( active: isApproved, label: "موافقة", svgPath: isApproved ? "assets/images/yes.svg" : null, activeColor: const Color(0xFF0A8A60), glowColor: const Color(0xFF00D7A3), ), const SizedBox(width: 12), // Space between circles buildStatusCircle( active: isDenied, label: "تم الرفض", svgPath: isDenied ? "assets/images/no.svg" : null, activeColor: const Color(0xFFE63946), glowColor: const Color(0xFFE63946), ), ], ), const SizedBox(height: 8), // Reduced height // ───────────── DATE (LEFT) + TYPE + TREE ICON (RIGHT) ───────────── Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ // Right cluster: tree icon + leave type Row( children: [ // Tree SVG in rounded square SizedBox( width: 32, // Smaller icon height: 32, child: Center( child: SvgPicture.asset( "assets/images/holiday.svg", width: 32, // Smaller icon height: 32, color: const Color(0xFF11663C), ), ), ), const SizedBox(width: 8), Text( request.leaveType, style: const TextStyle( fontSize: 12, // Smaller text color: Colors.black87, fontWeight: FontWeight.bold, ), ), ], ), // Left: date Text( dateText, style: const TextStyle( fontSize: 14, // Smaller text color: Colors.black87, fontWeight: FontWeight.w500, ), ), ], ), const SizedBox(height: 10), // Reduced height // Divider line Container(width: double.infinity, height: 1.4, color: lineColor), const SizedBox(height: 10), // Reduced height // Reason label // ───────────── Reason Row (inline with label) ───────────── Padding( padding: const EdgeInsets.only(top: 8), // Reduced padding child: Row( textDirection: TextDirection.ltr, children: [ // Reason text (LEFT) Expanded( child: Text( request.reason, textAlign: TextAlign.right, style: const TextStyle( fontSize: 13, // Smaller text color: Colors.black87, ), ), ), const SizedBox(width: 6), // Label (RIGHT) const Text( "السبب :", textAlign: TextAlign.right, style: TextStyle( fontSize: 14, // Smaller text color: Colors.black87, fontWeight: FontWeight.bold, ), ), ], ), ), ], ), ), ); } Widget _buildAdvanceRequestCard(AdvanceRequest request) { // Base colors const bgColor = Color(0xFFEAF8F3); const lineColor = Color(0xFF22A685); // const inactiveColor = Color(0xFFD6D6D6); // Status flags final bool isWaiting = request.status == "waiting"; final bool isApproved = request.status == "approved"; final bool isDenied = request.status == "denied"; // You can format a date if needed final String dateText = "${DateTime.now().year}.${DateTime.now().month}.${DateTime.now().day}"; return Directionality( textDirection: TextDirection.rtl, child: Container( width: MediaQuery.of(context).size.width * 0.8, // 80% of screen width margin: const EdgeInsets.only(bottom: 16), padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 14), // Reduced padding decoration: BoxDecoration( color: bgColor, borderRadius: BorderRadius.circular(16), ), child: Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ // ───────────────── STATUS ROW (centered) ───────────────── Row( mainAxisAlignment: MainAxisAlignment.center, // Center the status circles children: [ buildStatusCircle( active: isWaiting, label: "قيد الانتظار", svgPath: isWaiting ? "assets/images/waiting.svg" : null, activeColor: const Color(0xFFF9C8A01B), glowColor: const Color(0xB4FFDC69), ), const SizedBox(width: 12), // Space between circles buildStatusCircle( active: isApproved, label: "موافقة", svgPath: isApproved ? "assets/images/yes.svg" : null, activeColor: const Color(0xFF0A8A60), glowColor: const Color(0xFF00D7A3), ), const SizedBox(width: 12), // Space between circles buildStatusCircle( active: isDenied, label: "تم الرفض", svgPath: isDenied ? "assets/images/no.svg" : null, activeColor: const Color(0xFFE63946), glowColor: const Color(0xFFE63946), ), ], ), const SizedBox(height: 8), // Reduced height // ───────────────── TYPE + ICON + AMOUNT (same layout as leave card) ───────────────── Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ // Right: money icon + amount label Row( children: [ SizedBox( width: 32, // Smaller icon height: 32, child: Center( child: SvgPicture.asset( "assets/images/money.svg", width: 32, // Smaller icon height: 32, color: const Color(0xFF11663C), ), ), ), const SizedBox(width: 8), Text( "سلفة: ${request.amount.toStringAsFixed(0)} دع", style: const TextStyle( fontSize: 12, // Smaller text color: Colors.black87, fontWeight: FontWeight.bold, ), ), ], ), // Left: dummy date (or request.requestDate) Text( dateText, style: const TextStyle( fontSize: 14, // Smaller text color: Colors.black87, fontWeight: FontWeight.w500, ), ), ], ), const SizedBox(height: 10), // Reduced height // Divider line Container(width: double.infinity, height: 1, color: lineColor), const SizedBox(height: 10), // Reduced height // ───────────────── REASON ROW (identical to leave card) ───────────────── Padding( padding: const EdgeInsets.only(top: 8), // Reduced padding child: Row( textDirection: TextDirection.ltr, children: [ // Reason text (LEFT) Expanded( child: Text( request.reason, textAlign: TextAlign.right, style: const TextStyle( fontSize: 13, // Smaller text color: Colors.black87, ), ), ), const SizedBox(width: 6), // Label (RIGHT) const Text( "السبب :", textAlign: TextAlign.right, style: TextStyle( fontSize: 14, // Smaller text color: Colors.black87, fontWeight: FontWeight.bold, ), ), ], ), ), ], ), ), ); } } 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, ), ), ], ), ), ); } }