216 lines
7.4 KiB
Dart
216 lines
7.4 KiB
Dart
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:Intaleq/constant/box_name.dart';
|
|
import 'package:Intaleq/constant/colors.dart';
|
|
import 'package:Intaleq/constant/links.dart';
|
|
import 'package:Intaleq/constant/style.dart';
|
|
import 'package:Intaleq/controller/functions/crud.dart';
|
|
import 'package:Intaleq/main.dart';
|
|
import 'package:Intaleq/views/widgets/elevated_btn.dart';
|
|
import 'package:http_parser/http_parser.dart';
|
|
import 'package:mime/mime.dart';
|
|
|
|
import '../../../constant/api_key.dart';
|
|
import '../../../env/env.dart';
|
|
import '../../../print.dart';
|
|
import '../../../views/widgets/mydialoug.dart';
|
|
import '../../functions/encrypt_decrypt.dart';
|
|
|
|
class ComplaintController extends GetxController {
|
|
bool isLoading = false;
|
|
final formKey = GlobalKey<FormState>();
|
|
final complaintController = TextEditingController();
|
|
|
|
List feedBack = [];
|
|
Map<String, dynamic>? passengerReport;
|
|
Map<String, dynamic>? driverReport;
|
|
|
|
var isUploading = false.obs;
|
|
var uploadSuccess = false.obs;
|
|
String audioLink = ''; // سيتم تخزين رابط الصوت هنا بعد الرفع
|
|
|
|
@override
|
|
void onInit() {
|
|
super.onInit();
|
|
getLatestRidesForPassengers();
|
|
}
|
|
|
|
// --- دالة مخصصة لعرض إشعارات Snackbar بشكل جميل ---
|
|
void _showCustomSnackbar(String title, String message,
|
|
{bool isError = false}) {
|
|
Get.snackbar(
|
|
'', // العنوان سيتم التعامل معه عبر titleText
|
|
'', // الرسالة سيتم التعامل معها عبر messageText
|
|
titleText: Text(title.tr,
|
|
style: const TextStyle(
|
|
color: Colors.white, fontWeight: FontWeight.bold, fontSize: 16)),
|
|
messageText: Text(message.tr,
|
|
style: const TextStyle(color: Colors.white, fontSize: 14)),
|
|
backgroundColor: isError
|
|
? AppColor.redColor.withOpacity(0.95)
|
|
: const Color.fromARGB(255, 6, 148, 79).withOpacity(0.95),
|
|
icon: Icon(isError ? Icons.error_outline : Icons.check_circle_outline,
|
|
color: Colors.white, size: 28),
|
|
borderRadius: 12,
|
|
margin: const EdgeInsets.all(15),
|
|
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 18),
|
|
snackPosition: SnackPosition.BOTTOM,
|
|
duration: const Duration(seconds: 4),
|
|
colorText: Colors.white,
|
|
);
|
|
}
|
|
|
|
// --- هذه الدالة تبقى كما هي لجلب بيانات الرحلة ---
|
|
getLatestRidesForPassengers() async {
|
|
isLoading = true;
|
|
update();
|
|
var res = await CRUD().get(link: AppLink.getFeedBack, payload: {
|
|
'passengerId': box.read(BoxName.passengerID).toString(),
|
|
});
|
|
if (res != 'failure') {
|
|
var d = jsonDecode(res)['message'];
|
|
feedBack = d;
|
|
}
|
|
isLoading = false;
|
|
update();
|
|
}
|
|
|
|
// --- تم تحديث الهيدر في هذه الدالة ---
|
|
Future<void> uploadAudioFile(File audioFile) async {
|
|
try {
|
|
isUploading.value = true;
|
|
update();
|
|
|
|
var uri = Uri.parse('${AppLink.IntaleqSyriaServer}/upload_audio.php');
|
|
var request = http.MultipartRequest('POST', uri);
|
|
String token = r(box.read(BoxName.jwt)).toString().split(Env.addd)[0];
|
|
|
|
var mimeType = lookupMimeType(audioFile.path);
|
|
// ** التعديل: تم استخدام نفس هيدر التوثيق **
|
|
request.headers.addAll({
|
|
'Authorization': 'Bearer $token',
|
|
});
|
|
request.files.add(
|
|
await http.MultipartFile.fromPath(
|
|
'audio',
|
|
audioFile.path,
|
|
contentType: mimeType != null ? MediaType.parse(mimeType) : null,
|
|
),
|
|
);
|
|
|
|
var response = await request.send();
|
|
var responseBody = await http.Response.fromStream(response);
|
|
|
|
if (response.statusCode == 200) {
|
|
var jsonResponse = jsonDecode(responseBody.body);
|
|
if (jsonResponse['status'] == 'Audio file uploaded successfully.') {
|
|
uploadSuccess.value = true;
|
|
audioLink = jsonResponse['link']; // تخزين الرابط في المتغير
|
|
Get.back();
|
|
// استخدام الـ Snackbar الجديد
|
|
_showCustomSnackbar('Success', 'Audio uploaded successfully.');
|
|
} else {
|
|
uploadSuccess.value = false;
|
|
_showCustomSnackbar('Error', 'Failed to upload audio file.',
|
|
isError: true);
|
|
}
|
|
} else {
|
|
uploadSuccess.value = false;
|
|
_showCustomSnackbar('Error', 'Server error: ${response.statusCode}',
|
|
isError: true);
|
|
}
|
|
} catch (e) {
|
|
uploadSuccess.value = false;
|
|
_showCustomSnackbar(
|
|
'Error', 'An application error occurred during upload.',
|
|
isError: true);
|
|
} finally {
|
|
isUploading.value = false;
|
|
update();
|
|
}
|
|
}
|
|
|
|
// --- الدالة الجديدة التي تتصل بالسكريبت الجديد ---
|
|
Future<void> submitComplaintToServer() async {
|
|
// 1. التحقق من صحة الفورم
|
|
if (!formKey.currentState!.validate() || complaintController.text.isEmpty) {
|
|
// استخدام الـ Snackbar الجديد
|
|
_showCustomSnackbar(
|
|
'Error', 'Please describe your issue before submitting.',
|
|
isError: true);
|
|
return;
|
|
}
|
|
|
|
// 2. التحقق من وجود بيانات الرحلة
|
|
if (feedBack.isEmpty) {
|
|
// استخدام الـ Snackbar الجديد
|
|
_showCustomSnackbar(
|
|
'Error', 'Ride information not found. Please refresh the page.',
|
|
isError: true);
|
|
return;
|
|
}
|
|
|
|
isLoading = true;
|
|
update();
|
|
|
|
try {
|
|
// 3. استخراج البيانات المطلوبة
|
|
final rideId = feedBack[0]['id'].toString(); // ! تأكد أن اسم حقل ID صحيح
|
|
final complaint = complaintController.text;
|
|
String token = r(box.read(BoxName.jwt)).toString().split(Env.addd)[0];
|
|
|
|
// 4. استدعاء سكربت PHP الجديد باستخدام http.post
|
|
final response = await http.post(
|
|
Uri.parse(AppLink.add_solve_all),
|
|
headers: {'Authorization': 'Bearer $token'},
|
|
body: {
|
|
'ride_id': rideId,
|
|
'complaint_text': complaint,
|
|
'audio_link': audioLink,
|
|
},
|
|
);
|
|
|
|
Log.print('Server Response: ${response.body}');
|
|
|
|
if (response.statusCode != 200) {
|
|
_showCustomSnackbar(
|
|
'Error', 'Failed to connect to the server. Please try again.',
|
|
isError: true);
|
|
return;
|
|
}
|
|
|
|
// 5. التعامل مع محتوى الرد من الخادم
|
|
final responseData = jsonDecode(response.body);
|
|
|
|
if (responseData['status'] == 'success') {
|
|
passengerReport = responseData['data']['passenger_response'];
|
|
driverReport = responseData['data']['driver_response'];
|
|
update();
|
|
|
|
MyDialogContent().getDialog(
|
|
'Success'.tr, Text('Your complaint has been submitted.'.tr), () {
|
|
Get.back();
|
|
complaintController.clear();
|
|
audioLink = '';
|
|
formKey.currentState?.reset();
|
|
});
|
|
} else {
|
|
String errorMessage =
|
|
responseData['message'] ?? 'An unknown server error occurred'.tr;
|
|
_showCustomSnackbar('Submission Failed', errorMessage, isError: true);
|
|
}
|
|
} catch (e) {
|
|
Log.print("Submit Complaint Error: $e");
|
|
_showCustomSnackbar('Error', 'An application error occurred.'.tr,
|
|
isError: true);
|
|
} finally {
|
|
isLoading = false;
|
|
update();
|
|
}
|
|
}
|
|
}
|