Sempurnakan auth flow: AuthGate route ke LoginScreen saat sessionExpired, _ensureSessionAndAuth bedakan auth mati vs network blip, refresh() stop query saat auth mati, login() reset sessionExpired + muat data langsung

This commit is contained in:
Onie
2026-10-18 15:46:46 +07:00
parent 9e6b610549
commit bcea28fcc4
2 changed files with 27 additions and 7 deletions

View File

@@ -201,10 +201,11 @@ class AuthGate extends StatelessWidget {
), ),
); );
} }
return Selector<AppState, bool>( return Selector<AppState, ({bool loggedIn, bool expired})>(
selector: (context, state) => state.isLoggedIn, selector: (context, state) =>
builder: (context, loggedIn, child) { (loggedIn: state.isLoggedIn, expired: state.sessionExpired),
if (loggedIn) { builder: (context, auth, child) {
if (auth.loggedIn && !auth.expired) {
return const HomePage(); return const HomePage();
} }
return const LoginScreen(); return const LoginScreen();

View File

@@ -197,7 +197,13 @@ class AppState extends ChangeNotifier {
} }
Future<void> refresh() async { Future<void> 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 _loadProducts();
await _loadSales(); await _loadSales();
notifyListeners(); notifyListeners();
@@ -306,7 +312,13 @@ class AppState extends ChangeNotifier {
'Login', 'Login',
); );
userId = res.user?.id; userId = res.user?.id;
_sessionExpired = false;
await _loadProfile(); await _loadProfile();
// Muat produk/riwayat langsung agar user tidak menunggu poll berikut.
// Gagal load tak mematikan proses login.
try {
await refresh();
} catch (_) {}
notifyListeners(); notifyListeners();
return null; return null;
} on AuthException catch (e) { } on AuthException catch (e) {
@@ -551,8 +563,15 @@ class AppState extends ChangeNotifier {
if (res.session != null && !res.session!.isExpired) { if (res.session != null && !res.session!.isExpired) {
return true; return true;
} }
} catch (_) {} // Refresh jalan tapi session tetap tak valid → auth benar-benar mati.
_sessionExpired = true; _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; return false;
} }