purchase_plan_card.dart 6.7 KB
import 'package:flutter/material.dart';

import '../controllers/purchase_controller.dart';
import 'purchase_colors.dart';

class PurchasePlanCard extends StatelessWidget {
  const PurchasePlanCard({
    super.key,
    required this.plan,
    required this.selected,
    required this.onTap,
  });

  final PurchasePlan plan;
  final bool selected;
  final VoidCallback onTap;

  @override
  Widget build(BuildContext context) {
    return Semantics(
      selected: selected,
      button: true,
      child: GestureDetector(
        onTap: onTap,
        behavior: HitTestBehavior.opaque,
        child: AnimatedScale(
          scale: selected ? 1 : 0.985,
          duration: const Duration(milliseconds: 180),
          curve: Curves.easeOutCubic,
          child: SizedBox(
            width: 220,
            height: 123,
            child: Stack(
              clipBehavior: Clip.none,
              children: [
                Positioned(
                  left: 0,
                  right: 0,
                  bottom: 0,
                  child: AnimatedContainer(
                    duration: const Duration(milliseconds: 180),
                    curve: Curves.easeOutCubic,
                    height: 115,
                    padding: const EdgeInsets.fromLTRB(17, 16, 17, 12),
                    decoration: BoxDecoration(
                      color:
                          selected ? PurchaseColors.selectedCard : Colors.white,
                      borderRadius: BorderRadius.circular(16),
                      border: Border.all(
                        color: selected
                            ? PurchaseColors.proPurple
                            : Colors.transparent,
                        width: 2,
                      ),
                    ),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Row(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            Expanded(
                              child: Text(
                                plan.title,
                                maxLines: 1,
                                overflow: TextOverflow.ellipsis,
                                style: const TextStyle(
                                  color: PurchaseColors.title,
                                  fontSize: 16,
                                  fontWeight: FontWeight.w600,
                                  height: 1.2,
                                ),
                              ),
                            ),
                            _SelectionDot(selected: selected),
                          ],
                        ),
                        if (plan.subtitle.isNotEmpty) ...[
                          const SizedBox(height: 3),
                          Text(
                            plan.subtitle,
                            maxLines: 1,
                            overflow: TextOverflow.ellipsis,
                            style: const TextStyle(
                              color: PurchaseColors.subtitle,
                              fontSize: 12,
                              height: 1.2,
                            ),
                          ),
                        ],
                        const Spacer(),
                        Row(
                          crossAxisAlignment: CrossAxisAlignment.end,
                          children: [
                            Expanded(
                              child: plan.price.isEmpty
                                  ? const Align(
                                      alignment: Alignment.centerLeft,
                                      child: SizedBox(
                                        width: 18,
                                        height: 18,
                                        child: CircularProgressIndicator(
                                          strokeWidth: 2,
                                        ),
                                      ),
                                    )
                                  : Text(
                                      plan.price,
                                      maxLines: 1,
                                      overflow: TextOverflow.ellipsis,
                                      style: const TextStyle(
                                        color: PurchaseColors.title,
                                        fontSize: 24,
                                        fontWeight: FontWeight.w700,
                                        height: 1,
                                      ),
                                    ),
                            ),
                          ],
                        ),
                      ],
                    ),
                  ),
                ),
                if (plan.badge.isNotEmpty)
                  Positioned(
                    left: 16,
                    top: 0,
                    child: Container(
                      height: 20,
                      padding: const EdgeInsets.symmetric(horizontal: 6),
                      alignment: Alignment.center,
                      decoration: BoxDecoration(
                        color: PurchaseColors.proYellow,
                        borderRadius: BorderRadius.circular(8),
                      ),
                      child: Text(
                        plan.badge,
                        style: const TextStyle(
                          color: PurchaseColors.title,
                          fontSize: 12,
                          fontWeight: FontWeight.w500,
                          height: 1,
                        ),
                      ),
                    ),
                  ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

class _SelectionDot extends StatelessWidget {
  const _SelectionDot({required this.selected});

  final bool selected;

  @override
  Widget build(BuildContext context) {
    return AnimatedContainer(
      duration: const Duration(milliseconds: 180),
      curve: Curves.easeOutCubic,
      width: 18,
      height: 18,
      decoration: BoxDecoration(
        color: selected ? PurchaseColors.proPurple : Colors.transparent,
        shape: BoxShape.circle,
        border: selected ? null : Border.all(color: const Color(0xFFE2E0EA)),
      ),
      child: AnimatedSwitcher(
        duration: const Duration(milliseconds: 120),
        child: selected
            ? const Icon(
                Icons.check,
                key: ValueKey('selected'),
                size: 13,
                color: Colors.white,
              )
            : const SizedBox(key: ValueKey('unselected')),
      ),
    );
  }
}