import 'package:flutter/material.dart'; import 'package:marco/helpers/theme/theme_customizer.dart'; import 'package:marco/helpers/services/storage/local_storage.dart'; import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; import 'package:marco/helpers/utils/my_shadow.dart'; import 'package:marco/helpers/widgets/my_card.dart'; import 'package:marco/helpers/widgets/my_spacing.dart'; import 'package:marco/helpers/widgets/my_text.dart'; import 'package:flutter_lucide/flutter_lucide.dart'; import 'package:marco/model/employee_info.dart'; import 'package:marco/helpers/widgets/avatar.dart'; class UserProfileBar extends StatefulWidget { final bool isCondensed; const UserProfileBar({super.key, this.isCondensed = false}); @override _UserProfileBarState createState() => _UserProfileBarState(); } class _UserProfileBarState extends State with SingleTickerProviderStateMixin, UIMixin { final ThemeCustomizer customizer = ThemeCustomizer.instance; bool isCondensed = false; EmployeeInfo? employeeInfo; @override void initState() { super.initState(); _loadEmployeeInfo(); } void _loadEmployeeInfo() { setState(() { employeeInfo = LocalStorage.getEmployeeInfo(); }); } @override Widget build(BuildContext context) { isCondensed = widget.isCondensed; return MyCard( borderRadiusAll: 16, paddingAll: 0, shadow: MyShadow(position: MyShadowPosition.centerRight, elevation: 4), child: AnimatedContainer( decoration: BoxDecoration( gradient: LinearGradient( colors: [ leftBarTheme.background.withOpacity(0.95), leftBarTheme.background.withOpacity(0.85), ], begin: Alignment.topCenter, end: Alignment.bottomCenter, ), ), width: isCondensed ? 90 : 250, duration: const Duration(milliseconds: 300), curve: Curves.easeInOut, child: SafeArea( bottom: true, top: false, left: false, right: false, child: Column( children: [ userProfileSection(), MySpacing.height(8), supportAndSettingsMenu(), const Spacer(), logoutButton(), ], ), ), ), ); } Widget userProfileSection() { if (employeeInfo == null) { return const Padding( padding: EdgeInsets.all(24.0), child: Center(child: CircularProgressIndicator()), ); } return Container( width: double.infinity, padding: MySpacing.xy(58, 68), decoration: BoxDecoration( color: leftBarTheme.activeItemBackground, borderRadius: const BorderRadius.only( topLeft: Radius.circular(16), topRight: Radius.circular(16), ), ), child: Column( children: [ Avatar( firstName: employeeInfo?.firstName ?? 'First', lastName: employeeInfo?.lastName ?? 'Name', size: 60, ), MySpacing.height(12), MyText.labelLarge( "${employeeInfo?.firstName ?? 'First'} ${employeeInfo?.lastName ?? 'Last'}", fontWeight: 700, color: leftBarTheme.activeItemColor, textAlign: TextAlign.center, ), ], ), ); } Widget supportAndSettingsMenu() { return Padding( padding: MySpacing.xy(16, 16), child: Column( children: [ menuItem(icon: LucideIcons.settings, label: "Settings"), MySpacing.height(12), menuItem(icon: LucideIcons.badge_help, label: "Support"), ], ), ); } Widget menuItem({required IconData icon, required String label}) { return InkWell( onTap: () {}, borderRadius: BorderRadius.circular(10), hoverColor: leftBarTheme.activeItemBackground.withOpacity(0.2), splashColor: leftBarTheme.activeItemBackground.withOpacity(0.3), child: Padding( padding: MySpacing.xy(12, 10), child: Row( children: [ Icon(icon, size: 20, color: leftBarTheme.onBackground), MySpacing.width(12), Expanded( child: MyText.bodyMedium( label, color: leftBarTheme.onBackground, fontWeight: 500, ), ), ], ), ), ); } Widget logoutButton() { return InkWell( onTap: () async { bool? confirm = await showDialog( context: context, builder: (context) { return Dialog( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20), ), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 28), child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon( LucideIcons.log_out, size: 48, color: Colors.redAccent, ), const SizedBox(height: 16), Text( "Logout Confirmation", style: TextStyle( fontSize: 20, fontWeight: FontWeight.w700, color: Theme.of(context).colorScheme.onBackground, ), ), const SizedBox(height: 12), Text( "Are you sure you want to logout?\nYou will need to login again to continue.", textAlign: TextAlign.center, style: TextStyle( fontSize: 14, color: Theme.of(context) .colorScheme .onSurface .withOpacity(0.7), ), ), const SizedBox(height: 24), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: TextButton( onPressed: () => Navigator.pop(context, false), style: TextButton.styleFrom( foregroundColor: Colors.grey.shade700, ), child: const Text("Cancel"), ), ), const SizedBox(width: 12), Expanded( child: ElevatedButton( onPressed: () async { await LocalStorage.logout(); }, style: ElevatedButton.styleFrom( backgroundColor: Colors.redAccent, foregroundColor: Colors.white, padding: const EdgeInsets.symmetric(vertical: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ), child: const Text("Logout"), ), ), ], ) ], ), ), ); }, ); if (confirm == true) { // Show animated loader dialog showDialog( context: context, barrierDismissible: false, builder: (context) => Dialog( backgroundColor: Colors.transparent, child: Column( mainAxisSize: MainAxisSize.min, children: const [ CircularProgressIndicator(), SizedBox(height: 12), Text( "Logging you out...", style: TextStyle(color: Colors.white), ) ], ), ), ); await LocalStorage.logout(); if (mounted) { Navigator.pop(context); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Row( children: [ const Icon(LucideIcons.check, color: Colors.green), const SizedBox(width: 12), const Text("You’ve been logged out successfully."), ], ), backgroundColor: Colors.grey.shade900, behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), duration: const Duration(seconds: 3), ), ); } } }, borderRadius: const BorderRadius.only( bottomLeft: Radius.circular(16), bottomRight: Radius.circular(16), ), hoverColor: leftBarTheme.activeItemBackground.withOpacity(0.2), splashColor: leftBarTheme.activeItemBackground.withOpacity(0.3), child: AnimatedContainer( duration: const Duration(milliseconds: 150), curve: Curves.easeInOut, width: double.infinity, padding: MySpacing.all(16), decoration: BoxDecoration( color: leftBarTheme.activeItemBackground, borderRadius: const BorderRadius.only( bottomLeft: Radius.circular(16), bottomRight: Radius.circular(16), ), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ MyText.bodyMedium( "Logout", color: leftBarTheme.activeItemColor, fontWeight: 600, ), MySpacing.width(8), Icon( LucideIcons.log_out, size: 20, color: leftBarTheme.activeItemColor, ), ], ), ), ); } }