diff --git a/lib/presentation/report/widgets/inventory_report_widget.dart b/lib/presentation/report/widgets/inventory_report_widget.dart index a96ada1..561ed8c 100644 --- a/lib/presentation/report/widgets/inventory_report_widget.dart +++ b/lib/presentation/report/widgets/inventory_report_widget.dart @@ -28,228 +28,222 @@ class _InventoryReportWidgetState extends State { @override Widget build(BuildContext context) { - return Expanded( - flex: 4, - child: Container( - width: double.infinity, - decoration: BoxDecoration( - color: AppColors.white, - border: Border.all(color: AppColors.stroke, width: 1), - ), - child: SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // Report Header - Container( - width: double.infinity, - padding: const EdgeInsets.all(20), - decoration: BoxDecoration( - color: AppColors.light, - border: Border( - bottom: BorderSide(color: AppColors.stroke, width: 1), - ), + return Container( + width: double.infinity, + decoration: BoxDecoration( + color: AppColors.white, + border: Border.all(color: AppColors.stroke, width: 1), + ), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Report Header + Container( + width: double.infinity, + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: AppColors.light, + border: Border( + bottom: BorderSide(color: AppColors.stroke, width: 1), ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - widget.title, - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - color: AppColors.primary, - ), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + widget.title, + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: AppColors.primary, ), - const SizedBox(height: 4), - Text( - widget.searchDateFormatted, - style: TextStyle( - fontSize: 12, - color: AppColors.greyDark, - ), + ), + const SizedBox(height: 4), + Text( + widget.searchDateFormatted, + style: TextStyle( + fontSize: 12, + color: AppColors.greyDark, ), - ], - ), - Row( - children: [ - // Download Button - GestureDetector( - onTap: () async { - try { - final status = - await PermessionHelper().checkPermission(); - if (status) { - final pdfFile = - await InventoryReport.previewPdf( - searchDateFormatted: - widget.searchDateFormatted, - inventory: widget.inventory, - ); - log("pdfFile: $pdfFile"); - await HelperPdfService.openFile(pdfFile); - } else { - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text( - 'Storage permission is required to save PDF'), - backgroundColor: Colors.red, - ), - ); - } - } catch (e) { - log("Error generating PDF: $e"); + ), + ], + ), + Row( + children: [ + // Download Button + GestureDetector( + onTap: () async { + try { + final status = + await PermessionHelper().checkPermission(); + if (status) { + final pdfFile = await InventoryReport.previewPdf( + searchDateFormatted: widget.searchDateFormatted, + inventory: widget.inventory, + ); + log("pdfFile: $pdfFile"); + await HelperPdfService.openFile(pdfFile); + } else { ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text('Failed to generate PDF: $e'), + const SnackBar( + content: Text( + 'Storage permission is required to save PDF'), backgroundColor: Colors.red, ), ); } - }, - child: Container( - padding: const EdgeInsets.all(10), - decoration: BoxDecoration( - color: AppColors.primary.withOpacity(0.1), - borderRadius: BorderRadius.circular(8), - border: Border.all( - color: AppColors.primary, width: 1), - ), - child: Icon( - Icons.download_outlined, - size: 18, - color: AppColors.primary, - ), - ), - ), - const SizedBox(width: 12), - // Status Badge - Container( - padding: const EdgeInsets.symmetric( - horizontal: 12, - vertical: 6, - ), + } catch (e) { + log("Error generating PDF: $e"); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Failed to generate PDF: $e'), + backgroundColor: Colors.red, + ), + ); + } + }, + child: Container( + padding: const EdgeInsets.all(10), decoration: BoxDecoration( - color: AppColors.green.withOpacity(0.1), - borderRadius: BorderRadius.circular(20), + color: AppColors.primary.withOpacity(0.1), + borderRadius: BorderRadius.circular(8), border: - Border.all(color: AppColors.green, width: 1), + Border.all(color: AppColors.primary, width: 1), ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Icon( - Icons.check_circle, - size: 14, + child: Icon( + Icons.download_outlined, + size: 18, + color: AppColors.primary, + ), + ), + ), + const SizedBox(width: 12), + // Status Badge + Container( + padding: const EdgeInsets.symmetric( + horizontal: 12, + vertical: 6, + ), + decoration: BoxDecoration( + color: AppColors.green.withOpacity(0.1), + borderRadius: BorderRadius.circular(20), + border: Border.all(color: AppColors.green, width: 1), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Icon( + Icons.check_circle, + size: 14, + color: AppColors.green, + ), + const SizedBox(width: 6), + Text( + 'Aktif', + style: TextStyle( + fontSize: 12, color: AppColors.green, + fontWeight: FontWeight.w600, ), - const SizedBox(width: 6), - Text( - 'Aktif', - style: TextStyle( - fontSize: 12, - color: AppColors.green, - fontWeight: FontWeight.w600, - ), - ), - ], - ), + ), + ], ), - ], - ), - ], - ), + ), + ], + ), + ], ), + ), - // Summary Section - Padding( - padding: const EdgeInsets.all(20), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Icon( - Icons.analytics_outlined, - size: 20, - color: AppColors.primary, + // Summary Section + Padding( + padding: const EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon( + Icons.analytics_outlined, + size: 20, + color: AppColors.primary, + ), + const SizedBox(width: 8), + Text( + 'Ringkasan Inventori', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: AppColors.black, ), - const SizedBox(width: 8), - Text( - 'Ringkasan Inventori', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - color: AppColors.black, - ), - ), - ], - ), - const SizedBox(height: 16), + ), + ], + ), + const SizedBox(height: 16), - // Summary Grid - GridView.count( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - crossAxisCount: 3, - childAspectRatio: 2.2, - mainAxisSpacing: 12, - crossAxisSpacing: 12, - children: [ - _buildSummaryCard( - 'Total Produk', - (widget.inventory.summary.totalProducts).toString(), - AppColors.primary, - Icons.inventory_2_outlined, - ), - _buildSummaryCard( - 'Total Bahan', - widget.inventory.summary.totalIngredients.toString(), - AppColors.subtitle, - Icons.list_alt_outlined, - ), - _buildSummaryCard( - 'Total Nilai', - widget.inventory.summary.totalValue - .toString() - .currencyFormatRpV2, - AppColors.green, - Icons.monetization_on_outlined, - ), - ], - ), - ], - ), + // Summary Grid + GridView.count( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + crossAxisCount: 3, + childAspectRatio: 2.2, + mainAxisSpacing: 12, + crossAxisSpacing: 12, + children: [ + _buildSummaryCard( + 'Total Produk', + (widget.inventory.summary.totalProducts).toString(), + AppColors.primary, + Icons.inventory_2_outlined, + ), + _buildSummaryCard( + 'Total Bahan', + widget.inventory.summary.totalIngredients.toString(), + AppColors.subtitle, + Icons.list_alt_outlined, + ), + _buildSummaryCard( + 'Total Nilai', + widget.inventory.summary.totalValue + .toString() + .currencyFormatRpV2, + AppColors.green, + Icons.monetization_on_outlined, + ), + ], + ), + ], ), + ), - // Divider - Container( - height: 1, - margin: const EdgeInsets.symmetric(horizontal: 20), - color: AppColors.stroke, + // Divider + Container( + height: 1, + margin: const EdgeInsets.symmetric(horizontal: 20), + color: AppColors.stroke, + ), + + // Tabs + Container( + padding: const EdgeInsets.all(20), + child: Row( + children: [ + _buildTab('Produk', 0), + const SizedBox(width: 12), + _buildTab('Bahan Baku', 1), + ], ), + ), - // Tabs - Container( - padding: const EdgeInsets.all(20), - child: Row( - children: [ - _buildTab('Produk', 0), - const SizedBox(width: 12), - _buildTab('Bahan Baku', 1), - ], - ), - ), - - // Content based on selected tab - _selectedTabIndex == 0 - ? _buildProductsContent() - : _buildIngredientsContent(), - ], - ), + // Content based on selected tab + _selectedTabIndex == 0 + ? _buildProductsContent() + : _buildIngredientsContent(), + ], ), ), );