LCOV - code coverage report
Current view: top level - lib/pages/subscription/widgets - purchase_widget.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 0 65 0.0 %
Date: 2024-09-15 16:50:22 Functions: 0 0 -

          Line data    Source code
       1             : // Copyright 2023 The terCAD team. All rights reserved.
       2             : // Use of this source code is governed by a CC BY-NC-ND 4.0 license that can be found in the LICENSE file.
       3             : 
       4             : import 'package:app_finance/_classes/controller/purchase_controller.dart';
       5             : import 'package:app_finance/_classes/herald/app_design.dart';
       6             : import 'package:app_finance/_classes/herald/app_locale.dart';
       7             : import 'package:app_finance/_configs/custom_text_theme.dart';
       8             : import 'package:app_finance/_configs/theme_helper.dart';
       9             : import 'package:app_finance/_ext/build_context_ext.dart';
      10             : import 'package:app_finance/design/generic/loading_widget.dart';
      11             : import 'package:app_finance/design/generic/notification_bar.dart';
      12             : import 'package:app_finance/design/wrapper/row_widget.dart';
      13             : import 'package:app_finance/design/wrapper/text_wrapper.dart';
      14             : import 'package:flutter/material.dart';
      15             : import 'package:flutter_currency_picker/flutter_currency_picker.dart';
      16             : import 'package:flutter_grid_layout/flutter_grid_layout.dart';
      17             : import 'package:in_app_purchase/in_app_purchase.dart';
      18             : 
      19             : class PurchaseWidget extends StatefulWidget {
      20             :   final String path;
      21             :   final ProductDetails? product;
      22             :   final List<PurchaseDetails>? purchase;
      23             :   final double size;
      24             :   final String title;
      25             : 
      26           0 :   const PurchaseWidget(this.path, {super.key, required this.title, this.product, this.purchase, this.size = 150});
      27             : 
      28           0 :   @override
      29           0 :   PurchaseWidgetState createState() => PurchaseWidgetState();
      30             : }
      31             : 
      32             : class PurchaseWidgetState extends State<PurchaseWidget> {
      33             :   bool isLoading = false;
      34             : 
      35           0 :   Future<void> _purchase() async {
      36           0 :     if (widget.product == null) {
      37           0 :       NotificationBar.showSnackBar(context, AppLocale.labels.subscriptionInactive, true);
      38             :     } else {
      39           0 :       setState(() => isLoading = true);
      40           0 :       await PurchaseController.buy(widget.product!);
      41           0 :       setState(() => isLoading = false);
      42             :     }
      43             :   }
      44             : 
      45           0 :   @override
      46             :   Widget build(BuildContext context) {
      47           0 :     final indent = ThemeHelper.getIndent(0.5);
      48           0 :     final cost = widget.product?.rawPrice.toCurrency(code: widget.product?.currencyCode, withPattern: false) ?? '---';
      49           0 :     final costWidth = ThemeHelper.getTextWidth(Text(cost));
      50           0 :     return InkWell(
      51           0 :       onTap: _purchase,
      52           0 :       child: Container(
      53           0 :         width: widget.size,
      54           0 :         height: widget.size,
      55           0 :         margin: EdgeInsets.all(indent),
      56           0 :         decoration: BoxDecoration(
      57           0 :           color: context.colorScheme.surface,
      58           0 :           borderRadius: BorderRadius.circular(3),
      59           0 :           boxShadow: [
      60           0 :             BoxShadow(
      61           0 :               color: context.colorScheme.secondary.withOpacity(0.1),
      62           0 :               spreadRadius: indent / 2,
      63             :               blurRadius: indent,
      64           0 :               offset: Offset(0, indent / 2),
      65             :             ),
      66             :           ],
      67             :         ),
      68           0 :         child: isLoading
      69           0 :             ? LoadingWidget(isLoading: isLoading, size: Size(widget.size, widget.size))
      70           0 :             : GridContainer(
      71           0 :                 alignment: AppDesign.getAlignment<MainAxisAlignment>(),
      72             :                 rows: const [40, null, 40],
      73             :                 columns: const [40, null, 34],
      74           0 :                 children: [
      75           0 :                   GridItem(
      76             :                     start: const Size(0, 0),
      77             :                     end: const Size(4, 4),
      78           0 :                     child: SizedBox(
      79           0 :                       child: ClipPath(
      80           0 :                         clipper: _TopRightClipper(),
      81           0 :                         child: Image.asset(widget.path),
      82             :                       ),
      83             :                     ),
      84             :                   ),
      85           0 :                   GridItem(
      86             :                     start: const Size(2, 0),
      87             :                     end: const Size(3, 1),
      88           0 :                     child: Icon(
      89           0 :                       switch (widget.purchase?.last.status) {
      90           0 :                         PurchaseStatus.purchased => Icons.check,
      91           0 :                         PurchaseStatus.pending => Icons.pending,
      92             :                         _ => Icons.add
      93             :                       },
      94           0 :                       color: context.colorScheme.secondary.withOpacity(0.3),
      95             :                     ),
      96             :                   ),
      97           0 :                   GridItem(
      98             :                     start: const Size(0, 2),
      99             :                     end: const Size(3, 3),
     100             :                     order: 2,
     101           0 :                     child: Container(
     102           0 :                         color: context.colorScheme.surface.withOpacity(0.9),
     103           0 :                         padding: EdgeInsets.all(indent),
     104           0 :                         child: RowWidget(
     105           0 :                           chunk: [null, costWidth],
     106             :                           indent: indent,
     107             :                           alignment: MainAxisAlignment.spaceBetween,
     108           0 :                           maxWidth: widget.size - indent * 2,
     109           0 :                           children: [
     110           0 :                             [
     111           0 :                               Align(
     112             :                                   alignment: Alignment.centerLeft,
     113           0 :                                   child: TextWrapper(widget.title, maxLines: 2, style: context.textTheme.bodySmall)),
     114             :                             ],
     115           0 :                             [
     116           0 :                               Align(
     117             :                                 alignment: Alignment.centerRight,
     118           0 :                                 child: TextWrapper(cost, style: context.textTheme.numberMedium),
     119             :                               ),
     120             :                             ],
     121             :                           ],
     122             :                         )),
     123             :                   ),
     124             :                 ],
     125             :               ),
     126             :       ),
     127             :     );
     128             :   }
     129             : }
     130             : 
     131             : class _TopRightClipper extends CustomClipper<Path> {
     132           0 :   @override
     133             :   Path getClip(Size size) {
     134           0 :     final path = Path()
     135           0 :       ..moveTo(size.width / 3, 0)
     136           0 :       ..quadraticBezierTo(size.width * 3 / 4, 0, size.width, size.height / 2.5)
     137           0 :       ..lineTo(size.width, size.height)
     138           0 :       ..lineTo(0, size.height)
     139           0 :       ..lineTo(0, 0);
     140             : 
     141             :     return path;
     142             :   }
     143             : 
     144           0 :   @override
     145             :   bool shouldReclip(CustomClipper<Path> oldClipper) => false;
     146             : }

Generated by: LCOV version 1.14