diff --git a/lib/constants/api_endpoints.dart b/lib/constants/api_endpoints.dart index 562473c9b6a68f0de9027df39c36e20a334ae086..991077aec7971ab224ecd1576b27d1d3c3dc81d1 100644 --- a/lib/constants/api_endpoints.dart +++ b/lib/constants/api_endpoints.dart @@ -3,4 +3,5 @@ class ApiUrl { static const getOtp = '$baseUrl/api/user/requestOTP'; static const validateOtp = '$baseUrl/api/signIn'; static const getAllApplications = '$baseUrl/api/forms/getAllApplications'; + static const submitInspection = '$baseUrl/api/forms/submitInspection'; } diff --git a/lib/constants/color_constants.dart b/lib/constants/color_constants.dart index 322278c81e908d0ef69793e15dfe66984bb7ad89..0537d1aa50442f4e1aa4b830303995b66915a94a 100644 --- a/lib/constants/color_constants.dart +++ b/lib/constants/color_constants.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; class AppColors { static const scaffoldBackground = Color.fromRGBO(240, 243, 244, 1); + static const fieldBackground = Color.fromARGB(255, 236, 237, 238); static const primaryBlue = Color.fromRGBO(4, 93, 173, 1); static const radioSelected = Color.fromRGBO(0, 116, 182, 0.2); static const primaryGreen = Color.fromRGBO(48, 105, 51, 1); diff --git a/lib/models/application_model.dart b/lib/models/application_model.dart index 15a433e458d8944ca7d194158ee2d922f1d0b701..7ff923d20ebec1ed02c13cff7de422c04ca7f29e 100644 --- a/lib/models/application_model.dart +++ b/lib/models/application_model.dart @@ -7,6 +7,7 @@ class Application { final String email; final String status; final Map dataObject; + final List inspectors; final String scheduledDate; final String createdDate; final String createdBy; @@ -18,6 +19,7 @@ class Application { required this.email, required this.status, required this.dataObject, + required this.inspectors, required this.scheduledDate, required this.createdDate, required this.createdBy, @@ -31,7 +33,8 @@ class Application { email: json['email'] ?? '', status: json['status'], dataObject: json['dataObject'], - scheduledDate: json['scheduledDate'] ?? '2022-02-15', + inspectors: json['inspection']['assignedTo'] ?? [], + scheduledDate: json['inspection']['scheduledDate'] ?? '', createdDate: json['createdDate'] != null ? DateFormat.yMMMEd().format(DateTime.parse(json['createdDate'])) : '', @@ -46,6 +49,7 @@ class Application { email, status, dataObject, + inspectors, scheduledDate, createdDate, createdBy diff --git a/lib/pages/application_details_page.dart b/lib/pages/application_details_page.dart index a08da6b7ad5e831661c7efd5a2dc02f0fafdab25..19650a5f06d5b69f81b960e509ceec9e9f2bf11f 100644 --- a/lib/pages/application_details_page.dart +++ b/lib/pages/application_details_page.dart @@ -1,17 +1,25 @@ import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; +import 'package:provider/provider.dart'; import 'package:smf_mobile/constants/color_constants.dart'; import 'package:smf_mobile/pages/inspection_summary.dart'; +import 'package:smf_mobile/pages/login_email_page.dart'; +import 'package:smf_mobile/repositories/application_repository.dart'; +import 'package:smf_mobile/util/helper.dart'; import 'package:smf_mobile/widgets/application_field.dart'; import 'package:smf_mobile/widgets/silverappbar_delegate.dart'; class ApplicationDetailsPage extends StatefulWidget { + final String applicationId; final String applicationTitle; final Map applicationFields; + final List applicationInspectors; const ApplicationDetailsPage({ Key? key, + required this.applicationId, required this.applicationTitle, required this.applicationFields, + required this.applicationInspectors, }) : super(key: key); @override @@ -23,17 +31,18 @@ class _ApplicationDetailsPageState extends State<ApplicationDetailsPage> final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); TabController? _tabController; int _activeTabIndex = 0; + final Map _data = {}; final List<String> _tabs = []; final List<Map> _fields = []; + String _errorMessage = ''; @override void initState() { super.initState(); widget.applicationFields.forEach((key, value) => _tabs.add(key)); - widget.applicationFields.forEach((key, value) => _fields.add(value)); - // print(_fields); _tabController = TabController(vsync: this, length: _tabs.length); _tabController!.addListener(_setActiveTabIndex); + _populateFields(); } void _setActiveTabIndex() { @@ -42,6 +51,66 @@ class _ApplicationDetailsPageState extends State<ApplicationDetailsPage> }); } + void _populateFields() { + Map updatedFields = {}; + widget.applicationFields.forEach((key, value) => { + updatedFields = {}, + value.forEach((childKey, childValue) => { + updatedFields[childKey] = { + childValue: {'value': 'Correct', 'comments': ''} + } + }), + _data[key] = updatedFields + }); + _data.forEach((key, value) => _fields.add(value)); + } + + void updateField(Map fieldData) { + _data[_data.keys.elementAt(_activeTabIndex)].forEach((key, value) => { + if (key == fieldData.keys.elementAt(0)) + { + setState(() { + _data[_data.keys.elementAt(_activeTabIndex)][key] = + fieldData[fieldData.keys.elementAt(0)]; + _fields[_activeTabIndex] = + _data[_data.keys.elementAt(_activeTabIndex)]; + }) + } + }); + } + + void _validateUser() async { + bool tokenExpired = await Helper.isTokenExpired(); + if (tokenExpired) { + Helper.toastMessage('Your session has expired.'); + Navigator.of(context).pushReplacement(MaterialPageRoute( + builder: (context) => const LoginEmailPage(), + )); + } + } + + Future<void> _submitInspection() async { + _validateUser(); + Map data = {'applicationId': widget.applicationId, 'dataObject': _data}; + try { + final responseCode = + await Provider.of<ApplicationRespository>(context, listen: false) + .submitInspection(data); + if (responseCode == 200) { + Navigator.of(context).pushReplacement(MaterialPageRoute( + builder: (context) => InspectionSummaryPage( + inspectors: widget.applicationInspectors))); + } else { + _errorMessage = + Provider.of<ApplicationRespository>(context, listen: false) + .errorMessage; + Helper.toastMessage(_errorMessage); + } + } catch (err) { + throw Exception(err); + } + } + @override void dispose() { _tabController?.dispose(); @@ -145,7 +214,8 @@ class _ApplicationDetailsPageState extends State<ApplicationDetailsPage> itemBuilder: (context, i) { return ApplicationField( fieldName: field.keys.elementAt(i), - fieldValue: field[field.keys.elementAt(i)], + fieldData: field[field.keys.elementAt(i)], + parentAction: updateField, ); }) ]))))), @@ -214,10 +284,7 @@ class _ApplicationDetailsPageState extends State<ApplicationDetailsPage> )) : TextButton( onPressed: () { - Navigator.of(context).pushReplacement( - MaterialPageRoute( - builder: (context) => - const InspectionSummaryPage())); + _submitInspection(); }, style: TextButton.styleFrom( // primary: Colors.white, diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index 2f85de3cd3feb84de9969544e44f79d261cc45bb..40b9626ef927c470bfde858cb8e9c754310c0d34 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -5,6 +5,7 @@ import 'package:provider/provider.dart'; import 'package:smf_mobile/constants/app_urls.dart'; import 'package:smf_mobile/constants/color_constants.dart'; import 'package:smf_mobile/models/application_model.dart'; +import 'package:smf_mobile/pages/login_email_page.dart'; import 'package:smf_mobile/pages/past_applications.dart'; import 'package:smf_mobile/repositories/application_repository.dart'; import 'package:smf_mobile/util/helper.dart'; @@ -28,10 +29,20 @@ class _HomePageState extends State<HomePage> { @override void initState() { super.initState(); - _getApplications(context); + } + + void _validateUser() async { + bool tokenExpired = await Helper.isTokenExpired(); + if (tokenExpired) { + Helper.toastMessage('Your session has expired.'); + Navigator.of(context).pushReplacement(MaterialPageRoute( + builder: (context) => const LoginEmailPage(), + )); + } } Future<dynamic> _getApplications(context) async { + _validateUser(); _allApplications = await Provider.of<ApplicationRespository>(context, listen: false) .getApplications(); @@ -42,26 +53,24 @@ class _HomePageState extends State<HomePage> { _upcomingApplications.clear(); _pastApplications.clear(); if (_allApplications.isNotEmpty) { + List temp = []; for (Application application in _allApplications) { - int days = Helper.getDateDiffence( - DateTime.now(), DateTime.parse(application.scheduledDate)); - if (days == 0) { - _pendingApplications.add(application); - } else if (days > 0) { - _pastApplications.add(application); - } else { - _upcomingApplications.add(application); + if (application.scheduledDate != '') { + temp = application.scheduledDate.split("-"); + temp = List.from(temp.reversed); + int days = Helper.getDateDiffence( + DateTime.now(), DateTime.parse(temp.join("-"))); + if (days == 0) { + _pendingApplications.add(application); + } else if (days > 0) { + _pastApplications.add(application); + } else { + _upcomingApplications.add(application); + } } } } else if (_errorMessage.isNotEmpty) { - Fluttertoast.showToast( - msg: _errorMessage, - toastLength: Toast.LENGTH_SHORT, - gravity: ToastGravity.TOP, - timeInSecForIosWeb: 2, - backgroundColor: Colors.red, - textColor: Colors.white, - fontSize: 16.0); + Helper.toastMessage(_errorMessage); } return _allApplications; } diff --git a/lib/pages/inspection_summary.dart b/lib/pages/inspection_summary.dart index 399c833cc92b72afabc47fbea3c8c4ff3e23d2e2..36f8f683766f9d9d734419ebab20b8216a25511c 100644 --- a/lib/pages/inspection_summary.dart +++ b/lib/pages/inspection_summary.dart @@ -2,31 +2,47 @@ import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:smf_mobile/constants/app_urls.dart'; import 'package:smf_mobile/constants/color_constants.dart'; -import 'package:smf_mobile/widgets/people_card.dart'; - +import 'package:smf_mobile/util/helper.dart'; import 'inspection_completed.dart'; -// import 'dart:developer' as developer; - class InspectionSummaryPage extends StatefulWidget { static const route = AppUrl.inspectionSummary; + final List inspectors; - const InspectionSummaryPage({Key? key}) : super(key: key); + const InspectionSummaryPage({Key? key, required this.inspectors}) + : super(key: key); @override _InspectionSummaryPageState createState() => _InspectionSummaryPageState(); } class _InspectionSummaryPageState extends State<InspectionSummaryPage> { - final List<String> _dropdownItems = [ - 'Select from the list', - 'Somorjit Phuritshabam', - 'Shoaib Muhammed' - ]; - String _selectedItem = 'Select from the list'; + // final List<String> _dropdownItems = [ + // 'Select from the list', + // 'Somorjit Phuritshabam', + // 'Shoaib Muhammed' + // ]; + final List<Map> _inspectors = []; + + bool _iAgree = false; @override void initState() { super.initState(); + _populateInspectors(); + } + + Future<void> _populateInspectors() async { + String userId = await Helper.getUser('id'); + for (var i = 0; i < widget.inspectors.length; i++) { + if (userId != widget.inspectors[i]['id']) { + _inspectors.add({ + 'name': + '${widget.inspectors[i]['firstName']} ${widget.inspectors[i]['lastName']}', + 'designation': 'Inspector', + 'isChecked': false + }); + } + } } @override @@ -196,7 +212,88 @@ class _InspectionSummaryPageState extends State<InspectionSummaryPage> { // ), // ), // ])), - for (int i = 0; i < 3; i++) const PeopleCard(), + for (int i = 0; i < _inspectors.length; i++) + Container( + color: Colors.white, + // width: double.infinity, + margin: const EdgeInsets.only( + left: 20, right: 20, bottom: 10.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + width: MediaQuery.of(context).size.width - 80, + decoration: BoxDecoration( + color: AppColors.black08, + borderRadius: BorderRadius.circular(4), + // border: Border.all(color: AppColors.black08), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(15.0), + child: Container( + height: 48, + width: 48, + decoration: const BoxDecoration( + color: AppColors.primaryGreen, + borderRadius: + BorderRadius.all(Radius.circular(4.0)), + ), + child: Center( + child: Text( + Helper.getInitials( + _inspectors[i]['name']), + style: GoogleFonts.lato( + color: Colors.white)), + ), + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + '${_inspectors[i]['name']}', + style: GoogleFonts.lato( + color: AppColors.black87, + fontSize: 14.0, + fontWeight: FontWeight.w700), + ), + Padding( + padding: + const EdgeInsets.only(top: 10.0), + child: Text( + '${_inspectors[i]['designation']}', + style: GoogleFonts.lato( + color: AppColors.black60, + fontSize: 14.0, + fontWeight: FontWeight.w400), + ), + ), + ], + ), + ], + ), + const Spacer(), + Checkbox( + value: _inspectors[i]['isChecked'], + activeColor: AppColors.primaryBlue, + onChanged: (newValue) { + setState(() { + _inspectors[i]['isChecked'] = newValue!; + }); + }), + ], + ), + ), + ], + ), + ), const Divider(), Container( padding: const EdgeInsets.only(left: 10, bottom: 20), @@ -204,12 +301,12 @@ class _InspectionSummaryPageState extends State<InspectionSummaryPage> { crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Checkbox( - value: true, + value: _iAgree, activeColor: AppColors.primaryBlue, onChanged: (newValue) { - // setState(() { - // checkBoxValue = newValue; - // });), + setState(() { + _iAgree = newValue!; + }); }), Container( padding: const EdgeInsets.only(top: 10), diff --git a/lib/pages/login_email_page.dart b/lib/pages/login_email_page.dart index cb3a6c5022d03365190bd0e5676940185621a27d..1a5b6c17ff76574f9b3ab3fe30d5243c67c6e159 100644 --- a/lib/pages/login_email_page.dart +++ b/lib/pages/login_email_page.dart @@ -7,6 +7,7 @@ import 'package:google_fonts/google_fonts.dart'; import 'package:smf_mobile/pages/login_otp_page.dart'; import 'package:smf_mobile/repositories/login_repository.dart'; import 'package:fluttertoast/fluttertoast.dart'; +import 'package:smf_mobile/util/helper.dart'; class LoginEmailPage extends StatefulWidget { static const route = AppUrl.loginEmailPage; @@ -29,14 +30,7 @@ class _LoginEmailPageState extends State<LoginEmailPage> { Future<void> _generateOtp() async { final email = _emailController.text; if (email == '') { - Fluttertoast.showToast( - msg: 'Please enter email.', - // toastLength: Toast.LENGTH_SHORT, - gravity: ToastGravity.CENTER, - timeInSecForIosWeb: 2, - backgroundColor: Colors.red, - textColor: Colors.white, - fontSize: 16.0); + Helper.toastMessage('Please enter email.'); return; } SystemChannels.textInput.invokeMethod('TextInput.hide'); @@ -51,15 +45,7 @@ class _LoginEmailPageState extends State<LoginEmailPage> { } else { _errorMessage = Provider.of<LoginRespository>(context, listen: false).errorMessage; - Fluttertoast.showToast( - msg: _errorMessage, - toastLength: Toast.LENGTH_SHORT, - gravity: ToastGravity.TOP, - timeInSecForIosWeb: 2, - backgroundColor: Colors.red, - textColor: Colors.white, - fontSize: 16.0); - // print(_errorMessage); + Helper.toastMessage(_errorMessage); } } catch (err) { throw Exception(err); diff --git a/lib/pages/login_otp_page.dart b/lib/pages/login_otp_page.dart index 0580ec67b1ac2f325483f9285ce494cb462f7aed..d7f4b9bb37b561dd95cdbed854eab4e2542a396d 100644 --- a/lib/pages/login_otp_page.dart +++ b/lib/pages/login_otp_page.dart @@ -9,6 +9,7 @@ import 'package:otp_text_field/otp_field.dart'; import 'package:otp_text_field/style.dart'; import 'package:smf_mobile/repositories/login_repository.dart'; import 'package:fluttertoast/fluttertoast.dart'; +import 'package:smf_mobile/util/helper.dart'; class LoginOtpPage extends StatefulWidget { static const route = AppUrl.loginOtpPage; @@ -30,18 +31,6 @@ class _LoginOtpPageState extends State<LoginOtpPage> { Future<void> _validateOtp() async { String otp = _otp; - // if (otp.length != 6) { - // Fluttertoast.showToast( - // msg: 'Please enter 6 digits.', - // // toastLength: Toast.LENGTH_SHORT, - // gravity: ToastGravity.CENTER, - // timeInSecForIosWeb: 2, - // backgroundColor: Colors.red, - // textColor: Colors.white, - // fontSize: 16.0); - // return; - // } - try { final responseCode = await Provider.of<LoginRespository>(context, listen: false) @@ -53,15 +42,7 @@ class _LoginOtpPageState extends State<LoginOtpPage> { } else { _errorMessage = Provider.of<LoginRespository>(context, listen: false).errorMessage; - Fluttertoast.showToast( - msg: _errorMessage, - toastLength: Toast.LENGTH_SHORT, - gravity: ToastGravity.TOP, - timeInSecForIosWeb: 2, - backgroundColor: Colors.red, - textColor: Colors.white, - fontSize: 16.0); - // print(_errorMessage); + Helper.toastMessage(_errorMessage); } } catch (err) { throw Exception(err); diff --git a/lib/repositories/application_repository.dart b/lib/repositories/application_repository.dart index 5b7107291e40dab0e6df9dcdc3d5b39093e6bebc..008bc112037eee4777a4790260c298167fd056c5 100644 --- a/lib/repositories/application_repository.dart +++ b/lib/repositories/application_repository.dart @@ -26,5 +26,20 @@ class ApplicationRespository with ChangeNotifier { return _applications; } + Future<dynamic> submitInspection(Map data) async { + try { + final request = await ApplicationService.submitInspection(data); + _data = json.decode(request.body); + print(_data); + } catch (_) { + return _; + } + + if (_data['statusInfo']['statusCode'] != 200) { + _errorMessage = _data['statusInfo']['errorMessage']; + } + return _data['statusInfo']['statusCode']; + } + String get errorMessage => _errorMessage; } diff --git a/lib/services/application_service.dart b/lib/services/application_service.dart index ad56fd7ee8aac7e17f1d88b0461834a0ff6b0401..c8fcc220ddda5d0761d274e4377108da970c56ab 100644 --- a/lib/services/application_service.dart +++ b/lib/services/application_service.dart @@ -3,8 +3,8 @@ import 'dart:io'; import 'package:http/http.dart' as http; import 'package:smf_mobile/constants/api_endpoints.dart'; import 'package:smf_mobile/services/base_service.dart'; -import 'package:flutter_secure_storage/flutter_secure_storage.dart'; -// import 'dart:developer' as developer; +import 'package:smf_mobile/util/helper.dart'; +import 'dart:developer' as developer; class ApplicationService extends BaseService { ApplicationService(HttpClient client) : super(client); @@ -12,13 +12,20 @@ class ApplicationService extends BaseService { static Future<dynamic> getApplications() async { Map requestData = {'searchObjects': []}; var body = json.encode(requestData); - Map<String, String> headers = BaseService.defaultHeaders; - const _storage = FlutterSecureStorage(); - var authToken = await _storage.read(key: 'authToken'); - headers['Authorization'] = '$authToken'; + Map<String, String> headers = await Helper.getHeaders(); + final response = await http.post(Uri.parse(ApiUrl.getAllApplications), - headers: BaseService.defaultHeaders, body: body); - // developer.log('$authToken'); + headers: headers, body: body); + // developer.log(response.body); + return response; + } + + static Future<dynamic> submitInspection(Map data) async { + var body = json.encode(data); + Map<String, String> headers = await Helper.getHeaders(); + // developer.log(ApiUrl.submitInspection); + final response = await http.post(Uri.parse(ApiUrl.submitInspection), + headers: headers, body: body); return response; } } diff --git a/lib/services/base_service.dart b/lib/services/base_service.dart index a4cbce9eed8ba1a8c02c8ee9f93256d9569b9f94..c476c4e8c062460375c3002606bd09bf1444f930 100644 --- a/lib/services/base_service.dart +++ b/lib/services/base_service.dart @@ -2,9 +2,5 @@ import 'dart:io'; abstract class BaseService { final HttpClient client; - static Map<String, String> defaultHeaders = { - 'Accept': 'application/json', - 'Content-Type': 'application/json; charset=utf-8', - }; const BaseService(this.client); } diff --git a/lib/services/login_service.dart b/lib/services/login_service.dart index 733b6c862150ff1b138a932151b60c8022d39aad..687d670108e0da3f5ae8ceb8d8e51fa4602ad757 100644 --- a/lib/services/login_service.dart +++ b/lib/services/login_service.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'package:http/http.dart' as http; import 'package:smf_mobile/constants/api_endpoints.dart'; import 'package:smf_mobile/services/base_service.dart'; +import 'package:smf_mobile/util/helper.dart'; // import 'dart:developer' as developer; class LoginService extends BaseService { @@ -13,16 +14,18 @@ class LoginService extends BaseService { 'username': username, }; var body = json.encode(requestData); - final response = await http.post(Uri.parse(ApiUrl.getOtp), - headers: BaseService.defaultHeaders, body: body); + Map<String, String> headers = await Helper.getHeaders(); + final response = + await http.post(Uri.parse(ApiUrl.getOtp), headers: headers, body: body); return response; } static Future<dynamic> validateOtp(String username, String otp) async { Map requestData = {'username': username, 'otp': otp}; var body = json.encode(requestData); + Map<String, String> headers = await Helper.getHeaders(); final response = await http.post(Uri.parse(ApiUrl.validateOtp), - headers: BaseService.defaultHeaders, body: body); + headers: headers, body: body); return response; } } diff --git a/lib/util/helper.dart b/lib/util/helper.dart index f2e37be45f02de5c934e1e2b0a4671609c4819d7..b7f08c6a7c48ec1f3e3e25ed34d43152cddf28ea 100644 --- a/lib/util/helper.dart +++ b/lib/util/helper.dart @@ -1,4 +1,9 @@ +import 'package:flutter/material.dart'; +import 'package:fluttertoast/fluttertoast.dart'; import 'package:jwt_decoder/jwt_decoder.dart'; +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; + +const _storage = FlutterSecureStorage(); class Helper { static String getInitials(String name) { @@ -13,6 +18,11 @@ class Helper { return shortCode; } + static Future<dynamic> getUser(String key) async { + var value = await _storage.read(key: key); + return value; + } + static int getDateDiffence(DateTime today, DateTime dateTimeCreatedAt) { String month = today.month < 10 ? '0${today.month}' : '${today.month}'; DateTime dateTimeNow = DateTime.parse('${today.year}-$month-${today.day}'); @@ -20,8 +30,33 @@ class Helper { return differenceInDays; } - static bool isTokenExpired(String token) { - bool isTokenExpired = JwtDecoder.isExpired(token); + static Future<bool> isTokenExpired() async { + bool isTokenExpired = true; + var authToken = await _storage.read(key: 'authToken'); + isTokenExpired = JwtDecoder.isExpired(authToken!); return isTokenExpired; } + + static Future<Map<String, String>> getHeaders() async { + Map<String, String> headers = { + 'Accept': 'application/json', + 'Content-Type': 'application/json; charset=utf-8', + }; + var authToken = await _storage.read(key: 'authToken'); + if (authToken != '' && authToken != null) { + headers['Authorization'] = authToken; + } + return headers; + } + + static toastMessage(String message) { + Fluttertoast.showToast( + msg: message, + toastLength: Toast.LENGTH_SHORT, + gravity: ToastGravity.TOP, + timeInSecForIosWeb: 2, + backgroundColor: Colors.red, + textColor: Colors.white, + fontSize: 16.0); + } } diff --git a/lib/widgets/application_card.dart b/lib/widgets/application_card.dart index 26f0cc061e823339bc0d8082686defee761fd3eb..33fcee6de206307dea31a5ae883ad6b7863a2e87 100644 --- a/lib/widgets/application_card.dart +++ b/lib/widgets/application_card.dart @@ -28,8 +28,10 @@ class _ApplicationCardState extends State<ApplicationCard> { context, MaterialPageRoute( builder: (context) => ApplicationDetailsPage( + applicationId: widget.application.applicationId, applicationTitle: widget.application.title, applicationFields: widget.application.dataObject, + applicationInspectors: widget.application.inspectors, )), ), child: Container( diff --git a/lib/widgets/application_field.dart b/lib/widgets/application_field.dart index cba41c0c8eac5332660f5245fffd39c0ac2239da..cfacc73ae5ef68da8ab32b9452ad46e173f3ae0b 100644 --- a/lib/widgets/application_field.dart +++ b/lib/widgets/application_field.dart @@ -5,24 +5,43 @@ import 'package:smf_mobile/constants/color_constants.dart'; class ApplicationField extends StatefulWidget { final String fieldName; - final String fieldValue; + final Map fieldData; + final ValueChanged<Map> parentAction; const ApplicationField({ Key? key, required this.fieldName, - required this.fieldValue, + required this.fieldData, + required this.parentAction, }) : super(key: key); @override _ApplicationFieldState createState() => _ApplicationFieldState(); } class _ApplicationFieldState extends State<ApplicationField> { - String _radioValue = 'Correct'; + late Map _data; + late String _radioValue; final List<String> _options = ['Correct', 'Incorrect']; final TextEditingController _noteController = TextEditingController(); @override void initState() { super.initState(); + _data = widget.fieldData[widget.fieldData.keys.elementAt(0)]; + _radioValue = _data[_data.keys.elementAt(0)]; + _noteController.text = _data[_data.keys.elementAt(1)]; + } + + _triggerUpdate() { + Map data = { + widget.fieldName: { + widget.fieldData.keys.elementAt(0): { + 'value': _radioValue, + 'comments': _noteController.text + } + } + }; + // print(data); + widget.parentAction(data); } Future _displayCommentDialog() { @@ -32,15 +51,16 @@ class _ApplicationFieldState extends State<ApplicationField> { return Stack( children: [ Align( - alignment: FractionalOffset.topCenter, - child: Container( + alignment: FractionalOffset.topCenter, + child: Container( margin: const EdgeInsets.only(top: 150), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(4)), height: 285, width: MediaQuery.of(context).size.width - 40, - child: Padding( + child: Material( + child: Padding( padding: const EdgeInsets.all(20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -128,6 +148,7 @@ class _ApplicationFieldState extends State<ApplicationField> { child: TextButton( onPressed: () { Navigator.of(context).pop(false); + _triggerUpdate(); }, style: TextButton.styleFrom( // primary: Colors.white, @@ -156,7 +177,7 @@ class _ApplicationFieldState extends State<ApplicationField> { ], ), )), - ), + )), ], ); })); @@ -164,7 +185,10 @@ class _ApplicationFieldState extends State<ApplicationField> { @override Widget build(BuildContext context) { - // print(widget.field); + // if (_data != widget.fieldData[widget.fieldData.keys.elementAt(0)]) { + // _radioValue = _data[_data.keys.elementAt(0)]; + // _noteController.text = _data[_data.keys.elementAt(1)]; + // } return SingleChildScrollView( reverse: true, child: Container( @@ -212,7 +236,7 @@ class _ApplicationFieldState extends State<ApplicationField> { border: Border.all(color: AppColors.black16), ), child: Text( - widget.fieldValue, + widget.fieldData.keys.elementAt(0), style: GoogleFonts.lato( color: AppColors.black87, fontSize: 14.0, @@ -231,7 +255,7 @@ class _ApplicationFieldState extends State<ApplicationField> { borderRadius: BorderRadius.only( bottomLeft: Radius.circular(4), bottomRight: Radius.circular(4)), - color: AppColors.scaffoldBackground, + color: AppColors.fieldBackground, boxShadow: [ BoxShadow( color: AppColors.black16, @@ -263,54 +287,68 @@ class _ApplicationFieldState extends State<ApplicationField> { // alignment: MainAxisAlignment.start, children: <Widget>[ for (int i = 0; i < _options.length; i++) - Container( - padding: const EdgeInsets.only( - right: 15), - margin: const EdgeInsets.only( - right: 15), - decoration: BoxDecoration( - color: _radioValue == _options[i] - ? AppColors.radioSelected - : Colors.transparent, - borderRadius: - const BorderRadius.all( - Radius.circular(4.0)), - border: Border.all( - color: - _radioValue == _options[i] + InkWell( + onTap: () { + setState(() { + _radioValue = _options[i]; + }); + if (_options[i] == 'Incorrect') { + _displayCommentDialog(); + } + _triggerUpdate(); + }, + child: Container( + padding: const EdgeInsets.only( + right: 15), + margin: const EdgeInsets.only( + right: 15), + decoration: BoxDecoration( + color: _radioValue == + _options[i] + ? AppColors.radioSelected + : Colors.transparent, + borderRadius: + const BorderRadius.all( + Radius.circular(4.0)), + border: Border.all( + color: _radioValue == + _options[i] ? AppColors.primaryBlue : AppColors.black16, - ), - ), - child: Row(children: [ - Radio( - value: _options[i], - groupValue: _radioValue, - activeColor: - AppColors.primaryBlue, - materialTapTargetSize: - MaterialTapTargetSize - .shrinkWrap, - onChanged: (val) { - setState(() { - _radioValue = _options[i]; - }); - if (_options[i] == - 'Incorrect') { - _displayCommentDialog(); - } - }, - ), - Text( - _options[i], - style: GoogleFonts.lato( - color: AppColors.black87, - fontWeight: FontWeight.w400, - fontSize: 14.0, - letterSpacing: 0.25, + ), ), - ), - ])), + child: Row(children: [ + Radio( + value: _options[i], + groupValue: _radioValue, + activeColor: + AppColors.primaryBlue, + materialTapTargetSize: + MaterialTapTargetSize + .shrinkWrap, + onChanged: (val) { + setState(() { + _radioValue = + _options[i]; + }); + _triggerUpdate(); + if (_options[i] == + 'Incorrect') { + _displayCommentDialog(); + } + }, + ), + Text( + _options[i], + style: GoogleFonts.lato( + color: AppColors.black87, + fontWeight: + FontWeight.w400, + fontSize: 14.0, + letterSpacing: 0.25, + ), + ), + ]))), const Spacer(), Padding( padding: const EdgeInsets.only(left: 0), diff --git a/lib/widgets/people_card.dart b/lib/widgets/people_card.dart deleted file mode 100644 index e29922cf5c2d3abb32869b9e0f4dbf6b8e039cff..0000000000000000000000000000000000000000 --- a/lib/widgets/people_card.dart +++ /dev/null @@ -1,76 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:google_fonts/google_fonts.dart'; -import 'package:smf_mobile/constants/color_constants.dart'; - -class PeopleCard extends StatelessWidget { - const PeopleCard({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - color: Colors.white, - // width: double.infinity, - margin: const EdgeInsets.only(left: 20, right: 20, bottom: 10.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - width: MediaQuery.of(context).size.width - 80, - decoration: BoxDecoration( - color: AppColors.black08, - borderRadius: BorderRadius.circular(4), - // border: Border.all(color: AppColors.black08), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(15.0), - child: Container( - height: 48, - width: 48, - decoration: const BoxDecoration( - color: AppColors.primaryGreen, - borderRadius: BorderRadius.all(Radius.circular(4.0)), - ), - child: Center( - child: Text('SM', - style: GoogleFonts.lato(color: Colors.white)), - ), - ), - ), - Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Shoaib Muhammed', - style: GoogleFonts.lato( - color: AppColors.black87, - fontSize: 14.0, - fontWeight: FontWeight.w700), - ), - Padding( - padding: const EdgeInsets.only(top: 10.0), - child: Text( - 'Designation', - style: GoogleFonts.lato( - color: AppColors.black60, - fontSize: 14.0, - fontWeight: FontWeight.w400), - ), - ), - ], - ), - ], - ), - ], - ), - ), - ], - ), - ); - } -}