Files
prosappweb/lib/main.dart
T
Lizandro GuarnizoandClaude Sonnet 4.6 54f9cc272e fix: 4 audit findings in professionals location flow
- Clear button (✕) now resets _cityMismatch and _detectedCity so banner and CTA unblock
- _citiesMatch: replace bidirectional contains with equality + word-prefix check to prevent 'Cali' matching 'Calima'
- ProfessionalsProvider: track _currentUserId to reset state on user change (cross-user leak)
- ProfessionalsProvider: store _lastSearch so setLocationContext preserves active search term

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 20:47:14 -05:00

126 lines
5.3 KiB
Dart

import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter/material.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:prosapp_web_app/providers/auth_provider.dart';
import 'package:prosapp_web_app/providers/calendar_services_provider.dart';
import 'package:prosapp_web_app/providers/chat_provider.dart';
import 'package:prosapp_web_app/providers/cities_provider.dart';
import 'package:prosapp_web_app/providers/professional_detail_provider.dart';
import 'package:prosapp_web_app/providers/professional_form_provider.dart';
import 'package:prosapp_web_app/providers/professional_provider.dart';
import 'package:prosapp_web_app/providers/professionals_provider.dart';
import 'package:prosapp_web_app/providers/professions_provider.dart';
import 'package:prosapp_web_app/providers/profile_form_provider.dart';
import 'package:prosapp_web_app/providers/score_provider.dart';
import 'package:prosapp_web_app/providers/services_provider.dart';
import 'package:prosapp_web_app/providers/settings_provider.dart';
import 'package:prosapp_web_app/providers/sidemenu_provider.dart';
import 'package:prosapp_web_app/providers/theme_provider.dart';
import 'package:prosapp_web_app/router/router.dart';
import 'package:prosapp_web_app/services/local_storage.dart';
import 'package:prosapp_web_app/services/navigation_service.dart';
import 'package:prosapp_web_app/services/notifications_service.dart';
import 'package:prosapp_web_app/ui/layouts/auth/auth_layout.dart';
import 'package:prosapp_web_app/ui/layouts/dashboard/dashboard_layout.dart';
import 'package:prosapp_web_app/ui/layouts/splash/splash_layout.dart';
import 'package:provider/provider.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await dotenv.load(fileName: ".env");
await LocalStorage.configurePrefs();
await initializeDateFormatting('es_ES', null);
Flurorouter.configureRoutes();
runApp(const AppState());
}
class AppState extends StatelessWidget {
const AppState({super.key});
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(lazy: false, create: (_) => AuthProvider()),
ChangeNotifierProvider(lazy: false, create: (_) => SideMenuProvider()),
ChangeNotifierProvider(lazy: false, create: (_) => ProfessionalProvider()),
ChangeNotifierProvider(lazy: false, create: (_) => ThemeProvider()),
ChangeNotifierProvider(lazy: false, create: (_) => SettingsProvider()),
ChangeNotifierProvider(create: (_) => ProfileFormProvider()),
ChangeNotifierProvider(create: (_) => ProfessionalFormProvider()),
ChangeNotifierProxyProvider<AuthProvider, ProfessionalsProvider>(
create: (_) => ProfessionalsProvider(),
update: (_, auth, prev) => prev!..updateCity(auth.user?.city, userId: auth.user?.id),
),
ChangeNotifierProvider(create: (_) => ServicesProvider()),
ChangeNotifierProvider(create: (_) => CalendarServicesProvider()),
ChangeNotifierProvider(create: (_) => CitiesProvider()),
ChangeNotifierProvider(create: (_) => ProfessionsProvider()),
ChangeNotifierProvider(create: (_) => ProfessionalDetailProvider()),
ChangeNotifierProvider(create: (_) => ScoreProvider()),
ChangeNotifierProvider(create: (_) => ChatProvider()),
],
child: const MyApp(),
);
}
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
final themeProvider = Provider.of<ThemeProvider>(context);
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'ProsApp',
initialRoute: '/',
onGenerateRoute: Flurorouter.router.generator,
navigatorKey: NavigationService.navigatorKey,
scaffoldMessengerKey: NotificationsService.messengerKey,
themeMode: themeProvider.mode,
theme: _buildLight(),
darkTheme: _buildDark(),
builder: (_, child) {
final authProvider = Provider.of<AuthProvider>(context);
if (authProvider.authStatus == AuthStatus.checking) return const SplashLayout();
if (authProvider.authStatus == AuthStatus.authenticated) return DashboardLayout(child: child!);
return AuthLayout(child: child!);
},
);
}
ThemeData _buildLight() {
return ThemeData.light().copyWith(
colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFF42A4EF)),
scaffoldBackgroundColor: const Color(0xFFF4F6FA),
cardColor: Colors.white,
scrollbarTheme: const ScrollbarThemeData().copyWith(
thumbColor: WidgetStateProperty.all(Colors.grey.withOpacity(0.5)),
),
);
}
ThemeData _buildDark() {
return ThemeData.dark().copyWith(
colorScheme: ColorScheme.fromSeed(
seedColor: const Color(0xFF42A4EF),
brightness: Brightness.dark,
),
scaffoldBackgroundColor: const Color(0xFF0F172A),
cardColor: const Color(0xFF1E293B),
dialogBackgroundColor: const Color(0xFF1E293B),
appBarTheme: const AppBarTheme(backgroundColor: Color(0xFF1E293B)),
inputDecorationTheme: InputDecorationTheme(
filled: true,
fillColor: const Color(0xFF1E293B),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)),
),
scrollbarTheme: const ScrollbarThemeData().copyWith(
thumbColor: WidgetStateProperty.all(Colors.white24),
),
);
}
}