Commit 2a8fa440 authored by Sai Srinivas's avatar Sai Srinivas
Browse files

AttendanceScreen and hrm color and responsive

parents 96031396 9e243e0c
...@@ -42,8 +42,8 @@ android { ...@@ -42,8 +42,8 @@ android {
defaultConfig { defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "in.webgrid.generp" applicationId = "in.webgrid.generp"
minSdk = flutter.minSdkVersion minSdk = 23
targetSdk = flutter.targetSdkVersion targetSdk = 36
versionCode = flutter.versionCode versionCode = flutter.versionCode
versionName = flutter.versionName versionName = flutter.versionName
} }
......
...@@ -949,6 +949,11 @@ class Addnewleadsandprospectsprovider extends ChangeNotifier { ...@@ -949,6 +949,11 @@ class Addnewleadsandprospectsprovider extends ChangeNotifier {
nameError = "Please Enter Name"; nameError = "Please Enter Name";
isValid = false; isValid = false;
} }
if(nameError == "Name already exists"){
isValid = false;
}
if (customerMailIdController.text.trim().isNotEmpty && if (customerMailIdController.text.trim().isNotEmpty &&
!RegExp(r'\S+@\S+\.\S+').hasMatch(customerMailIdController.text)) { !RegExp(r'\S+@\S+\.\S+').hasMatch(customerMailIdController.text)) {
mailIdError = "Please enter a proper Email ID"; mailIdError = "Please enter a proper Email ID";
...@@ -963,6 +968,9 @@ class Addnewleadsandprospectsprovider extends ChangeNotifier { ...@@ -963,6 +968,9 @@ class Addnewleadsandprospectsprovider extends ChangeNotifier {
isValid = false; isValid = false;
} }
} }
if ( mobileError == "Mobile number already exists"){
isValid = false;
}
// if(designationController.text.trim().isEmpty){ // if(designationController.text.trim().isEmpty){
// designationError = "Please enter Designation"; // designationError = "Please enter Designation";
...@@ -973,6 +981,11 @@ class Addnewleadsandprospectsprovider extends ChangeNotifier { ...@@ -973,6 +981,11 @@ class Addnewleadsandprospectsprovider extends ChangeNotifier {
return isValid; return isValid;
} }
bool validateStep2() { bool validateStep2() {
bool isValid = true; bool isValid = true;
if (alternateMobileController.text.trim().isNotEmpty && if (alternateMobileController.text.trim().isNotEmpty &&
......
...@@ -52,6 +52,38 @@ class _AttendanceScreenState extends State<AttendanceScreen> { ...@@ -52,6 +52,38 @@ class _AttendanceScreenState extends State<AttendanceScreen> {
_connectivity.disposeStream(); _connectivity.disposeStream();
} }
// Responsive text size function
double getResponsiveTextSize(BuildContext context, double baseSize) {
final double scale = MediaQuery.of(context).textScaleFactor;
final double width = MediaQuery.of(context).size.width;
if (width < 360) { // Small phones
return baseSize * 0.9;
} else if (width < 400) { // Medium phones
return baseSize;
} else { // Large phones
return baseSize * 1.1;
}
}
// Responsive padding function
double getResponsivePadding(BuildContext context) {
final double width = MediaQuery.of(context).size.width;
return width * 0.04; // 4% of screen width
}
// Responsive height function
double getResponsiveHeight(BuildContext context, double baseHeight) {
final double height = MediaQuery.of(context).size.height;
if (height < 700) { // Small height devices
return baseHeight * 0.8;
} else if (height < 800) { // Medium height devices
return baseHeight;
} else { // Large height devices
return baseHeight * 1.1;
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
switch (_source.keys.toList()[0]) { switch (_source.keys.toList()[0]) {
...@@ -67,583 +99,592 @@ class _AttendanceScreenState extends State<AttendanceScreen> { ...@@ -67,583 +99,592 @@ class _AttendanceScreenState extends State<AttendanceScreen> {
} }
return (connection == 'Online') return (connection == 'Online')
? Platform.isAndroid ? Platform.isAndroid
? WillPopScope( ? WillPopScope(
onWillPop: () => onBackPressed(context), onWillPop: () => onBackPressed(context),
child: SafeArea( child: SafeArea(
top: false, top: false,
bottom: true, bottom: true,
child: _scaffold(context), child: _scaffold(context),
), ),
) )
: _scaffold(context) : _scaffold(context)
: NoNetwork(context); : NoNetwork(context);
} }
Widget _scaffold(BuildContext context) { Widget _scaffold(BuildContext context) {
return Consumer<AttendanceNotifier>( return LayoutBuilder(
builder: (context, attendance, index) { builder: (context, constraints) {
final timeString = final bool isSmallScreen = constraints.maxWidth < 360;
attendance.attendanceHistory.firstOrNull?['check_in_time'] final bool isLargeScreen = constraints.maxWidth > 400;
.toString() ??
""; return Consumer<AttendanceNotifier>(
final match = RegExp( builder: (context, attendance, index) {
r'^(\d{1,2}:\d{2})(am|pm)$', final timeString =
caseSensitive: false, attendance.attendanceHistory.firstOrNull?['check_in_time']
).firstMatch(timeString.replaceAll(' ', '').toLowerCase()); .toString() ??
"";
final timeString2 = final match = RegExp(
attendance.attendanceHistory.firstOrNull?['check_out_time'] r'^(\d{1,2}:\d{2})(am|pm)$',
.toString() ?? caseSensitive: false,
""; ).firstMatch(timeString.replaceAll(' ', '').toLowerCase());
final match2 = RegExp(
r'^(\d{1,2}:\d{2})(am|pm)$', final timeString2 =
caseSensitive: false, attendance.attendanceHistory.firstOrNull?['check_out_time']
).firstMatch(timeString2.replaceAll(' ', '').toLowerCase()); .toString() ??
"";
String formattedTime = match?.group(1) ?? "-"; final match2 = RegExp(
String period = match?.group(2)?.toUpperCase() ?? ""; r'^(\d{1,2}:\d{2})(am|pm)$',
caseSensitive: false,
String formattedTime2 = match2?.group(1) ?? "-"; ).firstMatch(timeString2.replaceAll(' ', '').toLowerCase());
String period2 = match2?.group(2)?.toUpperCase() ?? "";
String formattedTime = match?.group(1) ?? "-";
final dateArrayList = attendance.dateArrayList; String period = match?.group(2)?.toUpperCase() ?? "";
final penalityArrayList = attendance.penalityArrayList;
var selectedIndex = attendance.selectedIndex; String formattedTime2 = match2?.group(1) ?? "-";
String period2 = match2?.group(2)?.toUpperCase() ?? "";
// Calculate the custom period: 26th of previous month to 25th of current month
final startDate = DateTime( final dateArrayList = attendance.dateArrayList;
attendance.month.year, final penalityArrayList = attendance.penalityArrayList;
attendance.month.month - 1, var selectedIndex = attendance.selectedIndex;
26,
); // Calculate the custom period: 26th of previous month to 25th of current month
final endDate = DateTime( final startDate = DateTime(
attendance.month.year, attendance.month.year,
attendance.month.month, attendance.month.month - 1,
25, 26,
); );
final daysInPeriod = endDate.difference(startDate).inDays + 1; final endDate = DateTime(
final startingIndex = attendance.month.year,
startDate.weekday % 7; // 0 for Sunday, 1 for Monday, etc. attendance.month.month,
final currentDate = DateTime.now(); 25,
);
// Format the month label (e.g., "Mar - Apr 2025") final daysInPeriod = endDate.difference(startDate).inDays + 1;
final prevMonthName = DateFormat( final startingIndex =
'MMM', startDate.weekday % 7; // 0 for Sunday, 1 for Monday, etc.
).format(DateTime(attendance.month.year, attendance.month.month - 1)); final currentDate = DateTime.now();
final currentMonthName = DateFormat('MMM').format(attendance.month);
final year = DateFormat('yyyy').format(attendance.month); // Format the month label (e.g., "Mar - Apr 2025")
// final monthLabel = final prevMonthName = DateFormat(
// prevMonthName == currentMonthName 'MMM',
// ? '$currentMonthName $year' ).format(DateTime(attendance.month.year, attendance.month.month - 1));
// : '$prevMonthName - $currentMonthName $year'; final currentMonthName = DateFormat('MMM').format(attendance.month);
final monthLabel = '$currentMonthName $year'; final year = DateFormat('yyyy').format(attendance.month);
final monthLabel = '$currentMonthName $year';
return RefreshIndicator.adaptive(
color: AppColors.app_blue, return RefreshIndicator.adaptive(
color: AppColors.app_blue,
onRefresh: () async {
await Future.delayed(const Duration(milliseconds: 600)); onRefresh: () async {
attendance.getAttendanceList(context); await Future.delayed(const Duration(milliseconds: 600));
attendance.init(context); attendance.getAttendanceList(context);
attendance.loadAttendanceDetails(context); attendance.init(context);
}, attendance.loadAttendanceDetails(context);
child: Scaffold( },
resizeToAvoidBottomInset: true, child: Scaffold(
backgroundColor: AppColors.scaffold_bg_color, resizeToAvoidBottomInset: true,
appBar: appbarNew(context, "Attendance", 0xFFFFFFFF), backgroundColor: AppColors.scaffold_bg_color,
body: SingleChildScrollView( appBar: appbarNew(context, "Attendance", 0xFFFFFFFF),
child: Column( body: SingleChildScrollView(
crossAxisAlignment: CrossAxisAlignment.start, child: Column(
children: [ crossAxisAlignment: CrossAxisAlignment.start,
Container( children: [
decoration: BoxDecoration( Container(
color: Colors.white, decoration: BoxDecoration(
borderRadius: BorderRadius.vertical( color: Colors.white,
bottom: Radius.circular(20), borderRadius: BorderRadius.vertical(
), bottom: Radius.circular(20),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: EdgeInsets.only(
left: 15,
right: 10,
top: 15,
),
child: Row(
children: List.generate(2, (j) {
final heads = ["Check-in", "Check-out"];
return Expanded(
child: Text(
heads[j],
style: TextStyle(
color: AppColors.grey_thick,
fontSize: 14,
fontFamily: "JakartaMedium",
),
),
);
}),
), ),
), ),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: EdgeInsets.only(
left: getResponsivePadding(context),
right: getResponsivePadding(context),
top: 15,
),
child: Row(
children: List.generate(2, (j) {
final heads = ["Check-in", "Check-out"];
return Expanded(
child: Text(
heads[j],
style: TextStyle(
color: AppColors.grey_thick,
fontSize: getResponsiveTextSize(context, 14),
fontFamily: "JakartaMedium",
),
),
);
}),
),
),
SizedBox( Container(
child: Row( padding: EdgeInsets.symmetric(horizontal: getResponsivePadding(context)-6),
children: List.generate(2, (iii) { child: Row(
final times = [formattedTime, formattedTime2]; children: List.generate(2, (iii) {
final periods = [period, period2]; final times = [formattedTime, formattedTime2];
final locations = [ final periods = [period, period2];
attendance.attendanceHistory.isNotEmpty final locations = [
? attendance attendance.attendanceHistory.isNotEmpty
.attendanceHistory ? attendance
.first['check_in_location'] .attendanceHistory
.toString() ?? .first['check_in_location']
.toString() ??
"-" "-"
: "-", : "-",
attendance.attendanceHistory.isNotEmpty attendance.attendanceHistory.isNotEmpty
? attendance ? attendance
.attendanceHistory .attendanceHistory
.first['check_out_location'] .first['check_out_location']
.toString() ?? .toString() ??
"-" "-"
: "-", : "-",
]; ];
return Expanded( return Expanded(
child: Container( child: Container(
padding: EdgeInsets.symmetric( padding: EdgeInsets.symmetric(
horizontal: 10, horizontal: isSmallScreen ? 8 : 10,
vertical: 15, vertical: isSmallScreen ? 11 : 16,
), ),
margin: EdgeInsets.symmetric( margin: EdgeInsets.symmetric(
horizontal: 5, horizontal: isSmallScreen ? 3 : 5,
vertical: 5, vertical: isSmallScreen ? 3 : 5,
), ),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Color(0xFFF3EDFF), color: Color(0xFFE6F6FF),
borderRadius: BorderRadius.circular(20), borderRadius: BorderRadius.circular(20),
), ),
child: Column( child: Column(
crossAxisAlignment: crossAxisAlignment:
CrossAxisAlignment.start, CrossAxisAlignment.start,
children: [ children: [
RichText( RichText(
text: TextSpan( text: TextSpan(
children: [ children: [
TextSpan( TextSpan(
text: times[iii], text: times[iii],
style: TextStyle( style: TextStyle(
color: color:
times[iii] != "-" times[iii] != "-"
? Color(0xFF1286C7) ? Color(0xFF1286C7)
: Color(0xFFED3424), : Color(0xFF1286C7),
fontFamily: "JakartaRegular", fontFamily: "JakartaRegular",
fontSize: 20, fontSize: getResponsiveTextSize(context, 20),
), ),
), ),
TextSpan( TextSpan(
text: periods[iii], text: periods[iii],
style: TextStyle( style: TextStyle(
color: color:
periods[iii] != "-" periods[iii] != "-"
? Color(0xFF1286C7) ? Color(0xFF1286C7)
: Color(0xFFED3424), : Color(0xFFED3424),
fontFamily: "JakartaRegular", fontFamily: "JakartaRegular",
fontSize: 14, fontSize: getResponsiveTextSize(context, 14),
), ),
),
],
), ),
], ),
), SizedBox(height: isSmallScreen ? 12 : 16),
), Text(
SizedBox(height: 10), locations[iii],
Text( style: TextStyle(
locations[iii], color: AppColors.semi_black,
style: TextStyle( fontSize: getResponsiveTextSize(context, 12),
color: AppColors.semi_black, ),
fontSize: 12, ),
), ],
), ),
], ),
), );
), }),
); ),
}), ),
),
),
Container( Container(
padding: EdgeInsets.only(left: 10, top: 10), padding: EdgeInsets.only(
child: Text( left: getResponsivePadding(context),
"Attendance Details", top: 10
style: TextStyle( ),
fontFamily: "JakartaMedium", child: Text(
fontSize: 14, "Attendance Details",
color: Color(0xFF818181), style: TextStyle(
fontFamily: "JakartaMedium",
fontSize: getResponsiveTextSize(context, 14),
color: Color(0xFF818181),
),
),
), ),
), Container(
), padding: EdgeInsets.symmetric(
Container( horizontal: getResponsivePadding(context),
padding: EdgeInsets.symmetric( vertical: 10,
horizontal: 10, ),
vertical: 10,
),
child: GridView.builder( child: GridView.builder(
itemCount: 4, itemCount: 4,
shrinkWrap: true, shrinkWrap: true,
physics: NeverScrollableScrollPhysics(), physics: NeverScrollableScrollPhysics(),
gridDelegate: gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount( SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, crossAxisCount: 2,
crossAxisSpacing: 10, crossAxisSpacing: isSmallScreen ? 8 : 10,
mainAxisSpacing: 10, mainAxisSpacing: isSmallScreen ? 8 : 10,
childAspectRatio: 20 / 10, childAspectRatio: isSmallScreen ? 18/9 : 20/10,
), ),
itemBuilder: (context, index) { itemBuilder: (context, index) {
final numbers = [ final numbers = [
attendance.presentDays, attendance.presentDays,
attendance.absentDays, attendance.absentDays,
attendance.holidays, attendance.holidays,
attendance.latePenalties, attendance.latePenalties,
]; ];
final names = [ final names = [
"Present \nDays", "Present \nDays",
"Absent \nDays", "Absent \nDays",
"Holidays", "Holidays",
"Late \nPoints", "Late \nPoints",
]; ];
final colors = [ final colors = [
0xFFE7FFE5, 0xFFE7FFE5,
0xFFFFEFEF, 0xFFFFEFEF,
0xFFF3EDFF, 0xFFF3EDFF,
0xFFFFF6F0, 0xFFFFF6F0,
]; ];
final textcolors = [ final textcolors = [
0xFF0D9C00, 0xFF0D9C00,
0xFFFF0000, 0xFFFF0000,
0xFF493272, 0xFF493272,
0xFF91481B, 0xFF91481B,
]; ];
final assetNames = [ final assetNames = [
"assets/svg/attendance/present_ic.svg", "assets/svg/attendance/present_ic.svg",
"assets/svg/attendance/absent_ic.svg", "assets/svg/attendance/absent_ic.svg",
"assets/svg/attendance/holidays_ic.svg", "assets/svg/attendance/holidays_ic.svg",
"assets/svg/attendance/penalty_ic.svg", "assets/svg/attendance/penalty_ic.svg",
]; ];
return Container( return Container(
padding: EdgeInsets.symmetric(horizontal: 13), padding: EdgeInsets.symmetric(
decoration: BoxDecoration( horizontal: isSmallScreen ? 10 : 13
color: Color(colors[index]),
borderRadius: BorderRadius.circular(20),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
numbers[index].toString(),
style: TextStyle(
fontSize: 20,
fontFamily: "JakartaMedium",
color: Color(textcolors[index]),
),
), ),
Row( decoration: BoxDecoration(
color: Color(colors[index]),
borderRadius: BorderRadius.circular(20),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Expanded( Text(
flex: 4, numbers[index].toString(),
child: Text( style: TextStyle(
names[index], fontSize: getResponsiveTextSize(context, 20),
style: TextStyle( fontFamily: "JakartaMedium",
fontSize: 14, color: Color(textcolors[index]),
fontFamily: "JakartaRegular",
color: AppColors.semi_black,
),
), ),
), ),
Expanded( Row(
flex: 1, children: [
child: SvgPicture.asset( Expanded(
assetNames[index], flex: 4,
), child: Text(
names[index],
style: TextStyle(
fontSize: getResponsiveTextSize(context, 14),
fontFamily: "JakartaRegular",
color: AppColors.semi_black,
),
),
),
Expanded(
flex: 1,
child: SvgPicture.asset(
assetNames[index],
width: isSmallScreen ? 20 : 38,
height: isSmallScreen ? 20 : 38,
),
),
],
), ),
], ],
), ),
], );
), },
); ),
}, ),
), ],
), ),
], ),
), SizedBox(height: 15),
),
SizedBox(height: 15), ///calendar
Container(
///calendar margin: EdgeInsets.symmetric(
Container( horizontal: getResponsivePadding(context),
// padding: EdgeInsets.symmetric(horizontal: 10,vertical: 5), vertical: 10
margin: EdgeInsets.symmetric(horizontal: 15, vertical: 10), ),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
color: Colors.white, color: Colors.white,
), ),
child: Column( child: Column(
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.fromLTRB(30, 10, 30, 0), padding: EdgeInsets.fromLTRB(
child: Container( isSmallScreen ? 20 : 30,
child: Row( 10,
mainAxisAlignment: MainAxisAlignment.spaceBetween, isSmallScreen ? 20 : 30,
children: [ 0
SizedBox( ),
child: Row( child: Container(
children: [ child: Row(
GestureDetector( mainAxisAlignment: MainAxisAlignment.spaceBetween,
onTap: () { children: [
attendance.setPreviousMonth(context); SizedBox(
}, child: Row(
child: Padding( children: [
padding: const EdgeInsets.all(4.0), GestureDetector(
child: SvgPicture.asset( onTap: () {
"assets/svg/crm/calendar_left.svg", attendance.setPreviousMonth(context);
},
child: Padding(
padding: const EdgeInsets.all(4.0),
child: SvgPicture.asset(
"assets/svg/crm/calendar_left.svg",
width: isSmallScreen ? 18 : 24,
height: isSmallScreen ? 18 : 24,
),
),
), ),
), Padding(
), padding: const EdgeInsets.symmetric(
Padding( horizontal: 5.0,
padding: const EdgeInsets.symmetric( ),
horizontal: 5.0, child: Text(
), monthLabel,
child: Text( style: TextStyle(
monthLabel, overflow: TextOverflow.ellipsis,
style: TextStyle( fontFamily: "JakartaMedium",
overflow: TextOverflow.ellipsis, fontSize: getResponsiveTextSize(context, 14.5),
fontFamily: "JakartaMedium", color: Color(0xFF2D2D2D),
color: Color(0xFF2D2D2D), ),
),
), ),
), GestureDetector(
), onTap: () {
GestureDetector( attendance.setNextMonth(context);
onTap: () { },
attendance.setNextMonth(context); child: Padding(
}, padding: const EdgeInsets.all(4.0),
child: Padding( child: SvgPicture.asset(
padding: const EdgeInsets.all(4.0), "assets/svg/crm/calendar_right.svg",
child: SvgPicture.asset( width: isSmallScreen ? 18 : 24,
"assets/svg/crm/calendar_right.svg", height: isSmallScreen ? 18 : 24,
),
),
), ),
), ],
), ),
], ),
),
),
InkResponse( InkResponse(
onTap: () { onTap: () {
_showInfoBottomSheet(context); _showInfoBottomSheet(context);
}, },
child: SizedBox( child: SizedBox(
width: 20, width: isSmallScreen ? 18 : 20,
height: 20, height: isSmallScreen ? 18 : 20,
child: SvgPicture.asset( child: SvgPicture.asset(
"assets/svg/ic_info_new.svg", "assets/svg/ic_info_new.svg",
width: 20, width: isSmallScreen ? 18 : 20,
height: 20, height: isSmallScreen ? 18 : 20,
),
),
), ),
), ],
), ),
], ),
), ),
), SizedBox(height: 5),
), Padding(
SizedBox(height: 5), padding: const EdgeInsets.fromLTRB(4, 10, 2, 0),
Padding( child: Container(
padding: const EdgeInsets.fromLTRB(8, 10, 8, 0), child: Row(
child: Container( children: [
child: Row( for (
children: [ var i = 0;
for ( i <
var i = 0; [
i < 'S',
[ 'M',
'S', 'T',
'M', 'W',
'T', 'T',
'W', 'F',
'T', 'S',
'F', ].length;
'S', i++
].length; )
i++ Expanded(
) child: Text(
Expanded( ['S', 'M', 'T', 'W', 'T', 'F', 'S'][i],
child: Text( textAlign: TextAlign.center,
['S', 'M', 'T', 'W', 'T', 'F', 'S'][i], style: TextStyle(
textAlign: TextAlign.center, fontSize: getResponsiveTextSize(context, 15),
style: TextStyle( overflow: TextOverflow.ellipsis,
overflow: TextOverflow.ellipsis, color:
color:
i == 0 i == 0
? Color(0xFFFF0000) ? Color(0xFFFF0000)
: AppColors.semi_black, : AppColors.semi_black,
),
),
), ),
), ],
), ),
], ),
), ),
), SizedBox(height: 3,),
), Padding(
padding: const EdgeInsets.fromLTRB(4, 0, 2, 10),
Padding( child: Container(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 10), child: GridView.builder(
child: Container( itemCount: daysInPeriod + startingIndex,
child: GridView.builder( gridDelegate:
itemCount: daysInPeriod + startingIndex,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount( SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 7, crossAxisCount: 7,
crossAxisSpacing: 2, crossAxisSpacing: 2,
mainAxisSpacing: 1, mainAxisSpacing: 1,
childAspectRatio: (255 / 245), childAspectRatio: isSmallScreen ? 1.0 : (255 / 245),
), ),
padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
shrinkWrap: true, shrinkWrap: true,
physics: NeverScrollableScrollPhysics(), physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, index) { itemBuilder: (context, index) {
if (index < startingIndex) { if (index < startingIndex) {
return SizedBox.shrink(); return SizedBox.shrink();
} }
final dayIndex = index - startingIndex; final dayIndex = index - startingIndex;
final currentDateInPeriod = startDate.add( final currentDateInPeriod = startDate.add(
Duration(days: dayIndex), Duration(days: dayIndex),
); );
final currentDay = currentDateInPeriod.day; final currentDay = currentDateInPeriod.day;
final isFutureDate = currentDateInPeriod final isFutureDate = currentDateInPeriod
.isAfter(currentDate); .isAfter(currentDate);
// Find matching date in dateArrayList // Find matching date in dateArrayList
Map<String, dynamic>? dateMap; Map<String, dynamic>? dateMap;
try { try {
dateMap = dateArrayList[dayIndex]; dateMap = dateArrayList[dayIndex];
} catch (e) { } catch (e) {
dateMap = {}; dateMap = {};
} }
// Find matching penalty // Find matching penalty
Map<String, dynamic>? penaltyMap; Map<String, dynamic>? penaltyMap;
try { try {
penaltyMap = penalityArrayList[dayIndex]; penaltyMap = penalityArrayList[dayIndex];
} catch (e) { } catch (e) {
penaltyMap = {}; penaltyMap = {};
} }
String? dateColor = String? dateColor =
dateMap.isNotEmpty dateMap.isNotEmpty
? dateMap.values.first ? dateMap.values.first
: null; : null;
String? penaltyKey = String? penaltyKey =
penaltyMap.isNotEmpty penaltyMap.isNotEmpty
? penaltyMap.keys.first ? penaltyMap.keys.first
: null; : null;
int? datePenalty = int? datePenalty =
penaltyMap.isNotEmpty penaltyMap.isNotEmpty
? penaltyMap.values.first ? penaltyMap.values.first
: 0; : 0;
// Determine if this is the current day // Determine if this is the current day
final isCurrentDay = final isCurrentDay =
currentDateInPeriod.day == currentDateInPeriod.day ==
currentDate.day && currentDate.day &&
currentDateInPeriod.month == currentDateInPeriod.month ==
currentDate.month && currentDate.month &&
currentDateInPeriod.year == currentDateInPeriod.year ==
currentDate.year; currentDate.year;
return InkWell( return InkWell(
onTap: onTap:
isFutureDate isFutureDate
? null ? null
: () { : () {
selectedIndex = index; selectedIndex = index;
if (penaltyKey != null) { if (penaltyKey != null) {
attendance.dateWiseAttendance( attendance.dateWiseAttendance(
penaltyKey, penaltyKey,
context, context,
); );
} }
attendance.selectedDate = attendance.selectedDate =
currentDay.toString(); currentDay.toString();
_showAttDetailsBottomSheet(context); _showAttDetailsBottomSheet(context);
}, },
child: Card( child: Card(
elevation: 0, elevation: 0,
child: Column( child: Column(
children: [ children: [
// Row( Center(
// mainAxisAlignment: child: Container(
// MainAxisAlignment.center, padding : EdgeInsets.all(2),
// children: [ decoration: BoxDecoration(
// Text( shape: BoxShape.circle,
// "($datePenalty)", border: Border.all(
// style: TextStyle( color:
// fontWeight: FontWeight.w400,
// color: Colors.black,
// fontSize: 5
// ),
// ),
// ],
// ),
Center(
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color:
(isCurrentDay || (isCurrentDay ||
(selectedIndex == (selectedIndex ==
index)) index))
? Color(0xFF1487C9) ? Color(0xFF1487C9)
: Colors.transparent, : Colors.transparent,
), ),
color: color:
isFutureDate isFutureDate
? Colors.transparent ? Colors.transparent
: (isCurrentDay || : (isCurrentDay ||
(selectedIndex == (selectedIndex ==
index)) index))
? Color(0xFFFFFFFF) ? Color(0xFFFFFFFF)
: dateColor == 'g' : dateColor == 'g'
? Color( ? Color(
0xFFE7FFE5, 0xFFE8FFE6,
).withAlpha(50) )
: dateColor == 'r' : dateColor == 'r'
? Color( ? Color(
0xFFFF0000, 0xFFFF0000,
).withAlpha(50) ).withAlpha(50)
: dateColor == 'b' : dateColor == 'b'
? Color( ? Color(
0xFF493272, 0xFF493272,
).withAlpha(50) ).withAlpha(50)
: dateColor == 'br' : dateColor == 'br'
? Color(0xFFFFE8D0) ? Color(0xFFFFE8D0)
: dateColor == 'y' : dateColor == 'y'
? Color(0xFFFFF9B2) ? Color(0xFFFFF9B2)
: Colors.transparent, : Colors.transparent,
), ),
child: Center( child: Center(
child: Text( child: Text(
currentDay.toString(), currentDay.toString(),
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: getResponsiveTextSize(context, 13),
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
color: color:
isFutureDate isFutureDate
? AppColors.semi_black ? AppColors.semi_black
: (isCurrentDay || : (isCurrentDay ||
(selectedIndex == (selectedIndex ==
index)) index))
? Color(0xFF2D2D2D) ? Color(0xFF2D2D2D)
: dateColor == 'g' : dateColor == 'g'
? Color(0xFF0D9C00) ? Color(0xFF0D9C00)
...@@ -656,88 +697,92 @@ class _AttendanceScreenState extends State<AttendanceScreen> { ...@@ -656,88 +697,92 @@ class _AttendanceScreenState extends State<AttendanceScreen> {
: dateColor == 'y' : dateColor == 'y'
? Color(0xFF605C00) ? Color(0xFF605C00)
: Colors.transparent, : Colors.transparent,
),
),
), ),
), ),
), ),
), ],
), ),
], ),
), );
), },
); ),
}, ),
), ),
), ],
), ),
], ),
), SizedBox(height: 25),
],
), ),
SizedBox(height: 25), ),
], bottomNavigationBar:
),
),
bottomNavigationBar:
attendance.attendanceStatus == 0 || attendance.attendanceStatus == 0 ||
attendance.attendanceStatus == 1 attendance.attendanceStatus == 1
? Container( ? Container(
height: 75, height: getResponsiveHeight(context, 75),
decoration: BoxDecoration(color: Colors.white), decoration: BoxDecoration(color: Colors.white),
padding: EdgeInsets.symmetric(vertical: 10), padding: EdgeInsets.symmetric(vertical: 10),
child: Align( child: Align(
alignment: Alignment.center, alignment: Alignment.center,
child: InkWell( child: InkWell(
onTap: () async { onTap: () async {
var res = await Navigator.push( var res = await Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: builder:
(context) => CheckInOutScreen( (context) => CheckInOutScreen(
getAttendanceStatus: getAttendanceStatus:
attendance.attendanceStatus, attendance.attendanceStatus,
),
),
);
if (res == true) {
attendance.getAttendanceList(context);
attendance.init(context);
attendance.loadAttendanceDetails(context);
}
var f = FocusScope.of(context);
if (!f.hasPrimaryFocus) {
f.unfocus();
}
},
child: Container(
alignment: Alignment.bottomCenter,
height: 45,
margin: EdgeInsets.symmetric(horizontal: 10),
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: AppColors.app_blue,
borderRadius: BorderRadius.circular(15.0),
), ),
child: Center( ),
child: Text( );
attendance.attendanceStatus == 0 if (res == true) {
? "Check In" attendance.getAttendanceList(context);
: "Check Out", attendance.init(context);
textAlign: TextAlign.center, attendance.loadAttendanceDetails(context);
style: TextStyle( }
fontSize: 16,
color: Colors.white, var f = FocusScope.of(context);
fontFamily: "JakartaMedium", if (!f.hasPrimaryFocus) {
), f.unfocus();
), }
},
child: Container(
alignment: Alignment.bottomCenter,
height: 45,
margin: EdgeInsets.symmetric(
horizontal: getResponsivePadding(context)
),
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: AppColors.app_blue,
borderRadius: BorderRadius.circular(15.0),
),
child: Center(
child: Text(
attendance.attendanceStatus == 0
? "Check In"
: "Check Out",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: getResponsiveTextSize(context, 16),
color: Colors.white,
fontFamily: "JakartaMedium",
), ),
), ),
), ),
), ),
) ),
),
)
: SizedBox(height: 0), : SizedBox(height: 0),
floatingActionButtonLocation: floatingActionButtonLocation:
FloatingActionButtonLocation.centerFloat, FloatingActionButtonLocation.centerFloat,
), ),
);
},
); );
}, },
); );
...@@ -779,19 +824,19 @@ class _AttendanceScreenState extends State<AttendanceScreen> { ...@@ -779,19 +824,19 @@ class _AttendanceScreenState extends State<AttendanceScreen> {
style: TextStyle( style: TextStyle(
color: AppColors.app_blue, color: AppColors.app_blue,
fontFamily: "JakartaSemiBold", fontFamily: "JakartaSemiBold",
fontSize: 16, fontSize: getResponsiveTextSize(context, 16),
), ),
), ),
SizedBox(height: 15), SizedBox(height: 15),
GridView.builder( GridView.builder(
gridDelegate: gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount( SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3, crossAxisCount: 3,
crossAxisSpacing: 0, crossAxisSpacing: 0,
mainAxisExtent: 40, mainAxisExtent: 40,
mainAxisSpacing: 10, mainAxisSpacing: 10,
childAspectRatio: 6 / 1, childAspectRatio: 6 / 1,
), ),
physics: NeverScrollableScrollPhysics(), physics: NeverScrollableScrollPhysics(),
shrinkWrap: true, shrinkWrap: true,
itemCount: 5, itemCount: 5,
...@@ -825,8 +870,8 @@ class _AttendanceScreenState extends State<AttendanceScreen> { ...@@ -825,8 +870,8 @@ class _AttendanceScreenState extends State<AttendanceScreen> {
Expanded( Expanded(
flex: 1, flex: 1,
child: Container( child: Container(
width: 18, width: 25,
height: 18, height: 25,
decoration: BoxDecoration( decoration: BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,
color: colors[index], color: colors[index],
...@@ -836,7 +881,7 @@ class _AttendanceScreenState extends State<AttendanceScreen> { ...@@ -836,7 +881,7 @@ class _AttendanceScreenState extends State<AttendanceScreen> {
textSubs[index], textSubs[index],
style: TextStyle( style: TextStyle(
color: textColors[index], color: textColors[index],
fontSize: 10, fontSize: getResponsiveTextSize(context, 12),
), ),
), ),
), ),
...@@ -850,7 +895,7 @@ class _AttendanceScreenState extends State<AttendanceScreen> { ...@@ -850,7 +895,7 @@ class _AttendanceScreenState extends State<AttendanceScreen> {
maxLines: 2, maxLines: 2,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: getResponsiveTextSize(context, 14),
color: Colors.black, color: Colors.black,
), ),
), ),
...@@ -878,7 +923,6 @@ class _AttendanceScreenState extends State<AttendanceScreen> { ...@@ -878,7 +923,6 @@ class _AttendanceScreenState extends State<AttendanceScreen> {
isDismissible: true, isDismissible: true,
isScrollControlled: true, isScrollControlled: true,
showDragHandle: true, showDragHandle: true,
enableDrag: true, enableDrag: true,
context: context, context: context,
builder: (context) { builder: (context) {
...@@ -897,7 +941,6 @@ class _AttendanceScreenState extends State<AttendanceScreen> { ...@@ -897,7 +941,6 @@ class _AttendanceScreenState extends State<AttendanceScreen> {
padding: EdgeInsets.only( padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom, bottom: MediaQuery.of(context).viewInsets.bottom,
), ),
child: SingleChildScrollView( child: SingleChildScrollView(
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
...@@ -912,14 +955,14 @@ class _AttendanceScreenState extends State<AttendanceScreen> { ...@@ -912,14 +955,14 @@ class _AttendanceScreenState extends State<AttendanceScreen> {
style: TextStyle( style: TextStyle(
color: AppColors.app_blue, color: AppColors.app_blue,
fontFamily: "JakartaSemiBold", fontFamily: "JakartaSemiBold",
fontSize: 16, fontSize: getResponsiveTextSize(context, 16),
), ),
), ),
Text( Text(
provider.date, provider.date,
style: TextStyle( style: TextStyle(
color: Color(0xFF818181), color: Color(0xFF818181),
fontSize: 12, fontSize: getResponsiveTextSize(context, 12),
), ),
), ),
], ],
...@@ -940,12 +983,14 @@ class _AttendanceScreenState extends State<AttendanceScreen> { ...@@ -940,12 +983,14 @@ class _AttendanceScreenState extends State<AttendanceScreen> {
"Late Points ", "Late Points ",
style: TextStyle( style: TextStyle(
fontFamily: "JakartaMedium", fontFamily: "JakartaMedium",
fontSize: getResponsiveTextSize(context, 14),
), ),
), ),
Text( Text(
provider.penalties, provider.penalties,
style: TextStyle( style: TextStyle(
color: Color(0xFF91481B), color: Color(0xFF91481B),
fontSize: getResponsiveTextSize(context, 14),
), ),
), ),
], ],
...@@ -954,13 +999,12 @@ class _AttendanceScreenState extends State<AttendanceScreen> { ...@@ -954,13 +999,12 @@ class _AttendanceScreenState extends State<AttendanceScreen> {
], ],
), ),
Padding( Padding(
padding: EdgeInsets.symmetric(horizontal: 5), padding: EdgeInsets.symmetric(horizontal: 5, vertical: 15),
child: Divider( child: Divider(
color: Color(0xFFD7D7D7), color: Color(0xFFD7D7D7),
thickness: 0.5, thickness: 0.5,
), ),
), ),
SizedBox(height: 15),
...List.generate(4, (j) { ...List.generate(4, (j) {
final values = [ final values = [
"Check-in Time", "Check-in Time",
...@@ -974,31 +1018,43 @@ class _AttendanceScreenState extends State<AttendanceScreen> { ...@@ -974,31 +1018,43 @@ class _AttendanceScreenState extends State<AttendanceScreen> {
(provider.outtime), (provider.outtime),
(provider.outlocation), (provider.outlocation),
]; ];
return SizedBox(
height: 35, return Container(
margin: EdgeInsets.only(bottom: 12),
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Expanded( Expanded(
flex: 2,
child: Text( child: Text(
values[j], values[j],
style: TextStyle( style: TextStyle(
fontFamily: "JakartaMedium", fontFamily: "JakartaMedium",
color: AppColors.semi_black, color: AppColors.semi_black,
fontSize: getResponsiveTextSize(context, 14),
), ),
maxLines: 2,
overflow: TextOverflow.ellipsis,
), ),
), ),
SizedBox(width: 10),
Expanded( Expanded(
flex: 3,
child: Text( child: Text(
subvalues[j], subvalues[j].isEmpty ? "-" : subvalues[j],
style: TextStyle( style: TextStyle(
color: Color(0xFF818181), color: Color(0xFF818181),
fontSize: getResponsiveTextSize(context, 14),
), ),
maxLines: 3,
overflow: TextOverflow.ellipsis,
), ),
), ),
], ],
), ),
); );
}), }),
SizedBox(height: 10),
], ],
), ),
), ),
...@@ -1011,4 +1067,4 @@ class _AttendanceScreenState extends State<AttendanceScreen> { ...@@ -1011,4 +1067,4 @@ class _AttendanceScreenState extends State<AttendanceScreen> {
}, },
); );
} }
} }
\ No newline at end of file
...@@ -1440,7 +1440,6 @@ class _AddleadsprospectsscreenState extends State<Addleadsprospectsscreen> { ...@@ -1440,7 +1440,6 @@ class _AddleadsprospectsscreenState extends State<Addleadsprospectsscreen> {
null, null,
TextInputAction.done, TextInputAction.done,
), ),
errorWidget(context, provider.addressError), errorWidget(context, provider.addressError),
], ],
), ),
...@@ -1620,4 +1619,33 @@ class _AddleadsprospectsscreenState extends State<Addleadsprospectsscreen> { ...@@ -1620,4 +1619,33 @@ class _AddleadsprospectsscreenState extends State<Addleadsprospectsscreen> {
}, },
); );
} }
void showCustomSnackBar(BuildContext context, String message) {
final snackBar = SnackBar(
behavior: SnackBarBehavior.floating,
backgroundColor: Colors.black87,
elevation: 6,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
content: Row(
children: [
Icon(Icons.info_outline, color: Colors.white),
SizedBox(width: 12),
Expanded(
child: Text(
message,
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w500,
),
),
),
],
),
duration: Duration(seconds: 3),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
} }
...@@ -30,11 +30,43 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> { ...@@ -30,11 +30,43 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
"Casual Leave List" "Casual Leave List"
]; ];
// Responsive text size function
double getResponsiveTextSize(BuildContext context, double baseSize) {
final double scale = MediaQuery.of(context).textScaleFactor;
final double width = MediaQuery.of(context).size.width;
if (width < 360) { // Small phones
return baseSize * 0.85;
} else if (width < 400) { // Medium phones
return baseSize;
} else { // Large phones
return baseSize * 1.1;
}
}
// Responsive padding function
double getResponsivePadding(BuildContext context) {
final double width = MediaQuery.of(context).size.width;
return width * 0.04; // 4% of screen width
}
// Responsive height function
double getResponsiveHeight(BuildContext context, double baseHeight) {
final double height = MediaQuery.of(context).size.height;
if (height < 700) { // Small height devices
return baseHeight * 0.85;
} else if (height < 800) { // Medium height devices
return baseHeight;
} else { // Large height devices
return baseHeight * 1.15;
}
}
@override @override
void initState() { void initState() {
super.initState(); super.initState();
Future.microtask( Future.microtask(
() => Provider.of<HrmAccessiblePagesProvider>( () => Provider.of<HrmAccessiblePagesProvider>(
context, context,
listen: false, listen: false,
).fetchAccessiblePages(context), ).fetchAccessiblePages(context),
...@@ -43,6 +75,9 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> { ...@@ -43,6 +75,9 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final bool isSmallScreen = MediaQuery.of(context).size.width < 360;
final bool isLargeScreen = MediaQuery.of(context).size.width > 400;
return SafeArea( return SafeArea(
top: false, top: false,
child: Scaffold( child: Scaffold(
...@@ -55,14 +90,14 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> { ...@@ -55,14 +90,14 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
onTap: () => Navigator.pop(context, true), onTap: () => Navigator.pop(context, true),
child: SvgPicture.asset( child: SvgPicture.asset(
"assets/svg/appbar_back_button.svg", "assets/svg/appbar_back_button.svg",
height: 25, height: isSmallScreen ? 22 : 25,
), ),
), ),
const SizedBox(width: 10), SizedBox(width: isSmallScreen ? 8 : 10),
Text( Text(
"HRM", "HRM",
style: TextStyle( style: TextStyle(
fontSize: 18, fontSize: getResponsiveTextSize(context, 18),
fontFamily: "Plus Jakarta Sans", fontFamily: "Plus Jakarta Sans",
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: AppColors.semi_black, color: AppColors.semi_black,
...@@ -80,13 +115,16 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> { ...@@ -80,13 +115,16 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
children: [ children: [
Container( Container(
width: double.infinity, width: double.infinity,
height: 490, height: getResponsiveHeight(context, 490),
color: const Color(0xffF6F6F8), color: const Color(0xffF6F6F8),
), ),
Container( Container(
width: double.infinity, width: double.infinity,
height: 490, height: getResponsiveHeight(context, 490),
padding: const EdgeInsets.only(top: 1, bottom: 30), padding: EdgeInsets.only(
top: 1,
bottom: getResponsiveHeight(context, 30)
),
decoration: const BoxDecoration( decoration: const BoxDecoration(
gradient: LinearGradient( gradient: LinearGradient(
colors: [ colors: [
...@@ -101,10 +139,13 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> { ...@@ -101,10 +139,13 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
), ),
Container( Container(
width: double.infinity, width: double.infinity,
padding: const EdgeInsets.only(top: 1, bottom: 30), padding: EdgeInsets.only(
top: 1,
bottom: getResponsiveHeight(context, 30)
),
child: Image.asset( child: Image.asset(
"assets/images/vector.png", "assets/images/vector.png",
height: 230, height: getResponsiveHeight(context, 230),
width: double.infinity, width: double.infinity,
fit: BoxFit.fitWidth, fit: BoxFit.fitWidth,
), ),
...@@ -116,26 +157,27 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> { ...@@ -116,26 +157,27 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
/// Top Illustration & Button /// Top Illustration & Button
Container( Container(
width: double.infinity, width: double.infinity,
padding: const EdgeInsets.only(top: 60, bottom: 30), padding: EdgeInsets.only(
top: getResponsiveHeight(context, 60),
bottom: getResponsiveHeight(context, 30)
),
child: Column( child: Column(
children: [ children: [
SvgPicture.asset( SvgPicture.asset(
"assets/images/capa.svg", "assets/images/capa.svg",
height: 146, height: getResponsiveHeight(context, 146),
width: 400, width: MediaQuery.of(context).size.width * 0.9,
), ),
const SizedBox(height: 32), SizedBox(height: getResponsiveHeight(context, 32)),
Container( Container(
padding: const EdgeInsets.symmetric( padding: EdgeInsets.symmetric(
horizontal: 20, horizontal: isSmallScreen ? 16 : 20,
vertical: 8, vertical: isSmallScreen ? 6 : 8,
), ),
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all( border: Border.all(
color: const Color( color: const Color(0xFF1487C9),
0xFF1487C9, width: 1.2,
), // border color
width: 1.2, // thickness of the border
), ),
color: const Color(0xffEDF8FF), color: const Color(0xffEDF8FF),
borderRadius: BorderRadius.circular(30), borderRadius: BorderRadius.circular(30),
...@@ -154,23 +196,28 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> { ...@@ -154,23 +196,28 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
children: [ children: [
SvgPicture.asset( SvgPicture.asset(
"assets/svg/hrm/groupIc.svg", "assets/svg/hrm/groupIc.svg",
height: 29, height: isSmallScreen ? 25 : 29,
width: 29, width: isSmallScreen ? 25 : 29,
fit: BoxFit.contain, fit: BoxFit.contain,
), ),
const SizedBox(width: 7), SizedBox(width: isSmallScreen ? 5 : 7),
const Text( Flexible(
"Organization Structure", child: Text(
style: TextStyle( "Organization Structure",
fontSize: 15, style: TextStyle(
fontWeight: FontWeight.w500, fontSize: getResponsiveTextSize(context, 15),
fontStyle: FontStyle.normal, fontWeight: FontWeight.w500,
fontFamily: "Plus Jakarta Sans", fontStyle: FontStyle.normal,
fontFamily: "Plus Jakarta Sans",
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
), ),
), ),
const Icon( Icon(
Icons.chevron_right, Icons.chevron_right,
color: Colors.black54, color: Colors.black54,
size: isSmallScreen ? 18 : 20,
), ),
], ],
), ),
...@@ -183,9 +230,13 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> { ...@@ -183,9 +230,13 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
/// Grid Section /// Grid Section
LayoutBuilder( LayoutBuilder(
builder: (context, constraints) { builder: (context, constraints) {
final screenWidth = constraints.maxWidth;
final crossAxisCount = (screenWidth / 180).floor().clamp(2, 4);
final childAspectRatio = screenWidth < 360 ? 1.5 : 1.7;
return Padding( return Padding(
padding: const EdgeInsets.symmetric( padding: EdgeInsets.symmetric(
horizontal: 8, horizontal: getResponsivePadding(context),
vertical: 10, vertical: 10,
), ),
child: Consumer<HrmAccessiblePagesProvider>( child: Consumer<HrmAccessiblePagesProvider>(
...@@ -197,38 +248,40 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> { ...@@ -197,38 +248,40 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
} }
if (provider.errorMessage != null) { if (provider.errorMessage != null) {
return Center( return Center(
child: Text(provider.errorMessage!), child: Text(
provider.errorMessage!,
style: TextStyle(
fontSize: getResponsiveTextSize(context, 14),
),
),
); );
} }
final pages = final pages =
(provider.response?.pagesAccessible ?? []) (provider.response?.pagesAccessible ?? [])
.where( .where(
(page) => allowedPages.contains( (page) => allowedPages.contains(
page.pageName, page.pageName,
), ),
) ).toList();
.toList();
return GridView.builder( return GridView.builder(
itemCount: pages.length, itemCount: pages.length,
shrinkWrap: true, shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
gridDelegate: gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount( SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: (constraints.maxWidth / crossAxisCount: crossAxisCount,
180) crossAxisSpacing: isSmallScreen ? 2 : 4,
.floor() mainAxisSpacing: isSmallScreen ? 2 : 4,
.clamp(2, 6), childAspectRatio: childAspectRatio,
crossAxisSpacing: 1, ),
mainAxisSpacing: 2,
childAspectRatio: 1.8,
),
itemBuilder: (context, index) { itemBuilder: (context, index) {
final page = pages[index]; final page = pages[index];
return _buildTile( return _buildTile(
label: page.pageName ?? "",//in page number there is 6 items comming from serever it showing only four context: context,
label: page.pageName ?? "",
subtitle: _getSubtitle( subtitle: _getSubtitle(
page.pageName ?? "", page.pageName ?? "",
), ),
...@@ -236,10 +289,10 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> { ...@@ -236,10 +289,10 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
txtColor: const Color(0xff1487C9), txtColor: const Color(0xff1487C9),
onTap: onTap:
() => _handleNavigation( () => _handleNavigation(
context, context,
page.pageName ?? "", page.pageName ?? "",
page.mode ?? "", page.mode ?? "",
), ),
); );
}, },
); );
...@@ -249,10 +302,7 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> { ...@@ -249,10 +302,7 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
}, },
), ),
//////////// SizedBox(height: getResponsiveHeight(context, 40)),
SizedBox(height: 40,)
], ],
), ),
], ],
...@@ -266,12 +316,15 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> { ...@@ -266,12 +316,15 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
/// Card builder /// Card builder
Widget _buildTile({ Widget _buildTile({
required BuildContext context,
required String label, required String label,
required String subtitle, required String subtitle,
required String assetIcon, required String assetIcon,
required Color txtColor, required Color txtColor,
VoidCallback? onTap, VoidCallback? onTap,
}) { }) {
final bool isSmallScreen = MediaQuery.of(context).size.width < 360;
return LayoutBuilder( return LayoutBuilder(
builder: (context, constraints) { builder: (context, constraints) {
return InkWell( return InkWell(
...@@ -279,18 +332,28 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> { ...@@ -279,18 +332,28 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
borderRadius: BorderRadius.circular(14), borderRadius: BorderRadius.circular(14),
child: Container( child: Container(
padding: EdgeInsets.symmetric( padding: EdgeInsets.symmetric(
vertical: constraints.maxHeight * 0.05, vertical: constraints.maxHeight * 0.08,
horizontal: constraints.maxWidth * 0.05, horizontal: constraints.maxWidth * 0.06,
),
margin: EdgeInsets.symmetric(
vertical: isSmallScreen ? 4 : 7,
horizontal: isSmallScreen ? 3 : 5
), ),
margin: const EdgeInsets.symmetric(vertical: 7, horizontal: 5),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: Colors.white,
borderRadius: BorderRadius.circular(14), borderRadius: BorderRadius.circular(14),
// boxShadow: [
// BoxShadow(
// color: Colors.black12,
// blurRadius: 4,
// offset: Offset(0, 2),
// ),
// ],
), ),
child: Row( child: Row(
children: [ children: [
Expanded( Expanded(
flex: 2, flex: 3,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
...@@ -299,25 +362,29 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> { ...@@ -299,25 +362,29 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
child: Text( child: Text(
label, label,
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: getResponsiveTextSize(context, 14),
color: AppColors.app_blue, color: AppColors.app_blue,
fontFamily: "JakartaMedium", fontFamily: "JakartaMedium",
height: 1.2,
), ),
softWrap: true, softWrap: true,
overflow: TextOverflow.visible, overflow: TextOverflow.ellipsis,
maxLines: isSmallScreen ? 2 : 3,
), ),
), ),
const SizedBox(height: 4), SizedBox(height: isSmallScreen ? 2 : 6),
Flexible( Flexible(
child: Text( child: Text(
subtitle, subtitle,
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: getResponsiveTextSize(context, 12),
color: AppColors.grey_semi, color: AppColors.grey_semi,
fontFamily: "JakartaMedium", fontFamily: "JakartaMedium",
height: 1,
), ),
softWrap: true, softWrap: true,
overflow: TextOverflow.visible, overflow: TextOverflow.ellipsis,
maxLines: 2,
), ),
), ),
], ],
...@@ -326,8 +393,8 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> { ...@@ -326,8 +393,8 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
Expanded( Expanded(
flex: 1, flex: 1,
child: Container( child: Container(
height: constraints.maxHeight * 0.39, height: constraints.maxHeight * 0.45,
width: constraints.maxHeight * 0.39, width: constraints.maxHeight * 0.45,
decoration: BoxDecoration( decoration: BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,
color: const Color(0xFFEDF8FF), color: const Color(0xFFEDF8FF),
...@@ -335,8 +402,8 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> { ...@@ -335,8 +402,8 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
child: Center( child: Center(
child: SvgPicture.asset( child: SvgPicture.asset(
assetIcon, assetIcon,
height: constraints.maxHeight * 0.19, height: constraints.maxHeight * 0.22,
width: constraints.maxHeight * 0.19, width: constraints.maxHeight * 0.22,
), ),
), ),
), ),
...@@ -361,9 +428,9 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> { ...@@ -361,9 +428,9 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
case "Tour Bill List": case "Tour Bill List":
return "Submit and manage claims"; return "Submit and manage claims";
case "Team Leave Request Approval": case "Team Leave Request Approval":
return ""; return "Approve & Reject";
case "Team Attendance Approval": case "Team Attendance Approval":
return ""; return "Team Attendance Request";
case "Advance List": case "Advance List":
return "Advance Payment"; return "Advance Payment";
case "Casual Leave List": case "Casual Leave List":
...@@ -469,4 +536,4 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> { ...@@ -469,4 +536,4 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
break; break;
} }
} }
} }
\ No newline at end of file
...@@ -15,8 +15,42 @@ class RewardListScreen extends StatefulWidget { ...@@ -15,8 +15,42 @@ class RewardListScreen extends StatefulWidget {
} }
class _RewardListScreenState extends State<RewardListScreen> { class _RewardListScreenState extends State<RewardListScreen> {
// Responsive text size function
double getResponsiveTextSize(BuildContext context, double baseSize) {
final double width = MediaQuery.of(context).size.width;
if (width < 360) { // Small phones
return baseSize * 0.85;
} else if (width < 400) { // Medium phones
return baseSize;
} else { // Large phones
return baseSize * 1.1;
}
}
// Responsive padding function
double getResponsivePadding(BuildContext context) {
final double width = MediaQuery.of(context).size.width;
return width * 0.04; // 4% of screen width
}
// Responsive height function
double getResponsiveHeight(BuildContext context, double baseHeight) {
final double height = MediaQuery.of(context).size.height;
if (height < 700) { // Small height devices
return baseHeight * 0.85;
} else if (height < 800) { // Medium height devices
return baseHeight;
} else { // Large height devices
return baseHeight * 1.15;
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final bool isSmallScreen = MediaQuery.of(context).size.width < 360;
final bool isLargeScreen = MediaQuery.of(context).size.width > 400;
return SafeArea( return SafeArea(
top: false, top: false,
child: ChangeNotifierProvider( child: ChangeNotifierProvider(
...@@ -33,14 +67,14 @@ class _RewardListScreenState extends State<RewardListScreen> { ...@@ -33,14 +67,14 @@ class _RewardListScreenState extends State<RewardListScreen> {
onTap: () => Navigator.pop(context, true), onTap: () => Navigator.pop(context, true),
child: SvgPicture.asset( child: SvgPicture.asset(
"assets/svg/appbar_back_button.svg", "assets/svg/appbar_back_button.svg",
height: 25, height: isSmallScreen ? 22 : 25,
), ),
), ),
const SizedBox(width: 10), SizedBox(width: isSmallScreen ? 8 : 10),
Text( Text(
"Reward List", "Reward List",
style: TextStyle( style: TextStyle(
fontSize: 18, fontSize: getResponsiveTextSize(context, 18),
fontFamily: "Plus Jakarta Sans", fontFamily: "Plus Jakarta Sans",
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: AppColors.semi_black, color: AppColors.semi_black,
...@@ -64,10 +98,10 @@ class _RewardListScreenState extends State<RewardListScreen> { ...@@ -64,10 +98,10 @@ class _RewardListScreenState extends State<RewardListScreen> {
// }, // },
// child: SvgPicture.asset( // child: SvgPicture.asset(
// "assets/svg/search_ic.svg", // "assets/svg/search_ic.svg",
// height: 25, // height: isSmallScreen ? 22 : 25,
// ), // ),
// ), // ),
// const SizedBox(width: 20), // SizedBox(width: isSmallScreen ? 15 : 20),
// ], // ],
), ),
...@@ -80,10 +114,24 @@ class _RewardListScreenState extends State<RewardListScreen> { ...@@ -80,10 +114,24 @@ class _RewardListScreenState extends State<RewardListScreen> {
); );
} }
if (provider.errorMessage != null) { if (provider.errorMessage != null) {
return Center(child: Text(provider.errorMessage!)); return Center(
child: Text(
provider.errorMessage!,
style: TextStyle(
fontSize: getResponsiveTextSize(context, 14),
),
),
);
} }
if (provider.response == null) { if (provider.response == null) {
return const Center(child: Text("No details found")); return Center(
child: Text(
"No details found",
style: TextStyle(
fontSize: getResponsiveTextSize(context, 14),
),
),
);
} }
final rewardDetail = provider.response!; final rewardDetail = provider.response!;
final rewardResponse = provider.response!; final rewardResponse = provider.response!;
...@@ -93,16 +141,16 @@ class _RewardListScreenState extends State<RewardListScreen> { ...@@ -93,16 +141,16 @@ class _RewardListScreenState extends State<RewardListScreen> {
final disbursed = rewardResponse.disbursedAmount ?? "0"; final disbursed = rewardResponse.disbursedAmount ?? "0";
final balance = rewardResponse.balanceAmount ?? "0"; final balance = rewardResponse.balanceAmount ?? "0";
return SingleChildScrollView( return SingleChildScrollView(
padding: const EdgeInsets.all(16), padding: EdgeInsets.all(getResponsivePadding(context)),
child: Column( child: Column(
children: [ children: [
/// --- Top Summary Cards --- /// --- Top Summary Cards ---
Stack( Stack(
children: [ children: [
Container( Container(
height: 110, height: getResponsiveHeight(context, 110),
width: double.infinity, width: double.infinity,
padding: const EdgeInsets.all(18), padding: EdgeInsets.all(isSmallScreen ? 14 : 18),
decoration: BoxDecoration( decoration: BoxDecoration(
color: const Color(0xffd9ffd6), color: const Color(0xffd9ffd6),
borderRadius: BorderRadius.circular(18), borderRadius: BorderRadius.circular(18),
...@@ -113,19 +161,19 @@ class _RewardListScreenState extends State<RewardListScreen> { ...@@ -113,19 +161,19 @@ class _RewardListScreenState extends State<RewardListScreen> {
children: [ children: [
Text( Text(
"₹$achieved", // Achieved Amount from response "₹$achieved", // Achieved Amount from response
style: const TextStyle( style: TextStyle(
fontSize: 20, fontSize: getResponsiveTextSize(context, 20),
color: Color(0xff0D9C00), color: const Color(0xff0D9C00),
fontStyle: FontStyle.normal, fontStyle: FontStyle.normal,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
), ),
), ),
const SizedBox(height: 10), SizedBox(height: isSmallScreen ? 6 : 10),
const Text( Text(
"Achievement Amount", "Achievement Amount",
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: getResponsiveTextSize(context, 14),
color: Color(0xff2D2D2D), color: const Color(0xff2D2D2D),
fontStyle: FontStyle.normal, fontStyle: FontStyle.normal,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
), ),
...@@ -136,19 +184,19 @@ class _RewardListScreenState extends State<RewardListScreen> { ...@@ -136,19 +184,19 @@ class _RewardListScreenState extends State<RewardListScreen> {
// Positioned SVG Icon // Positioned SVG Icon
Positioned( Positioned(
bottom: 8, bottom: isSmallScreen ? 6 : 8,
right: 12, right: isSmallScreen ? 10 : 12,
child: Container( child: Container(
height: 42, height: isSmallScreen ? 36 : 42,
width: 42, width: isSmallScreen ? 36 : 42,
decoration: BoxDecoration( decoration: BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,
color: const Color(0xA0FFFFFF), // icon bg color: const Color(0xA0FFFFFF), // icon bg
), ),
child: Center( child: Center(
child: SvgPicture.asset( child: SvgPicture.asset(
height: 25, height: isSmallScreen ? 20 : 25,
width: 25, width: isSmallScreen ? 20 : 25,
"assets/svg/hrm/achievement_ic.svg", "assets/svg/hrm/achievement_ic.svg",
fit: BoxFit.contain, fit: BoxFit.contain,
), ),
...@@ -157,14 +205,14 @@ class _RewardListScreenState extends State<RewardListScreen> { ...@@ -157,14 +205,14 @@ class _RewardListScreenState extends State<RewardListScreen> {
), ),
], ],
), ),
const SizedBox(height: 12), SizedBox(height: isSmallScreen ? 8 : 12),
Row( Row(
children: [ children: [
Expanded( Expanded(
child: Container( child: Container(
height: 110, height: getResponsiveHeight(context, 110),
padding: const EdgeInsets.all(16), padding: EdgeInsets.all(isSmallScreen ? 12 : 16),
decoration: BoxDecoration( decoration: BoxDecoration(
color: const Color(0xffe8ddff), color: const Color(0xffe8ddff),
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
...@@ -173,22 +221,22 @@ class _RewardListScreenState extends State<RewardListScreen> { ...@@ -173,22 +221,22 @@ class _RewardListScreenState extends State<RewardListScreen> {
children: [ children: [
Column( Column(
crossAxisAlignment: crossAxisAlignment:
CrossAxisAlignment.start, CrossAxisAlignment.start,
children: [ children: [
Text( Text(
"₹$disbursed", // Disbursed Amount "₹$disbursed", // Disbursed Amount
style: const TextStyle( style: TextStyle(
fontSize: 20, fontSize: getResponsiveTextSize(context, 20),
color: Color(0xff493272), color: const Color(0xff493272),
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
), ),
), ),
const SizedBox(height: 8), SizedBox(height: isSmallScreen ? 6 : 8),
const Text( Text(
"Disbursed \nAmount", "Disbursed \nAmount",
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: getResponsiveTextSize(context, 14),
color: Color(0xff2D2D2D), color: const Color(0xff2D2D2D),
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
), ),
), ),
...@@ -198,18 +246,16 @@ class _RewardListScreenState extends State<RewardListScreen> { ...@@ -198,18 +246,16 @@ class _RewardListScreenState extends State<RewardListScreen> {
bottom: 2, bottom: 2,
right: 2, right: 2,
child: Container( child: Container(
height: 42, height: isSmallScreen ? 36 : 42,
width: 42, width: isSmallScreen ? 36 : 42,
decoration: BoxDecoration( decoration: BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,
color: const Color( color: const Color(0xA0FFFFFF),
0xA0FFFFFF,
), // icon bg
), ),
child: Center( child: Center(
child: SvgPicture.asset( child: SvgPicture.asset(
height: 25, height: isSmallScreen ? 20 : 25,
width: 25, width: isSmallScreen ? 20 : 25,
"assets/svg/hrm/location_ic.svg", "assets/svg/hrm/location_ic.svg",
fit: BoxFit.contain, fit: BoxFit.contain,
), ),
...@@ -220,11 +266,11 @@ class _RewardListScreenState extends State<RewardListScreen> { ...@@ -220,11 +266,11 @@ class _RewardListScreenState extends State<RewardListScreen> {
), ),
), ),
), ),
const SizedBox(width: 12), SizedBox(width: isSmallScreen ? 8 : 12),
Expanded( Expanded(
child: Container( child: Container(
height: 110, height: getResponsiveHeight(context, 110),
padding: const EdgeInsets.all(16), padding: EdgeInsets.all(isSmallScreen ? 12 : 16),
decoration: BoxDecoration( decoration: BoxDecoration(
color: const Color(0xfffffbc3), color: const Color(0xfffffbc3),
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
...@@ -233,21 +279,21 @@ class _RewardListScreenState extends State<RewardListScreen> { ...@@ -233,21 +279,21 @@ class _RewardListScreenState extends State<RewardListScreen> {
children: [ children: [
Column( Column(
crossAxisAlignment: crossAxisAlignment:
CrossAxisAlignment.start, CrossAxisAlignment.start,
children: [ children: [
Text( Text(
"₹$balance", // Balance Amount "₹$balance", // Balance Amount
style: const TextStyle( style: TextStyle(
fontSize: 18, fontSize: getResponsiveTextSize(context, 18),
color: Color(0xff605C00), color: const Color(0xff605C00),
), ),
), ),
const SizedBox(height: 8), SizedBox(height: isSmallScreen ? 6 : 8),
const Text( Text(
"Balance \nAmount", "Balance \nAmount",
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: getResponsiveTextSize(context, 14),
color: Color(0xff2D2D2D), color: const Color(0xff2D2D2D),
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
), ),
), ),
...@@ -257,18 +303,16 @@ class _RewardListScreenState extends State<RewardListScreen> { ...@@ -257,18 +303,16 @@ class _RewardListScreenState extends State<RewardListScreen> {
bottom: 2, bottom: 2,
right: 2, right: 2,
child: Container( child: Container(
height: 42, height: isSmallScreen ? 36 : 42,
width: 42, width: isSmallScreen ? 36 : 42,
decoration: BoxDecoration( decoration: BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,
color: const Color( color: const Color(0xA0FFFFFF),
0xA0FFFFFF,
), // icon bg
), ),
child: Center( child: Center(
child: SvgPicture.asset( child: SvgPicture.asset(
height: 25, height: isSmallScreen ? 20 : 25,
width: 25, width: isSmallScreen ? 20 : 25,
"assets/svg/hrm/ballance_ic.svg", "assets/svg/hrm/ballance_ic.svg",
fit: BoxFit.contain, fit: BoxFit.contain,
), ),
...@@ -282,14 +326,13 @@ class _RewardListScreenState extends State<RewardListScreen> { ...@@ -282,14 +326,13 @@ class _RewardListScreenState extends State<RewardListScreen> {
], ],
), ),
const SizedBox(height: 20), SizedBox(height: getResponsiveHeight(context, 20)),
/// --- Reward List Card --- /// --- Reward List Card ---
if (rewards != null) if (rewards != null)
_rewardListCard( _rewardListCard(
title: context: context,
rewards.description ?? title: rewards.description ?? "-",
"-", // rewardsList fields
dateTime: rewards.dateTime ?? "-", dateTime: rewards.dateTime ?? "-",
achieved: achieved, achieved: achieved,
disbursed: disbursed, disbursed: disbursed,
...@@ -297,7 +340,12 @@ class _RewardListScreenState extends State<RewardListScreen> { ...@@ -297,7 +340,12 @@ class _RewardListScreenState extends State<RewardListScreen> {
enteredBy: rewards.enteredBy ?? "-", enteredBy: rewards.enteredBy ?? "-",
) )
else else
const Text("No rewards available"), Text(
"No rewards available",
style: TextStyle(
fontSize: getResponsiveTextSize(context, 14),
),
),
], ],
), ),
); );
...@@ -312,6 +360,7 @@ class _RewardListScreenState extends State<RewardListScreen> { ...@@ -312,6 +360,7 @@ class _RewardListScreenState extends State<RewardListScreen> {
/// Reusable Reward Card Function /// Reusable Reward Card Function
Widget _rewardListCard({ Widget _rewardListCard({
required BuildContext context,
required String title, required String title,
required String dateTime, required String dateTime,
required String achieved, required String achieved,
...@@ -319,19 +368,14 @@ class _RewardListScreenState extends State<RewardListScreen> { ...@@ -319,19 +368,14 @@ class _RewardListScreenState extends State<RewardListScreen> {
required String balance, required String balance,
required String enteredBy, required String enteredBy,
}) { }) {
final bool isSmallScreen = MediaQuery.of(context).size.width < 360;
return Container( return Container(
margin: const EdgeInsets.only(bottom: 16), margin: EdgeInsets.only(bottom: getResponsiveHeight(context, 16)),
padding: const EdgeInsets.all(16), padding: EdgeInsets.all(isSmallScreen ? 12 : 16),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: Colors.white,
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
// boxShadow: [
// BoxShadow(
// color: Colors.grey.withOpacity(0.1),
// blurRadius: 6,
// offset: const Offset(0, 3),
// )
// ],
), ),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
...@@ -340,35 +384,38 @@ class _RewardListScreenState extends State<RewardListScreen> { ...@@ -340,35 +384,38 @@ class _RewardListScreenState extends State<RewardListScreen> {
Row( Row(
children: [ children: [
CircleAvatar( CircleAvatar(
radius: 22.5, radius: isSmallScreen ? 18 : 22.5,
backgroundColor: Color(0xffEDF8FF), backgroundColor: Color(0xffEDF8FF),
child: SvgPicture.asset( child: SvgPicture.asset(
height: 28, height: isSmallScreen ? 22 : 28,
width: 28, width: isSmallScreen ? 22 : 28,
"assets/svg/hrm/rewardList.svg", "assets/svg/hrm/rewardList.svg",
fit: BoxFit.contain, fit: BoxFit.contain,
), ),
), ),
const SizedBox(width: 8), SizedBox(width: isSmallScreen ? 6 : 8),
Expanded( Expanded(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
title, title,
style: const TextStyle( style: TextStyle(
fontSize: 14.5, fontSize: getResponsiveTextSize(context, 14.5),
color: Color(0xff2D2D2D), color: const Color(0xff2D2D2D),
fontFamily: "Plus Jakarta Sans", fontFamily: "Plus Jakarta Sans",
fontStyle: FontStyle.normal, fontStyle: FontStyle.normal,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
), ),
maxLines: 2,
overflow: TextOverflow.ellipsis,
), ),
SizedBox(height: isSmallScreen ? 2 : 4),
Text( Text(
dateTime, dateTime,
style: const TextStyle( style: TextStyle(
fontSize: 12.5, fontSize: getResponsiveTextSize(context, 12.5),
color: Color(0xff818181), color: const Color(0xff818181),
fontFamily: "Plus Jakarta Sans", fontFamily: "Plus Jakarta Sans",
fontStyle: FontStyle.normal, fontStyle: FontStyle.normal,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
...@@ -380,18 +427,21 @@ class _RewardListScreenState extends State<RewardListScreen> { ...@@ -380,18 +427,21 @@ class _RewardListScreenState extends State<RewardListScreen> {
], ],
), ),
const SizedBox(height: 12), SizedBox(height: isSmallScreen ? 8 : 12),
/// Amount Details /// Amount Details
Padding( Padding(
padding: const EdgeInsets.all(2.0), padding: const EdgeInsets.all(2.0),
child: Row( child: Row(
children: [ children: [
const Text( Text(
"Amount Details", "Amount Details",
style: TextStyle(fontSize: 14, fontFamily: "JakartaSemiBold"), style: TextStyle(
fontSize: getResponsiveTextSize(context, 14),
fontFamily: "JakartaSemiBold"
),
), ),
const SizedBox(width: 10), SizedBox(width: isSmallScreen ? 6 : 10),
Expanded( Expanded(
child: DottedLine( child: DottedLine(
dashGapLength: 4, dashGapLength: 4,
...@@ -404,24 +454,27 @@ class _RewardListScreenState extends State<RewardListScreen> { ...@@ -404,24 +454,27 @@ class _RewardListScreenState extends State<RewardListScreen> {
], ],
), ),
), ),
const SizedBox(height: 6), SizedBox(height: isSmallScreen ? 4 : 6),
_buildKeyValue("Achieved Amount", achieved), _buildKeyValue(context, "Achieved Amount", achieved),
_buildKeyValue("Disbursed Amount", disbursed), _buildKeyValue(context, "Disbursed Amount", disbursed),
_buildKeyValue("Balance Amount", balance), _buildKeyValue(context, "Balance Amount", balance),
const SizedBox(height: 10), SizedBox(height: isSmallScreen ? 8 : 10),
/// Employee Details /// Employee Details
Padding( Padding(
padding: const EdgeInsets.all(2.0), padding: const EdgeInsets.all(2.0),
child: Row( child: Row(
children: [ children: [
const Text( Text(
"Employee Details", "Employee Details",
style: TextStyle(fontSize: 14, fontFamily: "JakartaSemiBold"), style: TextStyle(
fontSize: getResponsiveTextSize(context, 14),
fontFamily: "JakartaSemiBold"
),
), ),
const SizedBox(width: 10), SizedBox(width: isSmallScreen ? 6 : 10),
Expanded( Expanded(
child: DottedLine( child: DottedLine(
dashGapLength: 4, dashGapLength: 4,
...@@ -435,34 +488,52 @@ class _RewardListScreenState extends State<RewardListScreen> { ...@@ -435,34 +488,52 @@ class _RewardListScreenState extends State<RewardListScreen> {
), ),
), ),
_buildKeyValue("Entered By", enteredBy), _buildKeyValue(context, "Entered By", enteredBy),
], ],
), ),
); );
} }
/// Key-Value Row /// Key-Value Row
Widget _buildKeyValue(String key, String value) { Widget _buildKeyValue(BuildContext context, String key, String value) {
final bool isSmallScreen = MediaQuery.of(context).size.width < 360;
return Padding( return Padding(
padding: const EdgeInsets.symmetric(vertical: 3.5, horizontal: 2), padding: EdgeInsets.symmetric(
vertical: isSmallScreen ? 2.5 : 3.5,
horizontal: 2
),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Expanded(
key, flex: 2,
style: TextStyle( child: Text(
fontFamily: "JakartaRegular", key,
fontSize: 14, style: TextStyle(
color: AppColors.semi_black, fontFamily: "JakartaRegular",
fontSize: getResponsiveTextSize(context, 14),
color: AppColors.semi_black,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
), ),
), ),
Expanded(
Text( flex: 1,
value, child: Text(
style: const TextStyle(fontSize: 14, color: Color(0xFF818181)), value,
style: TextStyle(
fontSize: getResponsiveTextSize(context, 14),
color: const Color(0xFF818181)
),
textAlign: TextAlign.right,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
), ),
], ],
), ),
); );
} }
} }
\ No newline at end of file
...@@ -445,10 +445,10 @@ packages: ...@@ -445,10 +445,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: fake_async name: fake_async
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.3" version: "1.3.2"
ffi: ffi:
dependency: transitive dependency: transitive
description: description:
...@@ -1180,26 +1180,26 @@ packages: ...@@ -1180,26 +1180,26 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: leak_tracker name: leak_tracker
sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "11.0.2" version: "10.0.8"
leak_tracker_flutter_testing: leak_tracker_flutter_testing:
dependency: transitive dependency: transitive
description: description:
name: leak_tracker_flutter_testing name: leak_tracker_flutter_testing
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.10" version: "3.0.9"
leak_tracker_testing: leak_tracker_testing:
dependency: transitive dependency: transitive
description: description:
name: leak_tracker_testing name: leak_tracker_testing
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.2" version: "3.0.1"
lints: lints:
dependency: transitive dependency: transitive
description: description:
...@@ -1873,10 +1873,10 @@ packages: ...@@ -1873,10 +1873,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.6" version: "0.7.4"
timezone: timezone:
dependency: transitive dependency: transitive
description: description:
...@@ -2017,10 +2017,10 @@ packages: ...@@ -2017,10 +2017,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: vector_math name: vector_math
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.0" version: "2.1.4"
vm_service: vm_service:
dependency: transitive dependency: transitive
description: description:
...@@ -2118,5 +2118,5 @@ packages: ...@@ -2118,5 +2118,5 @@ packages:
source: hosted source: hosted
version: "3.1.3" version: "3.1.3"
sdks: sdks:
dart: ">=3.8.0-0 <3.10.0-z" dart: ">=3.7.2 <3.10.0-z"
flutter: ">=3.27.0" flutter: ">=3.27.0"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment