diff --git a/lib/main.dart b/lib/main.dart index 60f70fc..0b8e5ba 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -201,10 +201,11 @@ class AuthGate extends StatelessWidget { ), ); } - return Selector( - selector: (context, state) => state.isLoggedIn, - builder: (context, loggedIn, child) { - if (loggedIn) { + return Selector( + selector: (context, state) => + (loggedIn: state.isLoggedIn, expired: state.sessionExpired), + builder: (context, auth, child) { + if (auth.loggedIn && !auth.expired) { return const HomePage(); } return const LoginScreen(); diff --git a/lib/state/app_state.dart b/lib/state/app_state.dart index 9c8c0cd..28b59ec 100644 --- a/lib/state/app_state.dart +++ b/lib/state/app_state.dart @@ -197,7 +197,13 @@ class AppState extends ChangeNotifier { } Future refresh() async { - await _ensureSessionAndAuth(); + final authOk = await _ensureSessionAndAuth(); + if (!authOk) { + // Auth mati: jangan lanjut query (pasti 401). Cukup notify agar + // AuthGate redirect ke LoginScreen. + notifyListeners(); + return; + } await _loadProducts(); await _loadSales(); notifyListeners(); @@ -306,7 +312,13 @@ class AppState extends ChangeNotifier { 'Login', ); userId = res.user?.id; + _sessionExpired = false; await _loadProfile(); + // Muat produk/riwayat langsung agar user tidak menunggu poll berikut. + // Gagal load tak mematikan proses login. + try { + await refresh(); + } catch (_) {} notifyListeners(); return null; } on AuthException catch (e) { @@ -551,8 +563,15 @@ class AppState extends ChangeNotifier { if (res.session != null && !res.session!.isExpired) { return true; } - } catch (_) {} - _sessionExpired = true; + // Refresh jalan tapi session tetap tak valid → auth benar-benar mati. + _sessionExpired = true; + } on AuthException { + // Token refresh ditolak server (invalid/kedaluwarsa) → auth mati. + _sessionExpired = true; + } catch (_) { + // Error jaringan/timeout: JANGAN tandai sessionExpired (bisa network + // blip). Data gagal load sementara, session belum dianggap mati. + } return false; }