346 lines
9.9 KiB
Dart
346 lines
9.9 KiB
Dart
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> {
|
|
// Featured payment methods
|
|
final List<Map<String, dynamic>> featuredMethods = [
|
|
{
|
|
'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',
|
|
'name': 'Kartu Kredit',
|
|
'subtitle':
|
|
'Minimal pembayaran Rp 10.000 dan mendukung Kartu Berlogo Visa, Mastercard dan JCB',
|
|
'icon': Icons.credit_card,
|
|
'iconColor': const Color(0xFF2E7D32),
|
|
'hasArrow': false,
|
|
},
|
|
];
|
|
|
|
// Other payment methods
|
|
final List<Map<String, dynamic>> otherMethods = [
|
|
{
|
|
'id': 'gopay',
|
|
'name': 'Gopay',
|
|
'subtitle': 'Aktifkan Sekarang',
|
|
'logo': 'assets/images/gopay.png',
|
|
'iconColor': const Color(0xFF00AA5B),
|
|
'hasArrow': true,
|
|
},
|
|
{
|
|
'id': 'dana',
|
|
'name': 'Dana',
|
|
'subtitle': 'Aktifkan Sekarang',
|
|
'logo': 'assets/images/dana.png',
|
|
'iconColor': const Color(0xFF118EEA),
|
|
'hasArrow': true,
|
|
},
|
|
{
|
|
'id': 'blu',
|
|
'name': 'blu',
|
|
'subtitle': 'Aktifkan Sekarang',
|
|
'logo': 'assets/images/blu.png',
|
|
'iconColor': const Color(0xFF00D4FF),
|
|
'hasArrow': true,
|
|
},
|
|
{
|
|
'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,
|
|
},
|
|
];
|
|
|
|
Widget _buildFeaturedCard(Map<String, dynamic> method) {
|
|
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: 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)
|
|
Container(
|
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
|
|
decoration: BoxDecoration(
|
|
color: method['badgeColor'],
|
|
borderRadius: BorderRadius.circular(12),
|
|
),
|
|
child: Text(
|
|
method['badge'],
|
|
style: AppStyle.sm.copyWith(
|
|
color: AppColor.white,
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
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);
|
|
},
|
|
),
|
|
)
|
|
: _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,
|
|
),
|
|
),
|
|
if (method['subtitle'] != null) ...[
|
|
const SizedBox(height: 2),
|
|
Text(
|
|
method['subtitle'],
|
|
style: AppStyle.md.copyWith(color: AppColor.textLight),
|
|
),
|
|
],
|
|
],
|
|
),
|
|
),
|
|
// 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,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
backgroundColor: const Color(0xFFFAFAFA),
|
|
appBar: AppBar(title: Text('Metode Pembayaran')),
|
|
body: SingleChildScrollView(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
const SizedBox(height: 16),
|
|
// Featured methods
|
|
...featuredMethods.map((method) => _buildFeaturedCard(method)),
|
|
|
|
const SizedBox(height: 16),
|
|
|
|
// Payment categories
|
|
...paymentCategories.map(
|
|
(category) => _buildCategoryCard(category),
|
|
),
|
|
|
|
// 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(),
|
|
),
|
|
),
|
|
|
|
const SizedBox(height: 32),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|