346 lines
9.9 KiB
Dart
Raw Normal View History

2025-08-29 21:52:34 +07:00
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import '../../../../common/theme/theme.dart';
@RoutePage()
class PaymentPage extends StatefulWidget {
const PaymentPage({super.key});
@override
State<PaymentPage> createState() => _PaymentPageState();
}
class _PaymentPageState extends State<PaymentPage> {
2025-09-04 21:47:54 +07:00
// Featured payment methods
final List<Map<String, dynamic>> featuredMethods = [
2025-08-29 21:52:34 +07:00
{
2025-09-04 21:47:54 +07:00
'id': 'qris',
'name': 'QRIS',
'subtitle': null,
'icon': 'assets/images/qris.png',
'iconColor': AppColor.black,
'badge': 'Baru',
'badgeColor': const Color(0xFFE57373),
},
];
// Main payment categories
final List<Map<String, dynamic>> paymentCategories = [
{
'id': 'credit_card',
2025-08-29 21:52:34 +07:00
'name': 'Kartu Kredit',
2025-09-04 21:47:54 +07:00
'subtitle':
'Minimal pembayaran Rp 10.000 dan mendukung Kartu Berlogo Visa, Mastercard dan JCB',
2025-08-29 21:52:34 +07:00
'icon': Icons.credit_card,
2025-09-04 21:47:54 +07:00
'iconColor': const Color(0xFF2E7D32),
'hasArrow': false,
2025-08-29 21:52:34 +07:00
},
2025-09-04 21:47:54 +07:00
];
// Other payment methods
final List<Map<String, dynamic>> otherMethods = [
2025-08-29 21:52:34 +07:00
{
2025-09-04 21:47:54 +07:00
'id': 'gopay',
'name': 'Gopay',
'subtitle': 'Aktifkan Sekarang',
'logo': 'assets/images/gopay.png',
'iconColor': const Color(0xFF00AA5B),
'hasArrow': true,
2025-08-29 21:52:34 +07:00
},
{
2025-09-04 21:47:54 +07:00
'id': 'dana',
'name': 'Dana',
'subtitle': 'Aktifkan Sekarang',
'logo': 'assets/images/dana.png',
'iconColor': const Color(0xFF118EEA),
'hasArrow': true,
2025-08-29 21:52:34 +07:00
},
{
2025-09-04 21:47:54 +07:00
'id': 'blu',
'name': 'blu',
'subtitle': 'Aktifkan Sekarang',
'logo': 'assets/images/blu.png',
'iconColor': const Color(0xFF00D4FF),
'hasArrow': true,
2025-08-29 21:52:34 +07:00
},
{
2025-09-04 21:47:54 +07:00
'id': 'shopeepay',
'name': 'ShopeePay',
'subtitle': 'Aktifkan Sekarang',
'logo': 'assets/images/shopeepay.png',
'iconColor': const Color(0xFFEE4D2D),
'hasArrow': true,
},
{
'id': 'ovo',
'name': 'OVO',
'subtitle': 'Aktifkan Sekarang',
'logo': 'assets/images/ovo.png',
'iconColor': const Color(0xFF4C3EC9),
'hasArrow': true,
2025-08-29 21:52:34 +07:00
},
];
2025-09-04 21:47:54 +07:00
Widget _buildFeaturedCard(Map<String, dynamic> method) {
2025-08-29 21:52:34 +07:00
return Container(
2025-09-04 21:47:54 +07:00
margin: const EdgeInsets.symmetric(horizontal: 20, vertical: 8),
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
2025-08-29 21:52:34 +07:00
color: AppColor.white,
2025-09-04 21:47:54 +07:00
borderRadius: BorderRadius.circular(12),
border: Border.all(color: AppColor.border.withOpacity(0.3)),
2025-08-29 21:52:34 +07:00
),
2025-09-04 21:47:54 +07:00
child: Row(
children: [
// Logo placeholder
Container(
width: 40,
height: 24,
decoration: BoxDecoration(
color: AppColor.black,
borderRadius: BorderRadius.circular(4),
),
child: Center(
child: Text(
method['name'],
style: AppStyle.sm.copyWith(
color: AppColor.white,
fontWeight: FontWeight.w700,
fontSize: 10,
),
),
),
),
const SizedBox(width: 16),
Text(
method['name'],
style: AppStyle.lg.copyWith(
fontWeight: FontWeight.w600,
color: AppColor.textPrimary,
),
),
const Spacer(),
if (method['badge'] != null)
2025-08-29 21:52:34 +07:00
Container(
2025-09-04 21:47:54 +07:00
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
2025-08-29 21:52:34 +07:00
decoration: BoxDecoration(
2025-09-04 21:47:54 +07:00
color: method['badgeColor'],
borderRadius: BorderRadius.circular(12),
),
child: Text(
method['badge'],
style: AppStyle.sm.copyWith(
color: AppColor.white,
fontWeight: FontWeight.w600,
),
2025-08-29 21:52:34 +07:00
),
),
2025-09-04 21:47:54 +07:00
],
),
);
}
Widget _buildCategoryCard(Map<String, dynamic> category) {
return Container(
margin: const EdgeInsets.symmetric(horizontal: 20, vertical: 8),
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: AppColor.white,
borderRadius: BorderRadius.circular(12),
border: Border.all(color: AppColor.border.withOpacity(0.3)),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
width: 40,
height: 40,
decoration: BoxDecoration(
color: category['iconColor'].withOpacity(0.1),
borderRadius: BorderRadius.circular(8),
),
child: Icon(
category['icon'],
color: category['iconColor'],
size: 20,
),
),
const SizedBox(width: 16),
Text(
category['name'],
style: AppStyle.lg.copyWith(
fontWeight: FontWeight.w600,
color: AppColor.textPrimary,
),
),
],
),
if (category['subtitle'] != null) ...[
const SizedBox(height: 12),
Text(
category['subtitle'],
style: AppStyle.md.copyWith(
color: const Color(0xFF4CAF50),
height: 1.4,
),
),
],
],
),
);
}
Widget _buildPaymentMethodCard(Map<String, dynamic> method) {
return Material(
color: Colors.transparent,
child: InkWell(
onTap: () {
// Handle method selection
},
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16),
decoration: const BoxDecoration(
color: AppColor.white,
border: Border(
bottom: BorderSide(color: Color(0xFFF5F5F5), width: 1),
),
),
child: Row(
children: [
// Method logo/icon
Container(
width: 40,
height: 40,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
),
child: method['logo'] != null
? ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Image.asset(
method['logo'],
fit: BoxFit.cover,
errorBuilder: (context, error, stackTrace) {
return _buildFallbackIcon(method);
},
2025-08-29 21:52:34 +07:00
),
2025-09-04 21:47:54 +07:00
)
: _buildFallbackIcon(method),
),
const SizedBox(width: 16),
// Method info
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
method['name'],
style: AppStyle.lg.copyWith(
fontWeight: FontWeight.w600,
color: AppColor.textPrimary,
2025-08-29 21:52:34 +07:00
),
2025-09-04 21:47:54 +07:00
),
if (method['subtitle'] != null) ...[
const SizedBox(height: 2),
2025-08-29 21:52:34 +07:00
Text(
2025-09-04 21:47:54 +07:00
method['subtitle'],
style: AppStyle.md.copyWith(color: AppColor.textLight),
2025-08-29 21:52:34 +07:00
),
],
2025-09-04 21:47:54 +07:00
],
),
2025-08-29 21:52:34 +07:00
),
2025-09-04 21:47:54 +07:00
// Arrow icon
if (method['hasArrow'] == true)
const Icon(
Icons.chevron_right,
color: AppColor.textLight,
size: 20,
),
],
),
),
),
);
}
Widget _buildFallbackIcon(Map<String, dynamic> method) {
String initial = method['name'][0].toUpperCase();
Color backgroundColor = method['iconColor'] ?? AppColor.primary;
return Container(
width: 40,
height: 40,
decoration: BoxDecoration(
color: backgroundColor.withOpacity(0.1),
borderRadius: BorderRadius.circular(8),
),
child: Center(
child: Text(
initial,
style: AppStyle.md.copyWith(
color: backgroundColor,
fontWeight: FontWeight.w700,
),
),
),
);
}
Widget _buildSectionHeader(String title) {
return Padding(
padding: const EdgeInsets.fromLTRB(20, 24, 20, 8),
child: Text(
title,
style: AppStyle.lg.copyWith(
fontWeight: FontWeight.w700,
color: AppColor.textPrimary,
2025-08-29 21:52:34 +07:00
),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
2025-09-04 21:47:54 +07:00
backgroundColor: const Color(0xFFFAFAFA),
2025-08-29 21:52:34 +07:00
appBar: AppBar(title: Text('Metode Pembayaran')),
2025-09-04 21:47:54 +07:00
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 16),
// Featured methods
...featuredMethods.map((method) => _buildFeaturedCard(method)),
2025-08-29 21:52:34 +07:00
2025-09-04 21:47:54 +07:00
const SizedBox(height: 16),
// Payment categories
...paymentCategories.map(
(category) => _buildCategoryCard(category),
2025-08-29 21:52:34 +07:00
),
2025-09-04 21:47:54 +07:00
// Section header for other methods
_buildSectionHeader('Metode Pembayaran Lainnya'),
// Other payment methods
Container(
decoration: const BoxDecoration(color: AppColor.white),
child: Column(
children: otherMethods
.map((method) => _buildPaymentMethodCard(method))
.toList(),
2025-08-29 21:52:34 +07:00
),
),
2025-09-04 21:47:54 +07:00
const SizedBox(height: 32),
],
),
2025-08-29 21:52:34 +07:00
),
);
}
}