feat: add admin page
This commit is contained in:
@@ -15,8 +15,20 @@ const _pinLength = 4;
|
||||
class PinEntryView extends StatefulWidget {
|
||||
final PinEntryMode mode;
|
||||
final VoidCallback? onSuccess;
|
||||
final bool isAdmin;
|
||||
final Future<bool> Function(String)? onVerify;
|
||||
final Future<bool> Function(String)? onSet;
|
||||
final String? Function()? errorMessage;
|
||||
|
||||
const PinEntryView({super.key, required this.mode, this.onSuccess});
|
||||
const PinEntryView({
|
||||
super.key,
|
||||
required this.mode,
|
||||
this.onSuccess,
|
||||
this.isAdmin = false,
|
||||
this.onVerify,
|
||||
this.onSet,
|
||||
this.errorMessage,
|
||||
});
|
||||
|
||||
@override
|
||||
State<PinEntryView> createState() => _PinEntryViewState();
|
||||
@@ -33,12 +45,22 @@ class _PinEntryViewState extends State<PinEntryView> {
|
||||
bool get _isCreateFlow => widget.mode == PinEntryMode.create;
|
||||
|
||||
String _title(AppLocalizations l10n) {
|
||||
if (widget.isAdmin) {
|
||||
if (!_isCreateFlow) return l10n.enterAdminPin;
|
||||
return _isConfirmStep ? l10n.confirmAdminPin : l10n.createAdminPin;
|
||||
}
|
||||
|
||||
if (!_isCreateFlow) return l10n.enterPin;
|
||||
return _isConfirmStep ? l10n.confirmPin : l10n.createPin;
|
||||
}
|
||||
|
||||
String? _subtitle(AppLocalizations l10n) {
|
||||
if (!_isCreateFlow) return null;
|
||||
|
||||
if (widget.isAdmin) {
|
||||
return _isConfirmStep ? l10n.confirmPinSubtitle : l10n.adminPinSubtitle;
|
||||
}
|
||||
|
||||
return _isConfirmStep ? l10n.confirmPinSubtitle : l10n.enterPinSubtitle;
|
||||
}
|
||||
|
||||
@@ -64,7 +86,6 @@ class _PinEntryViewState extends State<PinEntryView> {
|
||||
}
|
||||
|
||||
Future<void> _handleComplete() async {
|
||||
final viewModel = context.read<PinLockViewModel>();
|
||||
final l10n = AppLocalizations.of(context);
|
||||
|
||||
if (_isCreateFlow && !_isConfirmStep) {
|
||||
@@ -90,7 +111,7 @@ class _PinEntryViewState extends State<PinEntryView> {
|
||||
}
|
||||
|
||||
setState(() => _isSubmitting = true);
|
||||
final ok = await viewModel.setPin(_digits);
|
||||
final ok = await _setPin(_digits);
|
||||
if (!mounted) return;
|
||||
setState(() => _isSubmitting = false);
|
||||
|
||||
@@ -101,24 +122,45 @@ class _PinEntryViewState extends State<PinEntryView> {
|
||||
_firstEntry = null;
|
||||
_isConfirmStep = false;
|
||||
});
|
||||
_fail(l10n.localizedError(viewModel.errorMessage));
|
||||
_fail(l10n.localizedError(_errorMessage()));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Unlock flow.
|
||||
setState(() => _isSubmitting = true);
|
||||
final ok = await viewModel.verify(_digits);
|
||||
final ok = await _verify(_digits);
|
||||
if (!mounted) return;
|
||||
setState(() => _isSubmitting = false);
|
||||
|
||||
if (ok) {
|
||||
widget.onSuccess?.call();
|
||||
} else {
|
||||
_fail(l10n.localizedError(viewModel.errorMessage));
|
||||
_fail(l10n.localizedError(_errorMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> _setPin(String pin) {
|
||||
final callback = widget.onSet;
|
||||
if (callback != null) return callback(pin);
|
||||
|
||||
return context.read<PinLockViewModel>().setPin(pin);
|
||||
}
|
||||
|
||||
Future<bool> _verify(String pin) {
|
||||
final callback = widget.onVerify;
|
||||
if (callback != null) return callback(pin);
|
||||
|
||||
return context.read<PinLockViewModel>().verify(pin);
|
||||
}
|
||||
|
||||
String? _errorMessage() {
|
||||
final callback = widget.errorMessage;
|
||||
if (callback != null) return callback();
|
||||
|
||||
return context.read<PinLockViewModel>().errorMessage;
|
||||
}
|
||||
|
||||
void _fail(String message) {
|
||||
setState(() {
|
||||
_localError = message;
|
||||
|
||||
Reference in New Issue
Block a user