Matthias Nott
9 days ago 1bf6e76e31383aef77e42943fc2caf350cf7e096
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../providers/providers.dart';
import '../services/purchase_service.dart';
import '../theme/app_theme.dart';
/// Dismissible banner shown at the top of the chat screen when a free-tier
/// limit has been reached.  Tapping "Upgrade" initiates the IAP flow.
class PaywallBanner extends ConsumerStatefulWidget {
  const PaywallBanner({super.key});
  @override
  ConsumerState<PaywallBanner> createState() => _PaywallBannerState();
}
class _PaywallBannerState extends ConsumerState<PaywallBanner> {
  bool _dismissed = false;
  @override
  Widget build(BuildContext context) {
    final isPro = ref.watch(isProProvider);
    if (isPro || _dismissed) return const SizedBox.shrink();
    final sessions = ref.watch(sessionsProvider);
    if (sessions.length <= kFreeTierMaxSessions) return const SizedBox.shrink();
    return Material(
      color: Colors.transparent,
      child: Container(
        margin: const EdgeInsets.fromLTRB(8, 4, 8, 0),
        decoration: BoxDecoration(
          color: AppColors.accent.withAlpha(230),
          borderRadius: BorderRadius.circular(10),
        ),
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
          child: Row(
            children: [
              const Icon(Icons.lock_outline, color: Colors.white, size: 18),
              const SizedBox(width: 8),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    const Text(
                      'PAILot Pro',
                      style: TextStyle(
                        color: Colors.white,
                        fontWeight: FontWeight.bold,
                        fontSize: 13,
                      ),
                    ),
                    const Text(
                      'Unlimited sessions & persistent messages',
                      style: TextStyle(color: Colors.white70, fontSize: 11),
                    ),
                  ],
                ),
              ),
              const SizedBox(width: 8),
              TextButton(
                onPressed: _handleRestore,
                style: TextButton.styleFrom(
                  foregroundColor: Colors.white70,
                  padding: const EdgeInsets.symmetric(horizontal: 8),
                  minimumSize: Size.zero,
                  tapTargetSize: MaterialTapTargetSize.shrinkWrap,
                ),
                child: const Text('Restore', style: TextStyle(fontSize: 11)),
              ),
              ElevatedButton(
                onPressed: _handleUpgrade,
                style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.white,
                  foregroundColor: AppColors.accent,
                  padding:
                      const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
                  minimumSize: Size.zero,
                  tapTargetSize: MaterialTapTargetSize.shrinkWrap,
                  textStyle: const TextStyle(
                    fontSize: 12,
                    fontWeight: FontWeight.bold,
                  ),
                ),
                child: const Text('Upgrade \$4.99'),
              ),
              const SizedBox(width: 4),
              GestureDetector(
                onTap: () => setState(() => _dismissed = true),
                child: const Icon(Icons.close, color: Colors.white70, size: 16),
              ),
            ],
          ),
        ),
      ),
    );
  }
  Future<void> _handleUpgrade() async {
    await PurchaseService.instance.purchaseFullAccess();
  }
  Future<void> _handleRestore() async {
    await PurchaseService.instance.restorePurchases();
    if (mounted) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text('Checking for previous purchases...'),
          duration: Duration(seconds: 2),
        ),
      );
    }
  }
}