diff --git a/lib/screens/holiday_screen.dart b/lib/screens/holiday_screen.dart index 05bcfe2..76619d1 100644 --- a/lib/screens/holiday_screen.dart +++ b/lib/screens/holiday_screen.dart @@ -45,38 +45,53 @@ class _HolidayScreenState extends State { }); } - Color _getStatusColor(String status) { - switch (status) { - case 'approved': - return Colors.green; - case 'denied': - return Colors.red; - default: - return Colors.orange; - } + 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 + ], + ); } - String _getStatusText(String status) { - switch (status) { - case 'approved': - return 'موافق عليه'; - case 'denied': - return 'مرفوض'; - default: - return 'قيد الانتظار'; - } - } - String _getStatusIconPath(String status) { - switch (status) { - case 'approved': - return "assets/images/yes.svg"; - case 'denied': - return "assets/images/no.svg"; - default: - return "assets/images/waiting.svg"; - } - } @override Widget build(BuildContext context) { @@ -86,7 +101,7 @@ class _HolidayScreenState extends State { children: [ // Tabs Positioned( - top: 40, + top: 5, left: 0, right: 0, child: Row( @@ -153,10 +168,10 @@ class _HolidayScreenState extends State { // Content area for requests Positioned( - top: 100, // Position below the tabs + top: 30, // Position below the tabs left: 0, right: 0, - bottom: 120, // Leave space for action buttons + bottom: 0, // Leave space for action buttons child: activeTab == 1 ? _buildLeaveRequestsTab() : _buildAdvanceRequestsTab(), ), @@ -170,8 +185,8 @@ class _HolidayScreenState extends State { _HolidayActionButton( label: "طلب سلفة", svgPath: "assets/images/money2.svg", - iconWidth: 38, - iconHeight: 30, + iconWidth: 28, + iconHeight: 20, onTap: () async { // Navigate to RequestAdvanceScreen await Navigator.push( @@ -189,8 +204,8 @@ class _HolidayScreenState extends State { _HolidayActionButton( label: "طلب إجازة", svgPath: "assets/images/plus.svg", - iconWidth: 30, - iconHeight: 30, + iconWidth: 28, + iconHeight: 20, onTap: () async { await Navigator.push( context, @@ -222,19 +237,13 @@ class _HolidayScreenState extends State { ); } - return RefreshIndicator( - onRefresh: () async { - _initializeData(); + return ListView.builder( + padding: const EdgeInsets.symmetric(horizontal: 25, vertical: 20), + itemCount: _leaveRequests.length, + itemBuilder: (context, index) { + final request = _leaveRequests[index]; + return _buildLeaveRequestCard(request); }, - color: Colors.white, - child: ListView.builder( - padding: const EdgeInsets.symmetric(horizontal: 25, vertical: 20), - itemCount: _leaveRequests.length, - itemBuilder: (context, index) { - final request = _leaveRequests[index]; - return _buildLeaveRequestCard(request); - }, - ), ); } @@ -251,285 +260,320 @@ class _HolidayScreenState extends State { ); } - return RefreshIndicator( - onRefresh: () async { - _initializeData(); + return ListView.builder( + padding: const EdgeInsets.symmetric(horizontal: 25, vertical: 20), + itemCount: _advanceRequests.length, + itemBuilder: (context, index) { + final request = _advanceRequests[index]; + return _buildAdvanceRequestCard(request); }, - color: Colors.white, - child: 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) { - return Container( - margin: const EdgeInsets.only(bottom: 16), - padding: const EdgeInsets.all(16), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(16), - boxShadow: const [ - BoxShadow( - color: Color(0x33000000), - blurRadius: 10, - offset: Offset(0, 4), - ), - ], - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - // Header with type and status - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - // Status icon instead of text - Container( - padding: const EdgeInsets.all(8), - decoration: BoxDecoration( - color: _getStatusColor(request.status), - shape: BoxShape.circle, - ), - child: SvgPicture.asset( - _getStatusIconPath(request.status), - width: 24, - height: 24, - color: Colors.white, - ), - ), - Text( - request.isTimedLeave ? "أجازة زمنية" : request.leaveType, - style: const TextStyle( - color: Colors.black, - fontSize: 18, - fontWeight: FontWeight.bold, - ), - ), - ], - ), + // 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 - const SizedBox(height: 12), + // Status flags + final bool isWaiting = request.status == "waiting"; + final bool isApproved = request.status == "approved"; + final bool isDenied = request.status == "denied"; - // Date range - Directionality( - textDirection: TextDirection.rtl, - child: Row( - mainAxisAlignment: MainAxisAlignment.end, + 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: [ - Text( - 'من: ${request.fromDate.day}/${request.fromDate.month}/${request.fromDate.year}', - style: const TextStyle( - color: Colors.black87, - fontSize: 16, - ), + buildStatusCircle( + active: isWaiting, + label: "قيد الانتظار", + svgPath: isWaiting ? "assets/images/waiting.svg" : null, + activeColor: const Color(0xFFF9C8A01B), + glowColor: const Color(0xB4FFDC69), ), - const SizedBox(width: 20), + + 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( - 'إلى: ${request.toDate.day}/${request.toDate.month}/${request.toDate.year}', + dateText, style: const TextStyle( + fontSize: 14, // Smaller text color: Colors.black87, - fontSize: 16, + fontWeight: FontWeight.w500, ), ), ], ), - ), - if (request.isTimedLeave) ...[ - const SizedBox(height: 8), - Directionality( - textDirection: TextDirection.rtl, + 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( - mainAxisAlignment: MainAxisAlignment.end, + textDirection: TextDirection.ltr, children: [ - Text( - 'من: ${request.fromTime.hour}:${request.fromTime.minute.toString().padLeft(2, '0')}', - style: const TextStyle( - color: Colors.black87, - fontSize: 16, + // Reason text (LEFT) + Expanded( + child: Text( + request.reason, + textAlign: TextAlign.right, + style: const TextStyle( + fontSize: 13, // Smaller text + color: Colors.black87, + ), ), ), - const SizedBox(width: 20), - Text( - 'إلى: ${request.toTime.hour}:${request.toTime.minute.toString().padLeft(2, '0')}', - style: const TextStyle( + + const SizedBox(width: 6), + + // Label (RIGHT) + const Text( + "السبب :", + textAlign: TextAlign.right, + style: TextStyle( + fontSize: 14, // Smaller text color: Colors.black87, - fontSize: 16, + fontWeight: FontWeight.bold, ), ), ], ), ), ], - - const SizedBox(height: 12), - - // Reason - Directionality( - textDirection: TextDirection.rtl, - child: Container( - width: double.infinity, - padding: const EdgeInsets.all(12), - decoration: BoxDecoration( - color: const Color(0xFFF5F5F5), - borderRadius: BorderRadius.circular(8), - ), - child: Text( - request.reason, - style: const TextStyle( - color: Colors.black87, - fontSize: 16, - ), - ), - ), - ), - - const SizedBox(height: 12), - - // Request date - Directionality( - textDirection: TextDirection.rtl, - child: Text( - 'تاريخ الطلب: ${request.requestDate.day}/${request.requestDate.month}/${request.requestDate.year}', - style: const TextStyle( - color: Colors.grey, - fontSize: 14, - ), - ), - ), - - // Status text below the card - const SizedBox(height: 8), - Directionality( - textDirection: TextDirection.rtl, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - _getStatusText(request.status), - style: TextStyle( - color: _getStatusColor(request.status), - fontSize: 14, - fontWeight: FontWeight.w600, - ), - ), - ], - ), - ), - ], + ), ), ); } Widget _buildAdvanceRequestCard(AdvanceRequest request) { - return Container( - margin: const EdgeInsets.only(bottom: 16), - padding: const EdgeInsets.all(16), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(16), - boxShadow: const [ - BoxShadow( - color: Color(0x33000000), - blurRadius: 10, - offset: Offset(0, 4), - ), - ], - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - // Header with status icon - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - // Status icon instead of text - Container( - padding: const EdgeInsets.all(8), - decoration: BoxDecoration( - color: _getStatusColor(request.status), - shape: BoxShape.circle, - ), - child: SvgPicture.asset( - _getStatusIconPath(request.status), - width: 24, - height: 24, - color: Colors.white, - ), - ), - Text( - 'طلب سلفة', - style: const TextStyle( - color: Colors.black, - fontSize: 18, - fontWeight: FontWeight.bold, - ), - ), - ], - ), + // Base colors + const bgColor = Color(0xFFEAF8F3); + const lineColor = Color(0xFF22A685); + // const inactiveColor = Color(0xFFD6D6D6); - const SizedBox(height: 12), + // Status flags + final bool isWaiting = request.status == "waiting"; + final bool isApproved = request.status == "approved"; + final bool isDenied = request.status == "denied"; - // Amount - Directionality( - textDirection: TextDirection.rtl, - child: Text( - 'المبلغ: ${request.amount.toStringAsFixed(2)} دع', - style: const TextStyle( - color: Colors.black87, - fontSize: 16, - fontWeight: FontWeight.bold, - ), - ), - ), + // You can format a date if needed + final String dateText = + "${DateTime.now().year}.${DateTime.now().month}.${DateTime.now().day}"; - const SizedBox(height: 12), - - // Reason - Directionality( - textDirection: TextDirection.rtl, - child: Container( - width: double.infinity, - padding: const EdgeInsets.all(12), - decoration: BoxDecoration( - color: const Color(0xFFF5F5F5), - borderRadius: BorderRadius.circular(8), - ), - child: Text( - request.reason, - style: const TextStyle( - color: Colors.black87, - fontSize: 16, - ), - ), - ), - ), - - // Status text below the card - const SizedBox(height: 8), - Directionality( - textDirection: TextDirection.rtl, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, + 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( - _getStatusText(request.status), - style: TextStyle( - color: _getStatusColor(request.status), - fontSize: 14, - fontWeight: FontWeight.w600, + 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, + ), + ), + ], + ), + ), + ], + ), ), ); } @@ -556,7 +600,7 @@ class _HolidayActionButton extends StatelessWidget { onTap: onTap, child: Container( width: 80, - height: 80, + height: 70, decoration: BoxDecoration( color: Colors.white, shape: BoxShape.circle, diff --git a/lib/screens/main_screen.dart b/lib/screens/main_screen.dart index c7cc6c1..8c8c4f0 100644 --- a/lib/screens/main_screen.dart +++ b/lib/screens/main_screen.dart @@ -58,7 +58,7 @@ class _MainPageState extends State { child: IndexedStack(index: _currentIndex, children: _screens), ), - const SizedBox(height: 20), + // const SizedBox(height: 20), Floatingnavbar( items: _navItems,