chnages has been made for the request leave and request advance

This commit is contained in:
Daniah Ayad Al-sultani
2025-12-07 12:53:43 +03:00
parent dbf76b2d30
commit db044cb039
6 changed files with 238 additions and 225 deletions

View File

@@ -15,20 +15,33 @@ class HolidayScreen extends StatefulWidget {
class _HolidayScreenState extends State<HolidayScreen> {
int activeTab = 0; // 0 = السلف | 1 = الأجازات
// Use the singleton instance
final RequestService _requestService = RequestService();
late Future<List<LeaveRequest>> _leaveRequestsFuture;
late Future<List<AdvanceRequest>> _advanceRequestsFuture;
late List<LeaveRequest> _leaveRequests;
late List<AdvanceRequest> _advanceRequests;
@override
void initState() {
super.initState();
_refreshData();
_initializeData();
}
void _refreshData() {
setState(() {
_leaveRequestsFuture = Future.value(_requestService.leaveRequests);
_advanceRequestsFuture = Future.value(_requestService.advanceRequests);
void _initializeData() async {
// Get initial data
_leaveRequests = await _requestService.getLeaveRequests();
_advanceRequests = await _requestService.getAdvanceRequests();
// Listen for updates
_requestService.leaveRequestsStream.listen((requests) {
setState(() {
_leaveRequests = requests;
});
});
_requestService.advanceRequestsStream.listen((requests) {
setState(() {
_advanceRequests = requests;
});
});
}
@@ -36,7 +49,7 @@ class _HolidayScreenState extends State<HolidayScreen> {
switch (status) {
case 'approved':
return Colors.green;
case 'rejected':
case 'denied':
return Colors.red;
default:
return Colors.orange;
@@ -47,13 +60,24 @@ class _HolidayScreenState extends State<HolidayScreen> {
switch (status) {
case 'approved':
return 'موافق عليه';
case 'rejected':
case 'denied':
return 'مرفوض';
default:
return 'قيد الانتظار';
}
}
String _getStatusIconPath(String status) {
switch (status) {
case 'approved':
return "assets/images/yes.svg";
case 'denied':
return "assets/images/no.svg";
default:
return "assets/images/waiting.svg";
}
}
@override
Widget build(BuildContext context) {
return Directionality(
@@ -148,14 +172,15 @@ class _HolidayScreenState extends State<HolidayScreen> {
svgPath: "assets/images/money2.svg",
iconWidth: 38,
iconHeight: 30,
onTap: () {
onTap: () async {
// Navigate to RequestAdvanceScreen
Navigator.push(
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const RequestAdvanceScreen(),
),
).then((_) => _refreshData()); // Refresh data when returning
);
// Data will be updated automatically through the stream
},
),
const SizedBox(height: 18),
@@ -166,13 +191,14 @@ class _HolidayScreenState extends State<HolidayScreen> {
svgPath: "assets/images/plus.svg",
iconWidth: 30,
iconHeight: 30,
onTap: () {
Navigator.push(
onTap: () async {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const RequestLeaveScreen(),
),
).then((_) => _refreshData()); // Refresh data when returning
);
// Data will be updated automatically through the stream
},
),
],
@@ -184,80 +210,60 @@ class _HolidayScreenState extends State<HolidayScreen> {
}
Widget _buildLeaveRequestsTab() {
return FutureBuilder<List<LeaveRequest>>(
future: _leaveRequestsFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator(color: Colors.white));
} else if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}', style: TextStyle(color: Colors.white)));
} else if (!snapshot.hasData || snapshot.data!.isEmpty) {
return const Center(
child: Text(
'لا توجد طلبات أجازة',
style: TextStyle(
color: Colors.white,
fontSize: 18,
),
),
);
}
final leaveRequests = snapshot.data!;
return RefreshIndicator(
onRefresh: () async {
_refreshData();
},
color: Colors.white,
child: ListView.builder(
padding: const EdgeInsets.symmetric(horizontal: 25, vertical: 20),
itemCount: leaveRequests.length,
itemBuilder: (context, index) {
final request = leaveRequests[index];
return _buildLeaveRequestCard(request);
},
if (_leaveRequests.isEmpty) {
return const Center(
child: Text(
'لا توجد طلبات أجازة',
style: TextStyle(
color: Colors.white,
fontSize: 18,
),
);
),
);
}
return RefreshIndicator(
onRefresh: () async {
_initializeData();
},
color: Colors.white,
child: ListView.builder(
padding: const EdgeInsets.symmetric(horizontal: 25, vertical: 20),
itemCount: _leaveRequests.length,
itemBuilder: (context, index) {
final request = _leaveRequests[index];
return _buildLeaveRequestCard(request);
},
),
);
}
Widget _buildAdvanceRequestsTab() {
return FutureBuilder<List<AdvanceRequest>>(
future: _advanceRequestsFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator(color: Colors.white));
} else if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}', style: TextStyle(color: Colors.white)));
} else if (!snapshot.hasData || snapshot.data!.isEmpty) {
return const Center(
child: Text(
'لا توجد طلبات سلف',
style: TextStyle(
color: Colors.white,
fontSize: 18,
),
),
);
}
final advanceRequests = snapshot.data!;
return RefreshIndicator(
onRefresh: () async {
_refreshData();
},
color: Colors.white,
child: ListView.builder(
padding: const EdgeInsets.symmetric(horizontal: 25, vertical: 20),
itemCount: advanceRequests.length,
itemBuilder: (context, index) {
final request = advanceRequests[index];
return _buildAdvanceRequestCard(request);
},
if (_advanceRequests.isEmpty) {
return const Center(
child: Text(
'لا توجد طلبات سلف',
style: TextStyle(
color: Colors.white,
fontSize: 18,
),
);
),
);
}
return RefreshIndicator(
onRefresh: () async {
_initializeData();
},
color: Colors.white,
child: ListView.builder(
padding: const EdgeInsets.symmetric(horizontal: 25, vertical: 20),
itemCount: _advanceRequests.length,
itemBuilder: (context, index) {
final request = _advanceRequests[index];
return _buildAdvanceRequestCard(request);
},
),
);
}
@@ -283,19 +289,18 @@ class _HolidayScreenState extends State<HolidayScreen> {
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// Status icon instead of text
Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: _getStatusColor(request.status),
borderRadius: BorderRadius.circular(20),
shape: BoxShape.circle,
),
child: Text(
_getStatusText(request.status),
style: const TextStyle(
color: Colors.white,
fontSize: 14,
fontWeight: FontWeight.w600,
),
child: SvgPicture.asset(
_getStatusIconPath(request.status),
width: 24,
height: 24,
color: Colors.white,
),
),
Text(
@@ -399,43 +404,24 @@ class _HolidayScreenState extends State<HolidayScreen> {
),
),
// Action buttons for pending requests
if (request.status == 'pending') ...[
const SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
// Status text below the card
const SizedBox(height: 8),
Directionality(
textDirection: TextDirection.rtl,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
_updateLeaveRequestStatus(request.id, 'approved');
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
Text(
_getStatusText(request.status),
style: TextStyle(
color: _getStatusColor(request.status),
fontSize: 14,
fontWeight: FontWeight.w600,
),
child: const Text('موافق'),
),
ElevatedButton(
onPressed: () {
_updateLeaveRequestStatus(request.id, 'rejected');
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
),
child: const Text('رفض'),
),
],
),
],
),
],
),
);
@@ -459,23 +445,22 @@ class _HolidayScreenState extends State<HolidayScreen> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
// Header with status
// Header with status icon
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// Status icon instead of text
Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: _getStatusColor(request.status),
borderRadius: BorderRadius.circular(20),
shape: BoxShape.circle,
),
child: Text(
_getStatusText(request.status),
style: const TextStyle(
color: Colors.white,
fontSize: 14,
fontWeight: FontWeight.w600,
),
child: SvgPicture.asset(
_getStatusIconPath(request.status),
width: 24,
height: 24,
color: Colors.white,
),
),
Text(
@@ -526,72 +511,28 @@ class _HolidayScreenState extends State<HolidayScreen> {
),
),
// Request date - removed since advance requests don't have request date
// Action buttons for pending requests
if (request.status == 'pending') ...[
const SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
// Status text below the card
const SizedBox(height: 8),
Directionality(
textDirection: TextDirection.rtl,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
_updateAdvanceRequestStatus(request.id, 'approved');
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
Text(
_getStatusText(request.status),
style: TextStyle(
color: _getStatusColor(request.status),
fontSize: 14,
fontWeight: FontWeight.w600,
),
child: const Text('موافق'),
),
ElevatedButton(
onPressed: () {
_updateAdvanceRequestStatus(request.id, 'rejected');
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
),
child: const Text('رفض'),
),
],
),
],
),
],
),
);
}
void _updateLeaveRequestStatus(String id, String status) async {
await _requestService.updateLeaveRequestStatus(id, status);
_refreshData();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('تم ${status == 'approved' ? 'قبول' : 'رفض'} الطلب'),
backgroundColor: status == 'approved' ? Colors.green : Colors.red,
),
);
}
void _updateAdvanceRequestStatus(String id, String status) async {
await _requestService.updateAdvanceRequestStatus(id, status);
_refreshData();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('تم ${status == 'approved' ? 'قبول' : 'رفض'} الطلب'),
backgroundColor: status == 'approved' ? Colors.green : Colors.red,
),
);
}
}
class _HolidayActionButton extends StatelessWidget {