import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:gen_rentals/Screens/HelpScreens/EnquiryScreen.dart'; import 'package:gen_rentals/Screens/HelpScreens/HelpScreen.dart'; import 'package:gen_rentals/Screens/ProductsDetailScreen.dart'; import 'package:gen_rentals/Screens/TransactionsScreen.dart'; import 'package:provider/provider.dart'; import '../Models/DashboardResponse.dart'; import '../Notifier/DashboardProvider.dart'; import 'authScreen/LoginScreen.dart'; class DashboardScreen extends StatefulWidget { final String accId; const DashboardScreen({super.key, required this.accId}); @override State createState() => _DashboardScreenState(); } class _DashboardScreenState extends State { @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { // Only fetch dashboard if accId is valid if (widget.accId.isNotEmpty && widget.accId != "null") { Provider.of(context, listen: false).fetchDashboard(accId: widget.accId); } else { // If accId is invalid, navigate back to login WidgetsBinding.instance.addPostFrameCallback((_) { Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => LoginScreen()), ); }); } }); } @override Widget build(BuildContext context) { final dashboardProvider = Provider.of(context); final dashboardData = dashboardProvider.dashboardData; double screenWidth = MediaQuery.of(context).size.width; double screenHeight = MediaQuery.of(context).size.height; double bottomPadding = MediaQuery.of(context).padding.bottom; // Add null check at the beginning if (dashboardProvider.isLoading && dashboardData == null) { return Scaffold( body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ CircularProgressIndicator(), SizedBox(height: 20), Text("Loading dashboard..."), ], ), ), ); } return SafeArea( top: false, child: Scaffold( body: Container( color: const Color(0xFFF3F3F3), height: screenHeight, child: SingleChildScrollView( child: Column( children: [ // Top background image section Stack( children: [ // Background image Container( width: double.infinity, decoration: BoxDecoration( gradient: const LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Colors.white54, Color(0xFFF3F3F3), ], ), ), child: Image.asset( 'assets/images/sky_blue_bg.jpg', width: double.infinity, height: 400, fit: BoxFit.cover, ), ), // Content overlay Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Header with profile Container( width: double.infinity, height: 440, decoration: const BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Color(0x22FFFFFF), Color(0x33FFFFFF), Color(0x88FFFFFF), Color(0xFFF3F3F3), Color(0xFFF3F3F3), ], ), ), child: Column( children: [ const SizedBox(height: 50), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ // Profile icon Container( width: 50, height: 50, decoration: BoxDecoration( color: Colors.white.withOpacity(0.19), shape: BoxShape.circle, border: Border.all( color: Colors.white.withOpacity(0.5), width: 2, ), ), child: const Icon( Icons.person, color: Colors.white, size: 30, ), ), const SizedBox(width: 20) ], ), Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.start, children: [ Image.asset( 'assets/images/gene_png.png', height: 250, width: 250, ), const Text( "Welcome!", style: TextStyle( fontFamily: "Poppins", color: Colors.black, fontSize: 30, fontWeight: FontWeight.w500, ), ), // Use provider data for name Text( dashboardData?.raname ?? "Loading...", style: const TextStyle( fontFamily: "Poppins", color: Colors.grey, fontSize: 16, fontWeight: FontWeight.w400, ), ), ], ), ], ), ), const SizedBox(height: 10), // Main content section Container( padding: const EdgeInsets.symmetric(horizontal: 20), child: Column( children: [ // Balance Amount Card Container( width: double.infinity, padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ const Text( "Balance Amount", style: TextStyle( fontFamily: "Poppins", color: Color(0xFFF00000), fontSize: 14, fontWeight: FontWeight.w400, ), ), const SizedBox(width: 4), SvgPicture.asset( "assets/svg/continue_ic.svg", color: const Color(0xFFF00000), height: 18, width: 18, ), ], ), const SizedBox(height: 8), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ // Use provider data for balance amount - FIXED NULL CHECK Text( dashboardData?.balanceAmount ?? "0", style: const TextStyle( fontFamily: "Poppins", color: Colors.black, fontSize: 32, fontWeight: FontWeight.w500, ), ), InkResponse( onTap: () => showPaymentBottomSheet(context), child: Text( "Pay Now", style: TextStyle( fontFamily: "Poppins", color: Color(0xFF008CDE), fontSize: 14, fontWeight: FontWeight.w500, ), ), ), ], ), const SizedBox(height: 12), Text( "*Make sure to pay before you incur any fines.", style: TextStyle( fontFamily: "Poppins", color: Colors.grey.shade500, fontSize: 12, fontWeight: FontWeight.w400, ), ), ], ), ), const SizedBox(height: 20), // Feature cards grid Container( width: double.infinity, padding: const EdgeInsets.all(2), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Big card - Any Requirements Expanded( flex: 2, child: InkResponse( onTap: () { Navigator.push( context, MaterialPageRoute(builder: (context) => EnquiryScreen() ) ); }, child: Container( padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), border: Border.all( color: Colors.grey.shade200, width: 1, ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 16), Text( "Any \nRequirements ?", style: TextStyle( fontFamily: "Poppins", color: Color(0xFF008CDE), fontSize: 16, fontWeight: FontWeight.w400, ), ), const SizedBox(height: 8), Text( "Submit your enquiry for requirement", style: TextStyle( fontFamily: "Poppins", color: Colors.grey.shade600, fontSize: 14, ), ), ], ), const SizedBox(height: 20), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ SvgPicture.asset( "assets/svg/requirements.svg", height: 58, width: 58, ), ], ), ], ), ), ), ), const SizedBox(width: 10), // Side cards column Expanded( flex: 2, child: Column( children: [ // Have Complaints card Container( width: double.infinity, padding: const EdgeInsets.all(10), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), border: Border.all( color: Colors.grey.shade200, width: 1, ), ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( flex: 5, child: InkResponse( onTap: () { Navigator.push( context, MaterialPageRoute(builder: (context) => HelpScreen()), ); }, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( flex: 5, child: Text( "Need Help?", style: TextStyle( fontFamily: "Poppins", color: Color(0xFF008CDE), fontSize: 14, fontWeight: FontWeight.w400, ), ), ), Expanded( flex: 2, child: SvgPicture.asset( "assets/svg/have_compaints.svg", height: 35, width: 35, ), ), ], ), const SizedBox(height: 4), Text( "Raise a ticket to resolve your issues.", style: TextStyle( fontFamily: "Poppins", color: Colors.grey.shade600, fontWeight: FontWeight.w400, fontSize: 12, ), ), ], ), ), ), ], ), ), const SizedBox(height: 8), // Know Your Payments card InkResponse( onTap: () { Navigator.push( context, MaterialPageRoute(builder: (context) => TransactionsScreen()), ); }, child: Container( width: double.infinity, padding: const EdgeInsets.all(10), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), border: Border.all( color: Colors.grey.shade200, width: 1, ), ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( flex: 5, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( flex: 5, child: Text( "Transactions!", style: TextStyle( fontFamily: "Poppins", color: Color(0xFF008CDE), fontSize: 14, fontWeight: FontWeight.w400, ), ), ), Expanded( flex: 2, child: SvgPicture.asset( "assets/svg/know_pay.svg", height: 35, width: 35, ), ), ], ), const SizedBox(height: 4), Text( "View your all transactions with us.", style: TextStyle( fontFamily: "Poppins", color: Colors.grey.shade600, fontWeight: FontWeight.w400, fontSize: 12, ), ), ], ), ), ], ), ), ), ], ), ), ], ), ), const SizedBox(height: 20), // Subscribed Products Container( width: double.infinity, padding: const EdgeInsets.symmetric(horizontal: 2, vertical: 10), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Section Title Text( "Subscribed Products", style: TextStyle( fontFamily: "Poppins", color: Colors.grey.shade800, fontSize: 18, fontWeight: FontWeight.w600, ), ), const SizedBox(height: 16), // Show loading or products list if (dashboardProvider.isLoading && dashboardData == null) const Center( child: CircularProgressIndicator(), ) else if (dashboardData?.products == null || dashboardData!.products!.isEmpty) const Text( "No products subscribed", style: TextStyle( fontFamily: "Poppins", color: Colors.grey, fontSize: 14, ), ) else // List of subscribed products from API Column( children: dashboardData!.products!.map((product) { return Column( children: [ InkResponse( onTap: () { Navigator.push( context, MaterialPageRoute(builder: (context) => ProductsDetailScreen()), ); }, child: _buildProductItemFromApi(product), ), const SizedBox(height: 16), ], ); }).toList(), ), ], ), ) ], ), ), ], ), ], ), ], ), ), ), ), ); } // Helper widget for product item from API data Widget _buildProductItemFromApi(Products product) { return Stack( children: [ // Background strip for pending payment if (product.hasPendingPayment == true) Container( height: 130 + 50, padding: EdgeInsets.zero, decoration: BoxDecoration( color: Colors.red.withOpacity(0.6), borderRadius: BorderRadius.circular(15), border: Border.all( color: Colors.grey.shade200, width: 1, ), ), child: Column( children: [ SizedBox(height: 144), // Pending payment strip Container( width: double.infinity, padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 8), decoration: BoxDecoration( color: Colors.white38, borderRadius: const BorderRadius.only( bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10), ), ), child: Row( children: [ Icon( Icons.info_outline, color: Colors.red, size: 18, ), const SizedBox(width: 6), Expanded( child: Text( product.pendingPaymentText ?? "Payment Pending", style: TextStyle( fontFamily: "Poppins", color: Colors.black87, fontSize: 12, fontStyle: FontStyle.normal, fontWeight: FontWeight.w400, ), ), ), ], ), ), ], ), ), // Main content card Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), border: Border.all( color: Colors.grey.shade200, width: 1, ), ), child: Column( children: [ // Main content Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( flex: 6, child: Padding( padding: const EdgeInsets.all(10), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Expiring badge if (product.expiringText != null && product.expiringText!.isNotEmpty) Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6), decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), gradient: _getGradientByColor(product.expiringInColor), ), child: Text( product.expiringText!, style: const TextStyle( color: Colors.black87, fontSize: 12, fontStyle: FontStyle.normal, fontWeight: FontWeight.w400, ), ), ), const SizedBox(height: 8), // Product name and plan Text( product.productName ?? "Unknown Product", style: const TextStyle( color: Colors.black, fontSize: 16, fontStyle: FontStyle.normal, fontWeight: FontWeight.w400, ), ), const SizedBox(height: 4), Text( "Plan", style: TextStyle( fontFamily: "Poppins", color: Colors.grey.shade600, fontWeight: FontWeight.w400, fontStyle: FontStyle.normal, fontSize: 12, height: 1, ), ), Text( "₹${product.plan ?? "0"}", style: const TextStyle( fontFamily: "Poppins", color: Color(0xFF008CDE), fontSize: 18, fontStyle: FontStyle.normal, fontWeight: FontWeight.w500, height: 1.2 ), ), const SizedBox(height: 3), // Rented date Text( product.rentedDate ?? "Rented date not available", style: TextStyle( fontFamily: "Poppins", color: Colors.grey.shade500, fontStyle: FontStyle.normal, fontWeight: FontWeight.w400, fontSize: 12, ), ), ], ), ), ), Expanded( flex: 3, child: Container( padding: const EdgeInsets.all(14), decoration: BoxDecoration( color: const Color(0xffF2F2F2), borderRadius: BorderRadius.circular(16), ), child: product.productImage != null && product.productImage!.isNotEmpty ? Image.network( product.productImage!, height: 80, width: 80, fit: BoxFit.contain, errorBuilder: (context, error, stackTrace) { return Image.asset( 'assets/images/gene_png.png', height: 80, width: 80, fit: BoxFit.contain, ); }, ) : Image.asset( 'assets/images/gene_png.png', height: 80, width: 80, fit: BoxFit.contain, ), ), ), ], ), ], ), ), ], ); } // Helper method to get gradient based on color from API LinearGradient _getGradientByColor(String? color) { switch (color) { case "red": return const LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ Color(0xFFFFDDDD), Color(0xFFFFB5B5), ], ); case "green": default: return const LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ Color(0xFFE9FFDD), Color(0xFFB5FFD1), ], ); } } void showPaymentBottomSheet(BuildContext context) { showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (BuildContext context) { return SafeArea( bottom: true, child: Container( decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(24), topRight: Radius.circular(24), ), ), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ // Header - Drag handle Center( child: Container( width: 40, height: 4, decoration: BoxDecoration( color: Colors.grey.shade300, borderRadius: BorderRadius.circular(2), ), ), ), const SizedBox(height: 20), // Pay Amount Section Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "Pay", style: TextStyle( fontSize: 16, fontWeight: FontWeight.w400, color: Color(0xFF777777), ), ), SizedBox(height: 4), Text( "₹4218", style: TextStyle( fontSize: 24, fontWeight: FontWeight.w600, color: Colors.black, ), ), ], ), // Rent Amount Section Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ const Text( "Rent Amount", style: TextStyle( fontSize: 14, fontWeight: FontWeight.w400, color: Color(0xFF777777), ), ), const SizedBox(height: 4), GestureDetector( onTap: () { // Handle view bill details }, child: Text( "View Bill Details", style: TextStyle( fontSize: 14, fontWeight: FontWeight.w500, color: Color(0xFF008CDE), ), ), ), ], ), ], ), const SizedBox(height: 10), const Divider(height: 1, color: Color(0xFFEEEEEE)), const SizedBox(height: 18), // Continue Payment Button SizedBox( width: double.infinity, child: ElevatedButton( onPressed: () { // Handle continue payment }, style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF008CDE), foregroundColor: Colors.white, disabledBackgroundColor: const Color(0xFF266E99), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(30), ), padding: const EdgeInsets.symmetric(vertical: 16), ), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 22), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Text( "Continue Payment", style: TextStyle( color: Color(0xFFFFFFFF), fontSize: 16, ), ), SvgPicture.asset( "assets/svg/continue_ic.svg", color: Color(0xFFFFFFFF), height: 25, width: 25, ), ], ), ), ), ), ], ), ), ), ); }, ); } }