diff --git a/lib/ui/shared/sidebar.dart b/lib/ui/shared/sidebar.dart index bad6fe8..a4a9a88 100644 --- a/lib/ui/shared/sidebar.dart +++ b/lib/ui/shared/sidebar.dart @@ -9,8 +9,6 @@ import 'package:prosapp_web_app/services/notifications_service.dart'; import 'package:prosapp_web_app/ui/shared/widgets/menu_item.dart'; import 'package:prosapp_web_app/ui/shared/widgets/text_separator.dart'; import 'package:flutter/material.dart'; -import 'package:google_fonts/google_fonts.dart'; - import 'package:prosapp_web_app/ui/shared/widgets/logo.dart'; import 'package:provider/provider.dart'; @@ -29,169 +27,167 @@ class Sidebar extends StatelessWidget { final professionalProvider = Provider.of(context); return Container( - width: 200, + width: 220, height: double.infinity, decoration: buildBoxDecoration(), child: ListView( physics: const ClampingScrollPhysics(), children: [ const Logo(), - const SizedBox(height: 50), + const SizedBox(height: 8), + if (professionalProvider.isProModeActive) ...[ const TextSeparator(text: 'Profesional'), MenuItem( - isActive: - sideMenuProvider.currentPage == Flurorouter.profileRoute || - sideMenuProvider.currentPage == - Flurorouter.professionalProfileRoute, - text: 'Perfil', - icon: Icons.person_outlined, - onPressed: () { - if (professionalProvider.isProModeActive) { - navigateTo(Flurorouter.professionalProfileRoute); - } else { - navigateTo(Flurorouter.profileRoute); - } + isActive: sideMenuProvider.currentPage == Flurorouter.profileRoute || + sideMenuProvider.currentPage == Flurorouter.professionalProfileRoute, + text: 'Perfil', + icon: Icons.person_outlined, + onPressed: () { + if (professionalProvider.isProModeActive) { + navigateTo(Flurorouter.professionalProfileRoute); + } else { + navigateTo(Flurorouter.profileRoute); } - - // () => navigateTo(Flurorouter.profileRoute), - ), + }, + ), MenuItem( - isActive: sideMenuProvider.currentPage == - Flurorouter.professionalServicesRequestsRoute, + isActive: sideMenuProvider.currentPage == Flurorouter.professionalServicesRequestsRoute, text: 'Mis solicitudes', icon: Icons.room_service_outlined, - onPressed: () => { - Provider.of(context, listen: false) - .clearServices(), - navigateTo(Flurorouter.professionalServicesRequestsRoute) + onPressed: () { + Provider.of(context, listen: false).clearServices(); + navigateTo(Flurorouter.professionalServicesRequestsRoute); }, ), MenuItem( - isActive: sideMenuProvider.currentPage == - Flurorouter.professionalServicesRoute, + isActive: sideMenuProvider.currentPage == Flurorouter.professionalServicesRoute, text: 'Mis servicios', - icon: Icons.list, - onPressed: () => { - Provider.of(context, listen: false) - .clearServices(), - navigateTo(Flurorouter.professionalServicesRoute) + icon: Icons.list_alt_outlined, + onPressed: () { + Provider.of(context, listen: false).clearServices(); + navigateTo(Flurorouter.professionalServicesRoute); }, ), MenuItem( - isActive: sideMenuProvider.currentPage == - Flurorouter.professionalServicesHistoryRoute, + isActive: sideMenuProvider.currentPage == Flurorouter.professionalServicesHistoryRoute, text: 'Historial', icon: Icons.restore_outlined, - onPressed: () => { - Provider.of(context, listen: false) - .clearServices(), - navigateTo(Flurorouter.professionalServicesHistoryRoute) + onPressed: () { + Provider.of(context, listen: false).clearServices(); + navigateTo(Flurorouter.professionalServicesHistoryRoute); }, ), MenuItem( text: 'Calendario', icon: Icons.calendar_month_outlined, - onPressed: () => - navigateTo(Flurorouter.professionalCalendarRoute), + onPressed: () => navigateTo(Flurorouter.professionalCalendarRoute), ), ] else ...[ const TextSeparator(text: 'Usuario'), MenuItem( - isActive: - sideMenuProvider.currentPage == Flurorouter.profileRoute, + isActive: sideMenuProvider.currentPage == Flurorouter.profileRoute, text: 'Perfil', icon: Icons.person_outlined, onPressed: () => navigateTo(Flurorouter.profileRoute), ), MenuItem( - isActive: - sideMenuProvider.currentPage == Flurorouter.dashboardRoute, + isActive: sideMenuProvider.currentPage == Flurorouter.dashboardRoute, text: 'Solicitar', icon: Icons.room_service_outlined, onPressed: () => navigateTo(Flurorouter.dashboardRoute), ), MenuItem( - isActive: - sideMenuProvider.currentPage == Flurorouter.userServicesRoute, + isActive: sideMenuProvider.currentPage == Flurorouter.userServicesRoute, text: 'Mis servicios', - icon: Icons.list, - onPressed: () => { - Provider.of(context, listen: false) - .clearServices(), - navigateTo(Flurorouter.userServicesRoute) + icon: Icons.list_alt_outlined, + onPressed: () { + Provider.of(context, listen: false).clearServices(); + navigateTo(Flurorouter.userServicesRoute); }, ), MenuItem( - isActive: sideMenuProvider.currentPage == - Flurorouter.userServicesHistoryRoute, + isActive: sideMenuProvider.currentPage == Flurorouter.userServicesHistoryRoute, text: 'Historial', icon: Icons.restore_outlined, - onPressed: () => { - Provider.of(context, listen: false) - .clearServices(), - navigateTo(Flurorouter.userServicesHistoryRoute) + onPressed: () { + Provider.of(context, listen: false).clearServices(); + navigateTo(Flurorouter.userServicesHistoryRoute); }, ), MenuItem( - isActive: - sideMenuProvider.currentPage == Flurorouter.supportRoute, + isActive: sideMenuProvider.currentPage == Flurorouter.supportRoute, text: 'Soporte', icon: Icons.support_agent_outlined, onPressed: () => navigateTo(Flurorouter.supportRoute), ), ], - Material( - color: Colors.blueAccent, - child: InkWell( - onTap: () { - if (authProvider.user?.picture == '' || - authProvider.user?.city == '' || - authProvider.user?.name == null || - authProvider.user?.name == '' || - authProvider.user?.email == '') { - NotificationsService.showSnackBarError( - 'Primero completa tu perfil'); - navigateTo(Flurorouter.profileRoute); - return; - } - - if (authProvider.user?.proState == ProState.active) { - professionalProvider.toggleProMode(); - - if (professionalProvider.isProModeActive) { - navigateTo(Flurorouter.professionalServicesRequestsRoute); - } else { - navigateTo(Flurorouter.dashboardRoute); + const SizedBox(height: 16), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: MouseRegion( + cursor: SystemMouseCursors.click, + child: GestureDetector( + onTap: () { + if (authProvider.user?.name == null || + authProvider.user?.name == '') { + NotificationsService.showSnackBarError('Primero completa tu perfil'); + navigateTo(Flurorouter.profileRoute); + return; } - } else { - navigateTo(Flurorouter.requestProfessionalRoute); - } - }, - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 30, - vertical: 10, - ), - child: MouseRegion( - cursor: SystemMouseCursors.click, - child: Text( - 'Modo ${professionalProvider.isProModeActive ? 'Usuario' : 'Profesional'}', - style: GoogleFonts.roboto( - color: Colors.white.withOpacity(0.8)), + if (authProvider.user?.proState == ProState.active) { + professionalProvider.toggleProMode(); + if (professionalProvider.isProModeActive) { + navigateTo(Flurorouter.professionalServicesRequestsRoute); + } else { + navigateTo(Flurorouter.dashboardRoute); + } + } else { + navigateTo(Flurorouter.requestProfessionalRoute); + } + }, + child: Container( + padding: const EdgeInsets.symmetric(vertical: 11), + decoration: BoxDecoration( + gradient: const LinearGradient( + colors: [Color(0xFF42A4EF), Color(0xFF1565C0)], + ), + borderRadius: BorderRadius.circular(10), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + professionalProvider.isProModeActive + ? Icons.person_outlined + : Icons.work_outline, + color: Colors.white, + size: 16, + ), + const SizedBox(width: 8), + Text( + 'Modo ${professionalProvider.isProModeActive ? 'Usuario' : 'Profesional'}', + style: const TextStyle( + color: Colors.white, + fontSize: 13, + fontWeight: FontWeight.w600, + ), + ), + ], ), ), ), ), ), - const SizedBox(height: 50), - const TextSeparator(text: 'Salir'), + const SizedBox(height: 24), + const TextSeparator(text: 'Sesion'), MenuItem( - text: 'Cerrar sesión', + text: 'Cerrar sesion', icon: Icons.exit_to_app_outlined, onPressed: () => authProvider.logout(), ), + const SizedBox(height: 20), ], ), ); @@ -199,15 +195,18 @@ class Sidebar extends StatelessWidget { BoxDecoration buildBoxDecoration() => const BoxDecoration( gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, colors: [ - Color(0xff092044), - Color(0xff092042), + Color(0xFF0D1B3E), + Color(0xFF0A1628), ], ), boxShadow: [ BoxShadow( - color: Colors.black26, - blurRadius: 10, + color: Colors.black38, + blurRadius: 12, + offset: Offset(2, 0), ), ], ); diff --git a/lib/ui/shared/widgets/logo.dart b/lib/ui/shared/widgets/logo.dart index 9601d26..32352c5 100644 --- a/lib/ui/shared/widgets/logo.dart +++ b/lib/ui/shared/widgets/logo.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:google_fonts/google_fonts.dart'; class Logo extends StatelessWidget { const Logo({super.key}); @@ -7,21 +6,38 @@ class Logo extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - padding: EdgeInsets.only(top: 30), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, + padding: const EdgeInsets.symmetric(vertical: 28, horizontal: 20), + child: Column( children: [ - Image.asset('logo.png', width: 50, height: 50), - SizedBox(width: 8), - Text( - 'Prosapp', - style: GoogleFonts.montserratAlternates( - fontSize: 20, - fontWeight: FontWeight.w200, + Container( + padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10), + decoration: BoxDecoration( color: Colors.white, + borderRadius: BorderRadius.circular(12), + ), + child: Image.network( + 'https://www.prosapp.co/img/logo_prosapp.png', + height: 32, + fit: BoxFit.contain, + errorBuilder: (_, __, ___) => const Text( + 'ProsApp', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Color(0xFF42A4EF), + ), + ), + ), + ), + const SizedBox(height: 8), + const Text( + 'Conecta con profesionales', + style: TextStyle( + color: Color(0xFF8BAFD4), + fontSize: 10, + letterSpacing: 0.3, ), ), - SizedBox(width: 10), ], ), ); diff --git a/lib/ui/shared/widgets/menu_item.dart b/lib/ui/shared/widgets/menu_item.dart index 9baaaba..6809d1e 100644 --- a/lib/ui/shared/widgets/menu_item.dart +++ b/lib/ui/shared/widgets/menu_item.dart @@ -1,5 +1,10 @@ import 'package:flutter/material.dart'; -import 'package:google_fonts/google_fonts.dart'; + +const _kAccent = Color(0xFF42A4EF); +const _kTextActive = Colors.white; +const _kTextInactive = Color(0xFF8BAFD4); +const _kIconActive = _kAccent; +const _kIconInactive = Color(0xFF5A7A9B); class MenuItem extends StatefulWidget { final String text; @@ -24,45 +29,54 @@ class _MenuItemState extends State { @override Widget build(BuildContext context) { - return AnimatedContainer( - duration: const Duration(milliseconds: 300), - color: isHovered - ? Colors.white.withOpacity(0.1) - : widget.isActive - ? Colors.white.withOpacity(0.1) - : Colors.transparent, - child: Material( - color: Colors.transparent, - child: InkWell( - onTap: widget.isActive ? null : () => widget.onPressed(), - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 30, - vertical: 10, - ), - child: MouseRegion( - cursor: widget.isActive - ? SystemMouseCursors.basic - : SystemMouseCursors.click, - onEnter: (_) => setState(() => isHovered = true), - onExit: (_) => setState(() => isHovered = false), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Icon( - widget.icon, - color: Colors.white.withOpacity(0.3), + final active = widget.isActive; + final highlight = active || isHovered; + + return MouseRegion( + cursor: active ? SystemMouseCursors.basic : SystemMouseCursors.click, + onEnter: (_) => setState(() => isHovered = true), + onExit: (_) => setState(() => isHovered = false), + child: GestureDetector( + onTap: active ? null : () => widget.onPressed(), + child: AnimatedContainer( + duration: const Duration(milliseconds: 200), + margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 2), + decoration: BoxDecoration( + color: highlight + ? const Color(0xFF42A4EF).withOpacity(0.12) + : Colors.transparent, + borderRadius: BorderRadius.circular(10), + ), + child: Row( + children: [ + AnimatedContainer( + duration: const Duration(milliseconds: 200), + width: 3, + height: 36, + decoration: BoxDecoration( + color: active ? _kAccent : Colors.transparent, + borderRadius: const BorderRadius.only( + topRight: Radius.circular(3), + bottomRight: Radius.circular(3), ), - const SizedBox(width: 10), - Text( - widget.text, - style: GoogleFonts.roboto( - color: Colors.white.withOpacity(0.8), - ), - ), - ], + ), ), - ), + const SizedBox(width: 12), + Icon( + widget.icon, + color: active ? _kIconActive : _kIconInactive, + size: 20, + ), + const SizedBox(width: 10), + Text( + widget.text, + style: TextStyle( + color: active ? _kTextActive : _kTextInactive, + fontSize: 13, + fontWeight: active ? FontWeight.w600 : FontWeight.w400, + ), + ), + ], ), ), ), diff --git a/lib/ui/shared/widgets/text_separator.dart b/lib/ui/shared/widgets/text_separator.dart index 6fcf5c0..bc4ccb1 100644 --- a/lib/ui/shared/widgets/text_separator.dart +++ b/lib/ui/shared/widgets/text_separator.dart @@ -1,20 +1,29 @@ import 'package:flutter/material.dart'; -import 'package:google_fonts/google_fonts.dart'; class TextSeparator extends StatelessWidget { final String text; - const TextSeparator({super.key, required this.text}); @override Widget build(BuildContext context) { - return Container( - padding: EdgeInsets.symmetric(horizontal: 20), - margin: EdgeInsets.only(bottom: 5), - child: Text( - text, - style: GoogleFonts.roboto( - color: Colors.white.withOpacity(0.3), fontSize: 12), + return Padding( + padding: const EdgeInsets.fromLTRB(20, 16, 20, 4), + child: Row( + children: [ + Text( + text.toUpperCase(), + style: const TextStyle( + color: Color(0xFF4A6F8A), + fontSize: 10, + fontWeight: FontWeight.w600, + letterSpacing: 1.2, + ), + ), + const SizedBox(width: 8), + const Expanded( + child: Divider(color: Color(0xFF1E3A52), thickness: 1, height: 1), + ), + ], ), ); }