chnages was made
This commit is contained in:
13
lib/models/advance_request.dart
Normal file
13
lib/models/advance_request.dart
Normal file
@@ -0,0 +1,13 @@
|
||||
class AdvanceRequest {
|
||||
final String id;
|
||||
final double amount;
|
||||
final String reason;
|
||||
final String status; // e.g., "pending", "approved", "rejected"
|
||||
|
||||
AdvanceRequest({
|
||||
required this.id,
|
||||
required this.amount,
|
||||
required this.reason,
|
||||
this.status = "pending",
|
||||
});
|
||||
}
|
||||
26
lib/models/leave_request.dart
Normal file
26
lib/models/leave_request.dart
Normal file
@@ -0,0 +1,26 @@
|
||||
import 'package:flutter/material.dart' show TimeOfDay;
|
||||
|
||||
class LeaveRequest {
|
||||
final String id;
|
||||
final String leaveType;
|
||||
final bool isTimedLeave;
|
||||
final DateTime fromDate;
|
||||
final DateTime toDate;
|
||||
final TimeOfDay fromTime;
|
||||
final TimeOfDay toTime;
|
||||
final String reason;
|
||||
final DateTime requestDate;
|
||||
final String status; // e.g
|
||||
LeaveRequest({
|
||||
required this.id,
|
||||
required this.leaveType,
|
||||
required this.isTimedLeave,
|
||||
required this.fromDate,
|
||||
required this.toDate,
|
||||
required this.fromTime,
|
||||
required this.toTime,
|
||||
required this.reason,
|
||||
required this.requestDate,
|
||||
this.status = "pending",
|
||||
});
|
||||
}
|
||||
@@ -2,6 +2,9 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import '../screens/request_leave_screen.dart';
|
||||
import '../screens/request_advance_scrren.dart';
|
||||
import '../models/leave_request.dart';
|
||||
import '../models/advance_request.dart';
|
||||
import '../services/request_service.dart';
|
||||
|
||||
class HolidayScreen extends StatefulWidget {
|
||||
const HolidayScreen({super.key});
|
||||
@@ -12,6 +15,44 @@ class HolidayScreen extends StatefulWidget {
|
||||
|
||||
class _HolidayScreenState extends State<HolidayScreen> {
|
||||
int activeTab = 0; // 0 = السلف | 1 = الأجازات
|
||||
final RequestService _requestService = RequestService();
|
||||
late Future<List<LeaveRequest>> _leaveRequestsFuture;
|
||||
late Future<List<AdvanceRequest>> _advanceRequestsFuture;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_refreshData();
|
||||
}
|
||||
|
||||
void _refreshData() {
|
||||
setState(() {
|
||||
_leaveRequestsFuture = Future.value(_requestService.leaveRequests);
|
||||
_advanceRequestsFuture = Future.value(_requestService.advanceRequests);
|
||||
});
|
||||
}
|
||||
|
||||
Color _getStatusColor(String status) {
|
||||
switch (status) {
|
||||
case 'approved':
|
||||
return Colors.green;
|
||||
case 'rejected':
|
||||
return Colors.red;
|
||||
default:
|
||||
return Colors.orange;
|
||||
}
|
||||
}
|
||||
|
||||
String _getStatusText(String status) {
|
||||
switch (status) {
|
||||
case 'approved':
|
||||
return 'موافق عليه';
|
||||
case 'rejected':
|
||||
return 'مرفوض';
|
||||
default:
|
||||
return 'قيد الانتظار';
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -19,6 +60,7 @@ class _HolidayScreenState extends State<HolidayScreen> {
|
||||
textDirection: TextDirection.rtl,
|
||||
child: Stack(
|
||||
children: [
|
||||
// Tabs
|
||||
Positioned(
|
||||
top: 40,
|
||||
left: 0,
|
||||
@@ -84,6 +126,17 @@ class _HolidayScreenState extends State<HolidayScreen> {
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
// Content area for requests
|
||||
Positioned(
|
||||
top: 100, // Position below the tabs
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 120, // Leave space for action buttons
|
||||
child: activeTab == 1 ? _buildLeaveRequestsTab() : _buildAdvanceRequestsTab(),
|
||||
),
|
||||
|
||||
// Action buttons
|
||||
Positioned(
|
||||
bottom: 30,
|
||||
right: 20,
|
||||
@@ -96,14 +149,13 @@ class _HolidayScreenState extends State<HolidayScreen> {
|
||||
iconWidth: 38,
|
||||
iconHeight: 30,
|
||||
onTap: () {
|
||||
|
||||
// Navigate to RequestAdvanceScreen
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const RequestAdvanceScreen(),
|
||||
),
|
||||
);
|
||||
).then((_) => _refreshData()); // Refresh data when returning
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 18),
|
||||
@@ -120,7 +172,7 @@ class _HolidayScreenState extends State<HolidayScreen> {
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const RequestLeaveScreen(),
|
||||
),
|
||||
);
|
||||
).then((_) => _refreshData()); // Refresh data when returning
|
||||
},
|
||||
),
|
||||
],
|
||||
@@ -130,6 +182,416 @@ 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);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
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);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildLeaveRequestCard(LeaveRequest request) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(bottom: 16),
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
boxShadow: const [
|
||||
BoxShadow(
|
||||
color: Color(0x33000000),
|
||||
blurRadius: 10,
|
||||
offset: Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
// Header with type and status
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||
decoration: BoxDecoration(
|
||||
color: _getStatusColor(request.status),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: Text(
|
||||
_getStatusText(request.status),
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
request.isTimedLeave ? "أجازة زمنية" : request.leaveType,
|
||||
style: const TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const SizedBox(height: 12),
|
||||
|
||||
// Date range
|
||||
Directionality(
|
||||
textDirection: TextDirection.rtl,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Text(
|
||||
'من: ${request.fromDate.day}/${request.fromDate.month}/${request.fromDate.year}',
|
||||
style: const TextStyle(
|
||||
color: Colors.black87,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 20),
|
||||
Text(
|
||||
'إلى: ${request.toDate.day}/${request.toDate.month}/${request.toDate.year}',
|
||||
style: const TextStyle(
|
||||
color: Colors.black87,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
if (request.isTimedLeave) ...[
|
||||
const SizedBox(height: 8),
|
||||
Directionality(
|
||||
textDirection: TextDirection.rtl,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Text(
|
||||
'من: ${request.fromTime.hour}:${request.fromTime.minute.toString().padLeft(2, '0')}',
|
||||
style: const TextStyle(
|
||||
color: Colors.black87,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 20),
|
||||
Text(
|
||||
'إلى: ${request.toTime.hour}:${request.toTime.minute.toString().padLeft(2, '0')}',
|
||||
style: const TextStyle(
|
||||
color: Colors.black87,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
const SizedBox(height: 12),
|
||||
|
||||
// Reason
|
||||
Directionality(
|
||||
textDirection: TextDirection.rtl,
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF5F5F5),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Text(
|
||||
request.reason,
|
||||
style: const TextStyle(
|
||||
color: Colors.black87,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 12),
|
||||
|
||||
// Request date
|
||||
Directionality(
|
||||
textDirection: TextDirection.rtl,
|
||||
child: Text(
|
||||
'تاريخ الطلب: ${request.requestDate.day}/${request.requestDate.month}/${request.requestDate.year}',
|
||||
style: const TextStyle(
|
||||
color: Colors.grey,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// Action buttons for pending requests
|
||||
if (request.status == 'pending') ...[
|
||||
const SizedBox(height: 16),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
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),
|
||||
),
|
||||
),
|
||||
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('رفض'),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildAdvanceRequestCard(AdvanceRequest request) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(bottom: 16),
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
boxShadow: const [
|
||||
BoxShadow(
|
||||
color: Color(0x33000000),
|
||||
blurRadius: 10,
|
||||
offset: Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
// Header with status
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||
decoration: BoxDecoration(
|
||||
color: _getStatusColor(request.status),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: Text(
|
||||
_getStatusText(request.status),
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'طلب سلفة',
|
||||
style: const TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const SizedBox(height: 12),
|
||||
|
||||
// Amount
|
||||
Directionality(
|
||||
textDirection: TextDirection.rtl,
|
||||
child: Text(
|
||||
'المبلغ: ${request.amount.toStringAsFixed(2)} دع',
|
||||
style: const TextStyle(
|
||||
color: Colors.black87,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 12),
|
||||
|
||||
// Reason
|
||||
Directionality(
|
||||
textDirection: TextDirection.rtl,
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF5F5F5),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Text(
|
||||
request.reason,
|
||||
style: const TextStyle(
|
||||
color: Colors.black87,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// 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,
|
||||
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),
|
||||
),
|
||||
),
|
||||
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 {
|
||||
@@ -189,4 +651,4 @@ class _HolidayActionButton extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,8 @@ import 'package:flutter_svg/flutter_svg.dart';
|
||||
import '../widgets/app_background.dart';
|
||||
import '../widgets/settings_bar.dart';
|
||||
import '../widgets/onboarding_button.dart';
|
||||
import '../models/advance_request.dart';
|
||||
import '../services/request_service.dart';
|
||||
|
||||
class RequestAdvanceScreen extends StatefulWidget {
|
||||
const RequestAdvanceScreen({super.key});
|
||||
@@ -18,6 +20,56 @@ class _RequestAdvanceScreenState extends State<RequestAdvanceScreen> {
|
||||
// Text controller for reason
|
||||
final TextEditingController reasonController = TextEditingController();
|
||||
|
||||
final RequestService _requestService = RequestService();
|
||||
|
||||
// Method to save the advance request
|
||||
Future<void> _saveAdvanceRequest() async {
|
||||
if (amountController.text.isEmpty || reasonController.text.isEmpty) {
|
||||
// Show an error message if fields are empty
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('الرجاء إدخال جميع الحقول'),
|
||||
backgroundColor: Colors.red,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse the amount to double
|
||||
final amount = double.tryParse(amountController.text);
|
||||
if (amount == null || amount <= 0) {
|
||||
// Show an error message if amount is invalid
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('الرجاء إدخال مبلغ صحيح'),
|
||||
backgroundColor: Colors.red,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a new advance request
|
||||
final advanceRequest = AdvanceRequest(
|
||||
id: DateTime.now().millisecondsSinceEpoch.toString(),
|
||||
amount: amount,
|
||||
reason: reasonController.text,
|
||||
);
|
||||
|
||||
// Save the advance request
|
||||
await _requestService.addAdvanceRequest(advanceRequest);
|
||||
|
||||
// Show a success message
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('تم إرسال طلب السلفة بنجاح'),
|
||||
backgroundColor: Colors.green,
|
||||
),
|
||||
);
|
||||
|
||||
// Navigate back to the previous screen
|
||||
Navigator.pop(context);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
@@ -155,7 +207,8 @@ class _RequestAdvanceScreenState extends State<RequestAdvanceScreen> {
|
||||
controller: reasonController,
|
||||
maxLines: 5,
|
||||
textAlign:
|
||||
TextAlign.right, // Added this to align text to the right
|
||||
TextAlign
|
||||
.right, // Added this to align text to the right
|
||||
decoration: const InputDecoration(
|
||||
border: InputBorder.none,
|
||||
hintText:
|
||||
@@ -175,7 +228,7 @@ class _RequestAdvanceScreenState extends State<RequestAdvanceScreen> {
|
||||
text: "تأكيد الطلب",
|
||||
backgroundColor: const Color(0xFFD1FEF0),
|
||||
textColor: Colors.black,
|
||||
onPressed: () {},
|
||||
onPressed: _saveAdvanceRequest, // Call the save method
|
||||
),
|
||||
),
|
||||
|
||||
@@ -190,4 +243,4 @@ class _RequestAdvanceScreenState extends State<RequestAdvanceScreen> {
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,8 @@ import 'package:flutter_svg/flutter_svg.dart';
|
||||
import '../widgets/app_background.dart';
|
||||
import '../widgets/settings_bar.dart';
|
||||
import '../widgets/onboarding_button.dart';
|
||||
import '../models/leave_request.dart';
|
||||
import '../services/request_service.dart';
|
||||
|
||||
class RequestLeaveScreen extends StatefulWidget {
|
||||
const RequestLeaveScreen({super.key});
|
||||
@@ -28,6 +30,8 @@ class _RequestLeaveScreenState extends State<RequestLeaveScreen> {
|
||||
// Text controller for reason
|
||||
final TextEditingController reasonController = TextEditingController();
|
||||
|
||||
final RequestService _requestService = RequestService();
|
||||
|
||||
/// PICK DATE
|
||||
Future<void> pickDate(bool isFrom) async {
|
||||
DateTime initial = isFrom ? fromDate! : toDate!;
|
||||
@@ -74,6 +78,47 @@ class _RequestLeaveScreenState extends State<RequestLeaveScreen> {
|
||||
}
|
||||
}
|
||||
|
||||
// Method to save the leave request
|
||||
Future<void> _saveLeaveRequest() async {
|
||||
if (reasonController.text.isEmpty) {
|
||||
// Show an error message if reason is empty
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('الرجاء إدخال السبب'),
|
||||
backgroundColor: Colors.red,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a new leave request
|
||||
final leaveRequest = LeaveRequest(
|
||||
id: DateTime.now().millisecondsSinceEpoch.toString(),
|
||||
leaveType: leaveType,
|
||||
isTimedLeave: isTimedLeave,
|
||||
fromDate: fromDate!,
|
||||
toDate: toDate!,
|
||||
fromTime: fromTime!,
|
||||
toTime: toTime!,
|
||||
reason: reasonController.text,
|
||||
requestDate: DateTime.now(),
|
||||
);
|
||||
|
||||
// Save the leave request
|
||||
await _requestService.addLeaveRequest(leaveRequest);
|
||||
|
||||
// Show a success message
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('تم إرسال طلب الأجازة بنجاح'),
|
||||
backgroundColor: Colors.green,
|
||||
),
|
||||
);
|
||||
|
||||
// Navigate back to the previous screen
|
||||
Navigator.pop(context);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
@@ -104,7 +149,7 @@ class _RequestLeaveScreenState extends State<RequestLeaveScreen> {
|
||||
children: [
|
||||
// Fixed alignment for "طلب أجازة"
|
||||
const Align(
|
||||
alignment: Alignment.topRight, // Changed to centerRight
|
||||
alignment: Alignment.topRight,
|
||||
child: Text(
|
||||
"طلب أجازة ",
|
||||
style: TextStyle(
|
||||
@@ -459,7 +504,7 @@ class _RequestLeaveScreenState extends State<RequestLeaveScreen> {
|
||||
text: "تأكيد الطلب",
|
||||
backgroundColor: const Color(0xFFD1FEF0),
|
||||
textColor: Colors.black, // Changed to black
|
||||
onPressed: () {},
|
||||
onPressed: _saveLeaveRequest, // Call the save method
|
||||
),
|
||||
),
|
||||
|
||||
@@ -559,11 +604,13 @@ class _RequestLeaveScreenState extends State<RequestLeaveScreen> {
|
||||
case 4:
|
||||
return "الخميس";
|
||||
case 5:
|
||||
return "السبت";
|
||||
return "الجمعة";
|
||||
case 6:
|
||||
return "السبت";
|
||||
case 7:
|
||||
return "الأحد";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
57
lib/services/request_service.dart
Normal file
57
lib/services/request_service.dart
Normal file
@@ -0,0 +1,57 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../models/leave_request.dart';
|
||||
import '../models/advance_request.dart';
|
||||
|
||||
class RequestService {
|
||||
static final RequestService _instance = RequestService._internal();
|
||||
factory RequestService() => _instance;
|
||||
RequestService._internal();
|
||||
|
||||
final List<LeaveRequest> _leaveRequests = [];
|
||||
final List<AdvanceRequest> _advanceRequests = [];
|
||||
|
||||
List<LeaveRequest> get leaveRequests => List.unmodifiable(_leaveRequests);
|
||||
List<AdvanceRequest> get advanceRequests => List.unmodifiable(_advanceRequests);
|
||||
|
||||
Future<void> addLeaveRequest(LeaveRequest request) async {
|
||||
_leaveRequests.add(request);
|
||||
// In a real app, you would save this to a database or API
|
||||
}
|
||||
|
||||
Future<void> addAdvanceRequest(AdvanceRequest request) async {
|
||||
_advanceRequests.add(request);
|
||||
// In a real app, you would save this to a database or API
|
||||
}
|
||||
|
||||
Future<void> updateLeaveRequestStatus(String id, String status) async {
|
||||
final index = _leaveRequests.indexWhere((request) => request.id == id);
|
||||
if (index != -1) {
|
||||
final updatedRequest = LeaveRequest(
|
||||
id: _leaveRequests[index].id,
|
||||
leaveType: _leaveRequests[index].leaveType,
|
||||
isTimedLeave: _leaveRequests[index].isTimedLeave,
|
||||
fromDate: _leaveRequests[index].fromDate,
|
||||
toDate: _leaveRequests[index].toDate,
|
||||
fromTime: _leaveRequests[index].fromTime,
|
||||
toTime: _leaveRequests[index].toTime,
|
||||
reason: _leaveRequests[index].reason,
|
||||
requestDate: _leaveRequests[index].requestDate,
|
||||
status: status,
|
||||
);
|
||||
_leaveRequests[index] = updatedRequest;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> updateAdvanceRequestStatus(String id, String status) async {
|
||||
final index = _advanceRequests.indexWhere((request) => request.id == id);
|
||||
if (index != -1) {
|
||||
final updatedRequest = AdvanceRequest(
|
||||
id: _advanceRequests[index].id,
|
||||
amount: _advanceRequests[index].amount,
|
||||
reason: _advanceRequests[index].reason,
|
||||
status: status,
|
||||
);
|
||||
_advanceRequests[index] = updatedRequest;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user