chnages was made
This commit is contained in:
3
assets/images/waiting.svg
Normal file
3
assets/images/waiting.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="11" height="12" viewBox="0 0 11 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4.56543 0L4.11881 0.827619L10.0667 4.0374L10.5134 3.20978L4.56543 0ZM3.96178 1.40642L0.84422 7.18347L1.35813 7.4608L4.47568 1.68378L3.96178 1.40642ZM5.03776 1.98707C4.13962 3.69732 4.30305 5.01498 4.94941 5.62581C4.07265 5.41811 2.86134 6.02237 1.91932 7.76357L5.44464 9.66599C6.38303 7.92273 6.2242 6.57951 5.56997 5.9607C6.43498 6.16522 7.62469 5.57817 8.56133 3.88858L5.03776 1.98707ZM9.10617 4.18257L5.98861 9.95961L6.50255 10.237L9.62009 4.45994L9.10617 4.18257ZM0.446629 7.63241L0.000468303 8.45918L5.94841 11.669L6.39457 10.8422L0.446629 7.63241Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 683 B |
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