Created
November 27, 2024 06:11
-
-
Save dev-vickie/1636fd2773a698c81836baa7ab086b02 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import 'package:collection/collection.dart'; | |
| import 'package:flutter/material.dart'; | |
| import 'package:flutter_riverpod/flutter_riverpod.dart'; | |
| import 'package:kingpin/logic/odds_controller.dart'; | |
| import 'package:kingpin/models/new_odd_model.dart'; | |
| import 'package:purchases_flutter/purchases_flutter.dart'; | |
| import '../../logic/payments.dart'; | |
| import '../../widgets/odd_item.dart'; | |
| class VipPage extends ConsumerStatefulWidget { | |
| final String type; | |
| final String sectionId; | |
| final String itemName; | |
| final String weeklyPrice; | |
| final String monthlyPrice; | |
| const VipPage({ | |
| super.key, | |
| required this.type, | |
| required this.sectionId, | |
| required this.itemName, | |
| required this.weeklyPrice, | |
| required this.monthlyPrice, | |
| }); | |
| @override | |
| ConsumerState<VipPage> createState() => _VipPageState(); | |
| } | |
| class _VipPageState extends ConsumerState<VipPage> { | |
| Offering? offering; | |
| @override | |
| initState() { | |
| super.initState(); | |
| fetchOfferings(); | |
| } | |
| Future<void> fetchOfferings() async { | |
| final fetchedOffering = await PurchaseApi.getOffers(widget.sectionId); | |
| setState(() { | |
| offering = fetchedOffering; | |
| }); | |
| } | |
| @override | |
| Widget build(BuildContext context) { | |
| final revenueCatProvider = ref.watch(revenuecatProvider); | |
| final sectionDetails = allSections | |
| .firstWhere((section) => section.sectionId == widget.sectionId); | |
| final entitlement = | |
| revenueCatProvider.sectionEntitlements[widget.sectionId] ?? | |
| sectionDetails.defaultEntitlement; | |
| if (offering == null) { | |
| return Container( | |
| decoration: const BoxDecoration( | |
| gradient: LinearGradient( | |
| colors: [ | |
| Color.fromARGB(255, 44, 109, 7), | |
| Color.fromARGB(255, 11, 31, 9), | |
| ], | |
| begin: Alignment.centerLeft, | |
| end: Alignment.centerRight, | |
| ), | |
| ), | |
| child: Scaffold( | |
| appBar: AppBar( | |
| title: Text(widget.itemName), | |
| centerTitle: true, | |
| backgroundColor: Colors.transparent, | |
| ), | |
| body: Container( | |
| decoration: const BoxDecoration( | |
| image: DecorationImage( | |
| image: AssetImage( | |
| "assets/images/background.jpeg", | |
| ), | |
| fit: BoxFit.cover, | |
| ), | |
| ), | |
| child: const Center( | |
| child: CircularProgressIndicator(), | |
| ), | |
| ), | |
| ), | |
| ); | |
| } | |
| return Container( | |
| decoration: const BoxDecoration( | |
| gradient: LinearGradient( | |
| colors: [ | |
| Color.fromARGB(255, 44, 109, 7), | |
| Color.fromARGB(255, 11, 31, 9), | |
| ], | |
| begin: Alignment.centerLeft, | |
| end: Alignment.centerRight, | |
| ), | |
| ), | |
| child: Scaffold( | |
| backgroundColor: Colors.transparent, | |
| appBar: AppBar( | |
| title: Text(widget.itemName), | |
| centerTitle: true, | |
| backgroundColor: Colors.transparent, | |
| ), | |
| body: Container( | |
| decoration: const BoxDecoration( | |
| image: DecorationImage( | |
| image: AssetImage( | |
| "assets/images/background.jpeg", | |
| ), | |
| fit: BoxFit.cover, | |
| ), | |
| ), | |
| child: buildSubscription(entitlement), | |
| ), | |
| ), | |
| ); | |
| } | |
| Widget buildSubscription(Entitlement entitlement) { | |
| switch (entitlement) { | |
| case Entitlement.vip_tips: | |
| return buildPaywall(); | |
| case Entitlement.free: | |
| return Column( | |
| children: [ | |
| ref.watch(vipOddsProvider(widget.type)).when( | |
| data: (odds) { | |
| final groupedOdds = | |
| groupBy(odds, (OddModel odd) => odd.uploadTime); | |
| return Expanded( | |
| child: ListView( | |
| children: groupedOdds.entries | |
| .map( | |
| (entry) => Container( | |
| color: const Color.fromARGB(0, 0, 0, 0), | |
| margin: const EdgeInsets.symmetric(vertical: 0), | |
| child: Column( | |
| children: [ | |
| Container( | |
| width: double.infinity, | |
| color: | |
| const Color.fromARGB(255, 10, 61, 14), | |
| padding: const EdgeInsets.all(10), | |
| child: Text( | |
| entry.key, | |
| style: const TextStyle( | |
| color: Colors.white, | |
| fontSize: 20, | |
| fontWeight: FontWeight.bold, | |
| ), | |
| ), | |
| ), | |
| ...entry.value | |
| .map((odd) => OddItem(odd: odd)), | |
| ListTile( | |
| title: Text( | |
| "Total Odds: ${entry.value.map((e) => double.parse(e.odds)).reduce((a, b) => a * b).toStringAsFixed(2)}", | |
| style: const TextStyle( | |
| color: Colors.white, | |
| fontSize: 20, | |
| fontWeight: FontWeight.bold, | |
| ), | |
| ), | |
| ), | |
| ], | |
| ), | |
| ), | |
| ) | |
| .toList(), | |
| ), | |
| ); | |
| }, | |
| error: (e, s) => Center( | |
| child: Text("Error: $e"), | |
| ), | |
| loading: () => const Center( | |
| child: CircularProgressIndicator(), | |
| ), | |
| ), | |
| ], | |
| ); | |
| } | |
| } | |
| Future fetchandPurchaseOffering( | |
| BuildContext context, | |
| int index, | |
| ) async { | |
| final messenger = ScaffoldMessenger.of(context); | |
| final offering = await PurchaseApi.getOffers(widget.sectionId); | |
| if (offering == null) { | |
| messenger.showSnackBar( | |
| const SnackBar( | |
| content: Text('No offerings available'), | |
| ), | |
| ); | |
| } else { | |
| final requiredPackage = offering.availablePackages[index]; | |
| await PurchaseApi.purchasePackage(requiredPackage); | |
| setState(() {}); | |
| } | |
| } | |
| Widget buildPaywall() { | |
| return Scaffold( | |
| backgroundColor: Colors.transparent, | |
| body: Padding( | |
| padding: | |
| EdgeInsets.only(bottom: MediaQuery.of(context).size.height * 0.1), | |
| child: SizedBox( | |
| height: MediaQuery.of(context).size.height, | |
| child: Padding( | |
| padding: const EdgeInsets.all(12), | |
| child: Column( | |
| mainAxisAlignment: MainAxisAlignment.center, | |
| children: [ | |
| const Text("Join our VIP"), | |
| const SizedBox(height: 10), | |
| GestureDetector( | |
| onTap: () => fetchandPurchaseOffering(context, 0), | |
| child: Padding( | |
| padding: const EdgeInsets.symmetric(vertical: 3), | |
| child: Container( | |
| width: MediaQuery.of(context).size.width, | |
| height: 110, | |
| padding: const EdgeInsets.all(4), | |
| decoration: BoxDecoration( | |
| borderRadius: BorderRadius.circular(10), | |
| color: const Color.fromARGB(255, 6, 10, 2) | |
| .withOpacity(0.7), | |
| border: Border.all( | |
| color: Colors.lightGreenAccent.shade700, | |
| width: 2, | |
| ), | |
| ), | |
| child: Center( | |
| child: Row( | |
| mainAxisAlignment: MainAxisAlignment.spaceEvenly, | |
| children: [ | |
| const Expanded( | |
| child: Text( | |
| "Weekly VIP", | |
| style: TextStyle( | |
| color: Colors.white, | |
| fontSize: 25, | |
| fontWeight: FontWeight.bold, | |
| ), | |
| ), | |
| ), | |
| Padding( | |
| padding: const EdgeInsets.only(left: 5, right: 5), | |
| child: Row( | |
| children: [ | |
| Text( | |
| '${offering!.availablePackages[0].storeProduct.priceString}', | |
| style: const TextStyle( | |
| color: Colors.white, | |
| fontSize: 30, | |
| fontWeight: FontWeight.bold, | |
| ), | |
| ), | |
| ], | |
| ), | |
| ), | |
| ], | |
| ), | |
| ), | |
| ), | |
| ), | |
| ), | |
| Padding( | |
| padding: const EdgeInsets.symmetric(vertical: 3), | |
| child: GestureDetector( | |
| onTap: () => fetchandPurchaseOffering(context, 1), | |
| child: Container( | |
| width: MediaQuery.of(context).size.width, | |
| height: 110, | |
| padding: const EdgeInsets.all(2), | |
| decoration: BoxDecoration( | |
| borderRadius: BorderRadius.circular(10), | |
| color: const Color.fromARGB(255, 6, 10, 2) | |
| .withOpacity(0.7), | |
| border: Border.all( | |
| color: Colors.lightGreenAccent.shade700, | |
| width: 2, | |
| ), | |
| ), | |
| child: Center( | |
| child: Row( | |
| mainAxisAlignment: MainAxisAlignment.spaceEvenly, | |
| children: [ | |
| const Expanded( | |
| child: Text( | |
| "Monthly VIP", | |
| style: TextStyle( | |
| color: Colors.white, | |
| fontSize: 25, | |
| fontWeight: FontWeight.bold, | |
| ), | |
| ), | |
| ), | |
| Padding( | |
| padding: const EdgeInsets.only(left: 5, right: 5), | |
| child: Row( | |
| children: [ | |
| Text( | |
| '${offering!.availablePackages[1].storeProduct.priceString}', | |
| style: const TextStyle( | |
| color: Colors.white, | |
| fontSize: 30, | |
| fontWeight: FontWeight.bold, | |
| ), | |
| ), | |
| ], | |
| ), | |
| ), | |
| ], | |
| ), | |
| ), | |
| ), | |
| ), | |
| ), | |
| const Text( | |
| "Your subscription will be autorenewed when it ends. To change this please visit your Google Play Payment Profile.For more info or you're having problems,contact us by e-mail :\[email protected]", | |
| ) | |
| ], | |
| ), | |
| ), | |
| ), | |
| ), | |
| ); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment