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>(
selector: (context, state) => state.isLoggedIn,
builder: (context, loggedIn, child) {
if (loggedIn) {
return Selector<AppState, ({bool loggedIn, bool expired})>(
selector: (context, state) =>
(loggedIn: state.isLoggedIn, expired: state.sessionExpired),
builder: (context, auth, child) {
if (auth.loggedIn && !auth.expired) {
return const HomePage();
}
return const LoginScreen();

View File

@@ -197,7 +197,13 @@ class AppState extends ChangeNotifier {
}
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 _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 (_) {}
// 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;
}