import 'dart:convert'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'dart:html' as html; import 'package:frontend/config/apiUrl.dart'; // 1 newly added import 'package:frontend/services/apiService.dart'; import 'package:http/http.dart' as http; import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_quill/flutter_quill.dart'; import 'package:frontend/routes/custom_router.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'Screens/myTemplates/templateTest.dart'; import 'package:fluttertoast/fluttertoast.dart'; class MyApp extends StatefulWidget { const MyApp({super.key}); @override State createState() => _MyAppState(); } class _MyAppState extends State { final ApiService apiService = ApiService(); String? _authCode; String? userRole; bool _isAuthRedirect = false; // Only true for Microsoft redirect bool _isloading = false; @override void initState() { super.initState(); // SemanticsBinding.instance // .ensureSemantics(); // -only for testing uncomment, Otherwise Email Template wont allow to type if (kIsWeb) { final uri = Uri.parse(html.window.location.href); print("URI - $uri"); final fragment = uri.fragment; // e.g., 'authredirection?code=xyz123' print("Full URI: $uri"); print("Fragment: $fragment"); // Parse just the fragment safely final fragmentParts = fragment.split('?'); print("fragmentParts: $fragmentParts"); final fragmentPath = fragmentParts.first; print("fragmentPath: $fragmentPath"); final query = fragmentParts.length > 1 ? fragmentParts[1] : ''; print("query: $query"); final queryParams = Uri.splitQueryString(query); print("queryParams: $queryParams"); final authCode = queryParams['code']; if (fragmentPath == '/authredirection' && authCode != null) { setState(() { _isAuthRedirect = true; // Show loading screen ONLY for MS login }); print(" Auth code detected at startup: $authCode"); // ✅ Immediately begin token handling // WidgetsBinding.instance.addPostFrameCallback((_) { // handleTokenUsingMS(authCode); // }); handleTokenUsingMS(authCode).then((_) { // 🔥 No URL cleanup — leave it as is setState(() { _isAuthRedirect = false; }); }); html.window.console.log("Auth code detected: $authCode"); } else { html.window.console.log("No auth code found or wrong path."); } } } // Note : Doing any change means just refer on login_widget.dart file - _login function. 24july2025 Future handleTokenUsingMS(String authCode) async { print("handleTokenUsingMS- $authCode"); try { // final url = 'http://localhost:43627/tstat/auth/verifyMSAuthUser?code=$authCode'; final url = '$apiUrl/api/auth/verifyMSAuthUser?code=$authCode'; print("Microsoft BE URL - $url"); final response = await http.get( Uri.parse(url), headers: {'Content-Type': 'application/json'}, ); if (response.statusCode == 200) { final responseBody = json.decode(response.body); final token = responseBody['token']; print("Microsoft_Token - $token"); setState(() { _isloading = true; }); if (token != null && token.isNotEmpty) { print('Microsoft - Token Available'); final prefs = await SharedPreferences.getInstance(); await prefs.setString('is_microsoft_user', 'true'); await storeUserDetails(token); setState(() { _isloading = false; }); if (_isloading) { const CircularProgressIndicator(); } final userData = prefs.getString('user_data'); print("MS Userdata - $userData"); final orgDataString = prefs.getString('org_data'); print("MS orgdata - $orgDataString"); if (orgDataString != null && userData != null) { Fluttertoast.showToast( msg: "You're in!", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.CENTER, backgroundColor: Colors.green, textColor: Colors.white, fontSize: 16, webBgColor: "linear-gradient(to right, #28a745, #28a745)", ); print("Microsoft User Logged In Refer the Role - $userRole"); // Navigate based on role if (userRole == "Travel Agent") { router.go('/listTravelAgentPlan'); } else if (userRole == "Org Admin" || userRole == "Travel Admin") { router.go('/StatusDashboard'); } else { router.go('/listPlan'); } } } else { throw Exception('Token missing in response.'); } } else { final error = json.decode(response.body)['message'] ?? 'Auth failed'; throw Exception(error); } } catch (e) { Fluttertoast.showToast( msg: "Login Failed: $e", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.CENTER, backgroundColor: Colors.red, textColor: Colors.white, fontSize: 16, webBgColor: "linear-gradient(to right, #dc1c13, #dc1c13)", ); router.go('/'); } } // Note : Doing any change means just refer on login_widget.dart file - storeUserDetails function. 24july2025 Future storeUserDetails(String token) async { try { final parts = token.split('.'); if (parts.length != 3) throw Exception('Invalid token format'); final payload = json.decode( utf8.decode(base64Url.decode(base64Url.normalize(parts[1]))), ); final userData = payload['data']; final prefs = await SharedPreferences.getInstance(); await prefs.setString('auth_token', token); await prefs.setString( 'user_data', jsonEncode(userData), ); // Store full user data if (userData != null) { final pref = await SharedPreferences.getInstance(); await pref.setString('auth_token', token); await pref.setString('user_data', jsonEncode(userData)); userRole = userData['role']; print("MicroSoft UserData RAW - $userData"); print("MicroSoft UserData ROLE RAW - ${userData['role']}"); print("MicroSoft UserData ROLE FECTHED - $userRole"); } print("MicroSoft Started"); await apiService.getOrganizationData(context); print("MicroSoft end"); } catch (e) { print('Error decoding token MS: $e'); router.go('/'); } } @override Widget build(BuildContext context) { if (_isAuthRedirect) { return const MaterialApp( home: Scaffold(body: Center(child: CircularProgressIndicator())), ); } return MaterialApp.router( title: 'Trip Approval Tool', debugShowCheckedModeBanner: false, theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), ), routerConfig: router, // <- your configured GoRouter or other RouterConfig localizationsDelegates: const [ GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate, GlobalWidgetsLocalizations.delegate, FlutterQuillLocalizations.delegate, ], supportedLocales: const [Locale('en'), Locale('es')], ); } }