FarisaRahmaSari_E31222327/BBS/lib/view/home/pengajuan_izin.dart

347 lines
12 KiB
Dart

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:qyuota/config/colors.dart';
import 'package:qyuota/config/text_style.dart';
import 'package:qyuota/services/auth_service.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:qyuota/config/api_config.dart';
import 'package:file_picker/file_picker.dart';
import 'dart:io';
class PengajuanIzinPage extends StatefulWidget {
const PengajuanIzinPage({Key? key}) : super(key: key);
@override
State<PengajuanIzinPage> createState() => _PengajuanIzinPageState();
}
class _PengajuanIzinPageState extends State<PengajuanIzinPage> {
final _formKey = GlobalKey<FormState>();
String? selectedStatus;
String? keterangan;
File? selectedFile;
bool isLoading = false;
final List<String> statusList = ['Izin', 'Sakit'];
Future<void> _pickFile() async {
try {
FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ['jpg', 'jpeg', 'png', 'pdf'],
);
if (result != null) {
setState(() {
selectedFile = File(result.files.single.path!);
});
}
} catch (e) {
print('Error picking file: $e');
}
}
Future<void> _submitForm() async {
if (!_formKey.currentState!.validate()) return;
if (selectedFile == null) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Silakan pilih file bukti')),
);
return;
}
setState(() {
isLoading = true;
});
try {
final token = await AuthService().getToken();
if (token == null) return;
var request = http.MultipartRequest(
'POST',
Uri.parse('${ApiConfig.baseUrl}/api/mobile/presensi/izin'),
);
request.headers.addAll({
'Authorization': 'Bearer $token',
'Accept': 'application/json',
});
request.fields['status'] = selectedStatus!;
request.fields['keterangan'] = keterangan!;
request.files.add(
await http.MultipartFile.fromPath(
'file',
selectedFile!.path,
),
);
var response = await request.send();
var responseData = await response.stream.bytesToString();
var jsonResponse = json.decode(responseData);
if (response.statusCode == 200 && jsonResponse['success'] == true) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Pengajuan ${selectedStatus} berhasil dikirim'),
backgroundColor: Colors.green,
),
);
Navigator.pop(context);
} else {
// Display the specific error message from the backend
String errorMessage = jsonResponse['message'] ?? 'Gagal mengirim pengajuan';
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(errorMessage),
backgroundColor: Colors.red,
duration: Duration(seconds: 3),
),
);
}
} catch (e) {
print('Error submitting form: $e');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Terjadi kesalahan saat mengirim form'),
backgroundColor: Colors.red,
),
);
} finally {
setState(() {
isLoading = false;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: ConstColors.primaryColor,
elevation: 0,
title: Text(
'Pengajuan Izin',
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.w600,
),
),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () => Navigator.pop(context),
),
),
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
ConstColors.primaryColor,
Colors.white,
],
stops: [0.0, 0.3],
),
),
child: SingleChildScrollView(
padding: EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 10,
offset: Offset(0, 5),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(
Icons.event_note,
color: ConstColors.primaryColor,
size: 24,
),
SizedBox(width: 10),
Text(
'Form Pengajuan Izin',
style: pSemiBold18.copyWith(
fontSize: 20,
color: ConstColors.primaryColor,
),
),
],
),
SizedBox(height: 24),
// Status Dropdown
Container(
decoration: BoxDecoration(
color: Colors.grey[50],
borderRadius: BorderRadius.circular(10),
border: Border.all(color: Colors.grey[300]!),
),
child: DropdownButtonFormField<String>(
decoration: InputDecoration(
labelText: 'Jenis Pengajuan',
labelStyle: TextStyle(color: Colors.grey[700]),
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
prefixIcon: Icon(Icons.category, color: ConstColors.primaryColor),
),
value: selectedStatus,
items: statusList.map((String status) {
return DropdownMenuItem<String>(
value: status,
child: Text(status),
);
}).toList(),
onChanged: (String? newValue) {
setState(() {
selectedStatus = newValue;
});
},
validator: (value) {
if (value == null || value.isEmpty) {
return 'Silakan pilih jenis pengajuan';
}
return null;
},
),
),
SizedBox(height: 16),
// Keterangan Field
Container(
decoration: BoxDecoration(
color: Colors.grey[50],
borderRadius: BorderRadius.circular(10),
border: Border.all(color: Colors.grey[300]!),
),
child: TextFormField(
decoration: InputDecoration(
labelText: 'Keterangan',
labelStyle: TextStyle(color: Colors.grey[700]),
border: InputBorder.none,
contentPadding: EdgeInsets.all(16),
prefixIcon: Icon(Icons.description, color: ConstColors.primaryColor),
),
maxLines: 3,
onChanged: (value) {
keterangan = value;
},
validator: (value) {
if (value == null || value.isEmpty) {
return 'Silakan isi keterangan';
}
return null;
},
),
),
SizedBox(height: 16),
// File Upload Button
Container(
width: double.infinity,
decoration: BoxDecoration(
color: Colors.grey[50],
borderRadius: BorderRadius.circular(10),
border: Border.all(color: Colors.grey[300]!),
),
child: InkWell(
onTap: _pickFile,
borderRadius: BorderRadius.circular(10),
child: Padding(
padding: EdgeInsets.all(16),
child: Row(
children: [
Icon(Icons.upload_file, color: ConstColors.primaryColor),
SizedBox(width: 10),
Expanded(
child: Text(
selectedFile != null
? 'File terpilih: ${selectedFile!.path.split('/').last}'
: 'Pilih File Bukti',
style: TextStyle(
color: selectedFile != null ? Colors.black87 : Colors.grey[700],
),
),
),
Icon(Icons.arrow_forward_ios, size: 16, color: Colors.grey[600]),
],
),
),
),
),
if (selectedFile != null) ...[
SizedBox(height: 8),
Text(
'Format file: JPG, JPEG, PNG, PDF',
style: TextStyle(
color: Colors.grey[600],
fontSize: 12,
),
),
],
],
),
),
SizedBox(height: 24),
// Submit Button
Container(
width: double.infinity,
height: 50,
child: ElevatedButton(
onPressed: isLoading ? null : _submitForm,
child: isLoading
? SizedBox(
height: 20,
width: 20,
child: CircularProgressIndicator(
color: Colors.white,
strokeWidth: 2,
),
)
: Text(
'Kirim Pengajuan',
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
style: ElevatedButton.styleFrom(
backgroundColor: ConstColors.primaryColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
elevation: 2,
),
),
),
],
),
),
),
),
);
}
}