payment_confirmation_bottom_sheet.dart 6.35 KB
import 'package:doublefeel_flutter/core/theme/app_theme.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

/// A payment method displayed in [PaymentConfirmationBottomSheet].
class PaymentMethod {
  const PaymentMethod({
    required this.name,
    required this.iconAsset,
  });

  final String name;
  final String iconAsset;
}

/// Opens the shared payment confirmation bottom sheet.
void showPaymentConfirmationBottomSheet({
  required String amount,
  required String productName,
  required PaymentMethod paymentMethod,
  required VoidCallback onPay,
}) {
  Get.bottomSheet<void>(
    PaymentConfirmationBottomSheet(
      amount: amount,
      productName: productName,
      paymentMethod: paymentMethod,
      onPay: onPay,
    ),
    barrierColor: Colors.black.withValues(alpha: 0.72),
    isScrollControlled: true,
    enableDrag: false,
  );
}

/// Shared confirmation sheet for a single, preselected payment method.
class PaymentConfirmationBottomSheet extends StatelessWidget {
  const PaymentConfirmationBottomSheet({
    super.key,
    required this.amount,
    required this.productName,
    required this.paymentMethod,
    required this.onPay,
  });

  final String amount;
  final String productName;
  final PaymentMethod paymentMethod;
  final VoidCallback onPay;

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: const BoxDecoration(
        color: Color(0xFFF6F3FF),
        borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
      ),
      child: SafeArea(
        top: false,
        child: Padding(
          padding: const EdgeInsets.fromLTRB(16, 14, 16, 18),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              SizedBox(
                height: 30,
                width: double.infinity,
                child: Stack(
                  alignment: Alignment.center,
                  children: [
                    const Text(
                      '待支付',
                      style: TextStyle(
                        color: Color(0xFF0F0F11),
                        fontSize: 16,
                        fontWeight: FontWeight.w600,
                      ),
                    ),
                    Positioned(
                      left: 0,
                      child: IconButton(
                        onPressed: Get.back,
                        icon: const Icon(Icons.close_rounded),
                        color: const Color(0xFF8961F8),
                        iconSize: 22,
                        splashRadius: 20,
                      ),
                    ),
                  ],
                ),
              ),
              const SizedBox(height: 18),
              Text(
                amount,
                style: const TextStyle(
                  color: Colors.black,
                  fontSize: 40,
                  fontWeight: FontWeight.w700,
                  height: 1,
                ),
              ),
              const SizedBox(height: 12),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Container(
                    width: 16,
                    height: 16,
                    clipBehavior: Clip.antiAlias,
                    padding: EdgeInsets.all(1),
                    decoration: ShapeDecoration(
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(20),
                        ),
                        color: context.colors.primary),
                    child: Image.asset('assets/images/common/ic_pro.png'),
                  ),
                  const SizedBox(width: 2),
                  Text(
                    productName,
                    style: const TextStyle(
                      color: Color(0xFF78787D),
                      fontSize: 14,
                    ),
                  ),
                ],
              ),
              const SizedBox(height: 22),
              const Divider(height: 1, color: Color(0xFFE3DEEF)),
              const Padding(
                padding: EdgeInsets.only(top: 22, bottom: 14),
                child: Align(
                  alignment: Alignment.centerLeft,
                  child: Text(
                    '支付方式',
                    style: TextStyle(
                      color: Color(0xFF0F0F11),
                      fontSize: 15,
                      fontWeight: FontWeight.w600,
                    ),
                  ),
                ),
              ),
              _PaymentMethodTile(paymentMethod: paymentMethod),
              const SizedBox(height: 20),
              SizedBox(
                width: 280,
                height: 48,
                child: ElevatedButton(
                  onPressed: () {
                    Get.back();
                    onPay();
                  },
                  style: ElevatedButton.styleFrom(
                    elevation: 0,
                    backgroundColor: const Color(0xFF8961F8),
                    foregroundColor: Colors.white,
                    shape: const StadiumBorder(),
                    textStyle: const TextStyle(
                      fontSize: 16,
                      fontWeight: FontWeight.w600,
                    ),
                  ),
                  child: const Text('立即支付'),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class _PaymentMethodTile extends StatelessWidget {
  const _PaymentMethodTile({required this.paymentMethod});

  final PaymentMethod paymentMethod;

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 56,
      padding: const EdgeInsets.symmetric(horizontal: 16),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(16),
        border: Border.all(color: const Color(0xFF845EEE)),
      ),
      child: Row(
        children: [
          Image.asset(paymentMethod.iconAsset, width: 28, height: 28),
          const SizedBox(width: 10),
          Text(
            paymentMethod.name,
            style: const TextStyle(
              color: Color(0xFF0F0F11),
              fontSize: 15,
            ),
          ),
          const Spacer(),
          const Icon(Icons.check_circle_rounded,
              color: Color(0xFF8961F8), size: 22),
        ],
      ),
    );
  }
}