import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import '../../core/format.dart'; import '../../core/models.dart'; import '../../core/theme.dart'; class UserAvatar extends StatelessWidget { const UserAvatar({super.key, required this.user, this.size = 42}); final AppUser user; final double size; @override Widget build(BuildContext context) { final admin = user.isAdmin; final dot = (size * 0.3).clamp(10.0, 18.0); return SizedBox( width: size + 2, height: size + 2, child: Stack( children: [ Opacity( opacity: user.active ? 1 : 0.55, child: Container( width: size, height: size, alignment: Alignment.center, decoration: BoxDecoration( color: admin ? C.navy : C.chip, borderRadius: BorderRadius.circular(size * 0.3), ), child: Text( initials(user.username), style: ts(size * 0.36, w: w7, c: admin ? C.gold : C.navy), ), ), ), Positioned( right: 0, bottom: 0, child: Container( width: dot, height: dot, decoration: BoxDecoration( color: user.active ? C.green : C.placeholder, shape: BoxShape.circle, border: Border.all(color: Colors.white, width: 2), ), ), ), ], ), ); } } class StatusLabel extends StatelessWidget { const StatusLabel({super.key, required this.active}); final bool active; @override Widget build(BuildContext context) => Row( mainAxisSize: MainAxisSize.min, children: [ Container( width: 8, height: 8, decoration: BoxDecoration( color: active ? C.green : C.placeholder, shape: BoxShape.circle, ), ), const SizedBox(width: S.s8), Text( active ? 'Active' : 'Inactive', style: ts(13, w: w5, c: active ? C.ink : C.muted), ), ], ); } class ShopCodes extends StatelessWidget { const ShopCodes({super.key, required this.shops}); final List shops; @override Widget build(BuildContext context) { if (shops.isEmpty) { return Text('No shops', style: ts(13, c: C.placeholder)); } const tile = 40.0, gap = S.s6, more = 36.0; return LayoutBuilder( builder: (context, c) { var fit = ((c.maxWidth + gap) / (tile + gap)).floor(); if (fit < shops.length) { fit = ((c.maxWidth - more) / (tile + gap)).floor().clamp( 0, shops.length, ); } final shown = shops.take(fit).toList(); final rest = shops.length - shown.length; return Row( mainAxisSize: MainAxisSize.min, children: [ for (final s in shown) Padding( padding: const EdgeInsets.only(right: gap), child: Tooltip( message: s.name, child: Container( width: tile, height: 26, alignment: Alignment.center, decoration: BoxDecoration( color: C.chip, borderRadius: BorderRadius.circular(R.sm), ), child: Text( s.code.length > 4 ? s.code.substring(0, 4) : s.code, style: ts(11, w: w7, c: C.navy, ls: 0.3), ), ), ), ), if (rest > 0) Tooltip( message: shops.skip(shown.length).map((s) => s.name).join(', '), child: Container( height: 26, constraints: const BoxConstraints(minWidth: 32), padding: const EdgeInsets.symmetric(horizontal: S.s6), alignment: Alignment.center, decoration: BoxDecoration( border: Border.all(color: C.border2), borderRadius: BorderRadius.circular(R.sm), ), child: Text( '+$rest', style: ts(12, w: w7, c: C.navy), ), ), ), ], ); }, ); } } class WhatsAppLogo extends StatelessWidget { const WhatsAppLogo({super.key, this.size = 20, this.color}); final double size; final Color? color; static const brand = Color(0xFF25D366); @override Widget build(BuildContext context) => ExcludeSemantics( child: SvgPicture.asset( 'assets/icons/whatsapp.svg', width: size, height: size, colorFilter: ColorFilter.mode(color ?? brand, BlendMode.srcIn), ), ); }