Advertisement
Zuhairy_Harry

screen.dart v2

Jun 13th, 2025
275
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Dart 19.56 KB | None | 0 0
  1. import 'package:einventorycomputer/modules/home/screen/location/location.dart';
  2. import 'package:einventorycomputer/services/auth.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:firebase_auth/firebase_auth.dart';
  5. import 'package:cloud_firestore/cloud_firestore.dart';
  6. import 'package:einventorycomputer/modules/home/screen/home.dart';
  7. import 'package:einventorycomputer/modules/home/screen/devices/inventory.dart';
  8. import 'package:einventorycomputer/modules/home/screen/settings/settings.dart';
  9. import 'package:einventorycomputer/modules/home/screen/user/account.dart';
  10. import 'package:einventorycomputer/modules/home/screen/devices/add_device.dart';
  11.  
  12. class ScreenPage extends StatefulWidget {
  13.   @override
  14.   _ScreenPageState createState() => _ScreenPageState();
  15. }
  16.  
  17. class _ScreenPageState extends State<ScreenPage> with TickerProviderStateMixin {
  18.   final AuthService _auth = AuthService();
  19.   int _selectedIndex = 0;
  20.   String? _username;
  21.   String? _profileImageUrl;  // Added for profile image
  22.   late AnimationController _drawerAnimationController;
  23.   late AnimationController _fabAnimationController;
  24.  
  25.   final List<String> _titles = [
  26.     "Home",
  27.     "Inventory",
  28.     "Add Device",
  29.     "Settings",
  30.     "Account",
  31.     "Location",
  32.   ];
  33.  
  34.   final List<Widget> _pages = [
  35.     HomePage(),
  36.     InventoryPage(),
  37.     AddDevicePage(),
  38.     SettingsPage(),
  39.     AccountPage(),
  40.     LocationPage(),
  41.   ];
  42.  
  43.   // Define which indices are in the bottom navigation
  44.   final List<int> _bottomNavIndexes = [0, 1, 4, 5];
  45.  
  46.   @override
  47.   void initState() {
  48.     super.initState();
  49.     _loadUserData();  // Changed from _loadUsername to _loadUserData
  50.     _drawerAnimationController = AnimationController(
  51.       duration: const Duration(milliseconds: 300),
  52.       vsync: this,
  53.     );
  54.     _fabAnimationController = AnimationController(
  55.       duration: const Duration(milliseconds: 300),
  56.       vsync: this,
  57.     );
  58.     _fabAnimationController.forward();
  59.   }
  60.  
  61.   @override
  62.   void dispose() {
  63.     _drawerAnimationController.dispose();
  64.     _fabAnimationController.dispose();
  65.     super.dispose();
  66.   }
  67.  
  68.   Future<void> _loadUserData() async {  // Updated method name and functionality
  69.     final user = FirebaseAuth.instance.currentUser;
  70.     if (user != null) {
  71.       try {
  72.         final doc = await FirebaseFirestore.instance.collection('users').doc(user.uid).get();
  73.         if (doc.exists && mounted) {
  74.           final data = doc.data();
  75.           setState(() {
  76.             _username = data?['username'] ?? 'User';
  77.             _profileImageUrl = data?['profileImageUrl'];  // Get profile image URL
  78.           });
  79.           print('Profile image URL: $_profileImageUrl'); // Debug print
  80.         }
  81.       } catch (e) {
  82.         print('Error loading user data: $e'); // Debug print
  83.       }
  84.     }
  85.   }
  86.  
  87.   void _onSelect(int index) {
  88.     if (_selectedIndex != index) {
  89.       setState(() {
  90.         _selectedIndex = index;
  91.       });
  92.       // Refresh user data when navigating to Account page
  93.       if (index == 4) { // Account page index
  94.         _loadUserData();
  95.       }
  96.     }
  97.     Navigator.pop(context); // Close drawer
  98.   }
  99.  
  100.   void _onFabPressed() {
  101.     // Add a small animation when pressed
  102.     _fabAnimationController.reverse().then((_) {
  103.       _fabAnimationController.forward();
  104.     });
  105.    
  106.     setState(() {
  107.       _selectedIndex = 2; // Navigate to Add Device page (index 2)
  108.     });
  109.   }
  110.  
  111.   Widget _buildProfileImage() {  // New method to build profile image widget
  112.     return Container(
  113.       width: 80,
  114.       height: 80,
  115.       decoration: BoxDecoration(
  116.         borderRadius: BorderRadius.circular(20),
  117.         boxShadow: [
  118.           BoxShadow(
  119.             color: const Color(0xFFFFC727).withOpacity(0.3),
  120.             blurRadius: 12,
  121.             offset: const Offset(0, 4),
  122.           ),
  123.         ],
  124.       ),
  125.       child: ClipRRect(
  126.         borderRadius: BorderRadius.circular(20),
  127.         child: Container(
  128.           width: 80,
  129.           height: 80,
  130.           color: const Color(0xFFFFC727),
  131.           child: _profileImageUrl != null && _profileImageUrl!.isNotEmpty
  132.               ? Image.network(
  133.                   _profileImageUrl!,
  134.                   width: 80,
  135.                   height: 80,
  136.                   fit: BoxFit.cover,
  137.                   errorBuilder: (context, error, stackTrace) {
  138.                     print('Error loading image: $error'); // Debug print
  139.                     return const Icon(
  140.                       Icons.person_rounded,
  141.                       size: 40,
  142.                       color: Color(0xFF212529),
  143.                     );
  144.                   },
  145.                   loadingBuilder: (context, child, loadingProgress) {
  146.                     if (loadingProgress == null) return child;
  147.                     return const Center(
  148.                       child: CircularProgressIndicator(
  149.                         valueColor: AlwaysStoppedAnimation<Color>(Color(0xFF212529)),
  150.                         strokeWidth: 2,
  151.                       ),
  152.                     );
  153.                   },
  154.                 )
  155.               : const Icon(
  156.                   Icons.person_rounded,
  157.                   size: 40,
  158.                   color: Color(0xFF212529),
  159.                 ),
  160.         ),
  161.       ),
  162.     );
  163.   }
  164.  
  165.   @override
  166.   Widget build(BuildContext context) {
  167.     final isBottomNavPage = _bottomNavIndexes.contains(_selectedIndex);
  168.     final safeCurrentIndex = _bottomNavIndexes.indexWhere((i) => i == _selectedIndex);
  169.  
  170.     return Scaffold(
  171.       backgroundColor: const Color(0xFFF8F9FA),
  172.       appBar: AppBar(
  173.         title: Text(
  174.           _titles[_selectedIndex],
  175.           style: const TextStyle(
  176.             fontFamily: 'SansRegular',
  177.             color: Color(0xFF212529),
  178.             fontWeight: FontWeight.w600,
  179.             fontSize: 20,
  180.           ),
  181.         ),
  182.         backgroundColor: Colors.transparent,
  183.         elevation: 0,
  184.         iconTheme: const IconThemeData(color: Color(0xFF212529)),
  185.         leading: Builder(
  186.           builder: (context) => IconButton(
  187.             icon: Container(
  188.               padding: const EdgeInsets.all(8),
  189.               decoration: BoxDecoration(
  190.                 color: Colors.white,
  191.                 borderRadius: BorderRadius.circular(12),
  192.                 boxShadow: [
  193.                   BoxShadow(
  194.                     color: Colors.black.withOpacity(0.1),
  195.                     blurRadius: 8,
  196.                     offset: const Offset(0, 2),
  197.                   ),
  198.                 ],
  199.               ),
  200.               child: const Icon(
  201.                 Icons.menu_rounded,
  202.                 color: Color(0xFF212529),
  203.                 size: 20,
  204.               ),
  205.             ),
  206.             onPressed: () => Scaffold.of(context).openDrawer(),
  207.           ),
  208.         ),
  209.       ),
  210.       drawer: Drawer(
  211.         backgroundColor: Colors.white,
  212.         elevation: 0,
  213.         child: SafeArea(
  214.           child: Column(
  215.             children: [
  216.               // Header Section
  217.               Container(
  218.                 width: double.infinity,
  219.                 padding: const EdgeInsets.all(24),
  220.                 decoration: const BoxDecoration(
  221.                   color: Color(0xFF212529),
  222.                   borderRadius: BorderRadius.only(
  223.                     bottomLeft: Radius.circular(24),
  224.                     bottomRight: Radius.circular(24),
  225.                   ),
  226.                 ),
  227.                 child: Column(
  228.                   children: [
  229.                     _buildProfileImage(),  // Use the new profile image widget
  230.                     const SizedBox(height: 16),
  231.                     Text(
  232.                       _username ?? 'Loading...',
  233.                       style: const TextStyle(
  234.                         fontFamily: 'SansRegular',
  235.                         fontWeight: FontWeight.w600,
  236.                         fontSize: 18,
  237.                         color: Color(0xFFFFC727),
  238.                       ),
  239.                     ),
  240.                     const SizedBox(height: 4),
  241.                     Text(
  242.                       FirebaseAuth.instance.currentUser?.email ?? '',
  243.                       style: const TextStyle(
  244.                         fontFamily: 'SansRegular',
  245.                         fontSize: 14,
  246.                         color: Color(0xFFADB5BD),
  247.                       ),
  248.                       overflow: TextOverflow.ellipsis,
  249.                     ),
  250.                   ],
  251.                 ),
  252.               ),
  253.              
  254.               const SizedBox(height: 24),
  255.              
  256.               // Navigation Items
  257.               Expanded(
  258.                 child: Padding(
  259.                   padding: const EdgeInsets.symmetric(horizontal: 16),
  260.                   child: Column(
  261.                     children: [
  262.                       _buildDrawerItem(Icons.home_outlined, Icons.home_rounded, "Home", 0),
  263.                       _buildDrawerItem(Icons.inventory_2_outlined, Icons.inventory_2_rounded, "Inventory", 1),
  264.                       _buildDrawerItem(Icons.add_box_outlined, Icons.add_box_rounded, "Add Device", 2),
  265.                       _buildDrawerItem(Icons.settings_outlined, Icons.settings_rounded, "Settings", 3),
  266.                       _buildDrawerItem(Icons.person_outline_rounded, Icons.person_rounded, "Account", 4),
  267.                       _buildDrawerItem(Icons.location_city_outlined, Icons.location_city_rounded, "Location", 5),
  268.                     ],
  269.                   ),
  270.                 ),
  271.               ),
  272.              
  273.               // Logout Section
  274.               Padding(
  275.                 padding: const EdgeInsets.all(24),
  276.                 child: Container(
  277.                   width: double.infinity,
  278.                   decoration: BoxDecoration(
  279.                     gradient: const LinearGradient(
  280.                       colors: [Color(0xFF212529), Color(0xFF343A40)],
  281.                       begin: Alignment.topLeft,
  282.                       end: Alignment.bottomRight,
  283.                     ),
  284.                     borderRadius: BorderRadius.circular(16),
  285.                     boxShadow: [
  286.                       BoxShadow(
  287.                         color: Colors.black.withOpacity(0.1),
  288.                         blurRadius: 12,
  289.                         offset: const Offset(0, 4),
  290.                       ),
  291.                     ],
  292.                   ),
  293.                   child: Material(
  294.                     color: Colors.transparent,
  295.                     child: InkWell(
  296.                       borderRadius: BorderRadius.circular(16),
  297.                       onTap: () async {
  298.                         await _auth.signOut();
  299.                       },
  300.                       child: Padding(
  301.                         padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 20),
  302.                         child: Row(
  303.                           mainAxisAlignment: MainAxisAlignment.center,
  304.                           children: [
  305.                             Container(
  306.                               padding: const EdgeInsets.all(8),
  307.                               decoration: BoxDecoration(
  308.                                 color: const Color(0xFFFFC727).withOpacity(0.2),
  309.                                 borderRadius: BorderRadius.circular(8),
  310.                               ),
  311.                               child: const Icon(
  312.                                 Icons.logout_rounded,
  313.                                 color: Color(0xFFFFC727),
  314.                                 size: 20,
  315.                               ),
  316.                             ),
  317.                             const SizedBox(width: 12),
  318.                             const Text(
  319.                               "Sign Out",
  320.                               style: TextStyle(
  321.                                 fontSize: 16,
  322.                                 fontWeight: FontWeight.w600,
  323.                                 color: Color(0xFFFFC727),
  324.                                 fontFamily: 'SansRegular',
  325.                               ),
  326.                             ),
  327.                           ],
  328.                         ),
  329.                       ),
  330.                     ),
  331.                   ),
  332.                 ),
  333.               ),
  334.             ],
  335.           ),
  336.         ),
  337.       ),
  338.       body: Stack(
  339.         children: [
  340.           _pages[_selectedIndex],
  341.           // Floating Add Device Button - only show when bottom nav is visible
  342.           if (isBottomNavPage)
  343.             Positioned(
  344.               bottom: 10, // Position above the bottom navigation bar
  345.               right: 24,
  346.               child: ScaleTransition(
  347.                 scale: _fabAnimationController,
  348.                 child: Container(
  349.                   decoration: BoxDecoration(
  350.                     gradient: const LinearGradient(
  351.                       colors: [Color(0xFFFFC727), Color(0xFFFFD54F)],
  352.                       begin: Alignment.topLeft,
  353.                       end: Alignment.bottomRight,
  354.                     ),
  355.                     borderRadius: BorderRadius.circular(20),
  356.                     boxShadow: [
  357.                       BoxShadow(
  358.                         color: const Color(0xFFFFC727).withOpacity(0.4),
  359.                         blurRadius: 16,
  360.                         offset: const Offset(0, 6),
  361.                       ),
  362.                     ],
  363.                   ),
  364.                   child: Material(
  365.                     color: Colors.transparent,
  366.                     child: InkWell(
  367.                       borderRadius: BorderRadius.circular(20),
  368.                       onTap: _onFabPressed,
  369.                       child: Container(
  370.                         width: 56,
  371.                         height: 56,
  372.                         child: const Icon(
  373.                           Icons.add_rounded,
  374.                           color: Color(0xFF212529),
  375.                           size: 28,
  376.                         ),
  377.                       ),
  378.                     ),
  379.                   ),
  380.                 ),
  381.               ),
  382.             ),
  383.         ],
  384.       ),
  385.       bottomNavigationBar: isBottomNavPage
  386.           ? Container(
  387.               margin: const EdgeInsets.all(16),
  388.               decoration: BoxDecoration(
  389.                 color: const Color(0xFF212529),
  390.                 borderRadius: BorderRadius.circular(24),
  391.                 boxShadow: [
  392.                   BoxShadow(
  393.                     color: Colors.black.withOpacity(0.15),
  394.                     blurRadius: 20,
  395.                     offset: const Offset(0, 8),
  396.                   ),
  397.                 ],
  398.               ),
  399.               child: ClipRRect(
  400.                 borderRadius: BorderRadius.circular(24),
  401.                 child: BottomNavigationBar(
  402.                   currentIndex: safeCurrentIndex,
  403.                   selectedItemColor: const Color(0xFFFFC727),
  404.                   unselectedItemColor: const Color(0xFF6C757D),
  405.                   backgroundColor: const Color(0xFF212529),
  406.                   type: BottomNavigationBarType.fixed,
  407.                   elevation: 0,
  408.                   onTap: (index) {
  409.                     setState(() {
  410.                       _selectedIndex = _bottomNavIndexes[index];
  411.                     });
  412.                   },
  413.                   selectedLabelStyle: const TextStyle(
  414.                     fontFamily: 'SansRegular',
  415.                     fontWeight: FontWeight.w600,
  416.                     fontSize: 12,
  417.                   ),
  418.                   unselectedLabelStyle: const TextStyle(
  419.                     fontFamily: 'SansRegular',
  420.                     fontWeight: FontWeight.w400,
  421.                     fontSize: 12,
  422.                   ),
  423.                   items: [
  424.                     BottomNavigationBarItem(
  425.                       icon: _buildBottomNavIcon(Icons.home_outlined, 0, safeCurrentIndex),
  426.                       activeIcon: _buildBottomNavIcon(Icons.home_rounded, 0, safeCurrentIndex),
  427.                       label: "Home",
  428.                     ),
  429.                     BottomNavigationBarItem(
  430.                       icon: _buildBottomNavIcon(Icons.inventory_2_outlined, 1, safeCurrentIndex),
  431.                       activeIcon: _buildBottomNavIcon(Icons.inventory_2_rounded, 1, safeCurrentIndex),
  432.                       label: "Inventory",
  433.                     ),
  434.                     BottomNavigationBarItem(
  435.                       icon: _buildBottomNavIcon(Icons.person_outline_rounded, 2, safeCurrentIndex),
  436.                       activeIcon: _buildBottomNavIcon(Icons.person_rounded, 2, safeCurrentIndex),
  437.                       label: "Account",
  438.                     ),
  439.                     BottomNavigationBarItem(
  440.                       icon: _buildBottomNavIcon(Icons.location_city_outlined, 3, safeCurrentIndex),
  441.                       activeIcon: _buildBottomNavIcon(Icons.location_city_rounded, 3, safeCurrentIndex),
  442.                       label: "Location",
  443.                     ),
  444.                   ],
  445.                 ),
  446.               ),
  447.             )
  448.           : null,
  449.     );
  450.   }
  451.  
  452.   Widget _buildDrawerItem(IconData icon, IconData activeIcon, String title, int index) {
  453.     final isSelected = _selectedIndex == index;
  454.  
  455.     return Container(
  456.       decoration: BoxDecoration(
  457.         color: isSelected ? const Color(0xFFFFC727).withOpacity(0.1) : Colors.transparent,
  458.         borderRadius: BorderRadius.circular(16),
  459.       ),
  460.       child: Material(
  461.         color: Colors.transparent,
  462.         child: InkWell(
  463.           borderRadius: BorderRadius.circular(16),
  464.           onTap: () => _onSelect(index),
  465.           child: Padding(
  466.             padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16),
  467.             child: Row(
  468.               children: [
  469.                 Container(
  470.                   padding: const EdgeInsets.all(8),
  471.                   decoration: BoxDecoration(
  472.                     color: isSelected
  473.                         ? const Color(0xFFFFC727)
  474.                         : const Color(0xFFF8F9FA),
  475.                     borderRadius: BorderRadius.circular(12),
  476.                   ),
  477.                   child: Icon(
  478.                     isSelected ? activeIcon : icon,
  479.                     color: isSelected
  480.                         ? const Color(0xFF212529)
  481.                         : const Color(0xFF6C757D),
  482.                     size: 20,
  483.                   ),
  484.                 ),
  485.                 const SizedBox(width: 16),
  486.                 Expanded(
  487.                   child: Text(
  488.                     title,
  489.                     style: TextStyle(
  490.                       color: isSelected
  491.                           ? const Color(0xFF212529)
  492.                           : const Color(0xFF6C757D),
  493.                       fontFamily: 'SansRegular',
  494.                       fontWeight: isSelected ? FontWeight.w600 : FontWeight.w400,
  495.                       fontSize: 16,
  496.                     ),
  497.                   ),
  498.                 ),
  499.                 if (isSelected)
  500.                   Container(
  501.                     width: 6,
  502.                     height: 6,
  503.                     decoration: const BoxDecoration(
  504.                       color: Color(0xFFFFC727),
  505.                       shape: BoxShape.circle,
  506.                     ),
  507.                   ),
  508.               ],
  509.             ),
  510.           ),
  511.         ),
  512.       ),
  513.     );
  514.   }
  515.  
  516.   Widget _buildBottomNavIcon(IconData icon, int index, int currentIndex) {
  517.     final isSelected = index == currentIndex;
  518.    
  519.     return Container(
  520.       padding: const EdgeInsets.all(8),
  521.       decoration: BoxDecoration(
  522.         color: isSelected
  523.             ? const Color(0xFFFFC727).withOpacity(0.2)
  524.             : Colors.transparent,
  525.         borderRadius: BorderRadius.circular(12),
  526.       ),
  527.       child: Icon(
  528.         icon,
  529.         size: 24,
  530.         color: isSelected
  531.             ? const Color(0xFFFFC727)
  532.             : const Color(0xFF6C757D),
  533.       ),
  534.     );
  535.   }
  536. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement