From 8f4e2c8c99d0a13fdc31580c5d3ed6b82c2efca9 Mon Sep 17 00:00:00 2001 From: VE10-Sanjeev Date: Mon, 26 May 2025 05:31:18 +0000 Subject: [PATCH] status dashboard --- lib/Screens/dashboard/status_dashboard.dart | 202 ++++++++++++++++++++ lib/routes/custom_appBar.dart | 7 + lib/routes/custom_router.dart | 5 + 3 files changed, 214 insertions(+) create mode 100644 lib/Screens/dashboard/status_dashboard.dart diff --git a/lib/Screens/dashboard/status_dashboard.dart b/lib/Screens/dashboard/status_dashboard.dart new file mode 100644 index 0000000..6a42b8a --- /dev/null +++ b/lib/Screens/dashboard/status_dashboard.dart @@ -0,0 +1,202 @@ +import 'dart:convert'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:http/http.dart' as http; +import 'package:responsive_builder/responsive_builder.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +import '../../config/apiUrl.dart'; +import '../../routes/custom_appBar.dart'; +import '../../routes/custom_drawer.dart'; +import '../../services/apiService.dart'; +import '../../utils/auth_utils.dart'; +import '../../utils/pagination.dart'; + +class StatusDashboard extends StatefulWidget { + + const StatusDashboard({super.key}); + + @override + StatusDashboardState createState() => StatusDashboardState(); +} + +class StatusDashboardState extends State { + + Map? apiData; + String? organizationId; + + @override + void initState() { + super.initState(); + loadDashboardData(); + + } + + Future loadDashboardData() async { + try { + final data = await fetchStatusDashboard(); + setState(() { + apiData = data; + }); + } catch (e) { + print("Error loading dashboard: $e"); + } + } + + Future getToken() async { + final prefs = await SharedPreferences.getInstance(); + return prefs.getString('auth_token'); + } + + Future getOrgId() async { + final prefs = await SharedPreferences.getInstance(); + final String? userDataString = prefs.getString('user_data'); + + if (userDataString != null) { + try { + final Map userData = jsonDecode(userDataString); + return userData["org_id"]?.toString(); + } catch (e) { + return null; + } + } + return null; + } + + + Future> fetchStatusDashboard() async { + + + organizationId = await getOrgId(); + + final String apiUrlData = '$apiUrl/api/plans/statusDashboard?org_id=$organizationId'; + final String? token = await getToken(); + + print("Fetch StatusDashboard -- 2KN Here : $token"); + + if (token == null) { + throw Exception('Token not found. Please log in.'); + } + + final response = await http.get( + Uri.parse(apiUrlData), + headers: { + 'Authorization': 'Bearer $token', + 'Content-Type': 'application/json', + }, + ); + print("called api : $apiUrlData"); + if (response.statusCode == 200) { + final apiData = json.decode(response.body); + print("Fetch StatusDashboard -- Reponse Here : $apiData"); + return apiData; // Returning raw JSON list + } else { + throw Exception('Failed to load users'); + } + } + + @override + Widget build(BuildContext context) { + final typeBasedCount = List>.from( + (apiData?['data']?['typeBasedCount']) ?? []); + + print("apiData - => $apiData"); + print("typeBasedCount => $typeBasedCount"); + + final statusBasedCount = List>.from( + (apiData?['data']?['statusBasedCount']) ?? []); + print("statusBasedCount - => $statusBasedCount"); + // 👇 Local function to create the card widget + Widget buildInfoCard(String title, int count) { + return Card( + elevation: 3, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + child: Container( + width: 150, + padding: const EdgeInsets.all(12), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + title, + textAlign: TextAlign.center, + style: const TextStyle(fontWeight: FontWeight.w600), + + ), + const SizedBox(height: 8), + Text( + count.toString(), + style: const TextStyle( + fontSize: 22, + fontWeight: FontWeight.bold, + color: Colors.blue, + ), + ), + ], + ), + ), + ); + } + + return ResponsiveBuilder(builder: (context, sizingInfo) { + bool isDesktop = sizingInfo.deviceScreenType == DeviceScreenType.desktop; + + return Scaffold( + backgroundColor: const Color(0xFFf5f5f5), + appBar: CustomAppBar(isDesktop: isDesktop), + drawer: CustomDrawer(isDesktop: false), + body: Padding( + padding: isDesktop + ? EdgeInsets.symmetric( + horizontal: MediaQuery.of(context).size.width * 0.1, + vertical: 0, + ) + : const EdgeInsets.all(0), + child: Row( + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + 'Type Based Count', + style: + TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + Wrap( + spacing: 10, + runSpacing: 10, + children: typeBasedCount + .map((item) => buildInfoCard(item['value'], item['count'])) + .toList(), + ), + const SizedBox(height: 20), + const Text( + 'Status Based Count', + style: + TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + Wrap( + spacing: 10, + runSpacing: 10, + children: statusBasedCount + .map((item) => buildInfoCard(item['value'], item['count'])) + .toList(), + ), + ], + ), + ), + ), + ], + ), + ), + ); + }); + } + +} \ No newline at end of file diff --git a/lib/routes/custom_appBar.dart b/lib/routes/custom_appBar.dart index 338892a..b667c63 100644 --- a/lib/routes/custom_appBar.dart +++ b/lib/routes/custom_appBar.dart @@ -352,6 +352,8 @@ class _CustomAppBarState extends State { // context.go('/templateList'); // case '/template': // context.go('/template'); + case '/StatusDashboard': + context.go('/StatusDashboard'); case '/CreateUserDetails': context.go( "/CreateUserDetails", @@ -479,6 +481,11 @@ final List> menuItems = [ 'icon': Icons.manage_accounts, 'label': 'User Management' }, + { + 'value': '/StatusDashboard', + 'icon': Icons.dashboard_sharp, + 'label': 'Status Dashboard' + }, // {'value': '/group', 'icon': Icons.group, 'label': 'Group'}, // {'value': '/department', 'icon': Icons.group, 'label': 'Department'}, // {'value': '/PolicyList', 'icon': Icons.policy, 'label': 'Policy'}, diff --git a/lib/routes/custom_router.dart b/lib/routes/custom_router.dart index 62ee825..f6f26b1 100644 --- a/lib/routes/custom_router.dart +++ b/lib/routes/custom_router.dart @@ -26,6 +26,7 @@ import '../Screens/myTemplates/template.dart'; import '../Screens/userManagement/create_user/create_user.dart'; import '../Screens/department/department_list.dart'; import '../Screens/costCenter/costCenter_list.dart'; +import '../Screens/dashboard/status_dashboard.dart'; final GoRouter router = GoRouter( routes: [ @@ -136,6 +137,10 @@ final GoRouter router = GoRouter( path: '/costcenter', builder: (context, state) => CostCenterList(), ), + GoRoute( + path: '/statusdashboard', + builder: (context, state) => StatusDashboard(), + ), GoRoute( path: '/CreateGroup', pageBuilder: (context, state) => MaterialPage(