import 'package:flutter/material.dart'; import 'package:p_tits_pas/services/api/api_config.dart'; import 'package:p_tits_pas/widgets/common/auth_network_image.dart'; class AdminUserCard extends StatefulWidget { final String title; final List subtitleLines; final String? avatarUrl; final IconData fallbackIcon; final List actions; final Color? borderColor; final Color? backgroundColor; final Color? titleColor; final Color? infoColor; const AdminUserCard({ super.key, required this.title, required this.subtitleLines, this.avatarUrl, this.fallbackIcon = Icons.person, this.actions = const [], this.borderColor, this.backgroundColor, this.titleColor, this.infoColor, }); @override State createState() => _AdminUserCardState(); } class _AdminUserCardState extends State { bool _isHovered = false; @override Widget build(BuildContext context) { final infoLine = widget.subtitleLines.where((e) => e.trim().isNotEmpty).join(' '); final actionsWidth = widget.actions.isNotEmpty ? widget.actions.length * 30.0 : 0.0; final avatarUrl = ApiConfig.absoluteMediaUrl(widget.avatarUrl); return MouseRegion( onEnter: (_) => setState(() => _isHovered = true), onExit: (_) => setState(() => _isHovered = false), child: Material( color: Colors.transparent, borderRadius: BorderRadius.circular(10), child: InkWell( onTap: () {}, borderRadius: BorderRadius.circular(10), hoverColor: const Color(0x149CC5C0), child: Card( margin: const EdgeInsets.only(bottom: 12), elevation: 0, color: widget.backgroundColor, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), side: BorderSide(color: widget.borderColor ?? Colors.grey.shade300), ), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 9), child: Row( children: [ _buildAvatar(avatarUrl), const SizedBox(width: 10), Expanded( child: Row( children: [ Flexible( fit: FlexFit.loose, child: Text( widget.title.isNotEmpty ? widget.title : 'Sans nom', style: const TextStyle( fontWeight: FontWeight.w600, fontSize: 14, ).copyWith(color: widget.titleColor), maxLines: 1, overflow: TextOverflow.ellipsis, ), ), const SizedBox(width: 10), Expanded( child: Text( infoLine, style: const TextStyle( color: Colors.black54, fontSize: 12, ).copyWith(color: widget.infoColor), maxLines: 1, overflow: TextOverflow.ellipsis, ), ), ], ), ), if (widget.actions.isNotEmpty) SizedBox( width: actionsWidth, child: AnimatedOpacity( duration: const Duration(milliseconds: 120), opacity: _isHovered ? 1 : 0, child: IgnorePointer( ignoring: !_isHovered, child: IconTheme( data: const IconThemeData(size: 17), child: IconButtonTheme( data: IconButtonThemeData( style: IconButton.styleFrom( visualDensity: VisualDensity.compact, padding: const EdgeInsets.all(4), minimumSize: const Size(28, 28), ), ), child: Row( mainAxisSize: MainAxisSize.min, children: widget.actions, ), ), ), ), ), ), ], ), ), ), ), ), ); } Widget _buildAvatar(String url) { const size = 28.0; const bg = Color(0xFFEDE5FA); const iconColor = Color(0xFF6B3FA0); if (url.isEmpty) { return CircleAvatar( radius: 14, backgroundColor: bg, child: Icon(widget.fallbackIcon, size: 16, color: iconColor), ); } return ClipOval( child: SizedBox( width: size, height: size, child: AuthNetworkImage( url: url, width: size, height: size, fit: BoxFit.cover, errorBuilder: (_, __, ___) => ColoredBox( color: bg, child: Icon(widget.fallbackIcon, size: 16, color: iconColor), ), ), ), ); } }