/// PocketBase sign-in state. Local tx/bank data is unchanged by auth. library; import 'package:flutter/foundation.dart'; import 'package:pocketbase/pocketbase.dart'; import '../services/storage_service.dart'; import '../utils/constants.dart'; /// Owns the PocketBase client, session persistence, and login/logout. class AuthController extends ChangeNotifier { AuthController(this._storage); final StorageService _storage; PocketBase? _client; PocketBase get client { final pb = _client; if (pb == null) { throw StateError('AuthController.init() must be called before use.'); } return pb; } bool get isLoggedIn => _client?.authStore.isValid ?? false; RecordModel? get user => _client?.authStore.record; String? get email { final value = user?.getStringValue('email'); return value == null || value.isEmpty ? null : value; } String? get name { final value = user?.getStringValue('name'); return value == null || value.isEmpty ? null : value; } String get displayName { final n = name; if (n != null && n.isNotEmpty) return n; final e = email; if (e != null && e.isNotEmpty) return e.split('@').first; return 'Account'; } String get initials { final source = name ?? email ?? '?'; final parts = source.trim().split(RegExp(r'\s+')); if (parts.length >= 2 && parts[0].isNotEmpty && parts[1].isNotEmpty) { return '${parts[0][0]}${parts[1][0]}'.toUpperCase(); } if (source.isNotEmpty) return source[0].toUpperCase(); return '?'; } Future init() async { final store = AsyncAuthStore( save: (String data) async { if (data.isEmpty) { await _storage.clearPocketBaseAuth(); } else { await _storage.setPocketBaseAuth(data); } }, initial: _storage.pocketBaseAuth, ); _client = PocketBase(kPocketBaseUrl, authStore: store); _client!.authStore.onChange.listen((_) => notifyListeners()); notifyListeners(); } Future login({ required String email, required String password, }) async { await client .collection(kPocketBaseUsersCollection) .authWithPassword(email.trim(), password); notifyListeners(); } Future logout() async { client.authStore.clear(); notifyListeners(); } }