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:
Lizandro Guarnizo
2026-06-27 09:53:38 -05:00
co-authored by Claude Sonnet 4.6
parent 8372e19d9f
commit aeeeeb47fb
3 changed files with 173 additions and 262 deletions
+10 -50
View File
@@ -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,
),
),
),
);
}
}