EnakPoint & EnakCoin wallet, PIN, outlet, order, community, reward
- Wallet EnakPoint & EnakCoin: beranda, riwayat, saldo kedaluwarsa, kode bayar, tukar EnakCoin, transfer - PIN (buat, ganti, lupa), outlet, riwayat order, game spin - Halaman community, webview, coming soon, dan ikon menu beranda baru - Redesign Reward Saya: kartu tiket, filter chip, detail kode + QR - Hapus customer point loader, menu, dan checkout lama - Base URL ke enaklo-pos-api.altru.id Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
5954510b93
commit
f5e3075205
@@ -0,0 +1,96 @@
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
|
||||
import '../../../common/theme/theme.dart';
|
||||
import '../../../domain/wallet/wallet.dart';
|
||||
import '../../../injection.dart';
|
||||
import '../../components/toast/flushbar.dart';
|
||||
import '../../router/app_router.gr.dart';
|
||||
import '../wallet/wallet_ui.dart';
|
||||
|
||||
/// Memastikan customer siap memasukkan PIN (§6.1) sebelum aksi yang butuh PIN.
|
||||
///
|
||||
/// - Belum punya PIN: buka alur buat PIN, lalu lanjut bila berhasil dibuat.
|
||||
/// - PIN terkunci: tampilkan jam buka kunci dan tawarkan "Lupa PIN".
|
||||
///
|
||||
/// Mengembalikan `true` bila aksi boleh dilanjutkan ke input PIN.
|
||||
Future<bool> ensurePinReady(BuildContext context) async {
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (_) => const Center(
|
||||
child: SpinKitFadingCircle(color: AppColor.white, size: 40),
|
||||
),
|
||||
);
|
||||
|
||||
final result = await getIt<IPinRepository>().getStatus();
|
||||
|
||||
if (!context.mounted) return false;
|
||||
Navigator.of(context, rootNavigator: true).pop();
|
||||
|
||||
final failure = result.fold((f) => f, (_) => null);
|
||||
if (failure != null) {
|
||||
AppFlushbar.showError(context, walletFailureMessage(failure));
|
||||
return false;
|
||||
}
|
||||
|
||||
final status = result.getOrElse(() => const PinStatus(hasPin: false));
|
||||
|
||||
if (!status.hasPin) {
|
||||
final created = await context.router.push<bool>(
|
||||
PinSetupRoute(purpose: PinOtpPurpose.setup),
|
||||
);
|
||||
return created == true;
|
||||
}
|
||||
|
||||
if (status.isLocked) {
|
||||
await showPinLockedDialog(context, status.lockedUntil!);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Future<void> showPinLockedDialog(
|
||||
BuildContext context,
|
||||
DateTime lockedUntil,
|
||||
) async {
|
||||
final forgot = await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (dialogContext) => AlertDialog(
|
||||
backgroundColor: AppColor.white,
|
||||
title: Text(
|
||||
'PIN terkunci',
|
||||
style: AppStyle.lg.copyWith(fontWeight: FontWeight.w700),
|
||||
),
|
||||
content: Text(
|
||||
'PIN terkunci sampai ${formatWibTime(lockedUntil)}.',
|
||||
style: AppStyle.md,
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(dialogContext).pop(false),
|
||||
child: Text(
|
||||
'Tutup',
|
||||
style: AppStyle.md.copyWith(color: AppColor.textSecondary),
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(dialogContext).pop(true),
|
||||
child: Text(
|
||||
'Lupa PIN',
|
||||
style: AppStyle.md.copyWith(
|
||||
color: AppColor.primary,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
if (forgot == true && context.mounted) {
|
||||
context.router.push(PinSetupRoute(purpose: PinOtpPurpose.reset));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user