Flutter Android login vault: local DB (id+base64 content), email/Google auth, dashboard search/edit/swipe-delete, dark/system theme, minSdk 29
This commit is contained in:
128
lib/auth_screen.dart
Normal file
128
lib/auth_screen.dart
Normal file
@@ -0,0 +1,128 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_sign_in/google_sign_in.dart';
|
||||
import 'package:login_vault_app/auth_service.dart';
|
||||
|
||||
/// First-launch screen: register with email+password, or with Google.
|
||||
class AuthScreen extends StatefulWidget {
|
||||
final AuthService auth;
|
||||
const AuthScreen({super.key, required this.auth});
|
||||
|
||||
@override
|
||||
State<AuthScreen> createState() => _AuthScreenState();
|
||||
}
|
||||
|
||||
class _AuthScreenState extends State<AuthScreen> {
|
||||
final _emailCtrl = TextEditingController();
|
||||
final _passCtrl = TextEditingController();
|
||||
bool _isLogin = true; // toggle register/login
|
||||
bool _busy = false;
|
||||
String? _error;
|
||||
|
||||
Future<void> _submitEmail() async {
|
||||
setState(() => _busy = true);
|
||||
final email = _emailCtrl.text.trim();
|
||||
final pass = _passCtrl.text;
|
||||
if (email.isEmpty || pass.isEmpty) {
|
||||
setState(() => _error = 'Email & password wajib diisi');
|
||||
_busy = false;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (_isLogin) {
|
||||
final stored = await widget.auth.getAppPassword();
|
||||
final ok = await widget.auth.verifyPassword(pass);
|
||||
if (stored == null) {
|
||||
setState(() => _error = 'Belum terdaftar, silakan registrasi');
|
||||
} else if (!ok) {
|
||||
setState(() => _error = 'Password aplikasi salah');
|
||||
} else {
|
||||
// success -> pop true
|
||||
if (mounted) Navigator.pop(context, true);
|
||||
}
|
||||
} else {
|
||||
await widget.auth.registerWithEmail(email, pass);
|
||||
if (mounted) Navigator.pop(context, true);
|
||||
}
|
||||
} catch (e) {
|
||||
setState(() => _error = e.toString());
|
||||
} finally {
|
||||
if (mounted) setState(() => _busy = false);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _signInGoogle() async {
|
||||
setState(() => _busy = true);
|
||||
try {
|
||||
final gs = GoogleSignIn(scopes: ['email']);
|
||||
final account = await gs.signIn();
|
||||
if (account?.email != null) {
|
||||
await widget.auth.registerWithGoogle(account!.email);
|
||||
if (mounted) Navigator.pop(context, true);
|
||||
} else {
|
||||
setState(() => _error = 'Google sign-in dibatalkan');
|
||||
}
|
||||
} catch (e) {
|
||||
setState(() => _error = 'Google sign-in gagal: ${e.toString()}');
|
||||
} finally {
|
||||
if (mounted) setState(() => _busy = false);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('Login Vault')),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(_isLogin ? 'Masuk' : 'Daftar',
|
||||
style: Theme.of(context).textTheme.headlineSmall),
|
||||
const SizedBox(height: 16),
|
||||
TextField(
|
||||
controller: _emailCtrl,
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Email', border: OutlineInputBorder()),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
TextField(
|
||||
controller: _passCtrl,
|
||||
obscureText: true,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Password aplikasi', border: OutlineInputBorder()),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
if (_error != null)
|
||||
Text(_error!, style: const TextStyle(color: Colors.red)),
|
||||
const SizedBox(height: 12),
|
||||
_busy
|
||||
? const CircularProgressIndicator()
|
||||
: Column(
|
||||
children: [
|
||||
ElevatedButton(
|
||||
onPressed: _submitEmail,
|
||||
child: Text(_isLogin ? 'Masuk' : 'Daftar'),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () =>
|
||||
setState(() => _isLogin = !_isLogin),
|
||||
child: Text(_isLogin
|
||||
? 'Belum punya akun? Daftar'
|
||||
: 'Sudah punya akun? Masuk'),
|
||||
),
|
||||
const Divider(),
|
||||
OutlinedButton.icon(
|
||||
onPressed: _signInGoogle,
|
||||
icon: const Icon(Icons.login),
|
||||
label: const Text('Lanjut dengan Google'),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user