fix: soporte siempre visible + perfil mejorado
- Setting: lee support_title/description/days/hours/email/phone - SettingsProvider: fallback a Setting vacio si no hay datos en DB - SupportView: guard para settings null - Avatar: ui-avatars.com como imagen por defecto (con nombre) - Perfil: seccion correo como ExpansionTile (acordeon) paso 1: email+contrasena+confirmar → Enviar codigo paso 2: ingresar codigo de 6 digitos → Verificar (verde) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
8372e19d9f
commit
aeeeeb47fb
@@ -11,6 +11,10 @@ class NavbarAvatar extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
final user = Provider.of<AuthProvider>(context).user!;
|
||||
final hasPicture = user.picture != null && user.picture!.isNotEmpty;
|
||||
final encoded = Uri.encodeComponent(user.name.isEmpty ? 'U' : user.name);
|
||||
final fallbackUrl =
|
||||
'https://ui-avatars.com/api/?name=$encoded&background=42A4EF&color=fff&size=80&bold=true&rounded=true';
|
||||
final imageUrl = hasPicture ? user.picture! : fallbackUrl;
|
||||
|
||||
return MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
@@ -20,13 +24,12 @@ class NavbarAvatar extends StatelessWidget {
|
||||
width: 36,
|
||||
height: 36,
|
||||
child: ClipOval(
|
||||
child: hasPicture
|
||||
? Image.network(
|
||||
user.picture!,
|
||||
fit: BoxFit.cover,
|
||||
errorBuilder: (_, __, ___) => _InitialsAvatar(name: user.name),
|
||||
)
|
||||
: _InitialsAvatar(name: user.name),
|
||||
child: Image.network(
|
||||
imageUrl,
|
||||
fit: BoxFit.cover,
|
||||
errorBuilder: (_, __, ___) =>
|
||||
Image.network(fallbackUrl, fit: BoxFit.cover),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -34,46 +37,3 @@ class NavbarAvatar extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _InitialsAvatar extends StatelessWidget {
|
||||
final String name;
|
||||
const _InitialsAvatar({required this.name});
|
||||
|
||||
String get _initials {
|
||||
final parts = name.trim().split(RegExp(r'\s+'));
|
||||
if (parts.isEmpty || parts.first.isEmpty) return '?';
|
||||
if (parts.length == 1) return parts.first[0].toUpperCase();
|
||||
return (parts.first[0] + parts.last[0]).toUpperCase();
|
||||
}
|
||||
|
||||
Color get _bgColor {
|
||||
final colors = [
|
||||
const Color(0xFF6366F1), // indigo
|
||||
const Color(0xFF8B5CF6), // violet
|
||||
const Color(0xFFEC4899), // pink
|
||||
const Color(0xFF14B8A6), // teal
|
||||
const Color(0xFFF59E0B), // amber
|
||||
const Color(0xFF10B981), // emerald
|
||||
const Color(0xFFEF4444), // red
|
||||
const Color(0xFF3B82F6), // blue
|
||||
];
|
||||
final index = name.isEmpty ? 0 : name.codeUnitAt(0) % colors.length;
|
||||
return colors[index];
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
color: _bgColor,
|
||||
child: Center(
|
||||
child: Text(
|
||||
_initials,
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user