From 5cdfa102f317715e51b53623ae092c64e5085238 Mon Sep 17 00:00:00 2001 From: Daniah Ayad Al-sultani <148902945+Cactuskiller@users.noreply.github.com> Date: Sat, 13 Dec 2025 16:56:34 +0300 Subject: [PATCH] last changes --- lib/screens/attendence_screen.dart | 119 ++++---- lib/screens/finance_screen.dart | 101 +++++-- lib/screens/holiday_screen.dart | 458 ++++++++++------------------- lib/screens/main_screen.dart | 124 ++++---- lib/widgets/FloatingNavBar.dart | 71 ++--- 5 files changed, 389 insertions(+), 484 deletions(-) diff --git a/lib/screens/attendence_screen.dart b/lib/screens/attendence_screen.dart index b9478fa..08c0762 100644 --- a/lib/screens/attendence_screen.dart +++ b/lib/screens/attendence_screen.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import '../widgets/login_animation.dart'; +import '../widgets/login_animation.dart'; +import '../widgets/settings_bar.dart'; class AttendanceScreen extends StatelessWidget { const AttendanceScreen({super.key}); @@ -11,9 +12,33 @@ class AttendanceScreen extends StatelessWidget { textDirection: TextDirection.rtl, child: Stack( children: [ + + /// ------------------------------ + /// SETTINGS BAR (STATIC) + /// ------------------------------ + SafeArea( + child: Padding( + padding: const EdgeInsets.only(top: 10), + child: SettingsBar( + selectedIndex: 0, + showBackButton: false, + iconPaths: [ + 'assets/images/user.svg', + 'assets/images/ball.svg', + ], + onTap: (index) { + // Keep static, no animations + // You can navigate or add your logic later + }, + ), + ), + ), + + /// ------------------------------ /// GREETING TEXT + /// ------------------------------ Positioned( - top: 10, + top: 70, // moved down because settings bar now exists left: 0, right: 0, child: Center( @@ -24,58 +49,52 @@ class AttendanceScreen extends StatelessWidget { fontWeight: FontWeight.w600, color: Colors.white, shadows: [ - Shadow(color: const Color(0x42000000), blurRadius: 6), + Shadow(color: Color(0x42000000), blurRadius: 6), ], ), ), ), ), + + /// ------------------------------ + /// MAIN CARD AREA + /// ------------------------------ Positioned( - top: 100, + top: 160, // pushed down because of settings bar + greeting left: 0, right: 0, child: Center( child: Stack( children: [ - /// BACK SHADOW LAYER Container( height: 420, width: 260, decoration: BoxDecoration( borderRadius: BorderRadius.circular(32), boxShadow: [ - // TOP-RIGHT BLACK FADE - const BoxShadow( + BoxShadow( color: Color(0x1F2B2B2B), blurRadius: 5, - spreadRadius: 0, offset: Offset(10, -10), ), - - // BOTTOM-LEFT GREEN GLOW - const BoxShadow( + BoxShadow( color: Color(0xABCECECE), blurRadius: 5, - spreadRadius: 2, offset: Offset(-2, 5), ), - - // LIGHT GLOBAL GLOW BoxShadow( color: Color.fromARGB(148, 2, 70, 35), blurRadius: 80, - offset: const Offset(0, 10), + offset: Offset(0, 10), ), ], ), ), - - /// FRONT MAIN RECTANGLE Container( height: 420, width: 260, decoration: BoxDecoration( - color: const Color(0x92757575), + color: Color(0x92757575), borderRadius: BorderRadius.circular(32), ), ), @@ -84,13 +103,14 @@ class AttendanceScreen extends StatelessWidget { ), ), - /// ===== LOGIN BUTTON (TOP-LEFT) ===== + /// ------------------------------ + /// LOGIN BUTTON + /// ------------------------------ Positioned( - top: 70, + top: 130, left: 24, child: _ShadowedCard( - shadow: const [ - // Strong BLACK shadow bottom-right + shadow: [ BoxShadow( color: Color(0x62000000), blurRadius: 10, @@ -102,14 +122,12 @@ class AttendanceScreen extends StatelessWidget { icon: "assets/images/login.svg", label: "تسجيل الدخول", onTap: () { - // Navigate to LoginAnimationScreen with error state Navigator.of(context).push( MaterialPageRoute( - builder: - (context) => LoginAnimationScreen( - isLogin: true, - isSuccess: false, - ), + builder: (_) => LoginAnimationScreen( + isLogin: true, + isSuccess: false, + ), ), ); }, @@ -117,21 +135,20 @@ class AttendanceScreen extends StatelessWidget { ), ), - /// ===== LOGOUT BUTTON (BOTTOM-RIGHT) ===== + /// ------------------------------ + /// LOGOUT BUTTON + /// ------------------------------ Positioned( - bottom: 10, + bottom: 60, right: 24, child: _ShadowedCard( - shadow: const [ - // Strong BLACK shadow bottom-right + shadow: [ BoxShadow( color: Color(0xABCECECE), blurRadius: 5, spreadRadius: 3, offset: Offset(-6, -6), ), - - // LIGHT GLOBAL GLOW BoxShadow( color: Color(0x92014221), blurRadius: 10, @@ -148,14 +165,12 @@ class AttendanceScreen extends StatelessWidget { icon: "assets/images/logout.svg", label: "تسجيل خروج", onTap: () { - // Navigate to LoginAnimationScreen with error state Navigator.of(context).push( MaterialPageRoute( - builder: - (context) => LoginAnimationScreen( - isLogin: false, - isSuccess: true, - ), + builder: (_) => LoginAnimationScreen( + isLogin: false, + isSuccess: true, + ), ), ); }, @@ -168,7 +183,10 @@ class AttendanceScreen extends StatelessWidget { } } -/// Wrapper that applies custom layered shadows BEHIND each card +/// --------------------------------------------- +/// SHADOW WRAPPER +/// --------------------------------------------- + class _ShadowedCard extends StatelessWidget { final Widget child; final List shadow; @@ -179,7 +197,6 @@ class _ShadowedCard extends StatelessWidget { Widget build(BuildContext context) { return Stack( children: [ - /// BACK SHADOW LAYER Container( height: 160, width: 160, @@ -188,44 +205,46 @@ class _ShadowedCard extends StatelessWidget { boxShadow: shadow, ), ), - - /// FRONT CARD child, ], ); } } +/// --------------------------------------------- +/// BUTTON WIDGET +/// --------------------------------------------- + class _FingerButton extends StatelessWidget { final String icon; final String label; - final VoidCallback onTap; // Added onTap callback + final VoidCallback onTap; const _FingerButton({ required this.icon, required this.label, - required this.onTap, // Added this parameter + required this.onTap, }); @override Widget build(BuildContext context) { return GestureDetector( - onTap: onTap, // Added gesture detection + onTap: onTap, child: Container( height: 160, width: 160, decoration: BoxDecoration( - color: const Color(0xFFEAFBF3), + color: Color(0xFFEAFBF3), borderRadius: BorderRadius.circular(32), ), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ SvgPicture.asset(icon, width: 62, height: 62), - const SizedBox(height: 10), + SizedBox(height: 10), Text( label, - style: const TextStyle( + style: TextStyle( fontSize: 18, fontWeight: FontWeight.w600, color: Colors.black, diff --git a/lib/screens/finance_screen.dart b/lib/screens/finance_screen.dart index f967d4b..7eed5fb 100644 --- a/lib/screens/finance_screen.dart +++ b/lib/screens/finance_screen.dart @@ -1,9 +1,13 @@ import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; import '../widgets/finance_summary_card.dart'; import '../widgets/work_day_card.dart'; +import '../widgets/settings_bar.dart'; class FinanceScreen extends StatefulWidget { - const FinanceScreen({super.key}); + final void Function(bool isScrollingDown)? onScrollEvent; + + const FinanceScreen({super.key, this.onScrollEvent}); @override State createState() => _FinanceScreenState(); @@ -11,30 +15,87 @@ class FinanceScreen extends StatefulWidget { class _FinanceScreenState extends State { String dropdownValue = "الكل"; + bool _showSettings = true; // local control of settings bar @override Widget build(BuildContext context) { - return ListView( - padding: const EdgeInsets.only(top: 20, bottom: 120), - children: [ - FinanceSummaryCard( - totalAmount: "333,000", - dropdownValue: dropdownValue, - onCalendarTap: () => showDatePicker( - context: context, - initialDate: DateTime.now(), - firstDate: DateTime(2020), - lastDate: DateTime(2030), + return Directionality( + textDirection: TextDirection.rtl, + child: Stack( + children: [ + /// -------------------------------------------------- + /// SETTINGS BAR (STATIC, INSIDE THE SCREEN) + /// -------------------------------------------------- + AnimatedPositioned( + duration: const Duration(milliseconds: 250), + top: _showSettings ? 0 : -80, + left: 0, + right: 0, + child: SafeArea( + child: Padding( + padding: const EdgeInsets.only(top: 8), + child: SettingsBar( + selectedIndex: 0, + showBackButton: false, + iconPaths: [ + 'assets/images/user.svg', + 'assets/images/ball.svg', + ], + onTap: (index) { + // Your logic here + }, + ), + ), + ), ), - onDropdownChanged: (value) { - setState(() => dropdownValue = value!); - }, - ), - const WorkDayCard(), - const WorkDayCard(), - const WorkDayCard(), - ], + /// -------------------------------------------------- + /// MAIN CONTENT - LIST + /// -------------------------------------------------- + Positioned.fill( + top: 70, // space for SettingsBar + child: NotificationListener( + onNotification: (notif) { + if (notif.direction == ScrollDirection.reverse) { + setState(() => _showSettings = false); + widget.onScrollEvent?.call(true); + } else if (notif.direction == ScrollDirection.forward) { + setState(() => _showSettings = true); + widget.onScrollEvent?.call(false); + } + return true; + }, + + child: ListView( + padding: const EdgeInsets.only( + top: 0, + bottom: 120), + children: [ + /// SUMMARY CARD + FinanceSummaryCard( + totalAmount: "333,000", + dropdownValue: dropdownValue, + onCalendarTap: () => showDatePicker( + context: context, + initialDate: DateTime.now(), + firstDate: DateTime(2020), + lastDate: DateTime(2030), + ), + onDropdownChanged: (value) { + setState(() => dropdownValue = value!); + }, + ), + + /// WORK DAY CARDS + const WorkDayCard(), + const WorkDayCard(), + const WorkDayCard(), + ], + ), + ), + ), + ], + ), ); } } diff --git a/lib/screens/holiday_screen.dart b/lib/screens/holiday_screen.dart index 6396dd8..d048d3d 100644 --- a/lib/screens/holiday_screen.dart +++ b/lib/screens/holiday_screen.dart @@ -2,6 +2,7 @@ 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'; @@ -9,43 +10,49 @@ import '../models/advance_request.dart'; import '../services/request_service.dart'; class HolidayScreen extends StatefulWidget { - const HolidayScreen({super.key}); + final void Function(bool isScrollingDown)? onScrollEvent; + + const HolidayScreen({super.key, this.onScrollEvent}); @override State createState() => _HolidayScreenState(); } class _HolidayScreenState extends State { - int activeTab = 0; // 0 = السلف | 1 = الأجازات + int activeTab = 0; final RequestService _requestService = RequestService(); List _leaveRequests = []; List _advanceRequests = []; - /// ⭐ Telegram-style FAB animation final ScrollController _scrollController = ScrollController(); bool _showActions = true; + bool _showSettings = true; // NEW — local control for SettingsBar @override void initState() { super.initState(); _initializeData(); - // ⭐ Listen to scroll and animate the floating buttons (Telegram style) _scrollController.addListener(() { final direction = _scrollController.position.userScrollDirection; if (direction == ScrollDirection.reverse) { - // scrolling DOWN → hide buttons if (_showActions) setState(() => _showActions = false); + setState(() => _showSettings = false); + widget.onScrollEvent?.call(true); } else if (direction == ScrollDirection.forward) { - // scrolling UP → show buttons if (!_showActions) setState(() => _showActions = true); + setState(() => _showSettings = true); + widget.onScrollEvent?.call(false); } - // If user reaches top → force visible - if (_scrollController.position.pixels <= 10) { - if (!_showActions) setState(() => _showActions = true); + if (_scrollController.position.pixels <= 5) { + setState(() { + _showActions = true; + _showSettings = true; + }); + widget.onScrollEvent?.call(false); } }); } @@ -55,74 +62,55 @@ class _HolidayScreenState extends State { _advanceRequests = await _requestService.getAdvanceRequests(); _requestService.leaveRequestsStream.listen((requests) { - setState(() { - _leaveRequests = requests; - }); + if (mounted) setState(() => _leaveRequests = requests); }); _requestService.advanceRequestsStream.listen((requests) { - setState(() { - _advanceRequests = requests; - }); + if (mounted) 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, - 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, - height: 18, - color: const Color(0xFFFFFFFF), - ), - ) - : null, - ), - const SizedBox(height: 4), - Text(label, style: const TextStyle(fontSize: 10)), - ], - ); - } - @override Widget build(BuildContext context) { return Directionality( textDirection: TextDirection.rtl, child: Stack( children: [ - // -------------------- TABS -------------------- - Positioned( - top: 0, + // --------------------------------------------------------- + // ⭐ SETTINGS BAR (now inside Holiday screen) + // --------------------------------------------------------- + AnimatedPositioned( + duration: const Duration(milliseconds: 250), + top: _showSettings ? 0 : -80, left: 0, right: 0, - bottom: 5, + child: SafeArea( + child: Padding( + padding: const EdgeInsets.only(top: 8), + child: SettingsBar( + selectedIndex: 0, + showBackButton: false, + iconPaths: [ + 'assets/images/user.svg', + 'assets/images/ball.svg', + ], + onTap: (index) { + // do your navigation logic + }, + ), + ), + ), + ), + + // --------------------------------------------------------- + // ⭐ TABS SECTION + // Directly under SettingsBar, NO GAP + // --------------------------------------------------------- + Positioned( + top: 70, + left: 0, + right: 0, + height: 55, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -185,33 +173,30 @@ class _HolidayScreenState extends State { ), ), - // ------------- CONTENT AREA (LISTS) ------------- - Positioned( - top: 30, - left: 0, - right: 0, - bottom: 0, + // --------------------------------------------------------- + // ⭐ CONTENT AREA (LISTS) + // Starts right under the TABS + // --------------------------------------------------------- + Positioned.fill( + top: 130, child: activeTab == 1 ? _buildLeaveRequestsTab() : _buildAdvanceRequestsTab(), ), - // ------------------------------------------------------------- - // ⭐ TELEGRAM STYLE FLOATING ACTION BUTTONS (SLIDE + FADE) - // ------------------------------------------------------------- + // --------------------------------------------------------- + // ⭐ FLOATING ACTION BUTTONS + // --------------------------------------------------------- Positioned( - bottom: 30, + bottom: 60, right: 20, child: AnimatedSlide( - offset: _showActions ? const Offset(0, 0) : const Offset(0, 1.4), - duration: const Duration(milliseconds: 350), - curve: Curves.easeOut, - + offset: _showActions ? Offset.zero : const Offset(0, 1.3), + duration: const Duration(milliseconds: 300), child: AnimatedOpacity( - duration: const Duration(milliseconds: 250), opacity: _showActions ? 1 : 0, - + duration: const Duration(milliseconds: 250), child: Column( children: [ _HolidayActionButton( @@ -219,28 +204,26 @@ class _HolidayScreenState extends State { svgPath: "assets/images/money2.svg", iconWidth: 28, iconHeight: 20, - onTap: () async { - await Navigator.push( + onTap: () { + Navigator.push( context, MaterialPageRoute( - builder: (context) => const RequestAdvanceScreen(), + builder: (_) => const RequestAdvanceScreen(), ), ); }, ), - const SizedBox(height: 18), - _HolidayActionButton( label: "طلب إجازة", svgPath: "assets/images/plus.svg", iconWidth: 28, iconHeight: 20, - onTap: () async { - await Navigator.push( + onTap: () { + Navigator.push( context, MaterialPageRoute( - builder: (context) => const RequestLeaveScreen(), + builder: (_) => const RequestLeaveScreen(), ), ); }, @@ -255,15 +238,15 @@ class _HolidayScreenState extends State { ); } - // -------------------- LIST BUILDERS -------------------- + // ---------------------------------------------------------------- + // LISTS + // ---------------------------------------------------------------- Widget _buildLeaveRequestsTab() { if (_leaveRequests.isEmpty) { return const Center( - child: Text( - 'لا توجد طلبات أجازة', - style: TextStyle(color: Colors.white, fontSize: 18), - ), + child: + Text("لا توجد طلبات أجازة", style: TextStyle(color: Colors.white)), ); } @@ -280,10 +263,8 @@ class _HolidayScreenState extends State { Widget _buildAdvanceRequestsTab() { if (_advanceRequests.isEmpty) { return const Center( - child: Text( - 'لا توجد طلبات سلف', - style: TextStyle(color: Colors.white, fontSize: 18), - ), + child: + Text("لا توجد طلبات سلف", style: TextStyle(color: Colors.white)), ); } @@ -297,7 +278,9 @@ class _HolidayScreenState extends State { ); } - // -------------------- LEAVE REQUEST CARD -------------------- + // ---------------------------------------------------------------- + // CARD BUILDERS (unchanged) + // ---------------------------------------------------------------- Widget _buildLeaveRequestCard(LeaveRequest request) { const bgColor = Color(0xFFEAF8F3); @@ -313,7 +296,7 @@ class _HolidayScreenState extends State { return Directionality( textDirection: TextDirection.rtl, child: Container( - width: MediaQuery.of(context).size.width * 0.8, + width: double.infinity, margin: const EdgeInsets.only(bottom: 16), padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 14), decoration: BoxDecoration( @@ -323,261 +306,126 @@ class _HolidayScreenState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ - // Status circles + // STATUS ROW Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - buildStatusCircle( - active: isWaiting, - label: "قيد الانتظار", - svgPath: isWaiting ? "assets/images/waiting.svg" : null, - activeColor: const Color(0xFFF9C8A01B), - glowColor: const Color(0xB4FFDC69), - ), + _statusCircle(isWaiting, "قيد الانتظار", + isWaiting ? "assets/images/waiting.svg" : null, + const Color(0xFFA58A1B), const Color(0xFFFFDC69)), const SizedBox(width: 12), - buildStatusCircle( - active: isApproved, - label: "موافقة", - svgPath: isApproved ? "assets/images/yes.svg" : null, - activeColor: const Color(0xFF0A8A60), - glowColor: const Color(0xFF00D7A3), - ), + _statusCircle(isApproved, "موافقة", + isApproved ? "assets/images/yes.svg" : null, + const Color(0xFF0A8A60), const Color(0xFF00D7A3)), const SizedBox(width: 12), - buildStatusCircle( - active: isDenied, - label: "تم الرفض", - svgPath: isDenied ? "assets/images/no.svg" : null, - activeColor: const Color(0xFFE63946), - glowColor: const Color(0xFFE63946), - ), + _statusCircle(isDenied, "تم الرفض", + isDenied ? "assets/images/no.svg" : null, + const Color(0xFFE63946), const Color(0xFFE63946)), ], ), const SizedBox(height: 8), - // Title + date row + // TITLE + DATE Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - // icon + leave type Row( children: [ - SizedBox( + SvgPicture.asset( + "assets/images/holiday.svg", width: 32, height: 32, - child: Center( - child: SvgPicture.asset( - "assets/images/holiday.svg", - width: 32, - height: 32, - color: const Color(0xFF11663C), - ), - ), + color: const Color(0xFF11663C), ), const SizedBox(width: 8), Text( request.leaveType, style: const TextStyle( - fontSize: 12, - color: Colors.black87, fontWeight: FontWeight.bold, + fontSize: 13, ), ), ], ), - - // date - Text( - dateText, - style: const TextStyle( - fontSize: 14, - color: Colors.black87, - fontWeight: FontWeight.w500, - ), - ), + Text(dateText), ], ), const SizedBox(height: 10), - - // divider - Container(width: double.infinity, height: 1.4, color: lineColor), - + Container(height: 1.4, width: double.infinity, color: lineColor), const SizedBox(height: 10), - // Reason row - Padding( - padding: const EdgeInsets.only(top: 8), - child: Row( - textDirection: TextDirection.ltr, - children: [ - Expanded( - child: Text( - request.reason, - textAlign: TextAlign.right, - style: const TextStyle( - fontSize: 13, - color: Colors.black87, - ), - ), - ), - const SizedBox(width: 6), - const Text( - "السبب :", + // REASON ROW + Row( + children: [ + Expanded( + child: Text( + request.reason, textAlign: TextAlign.right, - style: TextStyle( - fontSize: 14, - color: Colors.black87, - fontWeight: FontWeight.bold, - ), ), - ], - ), - ), + ), + const SizedBox(width: 6), + const Text( + "السبب:", + style: TextStyle(fontWeight: FontWeight.bold), + ), + ], + ) ], ), ), ); } - // -------------------- ADVANCE REQUEST CARD -------------------- + 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) { - 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 = - "${DateTime.now().year}.${DateTime.now().month}.${DateTime.now().day}"; - - return Directionality( - textDirection: TextDirection.rtl, - child: Container( - width: MediaQuery.of(context).size.width * 0.8, - margin: const EdgeInsets.only(bottom: 16), - padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 14), - decoration: BoxDecoration( - color: bgColor, - borderRadius: BorderRadius.circular(16), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - buildStatusCircle( - active: isWaiting, - label: "قيد الانتظار", - svgPath: isWaiting ? "assets/images/waiting.svg" : null, - activeColor: const Color(0xFFF9C8A01B), - glowColor: const Color(0xB4FFDC69), - ), - const SizedBox(width: 12), - buildStatusCircle( - active: isApproved, - label: "موافقة", - svgPath: isApproved ? "assets/images/yes.svg" : null, - activeColor: const Color(0xFF0A8A60), - glowColor: const Color(0xFF00D7A3), - ), - const SizedBox(width: 12), - buildStatusCircle( - active: isDenied, - label: "تم الرفض", - svgPath: isDenied ? "assets/images/no.svg" : null, - activeColor: const Color(0xFFE63946), - glowColor: const Color(0xFFE63946), - ), - ], - ), - - const SizedBox(height: 8), - - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - SizedBox( - width: 32, - height: 32, - child: Center( - child: SvgPicture.asset( - "assets/images/money.svg", - width: 32, - height: 32, - color: const Color(0xFF11663C), - ), - ), - ), - const SizedBox(width: 8), - Text( - "سلفة: ${request.amount.toStringAsFixed(0)} دع", - style: const TextStyle( - fontSize: 12, - color: Colors.black87, - fontWeight: FontWeight.bold, - ), - ), - ], - ), - Text( - dateText, - style: const TextStyle( - fontSize: 14, - color: Colors.black87, - fontWeight: FontWeight.w500, - ), - ), - ], - ), - - const SizedBox(height: 10), - - Container(width: double.infinity, height: 1, color: lineColor), - - const SizedBox(height: 10), - - Padding( - padding: const EdgeInsets.only(top: 8), - child: Row( - textDirection: TextDirection.ltr, - children: [ - Expanded( - child: Text( - request.reason, - textAlign: TextAlign.right, - style: const TextStyle( - fontSize: 13, - color: Colors.black87, - ), - ), - ), - const SizedBox(width: 6), - const Text( - "السبب :", - textAlign: TextAlign.right, - style: TextStyle( - fontSize: 14, - color: Colors.black87, - fontWeight: FontWeight.bold, - ), - ), - ], - ), - ), - ], - ), + // 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 ACTION BUTTON -------------------- +// ---------------------------------------------------------------- +// FLOATING BUTTON WIDGET (unchanged) +// ---------------------------------------------------------------- class _HolidayActionButton extends StatelessWidget { final String label; diff --git a/lib/screens/main_screen.dart b/lib/screens/main_screen.dart index 53b2a46..93fc486 100644 --- a/lib/screens/main_screen.dart +++ b/lib/screens/main_screen.dart @@ -1,10 +1,6 @@ -import 'package:coda_project/screens/user_settings_screen.dart'; import 'package:flutter/material.dart'; -// import 'package:flutter_svg/flutter_svg.dart'; -import '../screens/notifications_screen.dart'; import '../widgets/app_background.dart'; import '../widgets/floatingnavbar.dart'; -import '../widgets/settings_bar.dart'; import '../screens/attendence_screen.dart'; import '../screens/finance_screen.dart'; import '../screens/holiday_screen.dart'; @@ -18,83 +14,63 @@ class MainPage extends StatefulWidget { class _MainPageState extends State { int _currentIndex = 0; - int _settingsIndex = 0; - final List _screens = [ - const AttendanceScreen(), - const FinanceScreen(), - const HolidayScreen(), - ]; - - final List _navItems = [ - NavBarItem(iconPath: 'assets/images/attendance.svg', label: 'الحضور'), - NavBarItem(iconPath: 'assets/images/finance.svg', label: 'المالية'), - NavBarItem(iconPath: 'assets/images/holiday.svg', label: 'الإجازة'), - ]; - - final List _settingsIconPaths = [ - 'assets/images/user.svg', - 'assets/images/ball.svg', - ]; + Widget _buildScreen() { + switch (_currentIndex) { + case 0: + return const AttendanceScreen(); + case 1: + return const FinanceScreen(); // no need for scroll callback anymore + case 2: + return const HolidayScreen(); // SettingsBar is inside the screen now + default: + return const AttendanceScreen(); + } + } @override Widget build(BuildContext context) { return Scaffold( - body: AppBackground( - child: SafeArea( - child: Column( - children: [ - SettingsBar( - selectedIndex: _settingsIndex, - onTap: (index) { - setState(() { - _settingsIndex = index; - }); + body: Stack( + children: [ + /// BACKGROUND + const AppBackground(child: SizedBox()), - // 🟢 If user clicked the first icon (user.svg), open settings screen - if (index == 0) { - Navigator.push( - context, - MaterialPageRoute( - builder: (_) => const UserSettingsScreen(), - ), - ); - } - - // 🔔 Ball icon → Notifications screen - if (index == 1) { - Navigator.push( - context, - MaterialPageRoute( - builder: - (_) => const NotificationsScreen(), // placeholder - ), - ); - } - }, - showBackButton: false, - iconPaths: _settingsIconPaths, - ), - - // Main content area - Expanded( - child: IndexedStack(index: _currentIndex, children: _screens), - ), - - // const SizedBox(height: 20), - Floatingnavbar( - items: _navItems, - selectedIndex: _currentIndex, - onTap: (index) { - setState(() { - _currentIndex = index; - }); - }, - ), - const SizedBox(height: 20), - ], + /// ACTIVE SCREEN (fills everything except navbar area) + Positioned.fill( + bottom: 100, // space for floating navbar + child: _buildScreen(), ), - ), + + /// FLOATING NAVBAR + Positioned( + left: 0, + right: 0, + bottom: 20, + child: Floatingnavbar( + items: [ + NavBarItem( + iconPath: 'assets/images/attendance.svg', + label: 'الحضور', + ), + NavBarItem( + iconPath: 'assets/images/finance.svg', + label: 'المالية', + ), + NavBarItem( + iconPath: 'assets/images/holiday.svg', + label: 'الإجازة', + ), + ], + selectedIndex: _currentIndex, + onTap: (index) { + setState(() { + _currentIndex = index; + }); + }, + ), + ), + ], ), ); } diff --git a/lib/widgets/FloatingNavBar.dart b/lib/widgets/FloatingNavBar.dart index 3e3d339..f4db02d 100644 --- a/lib/widgets/FloatingNavBar.dart +++ b/lib/widgets/FloatingNavBar.dart @@ -25,44 +25,45 @@ class Floatingnavbar extends StatelessWidget { Widget build(BuildContext context) { final bottomPadding = MediaQuery.of(context).padding.bottom; - return ClipRRect( - - borderRadius: BorderRadius.circular(45), + return ClipRRect( + borderRadius: BorderRadius.circular(45), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 12, sigmaY: 12), + child: Container( + height: 70, + margin: EdgeInsets.only( + bottom: 10 + bottomPadding, + left: 28, + right: 28, + ), - child: Container( - color: Colors.transparent, - child: Container( - height: 70, - margin: EdgeInsets.only( - bottom: 10 + bottomPadding, - left: 28, - right: 28, - ), - - /// ⭐ Restored white container (same as your original design) - decoration: BoxDecoration( - color: const Color(0xFFE9E9E9), // White navbar restored - borderRadius: BorderRadius.circular(45), - ), - - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: - items.asMap().entries.map((entry) { - final index = entry.key; - final item = entry.value; - final isSelected = selectedIndex == index; - - return _NavBarItemTile( - item: item, - isSelected: isSelected, - onTap: () => onTap(index), - ); - }).toList(), - ), + decoration: BoxDecoration( + color: Colors.white, // ⭐ frosted-glass effect + borderRadius: BorderRadius.circular(45), + border: Border.all( + color: const Color(0x4DFFFFFF), // subtle glass border + width: 1.2, ), ), - ); + + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: items.asMap().entries.map((entry) { + final index = entry.key; + final item = entry.value; + final isSelected = selectedIndex == index; + + return _NavBarItemTile( + item: item, + isSelected: isSelected, + onTap: () => onTap(index), + ); + }).toList(), + ), + ), + ), +); + } }