import 'dart:convert'; import 'dart:core'; import 'package:frontend/data/models/plan.dart'; import 'package:go_router/go_router.dart'; import 'package:http/http.dart' as http; import 'package:flutter/material.dart'; import 'package:frontend/config/apiUrl.dart'; import 'package:responsive_builder/responsive_builder.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../../routes/custom_appBar.dart'; import '../../routes/custom_drawer.dart'; class ListPlans extends StatefulWidget{ const ListPlans({super.key}); @override _ListPlansState createState() => _ListPlansState(); } class _ListPlansState extends State{ late Future> futurePlans; String? userId; String? token; @override void initState(){ super.initState(); getToken(); initializeData(); // futurePlans = fetchPlans(); } Future initializeData ()async{ token = await getToken(); userId = await getUserId(); if(token == null || userId == null){ print("Token or USerId missing"); return; } else{ setState(() { futurePlans = fetchPlans(); }); } } Future getUserId() async { final prefs = await SharedPreferences.getInstance(); final String? userDataString = prefs.getString('user_data'); if(userDataString != null){ try{ final Map userData = jsonDecode(userDataString); return userData["user_id"]?.toString(); }catch(e){ return null; } } return null; } Future getToken() async { final prefs = await SharedPreferences.getInstance(); return prefs.getString('auth_token'); } // Fetch API Data Future> fetchPlans() async { // final String apiUrldata = '$apiUrl/api/plans'; final String apiUrldata = '$apiUrl/api/plans?user_id=$userId'; // final token = await getToken(); if (token == null) { throw Exception('Token not found. Please log in.'); } final response = await http.get( Uri.parse(apiUrldata), headers: { 'Authorization': 'Bearer $token', // Add token here 'Content-Type': 'application/json', }, ); if (response.statusCode == 200) { final data = json.decode(response.body); List plansJson = data['data']; return plansJson.map((json) => Plan.fromJson(json)).toList(); } else { throw Exception('Failed to load plans'); } } Future > getViewPlan(String planId) async{ final String apiUrldata = '$apiUrl/api/plans/find/$planId'; print("API URL: $apiUrldata"); // final token = await getToken(); if (token == null) { throw Exception('Token not found. Please log in.'); } final response = await http.put( Uri.parse(apiUrldata), headers: { 'Authorization': 'Bearer $token', // Add token here 'Content-Type': 'application/json', }, ); if (response.statusCode == 200) { final Map? resData = json.decode(response.body); return resData?["data"]; } else { throw Exception('Failed to load plans'); } } void viewPlan(String planId, {bool isViewMode = false}) async{ try { Map planData = await getViewPlan(planId); print("ViewAAA - $planData"); context.go('/createPlan',extra: {'planData': planData, 'isViewMode': isViewMode} ); } catch (e) { print("Error fetching plan: $e"); } } Widget build(BuildContext context) { return ResponsiveBuilder(builder: (context, sizingInfo) { bool isDesktop = sizingInfo.deviceScreenType == DeviceScreenType.desktop; return Scaffold( backgroundColor: Colors.white, appBar: isDesktop ? null : const CustomAppBar(title: 'Home'), drawer: isDesktop ? null : CustomDrawer(isDesktop: false), body: Row( children: [ if (isDesktop) CustomDrawer(isDesktop: true), Expanded(child: buildTableLayout(isDesktop)) ], ), ); }); } Widget buildTableLayout(isDesktop) { return Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ const Text('Plans List', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), IconButton( icon: const Icon(Icons.keyboard_arrow_down), onPressed: () {}, ), ], ), ElevatedButton( style: ElevatedButton.styleFrom( foregroundColor: Colors.white, backgroundColor: Colors.blueAccent), onPressed: () { context.go('/createPlan'); if (!isDesktop) Navigator.pop(context); }, child: Row( children: [ Icon(Icons.add_circle,color: Colors.white,), SizedBox(width: 5,), Text('NewPlan'), ], ), ), ], ), const SizedBox(height: 10), FutureBuilder>( future: futurePlans, // Use the futurePlans variable builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } else if (snapshot.hasError) { return Center(child: Text("Error: ${snapshot.error}")); } else if (!snapshot.hasData || snapshot.data!.isEmpty) { return const Center(child: Text("No plans available")); } List plans = snapshot.data!; // Extract the list of plans // Ensure planId is sorted in descending order plans.sort((a, b) => int.parse(b.planId.toString()).compareTo(int.parse(a.planId.toString()))); // return ResponsiveBuilder( // builder: (context, sizingInfo) { // bool isTabletOrDesktop = sizingInfo.isTablet || sizingInfo.isDesktop; // // return SingleChildScrollView( // scrollDirection: Axis.horizontal, // child: Container( // color: Colors.grey, // child: SizedBox( // width: MediaQuery.of(context).size.width , // child: SingleChildScrollView( // scrollDirection: Axis.vertical, // // scrollDirection: isTabletOrDesktop ? Axis.vertical : Axis.horizontal, // // // constraints: isTabletOrDesktop // // ? const BoxConstraints(maxWidth: double.infinity) // // : BoxConstraints.tightFor(width: 600), // // // child: DataTable( // // columnSpacing: 50.0, // dividerThickness: 0.5, // Reduce the thickness of row dividers // border: TableBorder( // horizontalInside: BorderSide(width: 0.5, color: Colors.grey.shade200), // Reduce horizontal line thickness // ), // columns: const [ // DataColumn(label: Text('Plan ID', style: TextStyle(color: Colors.grey, fontWeight: FontWeight.bold,))), // DataColumn(label: Text('Trip Title', style: TextStyle(color: Colors.grey, fontWeight: FontWeight.bold,))), // DataColumn(label: Text('Trip Type', style: TextStyle(color: Colors.grey, fontWeight: FontWeight.bold,))), // DataColumn(label: Text('Cost Center', style: TextStyle(color: Colors.grey, fontWeight: FontWeight.bold,))), // // DataColumn(label: Text('Functional Department', style: TextStyle(color: Colors.grey, fontWeight: FontWeight.bold,))), // // DataColumn(label: Text('Purpose Of Travel', style: TextStyle(color: Colors.grey, fontWeight: FontWeight.bold,))), // // DataColumn(label: Text('Description', style: TextStyle(color: Colors.grey, fontWeight: FontWeight.bold,))), // // // DataColumn(label: Text('Is Billable', style: TextStyle(color: Colors.grey, fontWeight: FontWeight.bold,))), // DataColumn(label: Text('Status', style: TextStyle(color: Colors.grey, fontWeight: FontWeight.bold,))), // DataColumn(label: Text('Actions', style: TextStyle(color: Colors.grey, fontWeight: FontWeight.bold,))), // ], // rows: plans.map((plan) { // return DataRow(cells: [ // DataCell(Text(plan.planId)), // // DataCell(Text(plan.tripTitle)), // DataCell(Row( // children: [ // Flexible( // child: Text( // plan.tripTitle, // softWrap: true, // overflow: TextOverflow.ellipsis, // Adds "..." if text is too long // ), // ), // ], // )), // // // DataCell(Text(plan.tripType)), // DataCell(Text(plan.costCenter)), // // DataCell(Text(plan.functionalDepartment)), // // DataCell(Text(plan.purposeOfTravel)), // // DataCell(Text(plan.description)), // // // DataCell(Text(plan.isBillable)), // DataCell(Text(plan.status)), // DataCell( // TextButton( // onPressed: () { // viewPlan(plan.planId); // print("View button clicked for ${plan.planId}"); // }, // child: const Text('View', // style: TextStyle(color: Colors.blueAccent)), // ), // ), // ]); // }).toList(), // ), // // // ), // ), // ), // ); // // }, // ); return Expanded( child: SingleChildScrollView( // scrollDirection: Axis.horizontal, // Outer wrapper for horizontal scrolling scrollDirection: Axis.vertical, child: SizedBox( width: MediaQuery.of(context).size.width * 1.5, // width: MediaQuery.of(context).size.width , // Ensure table is wider than screen // width: double.infinity , // Ensure table is wider than screen child: SingleChildScrollView( // scrollDirection: Axis.vertical, // Inner wrapper for vertical scrolling scrollDirection: Axis.horizontal, // Inner wrapper for vertical scrolling child: ConstrainedBox( constraints: BoxConstraints(minWidth: 1300), // width: MediaQuery.of(context).size.width , child: Container( // color: Colors.amber, child: DataTable( columnSpacing: 50.0, // Adjust spacing between columns dividerThickness: 0.5, border: TableBorder( horizontalInside: BorderSide(width: 0.5, color: Colors.grey.shade200), ), columns: const [ DataColumn(label: Text('Plan ID', style: TextStyle(fontWeight: FontWeight.bold))), DataColumn(label: Text('Trip Title', style: TextStyle(fontWeight: FontWeight.bold))), DataColumn(label: Text('Trip Type', style: TextStyle(fontWeight: FontWeight.bold))), DataColumn(label: Text('Cost Center', style: TextStyle(fontWeight: FontWeight.bold))), DataColumn(label: Text('Is Billable', style: TextStyle(fontWeight: FontWeight.bold))), DataColumn(label: Text('Status', style: TextStyle(fontWeight: FontWeight.bold))), DataColumn(label: Text('Actions', style: TextStyle(fontWeight: FontWeight.bold))), ], rows: plans.map((plan) { return DataRow(cells: [ DataCell(Text(plan.planId)), DataCell(Text(plan.tripTitle, softWrap: true, overflow: TextOverflow.ellipsis)), DataCell(Text(plan.tripType)), DataCell(Text(plan.costCenter)), DataCell(Text(plan.isBillable)), DataCell( Container( padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 10), // Padding for better look decoration: BoxDecoration( color: plan.status == "Active" ? Colors.green.shade50 : Colors.grey.shade50, // Background color borderRadius: BorderRadius.circular(10), // Rounded corners ), child: Text( plan.status, style: TextStyle( color: plan.status == "Active" ? Colors.green : Colors.grey, // Text color fontWeight: FontWeight.bold, // Optional: Make text bold ), ), ), ), DataCell( Row( children:[ IconButton( icon: Icon(Icons.remove_red_eye, color: Colors.blue), onPressed: () { viewPlan(plan.planId, isViewMode: true); }, ), IconButton( icon: Icon(Icons.edit, color: Colors.green), onPressed: () { viewPlan(plan.planId, isViewMode: false); }, ), // IconButton( // icon: Icon(Icons.delete, color: Colors.red), // onPressed: () { // deletePlan(plan.planId); // }, // ), ] ) ), ]); }).toList(), ), ), ), ), ), ), ); }, ), ], ), ); } }