TKK_E32230206/lib/features/auth/register_page.dart

176 lines
5.0 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../core/app_theme.dart';
import '../../core/routes.dart';
import '../../core/widgets/auth_primary_button.dart';
import '../../core/widgets/auth_password_field.dart';
import '../../core/widgets/auth_scaffold.dart';
import '../../core/widgets/auth_text_field.dart';
import 'auth_notifier.dart';
import 'auth_state.dart';
class RegisterPage extends ConsumerStatefulWidget {
const RegisterPage({super.key});
@override
ConsumerState<RegisterPage> createState() => _RegisterPageState();
}
class _RegisterPageState extends ConsumerState<RegisterPage> {
final _formKey = GlobalKey<FormState>();
final _nameCtrl = TextEditingController();
final _emailCtrl = TextEditingController();
final _passwordCtrl = TextEditingController();
final _confirmCtrl = TextEditingController();
AutovalidateMode _autoValidate = AutovalidateMode.disabled;
bool _isButtonEnabled = false;
@override
void initState() {
super.initState();
for (final c in [_nameCtrl, _emailCtrl, _passwordCtrl, _confirmCtrl]) {
c.addListener(_checkButton);
}
}
void _checkButton() {
final filled = _nameCtrl.text.isNotEmpty &&
_emailCtrl.text.isNotEmpty &&
_passwordCtrl.text.isNotEmpty &&
_confirmCtrl.text.isNotEmpty;
if (filled != _isButtonEnabled) {
setState(() => _isButtonEnabled = filled);
}
}
@override
void dispose() {
_nameCtrl.dispose();
_emailCtrl.dispose();
_passwordCtrl.dispose();
_confirmCtrl.dispose();
super.dispose();
}
Future<void> _submit() async {
setState(() => _autoValidate = AutovalidateMode.onUserInteraction);
if (!_formKey.currentState!.validate()) return;
await ref.read(authProvider.notifier).register(
_nameCtrl.text,
_emailCtrl.text,
_passwordCtrl.text,
);
if (!mounted) return;
final state = ref.read(authProvider);
if (state is AuthSuccess) {
Navigator.pushNamedAndRemoveUntil(context, AppRoutes.main, (route) => false);
} else if (state is AuthError) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(state.message),
backgroundColor: AppTheme.statusDanger,
),
);
ref.read(authProvider.notifier).resetError();
}
}
@override
Widget build(BuildContext context) {
final authState = ref.watch(authProvider);
final isLoading = authState is AuthLoading;
return AuthScaffold(
title: 'Register',
subtitle: 'Daftarkan dirimu untuk membuat akun baru',
child: Form(
key: _formKey,
autovalidateMode: _autoValidate,
child: Column(
children: [
AuthTextField(
controller: _nameCtrl,
label: 'Nama Lengkap',
prefixIcon: Icons.person_outline,
validator: (v) =>
(v == null || v.isEmpty) ? 'Nama tidak boleh kosong' : null,
),
const SizedBox(height: 20),
AuthTextField(
controller: _emailCtrl,
label: 'Email',
keyboardType: TextInputType.emailAddress,
prefixIcon: Icons.email_outlined,
validator: (v) {
if (v == null || v.isEmpty) return 'Email tidak boleh kosong';
if (!v.contains('@') || !v.contains('.')) {
return 'Format email tidak valid';
}
return null;
},
),
const SizedBox(height: 20),
AuthPasswordField(
controller: _passwordCtrl,
label: 'Password',
validator: (v) =>
(v == null || v.length < 6) ? 'Minimal 6 karakter' : null,
),
const SizedBox(height: 20),
AuthPasswordField(
controller: _confirmCtrl,
label: 'Konfirmasi Password',
validator: (v) =>
v != _passwordCtrl.text ? 'Password tidak sama' : null,
),
const SizedBox(height: 40),
AuthPrimaryButton(
text: 'Daftar Sekarang',
enabled: _isButtonEnabled,
isLoading: isLoading,
onPressed: _submit,
),
const SizedBox(height: 24),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'Sudah punya akun? ',
style: TextStyle(color: AppTheme.textSecondary),
),
GestureDetector(
onTap: () => Navigator.pushReplacementNamed(context, AppRoutes.login),
child: const Text(
'Masuk',
style: TextStyle(
color: AppTheme.primary,
fontWeight: FontWeight.bold,
),
),
),
],
),
],
),
),
);
}
}