import 'package:auto_route/auto_route.dart'; import 'package:dartz/dartz.dart' hide State; 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/button/button.dart'; import '../../router/app_router.gr.dart'; import '../wallet/wallet_ui.dart'; /// Menu PIN di profil: buat, ganti, dan lupa PIN. @RoutePage() class PinSettingsPage extends StatefulWidget { const PinSettingsPage({super.key}); @override State createState() => _PinSettingsPageState(); } class _PinSettingsPageState extends State { late Future> _status; @override void initState() { super.initState(); _load(); } void _load() { setState(() => _status = getIt().getStatus()); } Future _open(PageRouteInfo route) async { await context.router.push(route); if (mounted) _load(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: AppColor.background, appBar: AppBar(title: const Text('PIN')), body: FutureBuilder>( future: _status, builder: (context, snapshot) { if (!snapshot.hasData) { return const Center( child: SpinKitFadingCircle(color: AppColor.primary, size: 32), ); } return snapshot.data!.fold( (f) => Center( child: Padding( padding: const EdgeInsets.all(20), child: Column( mainAxisSize: MainAxisSize.min, children: [ Text(walletFailureMessage(f), textAlign: TextAlign.center), const SizedBox(height: 16), AppOutlineButton( title: 'Coba lagi', width: 160, onPressed: _load, ), ], ), ), ), (status) => ListView( children: [ Container( margin: const EdgeInsets.all(16), padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: AppColor.white, borderRadius: BorderRadius.circular(AppValue.borderRadius), ), child: Text( 'PIN 6 digit dipakai untuk membuat kode bayar, tukar ' 'EnakCoin, dan transfer. PIN berbeda dengan password ' 'login dan jangan diberitahukan kepada siapa pun.', style: AppStyle.md.copyWith(color: AppColor.textSecondary), ), ), if (status.isLocked) _buildNotice( 'PIN terkunci sampai ${formatWibTime(status.lockedUntil!)}. ' 'Gunakan Lupa PIN untuk membukanya.', ), if (status.transferBlockedUntil != null && status.transferBlockedUntil!.isAfter(DateTime.now())) _buildNotice( 'Transfer bisa dilakukan lagi pada ' '${formatWibDateTime(status.transferBlockedUntil!)}.', ), Container( color: AppColor.white, child: Column( children: status.hasPin ? [ _buildTile( icon: Icons.lock_reset, title: 'Ganti PIN', onTap: () => _open(const PinChangeRoute()), ), const Divider(height: 1, indent: 60), _buildTile( icon: Icons.help_outline, title: 'Lupa PIN', onTap: () => _open( PinSetupRoute(purpose: PinOtpPurpose.reset), ), ), ] : [ _buildTile( icon: Icons.lock_outline, title: 'Buat PIN', onTap: () => _open( PinSetupRoute(purpose: PinOtpPurpose.setup), ), ), ], ), ), ], ), ); }, ), ); } Widget _buildNotice(String text) { return Container( margin: const EdgeInsets.fromLTRB(16, 0, 16, 16), padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: AppColor.warningWithOpacity(0.1), borderRadius: BorderRadius.circular(AppValue.borderRadius), border: Border.all(color: AppColor.warning), ), child: Text(text, style: AppStyle.md), ); } Widget _buildTile({ required IconData icon, required String title, required VoidCallback onTap, }) { return ListTile( leading: Icon(icon, color: AppColor.textSecondary), title: Text(title, style: AppStyle.md), trailing: const Icon( Icons.arrow_forward_ios, size: 16, color: AppColor.textSecondary, ), onTap: onTap, ); } }