import 'package:dotted_line/dotted_line.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; import '../../Notifiers/hrmProvider/leaveApplicationDetailsProvider.dart'; import '../../Notifiers/HomeScreenNotifier.dart'; import '../../Utils/app_colors.dart'; import '../finance/FileViewer.dart'; /// Screen for leave application details class LeaveApplicationDetailScreen extends StatefulWidget { final String leaveRequestId; const LeaveApplicationDetailScreen({super.key, required this.leaveRequestId}); @override State createState() => _LeaveApplicationDetailScreenState(); } class _LeaveApplicationDetailScreenState extends State { @override Widget build(BuildContext context) { return ChangeNotifierProvider( create: (_) => LeaveApplicationDetailsProvider()..fetchLeaveApplicationDetails(context, widget.leaveRequestId), child: Consumer( builder: (context, provider, child) { return Scaffold( appBar: AppBar( automaticallyImplyLeading: false, backgroundColor: const Color(0xFFFFFFFF), title: Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [ InkResponse( onTap: () => Navigator.pop(context, true), child: SvgPicture.asset( "assets/svg/appbar_back_button.svg", height: 25, ), ), const SizedBox(width: 10), InkResponse( onTap: () => Navigator.pop(context, true), child: Text( "Leave Application Details", style: TextStyle( fontSize: 18, height: 1.1, fontFamily: "Plus Jakarta Sans", fontWeight: FontWeight.w600, color: AppColors.semi_black, ), ), ), ], ), ), backgroundColor: const Color(0xFFF6F6F8), body: Builder( builder: (context) { if (provider.isLoading) { return const Center(child: CircularProgressIndicator(color: Colors.blue)); } if (provider.errorMessage != null) { return Center(child: Text(provider.errorMessage!)); } if (provider.response?.requestDetails == null) { return const Center(child: Text("No details found")); } final details = provider.response!.requestDetails!; /// Screen content return SingleChildScrollView( padding: const EdgeInsets.all(16.0), child: Column( children: [ Card( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), elevation: 2, child: Padding( padding: const EdgeInsets.all(10.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ /// Header with status Container( margin: const EdgeInsets.only(bottom: 0.5), padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 2), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), ), child: Row( children: [ /// Left Avatar Container( height: 48, width: 48, decoration: BoxDecoration( shape: BoxShape.circle, color: const Color(0xFFEDF8FF), // icon bg ), child: Center( child: SvgPicture.asset( height: 28, width: 28, "assets/svg/hrm/leaveApplication.svg", // Use appropriate icon fit: BoxFit.contain, ), ), ), const SizedBox(width: 12), /// Middle text Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( details.leaveType ?? "-", style: TextStyle( decoration: TextDecoration.underline, decorationStyle: TextDecorationStyle.dotted, decorationColor: AppColors.grey_thick, height: 1.2, fontFamily: "JakartaRegular", fontSize: 14, color: AppColors.semi_black, ), ), const SizedBox(height: 2), Text( "Applied: ${details.appliedDate ?? "-"}", style: TextStyle( fontFamily: "JakartaRegular", fontSize: 14, color: AppColors.app_blue, ), ), ], ), ), /// Right side status badge Container( height: 30, padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 1), decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), color: _getStatusBackgroundColor(details.status), ), child: Center( child: Text( details.status ?? "-", textAlign: TextAlign.center, style: TextStyle( fontFamily: "JakartaMedium", fontSize: 12, color: _getStatusTextColor(details.status), ), ), ), ), ], ), ), /// Leave Details Padding( padding: const EdgeInsets.all(8.0), child: Column( children: [ _buildSectionHeader("Leave Details"), _buildDetailTile("Application ID", details.id), _buildDetailTile("Applied Date", details.appliedDate), _buildDetailTile("Leave Type", details.leaveType), _buildDateRangeTile("Leave Period", details.fromDate, details.toDate), _buildTimeRangeTile("Time Period", details.fromTime, details.toTime), _buildDetailTile("Reason", details.reason), /// Approval Details _buildSectionHeader("Approval Details"), _buildDetailTile("Requested To", details.requestedTo), _buildDetailTile("Approved By", details.approvedBy), _buildDetailTile("Approved Date", details.approvedDate), _buildDetailTile("Approval Remarks", details.approvalRemarks), /// Additional Information _buildSectionHeader("Additional Information"), _buildDetailTile("Status", details.status), _buildDetailTile("From Time", details.fromTime), _buildDetailTile("To Time", details.toTime), ], ), ), ], ), ), ), const SizedBox(height: 30), ], ), ); }, ), ); }, ), ); } /// Reusable Row Widget for details Widget _buildDetailTile(String label, String? value) { return Padding( padding: const EdgeInsets.symmetric(vertical: 3), child: Row( children: [ Expanded( flex: 6, child: Text( label, style: TextStyle( fontFamily: "JakartaRegular", fontSize: 14, color: AppColors.semi_black, ), ), ), Expanded( flex: 0, child: Text( value ?? "-", style: const TextStyle( fontSize: 14, color: Color(0xff818181), fontWeight: FontWeight.w400, ), ), ), ], ), ); } /// For date range display Widget _buildDateRangeTile(String label, String? fromDate, String? toDate) { return Padding( padding: const EdgeInsets.symmetric(vertical: 3), child: Row( children: [ Expanded( flex: 6, child: Text( label, style: TextStyle( fontFamily: "JakartaRegular", fontSize: 14, color: AppColors.semi_black, ), ), ), Expanded( flex: 0, child: Text( '${fromDate ?? "-"} to ${toDate ?? "-"}', style: const TextStyle( fontSize: 14, color: Color(0xff818181), fontWeight: FontWeight.w400, ), ), ), ], ), ); } /// For time range display Widget _buildTimeRangeTile(String label, String? fromTime, String? toTime) { if ((fromTime == null || fromTime.isEmpty) && (toTime == null || toTime.isEmpty)) { return const SizedBox.shrink(); // Hide if no time data } return Padding( padding: const EdgeInsets.symmetric(vertical: 3), child: Row( children: [ Expanded( flex: 6, child: Text( label, style: const TextStyle( fontSize: 14, color: Color(0xff2D2D2D), fontStyle: FontStyle.normal, fontFamily: "Plus Jakarta Sans", fontWeight: FontWeight.w400, ), ), ), Expanded( flex: 0, child: Text( '${fromTime ?? "-"} to ${toTime ?? "-"}', style: const TextStyle( fontSize: 14, color: Color(0xff818181), fontWeight: FontWeight.w400, ), ), ), ], ), ); } /// Section header with dotted line Widget _buildSectionHeader(String title) { return Padding( padding: const EdgeInsets.symmetric(vertical: 8), child: Row( children: [ Text( title, style: TextStyle( fontSize: 14, fontFamily: "JakartaSemiBold", ), ), const SizedBox(width: 10), Expanded( child: DottedLine( dashGapLength: 4, dashGapColor: Colors.white, dashColor: AppColors.grey_semi, dashLength: 2, lineThickness: 0.5, ), ), ], ), ); } /// Status background color Color _getStatusBackgroundColor(String? status) { switch (status?.toLowerCase()) { case 'approved': return AppColors.approved_bg_color; case 'rejected': return AppColors.rejected_bg_color; case 'requested': default: return AppColors.requested_bg_color; } } /// Status text color Color _getStatusTextColor(String? status) { switch (status?.toLowerCase()) { case 'approved': return AppColors.approved_text_color; case 'rejected': return AppColors.rejected_text_color; case 'requested': default: return AppColors.requested_text_color; } } }