import 'package:marco/helpers/theme/app_theme.dart'; import 'package:marco/helpers/theme/theme_customizer.dart'; import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; import 'package:marco/helpers/utils/my_shadow.dart'; import 'package:marco/helpers/widgets/my_button.dart'; import 'package:marco/helpers/widgets/my_card.dart'; import 'package:marco/helpers/widgets/my_container.dart'; import 'package:marco/helpers/widgets/my_dashed_divider.dart'; import 'package:marco/helpers/widgets/my_spacing.dart'; import 'package:marco/helpers/widgets/my_text.dart'; import 'package:marco/helpers/widgets/my_text_style.dart'; import 'package:marco/widgets/custom_pop_menu.dart'; import 'package:flutter/material.dart'; import 'package:flutter_lucide/flutter_lucide.dart'; import 'package:marco/helpers/services/storage/local_storage.dart'; import 'package:marco/model/employees/employee_info.dart'; import 'package:marco/helpers/widgets/avatar.dart'; class TopBar extends StatefulWidget { const TopBar({super.key}); @override _TopBarState createState() => _TopBarState(); } class _TopBarState extends State with SingleTickerProviderStateMixin, UIMixin { Function? languageHideFn; EmployeeInfo? employeeInfo; @override void initState() { super.initState(); _loadEmployeeInfo(); } void _loadEmployeeInfo() { setState(() { employeeInfo = LocalStorage.getEmployeeInfo(); }); } @override Widget build(BuildContext context) { return MyCard( shadow: MyShadow(position: MyShadowPosition.bottomRight, elevation: 0.5), height: 60, borderRadiusAll: 0, padding: MySpacing.x(24), color: topBarTheme.background.withAlpha(246), child: Row( children: [ Row( children: [ InkWell( splashColor: colorScheme.onSurface, highlightColor: colorScheme.onSurface, onTap: () { ThemeCustomizer.toggleLeftBarCondensed(); }, child: Icon( Icons.menu, color: topBarTheme.onBackground, )), MySpacing.width(24), SizedBox( width: 200, child: TextFormField( maxLines: 1, style: MyTextStyle.bodyMedium(), decoration: InputDecoration( hintText: "Search", hintStyle: MyTextStyle.bodySmall(xMuted: true), border: outlineInputBorder, enabledBorder: outlineInputBorder, focusedBorder: focusedInputBorder, prefixIcon: Align( alignment: Alignment.center, child: Icon( LucideIcons.search, size: 14, )), prefixIconConstraints: BoxConstraints( minWidth: 36, maxWidth: 36, minHeight: 32, maxHeight: 32), contentPadding: MySpacing.xy(16, 12), isCollapsed: true, floatingLabelBehavior: FloatingLabelBehavior.never), ), ), ], ), Expanded( child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ MySpacing.width(6), CustomPopupMenu( backdrop: true, onChange: (_) {}, offsetX: -120, menu: Padding( padding: MySpacing.xy(8, 8), child: Center( child: Icon( LucideIcons.bell, size: 18, ), ), ), menuBuilder: (_) => buildNotifications(), ), MySpacing.width(4), CustomPopupMenu( backdrop: true, onChange: (_) {}, offsetX: -60, offsetY: 8, menu: Padding( padding: MySpacing.xy(8, 8), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Avatar( firstName: employeeInfo?.firstName ?? 'First', lastName: employeeInfo?.lastName ?? 'Name', size: 31, ), MySpacing.width(8), MyText.labelSmall( "${employeeInfo?.firstName ?? 'First Name'} ${employeeInfo?.lastName ?? 'Last Name'}", fontWeight: 600, muted: true, ), ], ), ), menuBuilder: (_) => buildAccountMenu(), hideFn: (hide) => languageHideFn = hide, ), ], ), ) ], ), ); } Widget buildNotifications() { Widget buildNotification(String title, String description) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ MyText.labelLarge(title), MySpacing.height(4), MyText.bodySmall(description) ], ); } return MyContainer.bordered( paddingAll: 0, width: 250, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: MySpacing.xy(16, 12), child: MyText.titleMedium("Notification", fontWeight: 600), ), MyDashedDivider( height: 1, color: theme.dividerColor, dashSpace: 4, dashWidth: 6), Padding( padding: MySpacing.xy(16, 12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ buildNotification("Missed Check-in", "You missed check-in for Project Alpha on 21 May 2025."), MySpacing.height(12), buildNotification("Approval Required", "Regularization request pending approval for 20 May 2025."), MySpacing.height(12), buildNotification("Attendance Reminder", "Please check out before 6:00 PM today."), MySpacing.height(12), buildNotification("Late Check-out", "Your last check-out on 19 May 2025 was late by 15 minutes."), ], ), ), MyDashedDivider( height: 1, color: theme.dividerColor, dashSpace: 4, dashWidth: 6), Padding( padding: MySpacing.xy(16, 0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ MyButton.text( onPressed: () {}, splashColor: contentTheme.primary.withAlpha(28), child: MyText.labelSmall( "View All", color: contentTheme.primary, ), ), MyButton.text( onPressed: () {}, splashColor: contentTheme.danger.withAlpha(28), child: MyText.labelSmall( "Clear", color: contentTheme.danger, ), ), ], ), ) ], ), ); } Widget buildAccountMenu() { return MyContainer.bordered( paddingAll: 0, width: 150, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: MySpacing.xy(8, 8), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ MyButton( onPressed: () => {}, tapTargetSize: MaterialTapTargetSize.shrinkWrap, borderRadiusAll: AppStyle.buttonRadius.medium, padding: MySpacing.xy(8, 4), splashColor: colorScheme.onSurface.withAlpha(20), backgroundColor: Colors.transparent, child: Row( children: [ Icon( LucideIcons.user, size: 14, color: contentTheme.onBackground, ), MySpacing.width(8), MyText.labelMedium( "My Account", fontWeight: 600, ), ], ), ), MySpacing.height(4), MyButton( tapTargetSize: MaterialTapTargetSize.shrinkWrap, onPressed: () => {}, borderRadiusAll: AppStyle.buttonRadius.medium, padding: MySpacing.xy(8, 4), splashColor: colorScheme.onSurface.withAlpha(20), backgroundColor: Colors.transparent, child: Row( children: [ Icon( LucideIcons.settings, size: 14, color: contentTheme.onBackground, ), MySpacing.width(8), MyText.labelMedium( "Settings", fontWeight: 600, ), ], ), ), ], ), ), ], ), ); } }