Diseño mejorado

This commit is contained in:
Abraham
2026-01-12 23:27:56 -08:00
parent d1271a5578
commit 40a9be5936
7 changed files with 1849 additions and 546 deletions

View File

@@ -110,19 +110,33 @@ class _VideosLayoutState extends State<VideosLayout> {
Widget _buildSideMenu() {
return Container(
width: 280,
width: 300,
decoration: BoxDecoration(
color: AppTheme.of(context).secondaryBackground,
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
AppTheme.of(context).secondaryBackground,
AppTheme.of(context).primaryBackground,
],
),
border: Border(
right: BorderSide(
color: AppTheme.of(context).primaryColor.withOpacity(0.1),
color: AppTheme.of(context).primaryColor.withOpacity(0.15),
width: 1,
),
),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 30,
offset: const Offset(5, 0),
),
],
),
child: Column(
children: [
// Header con gradiente premium
// Header con gradiente premium y efecto glass
Container(
width: double.infinity,
padding: const EdgeInsets.all(32),
@@ -131,48 +145,87 @@ class _VideosLayoutState extends State<VideosLayout> {
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
const Color(0xFF4EC9F5),
const Color(0xFFFFB733),
Color(0xFF42BCEE),
Color(0xFF5865B5),
Color(0xFF653093),
],
stops: const [0.0, 0.5, 1.0],
),
boxShadow: [
BoxShadow(
color: AppTheme.of(context).primaryColor.withOpacity(0.3),
blurRadius: 20,
offset: const Offset(0, 5),
color: const Color(0xFF4EC9F5).withOpacity(0.4),
blurRadius: 30,
offset: const Offset(0, 8),
spreadRadius: 2,
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Logo de EnergyMedia
Image.asset(
'assets/images/logo_nh_b.png',
height: 50,
fit: BoxFit.contain,
),
const Gap(12),
Text(
'Content Manager',
style: AppTheme.of(context).bodyText2.override(
fontFamily: 'Poppins',
color: const Color(0xFF0B0B0D).withOpacity(0.8),
fontSize: 13,
// Logo con container elegante
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.2),
borderRadius: BorderRadius.circular(16),
border: Border.all(
color: Colors.white.withOpacity(0.3),
width: 2,
),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.2),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: Image.asset(
'assets/images/logo_nh_b.png',
height: 40,
fit: BoxFit.contain,
),
),
const Gap(16),
// Título con efecto
Container(
padding:
const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.25),
borderRadius: BorderRadius.circular(8),
),
child: Text(
'Content Manager',
style: AppTheme.of(context).bodyText1.override(
fontFamily: 'Poppins',
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 12,
letterSpacing: 1.2,
),
),
),
],
),
),
// Menu Items
const Gap(24),
// Sección de usuario (opcional)
if (currentUser != null) _buildUserSection(),
const Gap(8),
// Menu Items con mejor spacing
Expanded(
child: ListView(
padding: const EdgeInsets.symmetric(vertical: 24, horizontal: 16),
padding: const EdgeInsets.symmetric(horizontal: 16),
children: _menuItems.map((item) {
final isSelected = _selectedMenuIndex == item.index;
return Padding(
padding: const EdgeInsets.only(bottom: 8),
padding: const EdgeInsets.only(bottom: 12),
child: _buildPremiumMenuItem(
icon: item.icon,
title: item.title,
@@ -186,16 +239,24 @@ class _VideosLayoutState extends State<VideosLayout> {
),
),
// Theme Toggle en la parte inferior
// Theme Toggle mejorado
Container(
padding: const EdgeInsets.all(16),
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
padding: const EdgeInsets.all(6),
decoration: BoxDecoration(
border: Border(
top: BorderSide(
color: AppTheme.of(context).primaryColor.withOpacity(0.1),
width: 1,
),
color: AppTheme.of(context).tertiaryBackground,
borderRadius: BorderRadius.circular(16),
border: Border.all(
color: AppTheme.of(context).primaryColor.withOpacity(0.2),
width: 1,
),
boxShadow: [
BoxShadow(
color: AppTheme.of(context).primaryColor.withOpacity(0.1),
blurRadius: 10,
offset: const Offset(0, 2),
),
],
),
child: Consumer<VisualStateProvider>(
builder: (context, visualProvider, _) {
@@ -204,9 +265,9 @@ class _VideosLayoutState extends State<VideosLayout> {
),
),
// Botón de Logout
// Botón de Logout premium
Container(
padding: const EdgeInsets.fromLTRB(16, 8, 16, 16),
padding: const EdgeInsets.fromLTRB(16, 8, 16, 24),
child: _buildLogoutButton(),
),
],
@@ -214,6 +275,107 @@ class _VideosLayoutState extends State<VideosLayout> {
);
}
Widget _buildUserSection() {
return Container(
margin: const EdgeInsets.symmetric(horizontal: 16),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
AppTheme.of(context).primaryColor.withOpacity(0.1),
AppTheme.of(context).secondaryColor.withOpacity(0.1),
],
),
borderRadius: BorderRadius.circular(16),
border: Border.all(
color: AppTheme.of(context).primaryColor.withOpacity(0.2),
width: 1,
),
),
child: Row(
children: [
// Avatar con gradiente
Container(
width: 48,
height: 48,
decoration: BoxDecoration(
gradient: const LinearGradient(
colors: [
Color(0xFF4EC9F5),
Color(0xFFFFB733),
],
),
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
color: const Color(0xFF4EC9F5).withOpacity(0.4),
blurRadius: 12,
offset: const Offset(0, 4),
),
],
),
child: Center(
child: Text(
(currentUser?.fullName.substring(0, 1) ?? 'U').toUpperCase(),
style: const TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold,
fontFamily: 'Poppins',
),
),
),
),
const Gap(12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
currentUser?.fullName ?? 'Usuario',
style: AppTheme.of(context).bodyText1.override(
fontFamily: 'Poppins',
color: AppTheme.of(context).primaryText,
fontWeight: FontWeight.w600,
fontSize: 14,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
const Gap(2),
Container(
padding:
const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
decoration: BoxDecoration(
gradient: const LinearGradient(
colors: [
Color(0xFF4EC9F5),
Color(0xFFFFB733),
],
),
borderRadius: BorderRadius.circular(8),
),
child: Text(
'PREMIUM',
style: const TextStyle(
color: Colors.white,
fontSize: 9,
fontWeight: FontWeight.bold,
fontFamily: 'Poppins',
letterSpacing: 0.5,
),
),
),
],
),
),
],
),
);
}
Widget _buildPremiumMenuItem({
required IconData icon,
required String title,
@@ -223,25 +385,36 @@ class _VideosLayoutState extends State<VideosLayout> {
return MouseRegion(
cursor: SystemMouseCursors.click,
child: AnimatedContainer(
duration: const Duration(milliseconds: 200),
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
decoration: BoxDecoration(
gradient: isSelected
? LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
const Color(0xFF4EC9F5),
const Color(0xFFFFB733),
Color(0xFF42BCEE),
Color(0xFF5865B5),
Color(0xFF653093),
],
stops: const [0.0, 0.5, 1.0],
)
: null,
borderRadius: BorderRadius.circular(12),
color: isSelected ? null : Colors.transparent,
borderRadius: BorderRadius.circular(16),
boxShadow: isSelected
? [
BoxShadow(
color: AppTheme.of(context).primaryColor.withOpacity(0.3),
blurRadius: 12,
color: const Color(0xFF4EC9F5).withOpacity(0.5),
blurRadius: 20,
offset: const Offset(0, 8),
spreadRadius: 0,
),
BoxShadow(
color: const Color(0xFFFFB733).withOpacity(0.3),
blurRadius: 15,
offset: const Offset(0, 4),
spreadRadius: 0,
),
]
: null,
@@ -250,17 +423,47 @@ class _VideosLayoutState extends State<VideosLayout> {
color: Colors.transparent,
child: InkWell(
onTap: onTap,
borderRadius: BorderRadius.circular(12),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16),
borderRadius: BorderRadius.circular(16),
splashColor: AppTheme.of(context).primaryColor.withOpacity(0.2),
highlightColor: AppTheme.of(context).primaryColor.withOpacity(0.1),
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 18),
child: Row(
children: [
Icon(
icon,
color: isSelected
? const Color(0xFF0B0B0D)
: AppTheme.of(context).secondaryText,
size: 24,
// Icono con background circular
AnimatedContainer(
duration: const Duration(milliseconds: 300),
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: isSelected
? Colors.white.withOpacity(0.25)
: AppTheme.of(context).primaryColor.withOpacity(0.15),
shape: BoxShape.circle,
border: Border.all(
color: isSelected
? Colors.white.withOpacity(0.4)
: AppTheme.of(context)
.primaryColor
.withOpacity(0.3),
width: 2,
),
boxShadow: isSelected
? [
BoxShadow(
color: Colors.white.withOpacity(0.3),
blurRadius: 8,
offset: const Offset(0, 2),
),
]
: null,
),
child: Icon(
icon,
color: isSelected
? Colors.white
: AppTheme.of(context).primaryColor,
size: 22,
),
),
const Gap(16),
Expanded(
@@ -269,22 +472,34 @@ class _VideosLayoutState extends State<VideosLayout> {
style: AppTheme.of(context).bodyText1.override(
fontFamily: 'Poppins',
color: isSelected
? const Color(0xFF0B0B0D)
? Colors.white
: AppTheme.of(context).primaryText,
fontWeight:
isSelected ? FontWeight.bold : FontWeight.w500,
isSelected ? FontWeight.bold : FontWeight.w600,
fontSize: 15,
letterSpacing: isSelected ? 0.5 : 0,
),
),
),
if (isSelected)
Container(
width: 6,
height: 6,
decoration: BoxDecoration(
color: const Color(0xFF0B0B0D),
shape: BoxShape.circle,
),
// Indicador animado
AnimatedContainer(
duration: const Duration(milliseconds: 300),
width: isSelected ? 8 : 0,
height: isSelected ? 8 : 0,
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
boxShadow: isSelected
? [
BoxShadow(
color: Colors.white.withOpacity(0.6),
blurRadius: 8,
spreadRadius: 2,
),
]
: null,
),
),
],
),
),
@@ -340,24 +555,26 @@ class _VideosLayoutState extends State<VideosLayout> {
return GestureDetector(
onTap: onTap,
child: AnimatedContainer(
duration: const Duration(milliseconds: 200),
padding: const EdgeInsets.symmetric(vertical: 12),
duration: const Duration(milliseconds: 300),
padding: const EdgeInsets.symmetric(vertical: 14, horizontal: 4),
decoration: BoxDecoration(
gradient: isSelected
? LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
const Color(0xFF4EC9F5),
const Color(0xFFFFB733),
],
)
: null,
borderRadius: BorderRadius.circular(8),
borderRadius: BorderRadius.circular(12),
boxShadow: isSelected
? [
BoxShadow(
color: AppTheme.of(context).primaryColor.withOpacity(0.3),
blurRadius: 8,
offset: const Offset(0, 2),
color: const Color(0xFF4EC9F5).withOpacity(0.4),
blurRadius: 12,
offset: const Offset(0, 4),
),
]
: null,
@@ -365,23 +582,33 @@ class _VideosLayoutState extends State<VideosLayout> {
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
icon,
color: isSelected
? const Color(0xFF0B0B0D)
: AppTheme.of(context).secondaryText,
size: 20,
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: isSelected
? Colors.white.withOpacity(0.2)
: Colors.transparent,
shape: BoxShape.circle,
),
child: Icon(
icon,
color: isSelected
? Colors.white
: AppTheme.of(context).secondaryText,
size: 22,
),
),
const Gap(4),
const Gap(6),
Text(
label,
style: TextStyle(
color: isSelected
? const Color(0xFF0B0B0D)
? Colors.white
: AppTheme.of(context).secondaryText,
fontSize: 11,
fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
fontWeight: isSelected ? FontWeight.bold : FontWeight.w500,
fontFamily: 'Poppins',
letterSpacing: 0.5,
),
),
],
@@ -537,31 +764,66 @@ class _VideosLayoutState extends State<VideosLayout> {
builder: (context) => AlertDialog(
backgroundColor: AppTheme.of(context).secondaryBackground,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
borderRadius: BorderRadius.circular(24),
),
title: Text(
'¿Cerrar Sesión?',
style: AppTheme.of(context).title3.override(
fontFamily: 'Poppins',
color: AppTheme.of(context).primaryText,
fontWeight: FontWeight.bold,
title: Row(
children: [
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
gradient: const LinearGradient(
colors: [
Color(0xFFFF2D2D),
Color(0xFFFF7A3D),
],
),
borderRadius: BorderRadius.circular(12),
),
child: const Icon(
Icons.logout_rounded,
color: Colors.white,
size: 24,
),
),
const Gap(16),
Expanded(
child: Text(
'¿Cerrar Sesión?',
style: AppTheme.of(context).title3.override(
fontFamily: 'Poppins',
color: AppTheme.of(context).primaryText,
fontWeight: FontWeight.bold,
fontSize: 20,
),
),
),
],
),
content: Text(
'¿Estás seguro de que deseas cerrar sesión?',
style: AppTheme.of(context).bodyText1.override(
fontFamily: 'Poppins',
color: AppTheme.of(context).secondaryText,
),
content: Padding(
padding: const EdgeInsets.only(top: 8),
child: Text(
'¿Estás seguro de que deseas cerrar sesión?',
style: AppTheme.of(context).bodyText1.override(
fontFamily: 'Poppins',
color: AppTheme.of(context).secondaryText,
),
),
),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(false),
style: TextButton.styleFrom(
padding: const EdgeInsets.symmetric(
horizontal: 24,
vertical: 12,
),
),
child: Text(
'Cancelar',
style: TextStyle(
color: AppTheme.of(context).secondaryText,
fontFamily: 'Poppins',
fontWeight: FontWeight.w600,
),
),
),
@@ -573,18 +835,42 @@ class _VideosLayoutState extends State<VideosLayout> {
Color(0xFFFF7A3D),
],
),
borderRadius: BorderRadius.circular(8),
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: const Color(0xFFFF2D2D).withOpacity(0.4),
blurRadius: 12,
offset: const Offset(0, 4),
),
],
),
child: TextButton(
onPressed: () => Navigator.of(context).pop(true),
child: const Text(
'Cerrar Sesión',
style: TextStyle(
color: Colors.white,
fontFamily: 'Poppins',
fontWeight: FontWeight.bold,
style: TextButton.styleFrom(
padding: const EdgeInsets.symmetric(
horizontal: 24,
vertical: 12,
),
),
child: const Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
Icons.logout_rounded,
color: Colors.white,
size: 18,
),
Gap(8),
Text(
'Cerrar Sesión',
style: TextStyle(
color: Colors.white,
fontFamily: 'Poppins',
fontWeight: FontWeight.bold,
),
),
],
),
),
),
],
@@ -602,23 +888,48 @@ class _VideosLayoutState extends State<VideosLayout> {
}
}
},
borderRadius: BorderRadius.circular(12),
borderRadius: BorderRadius.circular(16),
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16),
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 18),
decoration: BoxDecoration(
color: AppTheme.of(context).error.withOpacity(0.1),
borderRadius: BorderRadius.circular(12),
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
AppTheme.of(context).error.withOpacity(0.15),
AppTheme.of(context).error.withOpacity(0.1),
],
),
borderRadius: BorderRadius.circular(16),
border: Border.all(
color: AppTheme.of(context).error.withOpacity(0.3),
width: 1,
width: 2,
),
boxShadow: [
BoxShadow(
color: AppTheme.of(context).error.withOpacity(0.2),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: Row(
children: [
Icon(
Icons.logout,
color: AppTheme.of(context).error,
size: 24,
Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: AppTheme.of(context).error.withOpacity(0.2),
shape: BoxShape.circle,
border: Border.all(
color: AppTheme.of(context).error.withOpacity(0.4),
width: 2,
),
),
child: Icon(
Icons.logout_rounded,
color: AppTheme.of(context).error,
size: 20,
),
),
const Gap(16),
Expanded(
@@ -627,10 +938,16 @@ class _VideosLayoutState extends State<VideosLayout> {
style: AppTheme.of(context).bodyText1.override(
fontFamily: 'Poppins',
color: AppTheme.of(context).error,
fontWeight: FontWeight.w500,
fontWeight: FontWeight.bold,
fontSize: 15,
),
),
),
Icon(
Icons.arrow_forward_ios_rounded,
color: AppTheme.of(context).error,
size: 16,
),
],
),
),