diff --git a/lib/constant/links.dart b/lib/constant/links.dart index 7c0fe13..ca12c89 100644 --- a/lib/constant/links.dart +++ b/lib/constant/links.dart @@ -48,6 +48,10 @@ class AppLink { static const String addFeedBack = "$ride/feedBack/add.php"; static const String getFeedBack = "$ride/feedBack/get.php"; static const String updateFeedBack = "$ride/feedBack/updateFeedBack.php"; + //-----------------license------------------ + static const String addLicense = "$ride/license/add.php"; + static const String getLicense = "$ride/license/get.php"; + static const String updateLicense = "$ride/license/updateFeedBack.php"; //-----------------DriverOrder------------------ diff --git a/lib/controller/auth/captin/login_captin_controller.dart b/lib/controller/auth/captin/login_captin_controller.dart index 0a4eb08..2c0c43c 100644 --- a/lib/controller/auth/captin/login_captin_controller.dart +++ b/lib/controller/auth/captin/login_captin_controller.dart @@ -82,7 +82,7 @@ class LoginCaptinController extends GetxController { 'email': emailController.text, 'token': randomNumber.toString(), }).then((value) => print(value)); - Get.to(() => const VerifyEmailPage()); + Get.to(() => VerifyEmailPage()); }, ); } diff --git a/lib/controller/auth/captin/ml_google_doc.dart b/lib/controller/auth/captin/ml_google_doc.dart new file mode 100644 index 0000000..e28eae2 --- /dev/null +++ b/lib/controller/auth/captin/ml_google_doc.dart @@ -0,0 +1,87 @@ +import 'dart:convert'; +import 'dart:io'; +import 'dart:ui'; + +import 'package:get/get.dart'; +import 'package:google_mlkit_text_recognition/google_mlkit_text_recognition.dart'; +import 'package:image_picker/image_picker.dart'; + +class CarRegistrationRecognizerController extends GetxController { + @override + void onInit() { + // scanText(); + super.onInit(); + } + + // The ImagePicker instance + final ImagePicker _imagePicker = ImagePicker(); + Map extractedData = {}; + + // The GoogleMlKit TextRecognizer instance + final TextRecognizer _textRecognizer = TextRecognizer(); + + // The scanned text + String? scannedText; + String? jsonOutput; + final List> lines = []; + XFile? image; + Map decode = {}; + // Picks an image from the camera or gallery and extracts the text + final List> extractedTextWithCoordinates = []; + Future scanText() async { + // Pick an image from the camera or gallery + image = await _imagePicker.pickImage(source: ImageSource.gallery); + update(); + // If no image was picked, return + if (image == null) { + return; + } + + // Convert the XFile object to an InputImage object + final InputImage inputImage = InputImage.fromFile(File(image!.path)); + + // Recognize the text in the image + final RecognizedText recognizedText = + await _textRecognizer.processImage(inputImage); + scannedText = recognizedText.text; + final Map extractedData = {}; + + for (TextBlock block in recognizedText.blocks) { + for (TextLine line in block.lines) { + final String lineText = line.text; + final Rect lineBoundingBox = line.boundingBox!; + + extractedTextWithCoordinates.add({ + 'text': lineText, + 'boundingBox': { + 'left': lineBoundingBox.left, + 'top': lineBoundingBox.top, + 'width': lineBoundingBox.width, + 'height': lineBoundingBox.height, + }, + }); + } + update(); + } + + print(jsonEncode(extractedTextWithCoordinates)); + + // Extract the scanned text line by line + final List> lines = []; + for (var i = 0; i < recognizedText.blocks.length; i++) { + lines.add({ + i.toString(): recognizedText.blocks[i].text, + }); + } + // print(jsonEncode(lines)); + + // Convert the list of lines to a JSON string + jsonOutput = jsonEncode(extractedData); + decode = jsonDecode(jsonOutput!); + + update(); + print('jsonOutput------------------------------'); + print(decode); + // print(jsonEncode(lines)); + } +} diff --git a/lib/controller/auth/captin/register_captin_controller.dart b/lib/controller/auth/captin/register_captin_controller.dart index 3c71a5f..ef1f68d 100644 --- a/lib/controller/auth/captin/register_captin_controller.dart +++ b/lib/controller/auth/captin/register_captin_controller.dart @@ -5,24 +5,34 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:ride/constant/links.dart'; import 'package:ride/controller/functions/crud.dart'; +import 'package:ride/controller/functions/ocr_controller.dart'; import 'package:ride/views/auth/captin/login_captin.dart'; +import 'package:ride/views/auth/captin/verify_email_captain.dart'; +import '../../../views/auth/captin/ai_page.dart'; import '../../../views/auth/verify_email_page.dart'; class RegisterCaptinController extends GetxController { final formKey = GlobalKey(); - TextEditingController firstNameController = TextEditingController(); - TextEditingController lastNameController = TextEditingController(); TextEditingController emailController = TextEditingController(); TextEditingController phoneController = TextEditingController(); TextEditingController passwordController = TextEditingController(); - TextEditingController siteController = TextEditingController(); TextEditingController verifyCode = TextEditingController(); String birthDate = 'Birth Date'.tr; String gender = 'Male'.tr; - bool isloading = false; + bool isLoading = false; + late String name; + late String licenseClass; + late String documentNo; + late String address; + late String height; + late String postalCode; + late String sex; + late String stateCode; + late String expireDate; + late String dob; @override void onInit() { super.onInit(); @@ -57,7 +67,7 @@ class RegisterCaptinController extends GetxController { update(); } - sendverfications() async { + sendVerifications() async { var res = await CRUD().post(link: AppLink.verifyEmail, payload: { 'email': emailController.text, 'token': verifyCode.text, @@ -68,22 +78,70 @@ class RegisterCaptinController extends GetxController { } } - void register() async { + void nextToAIDetection() async { + //Todo dont forget this if (formKey.currentState!.validate()) { - isloading = true; + isLoading = true; + update(); + Get.to(() => AiPage()); + } + } + + Map payloadLisence = {}; + + void getFromController() { + name = Get.find().name; + licenseClass = Get.find().licenseClass.toString(); + documentNo = Get.find().documentNo.toString(); + address = Get.find().address.toString(); + height = Get.find().height.toString(); + postalCode = Get.find().address.toString(); + sex = Get.find().sex.toString(); + stateCode = Get.find().postalCode.toString(); + expireDate = Get.find().expireDate.toString(); + dob = Get.find().dob.toString(); + update(); + } + + void addLisence() async { + getFromController(); + var res = await CRUD().post(link: AppLink.addLicense, payload: { + 'name': name, + 'licenseClass': licenseClass, + 'documentNo': documentNo, + 'address': address, + 'height': height, + 'postalCode': postalCode, + 'sex': sex == 'M' ? 'Male' : 'Female', + 'stateCode': stateCode, + 'expireDate': expireDate, + 'dateOfBirth': dob, + }); + print(jsonDecode(res)); + isLoading = false; + update(); + if (jsonDecode(res)['status'] == 'success') { + // Get.to(() => AiPage()); //todo rplace this + } + } + + void register() async { + getFromController(); + if (formKey.currentState!.validate()) { + isLoading = true; update(); var res = await CRUD().post(link: AppLink.signUpCaptin, payload: { - 'first_name': firstNameController.text, - 'last_name': lastNameController.text, + 'first_name': name.split(' ')[1], + 'last_name': name.split(' ')[0], 'email': emailController.text, 'phone': phoneController.text, 'password': passwordController.text, - 'gender': gender, - 'site': siteController.text, - 'birthdate': birthDate, + 'gender': sex, + 'site': address, + 'birthdate': dob, }); print(jsonDecode(res)); - isloading = false; + isLoading = false; update(); if (jsonDecode(res)['status'] == 'success') { print('sdfffffffffff'); @@ -92,7 +150,7 @@ class RegisterCaptinController extends GetxController { 'email': emailController.text, 'token': randomNumber.toString(), }).then((value) => print(value)); - Get.to(() => const VerifyEmailPage()); + Get.to(() => VerifyEmailCaptainPage()); } } } diff --git a/lib/controller/auth/login_controller.dart b/lib/controller/auth/login_controller.dart index 01cd304..cf62c7d 100644 --- a/lib/controller/auth/login_controller.dart +++ b/lib/controller/auth/login_controller.dart @@ -78,7 +78,7 @@ class LoginController extends GetxController { 'email': emailController.text, 'token': randomNumber.toString(), }).then((value) => print(value)); - Get.to(() => const VerifyEmailPage()); + Get.to(() => VerifyEmailPage()); }, ); } diff --git a/lib/controller/auth/register_controller.dart b/lib/controller/auth/register_controller.dart index 44fd381..286554d 100644 --- a/lib/controller/auth/register_controller.dart +++ b/lib/controller/auth/register_controller.dart @@ -61,8 +61,8 @@ class RegisterController extends GetxController { 'email': emailController.text, 'token': verfyCode.text, }); - - if (jsonDecode(res)['status'] == 'success') { + var dec = jsonDecode(res); + if (dec['status'] == 'success') { Get.offAll(() => LoginPage()); } } @@ -87,7 +87,7 @@ class RegisterController extends GetxController { 'email': emailController.text, 'token': randomNumber.toString(), }).then((value) => print(value)); - Get.to(() => const VerifyEmailPage()); + Get.to(() => VerifyEmailPage()); } } } diff --git a/lib/controller/functions/crud.dart b/lib/controller/functions/crud.dart index ce791b7..ccb17f9 100644 --- a/lib/controller/functions/crud.dart +++ b/lib/controller/functions/crud.dart @@ -70,8 +70,8 @@ class CRUD { 'Basic ${base64Encode(utf8.encode(AppCredintials.basicAuthCredentials))}', }, ); - // print(response.request); - // print(payload); + print(response.request); + print(payload); var jsonData = jsonDecode(response.body); if (response.statusCode == 200) { @@ -80,7 +80,7 @@ class CRUD { jsonData['status'], jsonData['message'], ); - // print(response.body); + print(response.body); return response.body; } } diff --git a/lib/controller/functions/ocr_controller.dart b/lib/controller/functions/ocr_controller.dart index a16ef97..06cc180 100644 --- a/lib/controller/functions/ocr_controller.dart +++ b/lib/controller/functions/ocr_controller.dart @@ -1,11 +1,13 @@ import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; +import 'package:camera/camera.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:google_mlkit_text_recognition/google_mlkit_text_recognition.dart'; import 'package:image_picker/image_picker.dart'; import 'package:http/http.dart' as http; +import 'package:path/path.dart' as path; +import 'package:path_provider/path_provider.dart' as path_provider; import 'package:ride/constant/box_name.dart'; import 'package:ride/constant/colors.dart'; import 'package:ride/constant/credential.dart'; @@ -15,6 +17,7 @@ import 'package:ride/constant/table_names.dart'; import 'package:ride/main.dart'; import 'package:ride/views/widgets/elevated_btn.dart'; +import '../../constant/links.dart'; import '../../views/auth/captin/car_license_page.dart'; import 'launch.dart'; @@ -229,6 +232,56 @@ class ScanDocumentsByApi extends GetxController { XFile? imageFace; late String imagePath; DateTime now = DateTime.now(); + late String name; + late String licenseClass; + late String documentNo; + late String address; + late String stateCode; + late String height; + late String sex; + late String postalCode; + late String dob; + late String expireDate; + + // /////////////////////// + // late CameraController cameraController; + // late List cameras; + // bool isCameraInitialized = false; + // // final TextRecognizer _textRecognizer = TextRecognizer(); + // String? scannedText; + + // Future initializeCamera(int cameraID) async { + // try { + // cameras = await availableCameras(); + // //update(); + // cameraController = CameraController( + // cameras[cameraID], + // ResolutionPreset.medium, + // enableAudio: false, + // ); + // await cameraController.initialize(); + // isCameraInitialized = true; + // update(); + // } catch (e) { + // if (e is CameraException) { + // switch (e.code) { + // case 'CameraAccessDenied': + // Get.defaultDialog( + // title: 'Camera Access Denied.'.tr, + // middleText: '', + // confirm: + // MyElevatedButton(title: 'Open Settings', onPressed: () {}), + // ); + // break; + // default: + // // Handle other errors here. + // break; + // } + // } + // } + // } + + /// Future scanDocumentsByApi() async { // Pick an image from the camera or gallery @@ -252,6 +305,17 @@ class ScanDocumentsByApi extends GetxController { if (response.statusCode == 200) { String responseString = await response.stream.bytesToString(); responseMap = jsonDecode(responseString); + var ocrData = responseMap['data']['ocr']; + name = ocrData['name'].toString(); + licenseClass = ocrData['dlClass'].toString(); + documentNo = ocrData['documentNumber'].toString(); + address = ocrData['address'].toString(); + height = ocrData['height'].toString(); + postalCode = ocrData['addressPostalCode'].toString(); + sex = ocrData['sex'].toString(); + stateCode = ocrData['addressJurisdictionCode'].toString(); + expireDate = ocrData['dateOfExpiry'].toString(); + dob = ocrData['dateOfBirth'].toString(); if (responseMap['data'] != null && responseMap['data']['image'] != null && responseMap['data']['image']['portrait'] != null) { @@ -303,10 +367,9 @@ class ScanDocumentsByApi extends GetxController { } else { if (times < 4) { times++; - + matchFaceApi(); sql.updateData( {'faceDetectTimes': times}, TableName.faceDetectTimes, 1); - matchFaceApi(); } else { Get.defaultDialog( barrierDismissible: false, @@ -366,10 +429,11 @@ class ScanDocumentsByApi extends GetxController { print(res); update(); - res['data']['result'].toString() == 'No face detected in image2' + res['data']['result'].toString().contains('No face detected in image') ? Get.defaultDialog( barrierDismissible: false, title: 'No face detected'.tr, + middleText: ''.tr, titleStyle: AppStyle.title, confirm: MyElevatedButton( kolor: AppColor.yellowColor, @@ -417,12 +481,44 @@ class ScanDocumentsByApi extends GetxController { print(response.reasonPhrase); } } + // Todo upload images and fields + + Future uploadImage(File imageFile) async { + var request = http.MultipartRequest( + 'POST', + Uri.parse(AppLink.uploadImage), + ); + + // Attach the image file to the request + request.files.add( + await http.MultipartFile.fromPath('image', imageFile.path), + ); // Add the headers to the request + request.headers.addAll({ + "Content-Type": "application/x-www-form-urlencoded", + 'Authorization': + 'Basic ${base64Encode(utf8.encode(AppCredintials.basicAuthCredentials))}', + }); + + // Add the driverID to the request + request.fields['driverID'] = box.read(BoxName.driverID); + // Send the request + var response = await request.send(); + + // Read the response + var responseData = await response.stream.toBytes(); + var responseString = String.fromCharCodes(responseData); + // scannedText = responseString; + update(); + // Return the link received from the server + return responseString; + } @override void onInit() { // scanDocumentsByApi(); + // initializeCamera(0); sql.getAllData(TableName.faceDetectTimes).then((value) { - if (value.isEmpty || value == null) { + if (value.isEmpty) { print(value); times = 0; print(times); @@ -435,110 +531,7 @@ class ScanDocumentsByApi extends GetxController { super.onInit(); } } -// -// class PassportRecognizerController extends GetxController { -// @override -// void onInit() { -// scanText(); -// super.onInit(); -// } -// -// // The ImagePicker instance -// final ImagePicker _imagePicker = ImagePicker(); -// Map extractedData = {}; -// -// // The GoogleMlKit TextRecognizer instance -// final TextRecognizer _textRecognizer = TextRecognizer(); -// -// // The scanned text -// String? scannedText; -// String? jsonOutput; -// final List> lines = []; -// -// Map decode = {}; -// // Picks an image from the camera or gallery and extracts the text -// -// Future scanText() async { -// // Pick an image from the camera or gallery -// final XFile? image = -// await _imagePicker.pickImage(source: ImageSource.gallery); -// -// // If no image was picked, return -// if (image == null) { -// return; -// } -// -// // Convert the XFile object to an InputImage object -// final InputImage inputImage = InputImage.fromFile(File(image.path)); -// -// // Recognize the text in the image -// final RecognizedText recognizedText = -// await _textRecognizer.processImage(inputImage); -// scannedText = recognizedText.text; -// // Extract the scanned text line by line -// final List> lines = []; -// for (var i = 0; i < recognizedText.blocks.length; i++) { -// lines.add({ -// i.toString() + -// '_' + -// recognizedText.blocks[i].text.toString().split('\n')[0]: -// recognizedText.blocks[i].text, -// }); -// } -// // for (var i = 0; i < recognizedText.blocks.length; i++) { -// // final block = recognizedText.blocks[i]; -// for (final line in lines) { -// final key = line.keys.first; -// final value = line.values.first; -// if (line.values.contains('UNITED STATES OF')) { -// final title = line; -// extractedData['title'] = title; -// } -// if (line.values.contains('PASSPORT CARD')) { -// final passport = line; -// extractedData['passport'] = passport; -// } -// if (key == "7_Surname") { -// final nextItem = lines[lines.indexOf(line) + 1]; -// extractedData['surname'] = nextItem.values.first; -// } -// if (key == "6_Nationality") { -// var nationality = value.split('\n')[1]; -// extractedData['nationality'] = nationality; -// } -// if (key.contains('CARD')) { -// var passportCard = value; -// extractedData['passportCard'] = passportCard; -// } -// if (key.contains("9_Given")) { -// var givenNames = value.split('\n')[1]; -// extractedData['givenNames'] = givenNames; -// } -// if (key.contains("13_Date of Birth")) { -// final parts = value.split('\n'); -// if (parts.length > 1) { -// var dateOfBirth = parts[1]; -// extractedData['dateOfBirth'] = dateOfBirth; -// -// var sex = parts[0].split(' ')[1]; -// extractedData['sex'] = sex; -// } -// } -// -// // } -// } -// -// // Convert the list of lines to a JSON string -// jsonOutput = jsonEncode(extractedData); -// decode = jsonDecode(jsonOutput!); -// -// update(); -// print('jsonOutput------------------------------'); -// print(decode); -// // print(jsonEncode(lines)); -// } -// } -// + // class PassportDataExtractor extends GetxController { // @override // void onInit() { diff --git a/lib/main.dart b/lib/main.dart index 4936804..d7f1d0c 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -43,9 +43,6 @@ void main() async { List initializationTasks = [ FirebaseMessagesController().getNotificationSettings(), FirebaseMessagesController().getToken(), - // availableCameras(), - // FirebaseMessagesController().getTokens(), - // Add more initialization tasks here ]; // cameras = await availableCameras(); await Future.wait(initializationTasks); diff --git a/lib/views/auth/captin/ai_page.dart b/lib/views/auth/captin/ai_page.dart index 56c260f..5da3254 100644 --- a/lib/views/auth/captin/ai_page.dart +++ b/lib/views/auth/captin/ai_page.dart @@ -50,7 +50,7 @@ class AiPage extends StatelessWidget { children: [ Container( decoration: AppStyle.boxDecoration, - height: Get.height * .35, + height: Get.height * .4, child: Padding( padding: const EdgeInsets.all(5), child: scanDocumentsByApi.responseMap.isEmpty @@ -78,7 +78,7 @@ class AiPage extends StatelessWidget { CrossAxisAlignment.start, children: [ Text( - 'Name :${scanDocumentsByApi.responseMap['data']['ocr']['name'].toString()}', + 'Name :${scanDocumentsByApi.name}', style: AppStyle.subtitle, ), Row( @@ -87,7 +87,7 @@ class AiPage extends StatelessWidget { .spaceBetween, children: [ Text( - 'Drivers License Class: ${scanDocumentsByApi.responseMap['data']['ocr']['dlClass'].toString()}', + 'Drivers License Class: ${scanDocumentsByApi.licenseClass}', style: AppStyle.title, ), Image.memory( @@ -108,7 +108,7 @@ class AiPage extends StatelessWidget { .spaceBetween, children: [ Text( - 'Document Number: ${scanDocumentsByApi.responseMap['data']['ocr']['documentNumber'].toString()}', + 'Document Number: ${scanDocumentsByApi.documentNo}', style: AppStyle.title, ), Image.memory( @@ -118,7 +118,7 @@ class AiPage extends StatelessWidget { ), ]), Text( - 'Address: ${scanDocumentsByApi.responseMap['data']['ocr']['address'].toString()}', + 'Address: ${scanDocumentsByApi.address}', style: AppStyle.title, ), Row( @@ -127,21 +127,21 @@ class AiPage extends StatelessWidget { .spaceBetween, children: [ Text( - 'Height: ${scanDocumentsByApi.responseMap['data']['ocr']['height'].toString()}', + 'Height: ${scanDocumentsByApi.height}', style: AppStyle.subtitle, ), Text( - 'Postal Code: ${scanDocumentsByApi.responseMap['data']['ocr']['addressPostalCode'].toString()}', + 'Postal Code: ${scanDocumentsByApi.postalCode}', style: AppStyle.subtitle, ), Text( - 'Sex: ${scanDocumentsByApi.responseMap['data']['ocr']['sex'].toString()}', + 'Sex: ${scanDocumentsByApi.sex}', style: AppStyle.subtitle, ), ], ), Text( - 'Jurisdiction Code: ${scanDocumentsByApi.responseMap['data']['ocr']['addressJurisdictionCode'].toString()}', + 'Territorial Code: ${scanDocumentsByApi.stateCode}', style: AppStyle.subtitle, ), Row( @@ -150,7 +150,7 @@ class AiPage extends StatelessWidget { .spaceBetween, children: [ Text( - 'Expiry Date: ${scanDocumentsByApi.responseMap['data']['ocr']['dateOfExpiry'].toString()}', + 'Expiry Date: ${scanDocumentsByApi.expireDate}', style: DateTime.parse( scanDocumentsByApi .responseMap['data'] @@ -168,7 +168,7 @@ class AiPage extends StatelessWidget { .greenColor), ), Text( - 'Date of Birth: ${scanDocumentsByApi.responseMap['data']['ocr']['dateOfBirth'].toString()}', + 'Date of Birth: ${scanDocumentsByApi.dob}', style: AppStyle.title, ), ], @@ -207,7 +207,8 @@ class AiPage extends StatelessWidget { ) : const SizedBox(), MyElevatedButton( - title: 'title', + title: 'get sql data', + kolor: AppColor.yellowColor, onPressed: () { // sql.deleteAllData(TableName.faceDetectTimes); sql diff --git a/lib/views/auth/captin/camera_widgets/camera_lisence_page.dart b/lib/views/auth/captin/camera_widgets/camera_lisence_page.dart new file mode 100644 index 0000000..f0acfaf --- /dev/null +++ b/lib/views/auth/captin/camera_widgets/camera_lisence_page.dart @@ -0,0 +1,83 @@ +import 'package:camera/camera.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:ride/views/widgets/elevated_btn.dart'; + +import '../../../../constant/colors.dart'; +import '../../../../constant/style.dart'; +import '../../../../controller/functions/camer_controller.dart'; +import '../../../../controller/functions/ocr_controller.dart'; +import '../../../widgets/my_scafold.dart'; + +class CameraLisencePage extends StatelessWidget { + CameraLisencePage.CameraLicensePage({super.key}); + final CameraClassController cameraClassController = + Get.put(CameraClassController()); + + @override + Widget build(BuildContext context) { + return MyScafolld( + title: 'Scan Driver License'.tr, + body: [ + Column(children: [ + Text( + 'Please put your licence in these border'.tr, + style: AppStyle.title.copyWith(color: AppColor.greenColor), + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12), + child: GetBuilder( + builder: (cameraClassController) => + cameraClassController.isCameraInitialized + ? Stack( + children: [ + Container( + decoration: AppStyle.boxDecoration, + child: CameraPreview( + cameraClassController.cameraController, + ), + ), + Positioned( + top: Get.height * .1, + right: 5, + left: 5, + child: Container( + height: Get.width * 3 / 4, + width: Get.width * .9, + decoration: BoxDecoration( + // color: AppColor.blueColor, + border: Border.all( + color: AppColor.yellowColor, width: 2), + ), + ), + ), + ], + ) + : Container( + decoration: AppStyle.boxDecoration, + height: Get.width * 3 / 4, + width: Get.width, + child: Center( + child: Text( + 'Camera not initialized yet', + style: AppStyle.title, + ), + ), + ), + ), + ), + const SizedBox( + height: 20, + ), + MyElevatedButton( + title: 'Take Image'.tr, + onPressed: () { + ScanDocumentsByApi().scanDocumentsByApi(); + }, + ) + ]), + ], + isleading: true, + ); + } +} diff --git a/lib/views/auth/captin/car_license_page.dart b/lib/views/auth/captin/car_license_page.dart index 58dea7e..745d94e 100644 --- a/lib/views/auth/captin/car_license_page.dart +++ b/lib/views/auth/captin/car_license_page.dart @@ -1,5 +1,9 @@ +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:ride/controller/auth/captin/ml_google_doc.dart'; +import 'package:ride/controller/auth/captin/register_captin_controller.dart'; import 'package:ride/views/widgets/my_scafold.dart'; import '../../../controller/functions/ocr_controller.dart'; @@ -7,7 +11,10 @@ import '../../widgets/elevated_btn.dart'; class CarLicensePage extends StatelessWidget { CarLicensePage({super.key}); - ScanDocumentsByApi scanDocumentsByApi = Get.put(ScanDocumentsByApi()); + CarRegistrationRecognizerController carRegistrationRecognizerController = + Get.put(CarRegistrationRecognizerController()); + RegisterCaptinController registerCaptainController = + Get.put(RegisterCaptinController()); @override Widget build(BuildContext context) { @@ -20,11 +27,65 @@ class CarLicensePage extends StatelessWidget { right: Get.width * .2, child: MyElevatedButton( title: 'Take Picture Of ID Card'.tr, - onPressed: () { - scanDocumentsByApi.scanDocumentsByApi(); + onPressed: () async { + await carRegistrationRecognizerController.scanText(); + }, + )), + Positioned( + top: 50, + child: SizedBox( + height: Get.height * .7, + width: Get.width, + child: buildImageWithBoundingBoxes(), + ), + ), + Positioned( + bottom: 20, + left: Get.width * .2, + right: Get.width * .2, + child: MyElevatedButton( + title: 'Register'.tr, + onPressed: () async { + registerCaptainController.addLisence(); + registerCaptainController.register(); }, )), ], isleading: true); } } + +Widget buildImageWithBoundingBoxes() { + CarRegistrationRecognizerController carRegistrationRecognizerController = + Get.put(CarRegistrationRecognizerController()); + if (carRegistrationRecognizerController.image == null) { + return Text('No image selected'); + } else { + return Stack( + children: [ + Positioned( + // top: 50, + // right: 5, + // left: 5, + // bottom: 50, + child: Image.file( + File(carRegistrationRecognizerController.image!.path), + fit: BoxFit.fill, + )), + // for (var line + // in carRegistrationRecognizerController.extractedTextWithCoordinates) + // Positioned( + // left: line['boundingBox']['left'], + // top: line['boundingBox']['top'] - Get.width * 2, + // width: line['boundingBox']['width'], + // height: line['boundingBox']['height'], + // child: Container( + // decoration: BoxDecoration( + // border: Border.all(color: Colors.red, width: 2), + // ), + // ), + // ), + ], + ); + } +} diff --git a/lib/views/auth/captin/login_captin.dart b/lib/views/auth/captin/login_captin.dart index 218b540..db3f50a 100644 --- a/lib/views/auth/captin/login_captin.dart +++ b/lib/views/auth/captin/login_captin.dart @@ -8,6 +8,7 @@ import 'package:ride/constant/box_name.dart'; import 'package:ride/constant/colors.dart'; import 'package:ride/constant/info.dart'; import 'package:ride/constant/style.dart'; +import 'package:ride/constant/table_names.dart'; import 'package:ride/controller/auth/captin/login_captin_controller.dart'; import 'package:ride/main.dart'; import 'package:ride/views/auth/captin/register_captin.dart'; @@ -190,7 +191,7 @@ class LoginCaptin extends StatelessWidget { ), IconButton( onPressed: () { - box.remove(BoxName.agreeTerms); + sql.deleteAllData(TableName.faceDetectTimes); }, icon: const Icon( Icons.delete, diff --git a/lib/views/auth/captin/register_captin.dart b/lib/views/auth/captin/register_captin.dart index 2884378..bdc73e6 100644 --- a/lib/views/auth/captin/register_captin.dart +++ b/lib/views/auth/captin/register_captin.dart @@ -1,13 +1,11 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:ride/constant/style.dart'; import 'package:ride/controller/auth/captin/register_captin_controller.dart'; +import 'package:ride/views/auth/captin/car_license_page.dart'; import 'package:ride/views/widgets/elevated_btn.dart'; import 'package:ride/views/widgets/my_scafold.dart'; -import 'package:ride/views/widgets/mycircular.dart'; import '../../../constant/colors.dart'; -import 'ai_page.dart'; class RegisterCaptin extends StatelessWidget { const RegisterCaptin({super.key}); @@ -16,7 +14,7 @@ class RegisterCaptin extends StatelessWidget { Widget build(BuildContext context) { Get.put(RegisterCaptinController()); return MyScafolld( - title: 'Register Captin'.tr, + title: 'Register Captain'.tr, body: [ GetBuilder( builder: (controller) => Form( @@ -37,250 +35,232 @@ class RegisterCaptin extends StatelessWidget { child: Padding( padding: const EdgeInsets.all(16), child: Column(children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - SizedBox( - width: Get.width * .4, - child: TextFormField( - keyboardType: TextInputType.text, - controller: controller.firstNameController, - decoration: InputDecoration( - focusedBorder: OutlineInputBorder( - borderSide: const BorderSide( - color: AppColor.primaryColor, - width: 2.0, - ), - borderRadius: BorderRadius.circular(10), - ), - fillColor: AppColor.accentColor, - hoverColor: AppColor.accentColor, - focusColor: AppColor.accentColor, - border: const OutlineInputBorder( - borderRadius: BorderRadius.all( - Radius.circular(12))), - labelText: 'First name'.tr, - hintText: 'Enter your first name'.tr, + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // SizedBox( + // width: Get.width * .4, + // child: TextFormField( + // keyboardType: TextInputType.text, + // controller: controller.firstNameController, + // decoration: InputDecoration( + // focusedBorder: OutlineInputBorder( + // borderSide: const BorderSide( + // color: AppColor.primaryColor, + // width: 2.0, + // ), + // borderRadius: BorderRadius.circular(10), + // ), + // fillColor: AppColor.accentColor, + // hoverColor: AppColor.accentColor, + // focusColor: AppColor.accentColor, + // border: const OutlineInputBorder( + // borderRadius: BorderRadius.all( + // Radius.circular(12))), + // labelText: 'First name'.tr, + // hintText: 'Enter your first name'.tr, + // ), + // validator: (value) { + // if (value!.isEmpty) { + // return 'Please enter your first name.'.tr; + // } + // return null; + // }, + // ), + // ), + // SizedBox( + // width: Get.width * .4, + // child: TextFormField( + // keyboardType: TextInputType.text, + // controller: controller.lastNameController, + // decoration: InputDecoration( + // focusedBorder: OutlineInputBorder( + // borderSide: const BorderSide( + // color: AppColor.primaryColor, + // width: 2.0, + // ), + // borderRadius: BorderRadius.circular(10), + // ), + // focusColor: AppColor.accentColor, + // fillColor: AppColor.accentColor, + // border: const OutlineInputBorder( + // borderRadius: BorderRadius.all( + // Radius.circular(12))), + // labelText: 'Last name'.tr, + // hintText: 'Enter your last name'.tr, + // ), + // validator: (value) { + // if (value!.isEmpty) { + // return 'Please enter your last name.'.tr; + // } + // return null; + // }, + // ), + // ), + // ], + // ), + // const SizedBox( + // height: 15, + // ), + SizedBox( + width: Get.width * .8, + child: TextFormField( + keyboardType: TextInputType.emailAddress, + controller: controller.emailController, + decoration: InputDecoration( + focusedBorder: OutlineInputBorder( + borderSide: const BorderSide( + color: AppColor.primaryColor, + width: 2.0, ), - validator: (value) { - if (value!.isEmpty) { - return 'Please enter your first name.'.tr; - } - return null; - }, + borderRadius: BorderRadius.circular(10), ), + fillColor: AppColor.accentColor, + hoverColor: AppColor.accentColor, + focusColor: AppColor.accentColor, + border: const OutlineInputBorder( + borderRadius: + BorderRadius.all(Radius.circular(12))), + labelText: 'Email'.tr, + hintText: 'Enter your email address'.tr, ), - SizedBox( - width: Get.width * .4, - child: TextFormField( - keyboardType: TextInputType.text, - controller: controller.lastNameController, - decoration: InputDecoration( - focusedBorder: OutlineInputBorder( - borderSide: const BorderSide( - color: AppColor.primaryColor, - width: 2.0, - ), - borderRadius: BorderRadius.circular(10), - ), - focusColor: AppColor.accentColor, - fillColor: AppColor.accentColor, - border: const OutlineInputBorder( - borderRadius: BorderRadius.all( - Radius.circular(12))), - labelText: 'Last name'.tr, - hintText: 'Enter your last name'.tr, - ), - validator: (value) { - if (value!.isEmpty) { - return 'Please enter your last name.'.tr; - } - return null; - }, - ), - ), - ], - ), - const SizedBox( - height: 15, - ), - TextFormField( - keyboardType: TextInputType.emailAddress, - controller: controller.emailController, - decoration: InputDecoration( - focusedBorder: OutlineInputBorder( - borderSide: const BorderSide( - color: AppColor.primaryColor, - width: 2.0, - ), - borderRadius: BorderRadius.circular(10), - ), - fillColor: AppColor.accentColor, - hoverColor: AppColor.accentColor, - focusColor: AppColor.accentColor, - border: const OutlineInputBorder( - borderRadius: - BorderRadius.all(Radius.circular(12))), - labelText: 'Email'.tr, - hintText: 'Enter your email address'.tr, + validator: (value) { + if (value!.isEmpty || + (!value.contains('@') || + !value.contains('.'))) { + return 'Please enter Your Email.'.tr; + } + return null; + }, ), - validator: (value) { - if (value!.isEmpty || - (!value.contains('@') || - !value.contains('.'))) { - return 'Please enter Your Email.'.tr; - } - return null; - }, ), const SizedBox( height: 15, ), - TextFormField( - obscureText: true, - keyboardType: TextInputType.emailAddress, - controller: controller.passwordController, - decoration: InputDecoration( - focusedBorder: OutlineInputBorder( - borderSide: const BorderSide( - color: AppColor.primaryColor, - width: 2.0, + SizedBox( + width: Get.width * .8, + child: TextFormField( + obscureText: true, + keyboardType: TextInputType.emailAddress, + controller: controller.passwordController, + decoration: InputDecoration( + focusedBorder: OutlineInputBorder( + borderSide: const BorderSide( + color: AppColor.primaryColor, + width: 2.0, + ), + borderRadius: BorderRadius.circular(10), ), - borderRadius: BorderRadius.circular(10), + fillColor: AppColor.accentColor, + hoverColor: AppColor.accentColor, + focusColor: AppColor.accentColor, + border: const OutlineInputBorder( + borderRadius: + BorderRadius.all(Radius.circular(12))), + labelText: 'Password'.tr, + hintText: 'Enter your Password'.tr, ), - fillColor: AppColor.accentColor, - hoverColor: AppColor.accentColor, - focusColor: AppColor.accentColor, - border: const OutlineInputBorder( - borderRadius: - BorderRadius.all(Radius.circular(12))), - labelText: 'Password'.tr, - hintText: 'Enter your Password'.tr, + validator: (value) { + if (value!.isEmpty) { + return 'Please enter Your Password.'.tr; + } + if (value.length < 6) { + return 'Password must br at least 6 character.' + .tr; + } + return null; + }, ), - validator: (value) { - if (value!.isEmpty || (value.length > 6)) { - return 'Please enter Your Password.'.tr; - } - return null; - }, ), const SizedBox( height: 15, ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - SizedBox( - width: Get.width * .4, - child: TextFormField( - keyboardType: TextInputType.phone, - cursorColor: AppColor.accentColor, - controller: controller.phoneController, - decoration: InputDecoration( - focusedBorder: OutlineInputBorder( - borderSide: const BorderSide( - color: AppColor.primaryColor, - width: 2.0, - ), - borderRadius: BorderRadius.circular(10), - ), - focusColor: AppColor.accentColor, - fillColor: AppColor.accentColor, - border: const OutlineInputBorder( - borderRadius: BorderRadius.all( - Radius.circular(12))), - labelText: 'Phone'.tr, - hintText: 'Enter your phone number'.tr, + SizedBox( + width: Get.width * .8, + child: TextFormField( + keyboardType: TextInputType.phone, + cursorColor: AppColor.accentColor, + controller: controller.phoneController, + decoration: InputDecoration( + focusedBorder: OutlineInputBorder( + borderSide: const BorderSide( + color: AppColor.primaryColor, + width: 2.0, ), - validator: (value) { - if (value!.isEmpty || value.length != 10) { - return 'Please enter your phone number.'.tr; - } - return null; - }, + borderRadius: BorderRadius.circular(10), ), + focusColor: AppColor.accentColor, + fillColor: AppColor.accentColor, + border: const OutlineInputBorder( + borderRadius: + BorderRadius.all(Radius.circular(12))), + labelText: 'Phone'.tr, + hintText: 'Enter your phone number'.tr, ), - SizedBox( - width: Get.width * .4, - child: TextFormField( - keyboardType: TextInputType.text, - controller: controller.siteController, - decoration: InputDecoration( - focusedBorder: OutlineInputBorder( - borderSide: const BorderSide( - color: AppColor.primaryColor, - width: 2.0, - ), - borderRadius: BorderRadius.circular(10), - ), - focusColor: AppColor.accentColor, - fillColor: AppColor.accentColor, - border: const OutlineInputBorder( - borderRadius: BorderRadius.all( - Radius.circular(12))), - labelText: 'City'.tr, - hintText: 'Enter your City'.tr, - ), - validator: (value) { - if (value!.isEmpty) { - return 'Please enter your City.'.tr; - } - return null; - }, - ), - ), - ], + validator: (value) { + if (value!.isEmpty || value.length != 10) { + return 'Please enter your phone number.'.tr; + } + return null; + }, + ), ), const SizedBox( height: 15, ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - InkWell( - onTap: () => controller.getBirthDate(), - child: Container( - height: 50, - width: Get.width * .4, - decoration: BoxDecoration( - border: Border.all(), - borderRadius: BorderRadius.circular(13)), - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 20), - child: Text( - controller.birthDate, - style: AppStyle.title, - ), - ), - ), - ), - DropdownButton( - value: controller.gender, - items: [ - DropdownMenuItem( - value: 'Male', - child: Text('Male'.tr), - ), - DropdownMenuItem( - value: 'Female', - child: Text('Female'.tr), - ), - ], - onChanged: (value) { - controller.changeGender(value!); - }, - ) - ], - ), + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // InkWell( + // onTap: () => controller.getBirthDate(), + // child: Container( + // height: 50, + // width: Get.width * .4, + // decoration: BoxDecoration( + // border: Border.all(), + // borderRadius: BorderRadius.circular(13)), + // child: Padding( + // padding: const EdgeInsets.symmetric( + // horizontal: 20), + // child: Text( + // controller.birthDate, + // style: AppStyle.title, + // ), + // ), + // ), + // ), + // DropdownButton( + // value: controller.gender, + // items: [ + // DropdownMenuItem( + // value: 'Male', + // child: Text('Male'.tr), + // ), + // DropdownMenuItem( + // value: 'Female', + // child: Text('Female'.tr), + // ), + // ], + // onChanged: (value) { + // controller.changeGender(value!); + // }, + // ) + // ], + // ), MyElevatedButton( title: 'Next'.tr, - onPressed: () => Get.to(() => AiPage())), - controller.isloading - ? const MyCircularProgressIndicator() - : MyElevatedButton( - title: 'Register Captain'.tr, - onPressed: () => controller.register()) + onPressed: () => controller.nextToAIDetection()), + MyElevatedButton( + //todo remove it for test + title: 'Car registration ai '.tr, + kolor: AppColor.blueColor, + onPressed: () => Get.to(() => CarLicensePage())), + + // controller.isloading + // ? const MyCircularProgressIndicator() + // : MyElevatedButton( + // title: 'Register Captain'.tr, + // onPressed: () => controller.register()) ]), ), ), diff --git a/lib/views/auth/captin/verify_email.dart b/lib/views/auth/captin/verify_email.dart deleted file mode 100644 index e69de29..0000000 diff --git a/lib/views/auth/captin/verify_email_captain.dart b/lib/views/auth/captin/verify_email_captain.dart new file mode 100644 index 0000000..d3a7188 --- /dev/null +++ b/lib/views/auth/captin/verify_email_captain.dart @@ -0,0 +1,91 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:ride/constant/colors.dart'; +import 'package:ride/constant/style.dart'; +import 'package:ride/controller/auth/captin/register_captin_controller.dart'; +import 'package:ride/views/widgets/elevated_btn.dart'; +import 'package:ride/views/widgets/my_scafold.dart'; + +class VerifyEmailCaptainPage extends StatelessWidget { + VerifyEmailCaptainPage({super.key}); + RegisterCaptinController registerCaptinController = + Get.put(RegisterCaptinController()); + @override + Widget build(BuildContext context) { + return MyScafolld( + title: 'Verify Email For Captain'.tr, + body: [ + Positioned( + top: 10, + left: 20, + child: Text( + 'We sent 5 digit to your Email provided'.tr, + style: AppStyle.title.copyWith(fontSize: 20), + )), + GetBuilder( + builder: (controller) => Positioned( + top: 100, + left: 80, + right: 80, + child: Padding( + padding: const EdgeInsets.all(10), + child: Column( + children: [ + SizedBox( + width: 100, + child: TextField( + controller: registerCaptinController.verifyCode, + decoration: InputDecoration( + labelStyle: AppStyle.title, + border: const OutlineInputBorder(), + hintText: '5 digit'.tr, + counterStyle: AppStyle.number, + hintStyle: AppStyle.subtitle + .copyWith(color: AppColor.accentColor), + ), + maxLength: 5, + keyboardType: TextInputType.number, + ), + ), + const SizedBox( + height: 30, + ), + MyElevatedButton( + title: 'Send Verfication Code'.tr, + onPressed: () { + registerCaptinController.sendVerifications(); + }) + ], + ), + ), + )), + ], + isleading: true, + ); + } + + Padding verifyEmail() { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 10), + child: Container( + decoration: BoxDecoration( + border: Border.all( + color: AppColor.accentColor, + width: 2, + ), + borderRadius: BorderRadius.circular(8), + ), + child: const Padding( + padding: EdgeInsets.all(10), + child: SizedBox( + width: 20, + child: TextField( + maxLength: 1, + keyboardType: TextInputType.number, + ), + ), + ), + ), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index 9abb477..a529829 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -21,10 +21,10 @@ packages: dependency: transitive description: name: archive - sha256: "0c8368c9b3f0abbc193b9d6133649a614204b528982bebc7026372d61677ce3a" + sha256: "7b875fd4a20b165a3084bd2d210439b22ebc653f21cea4842729c0c30c82596b" url: "https://pub.dev" source: hosted - version: "3.3.7" + version: "3.4.9" args: dependency: transitive description: @@ -716,18 +716,18 @@ packages: dependency: transitive description: name: google_mlkit_commons - sha256: af63771903947d5523d9e991a939a4b8bf994f11661c9b9c8a71d7d3997115f8 + sha256: "42173a8ba89f386486cc5b8249e84da4a4b861daa70498373627d985eb418689" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.5.0" google_mlkit_text_recognition: dependency: "direct main" description: name: google_mlkit_text_recognition - sha256: "6dc31f02beb1cfd6818da4bf29bf4ae5f4f9e16422c1efd0b515ed0756d73b8e" + sha256: "588021c99536fdfb173eeecc4ee1b60ea4e0bd4be9787f52363c85346ae20364" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.10.0" google_polyline_algorithm: dependency: "direct main" description: @@ -809,13 +809,37 @@ packages: source: hosted version: "4.0.2" image: - dependency: transitive + dependency: "direct main" description: name: image - sha256: a72242c9a0ffb65d03de1b7113bc4e189686fc07c7147b8b41811d0dd0e0d9bf + sha256: "028f61960d56f26414eb616b48b04eb37d700cbe477b7fb09bf1d7ce57fd9271" url: "https://pub.dev" source: hosted - version: "4.0.17" + version: "4.1.3" + image_cropper: + dependency: "direct main" + description: + name: image_cropper + sha256: "542c3453109d16bcc388e43ae2276044d2cd6a6d20c68bdcff2c94ab9363ea15" + url: "https://pub.dev" + source: hosted + version: "4.0.1" + image_cropper_for_web: + dependency: transitive + description: + name: image_cropper_for_web + sha256: "89c936aa772a35b69ca67b78049ae9fa163a4fb8da2f6dee3893db8883fb49d2" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + image_cropper_platform_interface: + dependency: transitive + description: + name: image_cropper_platform_interface + sha256: b232175c132b2f7ede3e1f101652bcd635cb4079a77c6dded8e6d32e6578d685 + url: "https://pub.dev" + source: hosted + version: "4.0.0" image_picker: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 19602ce..117dfb3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -40,11 +40,13 @@ dependencies: flutter_font_icons: ^2.2.5 device_info_plus: ^9.1.0 image_picker: ^1.0.4 - google_mlkit_text_recognition: # ^0.10.0 + google_mlkit_text_recognition: ^0.10.0 flutter_stripe: ^9.5.0+1 camera: ^0.10.5+5 flutter_widget_from_html: ^0.14.6 local_auth: ^2.1.7 + image: ^4.1.3 + image_cropper: ^4.0.1