import 'package:flutter/material.dart'; class DesktopTopBar extends StatelessWidget { final String username; final String? profileImage; final VoidCallback? onSearchTap; final VoidCallback? onNotificationTap; final VoidCallback? onAvatarTap; const DesktopTopBar({ Key? key, required this.username, this.profileImage, this.onSearchTap, this.onNotificationTap, this.onAvatarTap, }) : super(key: key); @override Widget build(BuildContext context) { final theme = Theme.of(context); return Container( height: 64, padding: const EdgeInsets.symmetric(horizontal: 24), decoration: BoxDecoration( color: theme.scaffoldBackgroundColor, border: Border( bottom: BorderSide( color: theme.dividerColor.withValues(alpha: 0.3), ), ), ), child: Row( children: [ // Left: search bar Expanded( child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 400), child: SizedBox( height: 44, child: TextField( onTap: onSearchTap, readOnly: onSearchTap != null, decoration: InputDecoration( filled: true, fillColor: theme.colorScheme.surfaceContainerHighest .withValues(alpha: 0.4), prefixIcon: Icon(Icons.search, color: theme.hintColor), hintText: 'Search', hintStyle: theme.textTheme.bodyMedium ?.copyWith(color: theme.hintColor), border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide.none, ), contentPadding: const EdgeInsets.symmetric(vertical: 0), ), style: theme.textTheme.bodyLarge, ), ), ), ), const SizedBox(width: 16), // Right: notification bell + avatar Stack( children: [ IconButton( onPressed: onNotificationTap, icon: Icon( Icons.notifications_none, color: theme.iconTheme.color, ), ), Positioned( right: 6, top: 6, child: CircleAvatar( radius: 8, backgroundColor: Colors.red, child: Text( '2', style: theme.textTheme.bodySmall?.copyWith( color: Colors.white, fontSize: 10, ), ), ), ), ], ), const SizedBox(width: 8), GestureDetector( onTap: onAvatarTap, child: _buildAvatar(), ), ], ), ); } Widget _buildAvatar() { if (profileImage != null && profileImage!.trim().isNotEmpty) { final url = profileImage!.trim(); if (url.startsWith('http')) { return CircleAvatar( radius: 20, backgroundColor: Colors.grey.shade200, backgroundImage: NetworkImage(url), onBackgroundImageError: (_, __) {}, ); } } final name = username.trim(); String initials = 'U'; if (name.isNotEmpty) { if (name.contains('@')) { initials = name[0].toUpperCase(); } else { final parts = name.split(' ').where((p) => p.isNotEmpty).toList(); initials = parts.isEmpty ? 'U' : parts.take(2).map((p) => p[0].toUpperCase()).join(); } } return CircleAvatar( radius: 20, backgroundColor: Colors.blue.shade600, child: Text( initials, style: const TextStyle( color: Colors.white, fontWeight: FontWeight.bold, ), ), ); } }